csharp-sdk-upm/Storage/Source/Internal/Utilities/AVObjectExtensions.cs

226 lines
7.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Linq;
using System.Globalization;
using System.ComponentModel;
using System.Collections;
namespace LeanCloud.Storage.Internal
{
/// <summary>
/// So here's the deal. We have a lot of internal APIs for AVObject, AVUser, etc.
///
/// These cannot be 'internal' anymore if we are fully modularizing things out, because
/// they are no longer a part of the same library, especially as we create things like
/// Installation inside push library.
///
/// So this class contains a bunch of extension methods that can live inside another
/// namespace, which 'wrap' the intenral APIs that already exist.
/// </summary>
public static class AVObjectExtensions
{
public static T FromState<T>(IObjectState state, string defaultClassName) where T : AVObject
{
return AVObject.FromState<T>(state, defaultClassName);
}
public static IObjectState GetState(this AVObject obj)
{
return obj.State;
}
public static void HandleFetchResult(this AVObject obj, IObjectState serverState)
{
obj.HandleFetchResult(serverState);
}
public static IDictionary<string, IAVFieldOperation> GetCurrentOperations(this AVObject obj)
{
return obj.CurrentOperations;
}
public static IDictionary<string, object> Encode(this AVObject obj)
{
return PointerOrLocalIdEncoder.Instance.EncodeAVObject(obj, false);
}
public static IEnumerable<object> DeepTraversal(object root, bool traverseAVObjects = false, bool yieldRoot = false)
{
return AVObject.DeepTraversal(root, traverseAVObjects, yieldRoot);
}
public static void SetIfDifferent<T>(this AVObject obj, string key, T value)
{
obj.SetIfDifferent<T>(key, value);
}
public static IDictionary<string, object> ServerDataToJSONObjectForSerialization(this AVObject obj)
{
return obj.ServerDataToJSONObjectForSerialization();
}
public static void Set(this AVObject obj, string key, object value)
{
obj.Set(key, value);
}
public static void DisableHooks(this AVObject obj, IEnumerable<string> hookKeys)
{
obj.Set("__ignore_hooks", hookKeys);
}
public static void DisableHook(this AVObject obj, string hookKey)
{
var newList = new List<string>();
if (obj.ContainsKey("__ignore_hooks"))
{
var hookKeys = obj.Get<IEnumerable<string>>("__ignore_hooks");
newList = hookKeys.ToList();
}
newList.Add(hookKey);
obj.DisableHooks(newList);
}
public static void DisableAfterHook(this AVObject obj)
{
obj.DisableAfterSave();
obj.DisableAfterUpdate();
obj.DisableAfterDelete();
}
public static void DisableBeforeHook(this AVObject obj)
{
obj.DisableBeforeSave();
obj.DisableBeforeDelete();
obj.DisableBeforeUpdate();
}
public static void DisableBeforeSave(this AVObject obj)
{
obj.DisableHook("beforeSave");
}
public static void DisableAfterSave(this AVObject obj)
{
obj.DisableHook("afterSave");
}
public static void DisableBeforeUpdate(this AVObject obj)
{
obj.DisableHook("beforeUpdate");
}
public static void DisableAfterUpdate(this AVObject obj)
{
obj.DisableHook("afterUpdate");
}
public static void DisableBeforeDelete(this AVObject obj)
{
obj.DisableHook("beforeDelete");
}
public static void DisableAfterDelete(this AVObject obj)
{
obj.DisableHook("afterDelete");
}
#region on property updated or changed or collection updated
/// <summary>
/// On the property changed.
/// </summary>
/// <param name="avObj">Av object.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="handler">Handler.</param>
public static void OnPropertyChanged(this AVObject avObj, string propertyName, PropertyChangedEventHandler handler)
{
avObj.PropertyChanged += (sender, e) =>
{
if (e.PropertyName == propertyName)
{
handler(sender, e);
}
};
}
/// <summary>
/// On the property updated.
/// </summary>
/// <param name="avObj">Av object.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="handler">Handler.</param>
public static void OnPropertyUpdated(this AVObject avObj, string propertyName, PropertyUpdatedEventHandler handler)
{
avObj.PropertyUpdated += (sender, e) =>
{
if (e.PropertyName == propertyName)
{
handler(sender, e);
}
};
}
/// <summary>
/// On the property updated.
/// </summary>
/// <param name="avObj">Av object.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="handler">Handler.</param>
public static void OnPropertyUpdated(this AVObject avObj, string propertyName, Action<object, object> handler)
{
avObj.OnPropertyUpdated(propertyName,(object sender, PropertyUpdatedEventArgs e) =>
{
handler(e.OldValue, e.NewValue);
});
}
/// <summary>
/// On the collection property updated.
/// </summary>
/// <param name="avObj">Av object.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="handler">Handler.</param>
public static void OnCollectionPropertyUpdated(this AVObject avObj, string propertyName, CollectionPropertyUpdatedEventHandler handler)
{
avObj.CollectionPropertyUpdated += (sender, e) =>
{
if (e.PropertyName == propertyName)
{
handler(sender, e);
}
};
}
/// <summary>
/// On the collection property added.
/// </summary>
/// <param name="avObj">Av object.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="handler">Handler.</param>
public static void OnCollectionPropertyAdded(this AVObject avObj, string propertyName, Action<IEnumerable> handler)
{
avObj.OnCollectionPropertyUpdated(propertyName, (sender, e) =>
{
if (e.CollectionAction == NotifyCollectionUpdatedAction.Add)
{
handler(e.NewValues);
}
});
}
/// <summary>
/// On the collection property removed.
/// </summary>
/// <param name="avObj">Av object.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="handler">Handler.</param>
public static void OnCollectionPropertyRemoved(this AVObject avObj, string propertyName, Action<IEnumerable> handler)
{
avObj.OnCollectionPropertyUpdated(propertyName, (sender, e) =>
{
if (e.CollectionAction == NotifyCollectionUpdatedAction.Remove)
{
handler(e.NewValues);
}
});
}
#endregion
}
}