2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-26 21:13:13 +00:00
This commit is contained in:
2019-11-10 12:41:31 +03:00
parent 8d06fd05ad
commit 5e87ea5247
41 changed files with 2076 additions and 431 deletions

View File

@ -12,6 +12,7 @@ using Esiur.Security.Permissions;
using Esiur.Resource.Template;
using Esiur.Security.Authority;
using Esiur.Proxy;
using Esiur.Core;
namespace Esiur.Resource
{
@ -19,16 +20,17 @@ namespace Esiur.Resource
{
string name;
AutoList<IResource, Instance> children;// = new AutoList<IResource, Instance>();
IResource resource;
//IQueryable<IResource> children;//
//AutoList<IResource, Instance> children;// = new AutoList<IResource, Instance>();
WeakReference<IResource> resource;
IStore store;
AutoList<IResource, Instance> parents;// = new AutoList<IResource>();
//AutoList<IResource, Instance> parents;// = new AutoList<IResource>();
//bool inherit;
ResourceTemplate template;
AutoList<IPermissionsManager, Instance> managers;// = new AutoList<IPermissionManager, Instance>();
public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue);
//public delegate void ResourceEventOccurredEvent(IResource resource, string eventName, string[] users, DistributedConnection[] connections, object[] args);
@ -40,6 +42,8 @@ namespace Esiur.Resource
public event ResourceEventOccurredEvent ResourceEventOccurred;
public event ResourceDestroyedEvent ResourceDestroyed;
bool loading = false;
KeyList<string, object> attributes;
List<ulong> ages = new List<ulong>();
@ -90,7 +94,7 @@ namespace Esiur.Resource
attributes = clone.ToArray();// this.attributes.Keys.ToList().Add("managers");
}
foreach(var attr in attributes)
foreach (var attr in attributes)
{
if (attr == "name")
st["name"] = this.name;
@ -109,15 +113,15 @@ namespace Esiur.Resource
}
else if (attr == "parents")
{
st["parents"] = parents.ToArray();
//st["parents"] = parents.ToArray();
}
else if (attr == "children")
{
st["children"] = children.ToArray();
//st["children"] = children.ToArray();
}
else if (attr == "childrenCount")
{
st["childrenCount"] = children.Count;
//st["childrenCount"] = children.Count;
}
else if (attr == "type")
{
@ -131,7 +135,7 @@ namespace Esiur.Resource
}
public bool SetAttributes(Structure attributes, bool clearAttributes = false)
{
{
try
{
@ -155,8 +159,13 @@ namespace Esiur.Resource
{
var settings = m["settings"] as Structure;
var manager = Activator.CreateInstance(type) as IPermissionsManager;
manager.Initialize(settings, this.resource);
this.managers.Add(manager);
IResource res;
if (this.resource.TryGetTarget(out res))
{
manager.Initialize(settings, res);
this.managers.Add(manager);
}
}
else
return false;
@ -166,7 +175,7 @@ namespace Esiur.Resource
{
this.attributes[attr.Key] = attr.Value;
}
}
catch
{
@ -175,7 +184,7 @@ namespace Esiur.Resource
return true;
}
/*
public Structure GetAttributes()
{
@ -256,7 +265,7 @@ namespace Esiur.Resource
return DateTime.MinValue;
}
/// <summary>
/// Load property value (used by stores)
/// </summary>
@ -266,13 +275,19 @@ namespace Esiur.Resource
/// <returns></returns>
public bool LoadProperty(string name, ulong age, DateTime modificationDate, object value)
{
IResource res;
if (!resource.TryGetTarget(out res))
return false;
var pt = template.GetPropertyTemplateByName(name);
if (pt == null)
return false;
/*
#if NETSTANDARD1_5
#if NETSTANDARD
var pi = resource.GetType().GetTypeInfo().GetProperty(name, new[] { resource.GetType() });
#else
var pi = resource.GetType().GetProperty(pt.Name);
@ -282,18 +297,25 @@ namespace Esiur.Resource
if (pt.Info.PropertyType == typeof(DistributedPropertyContext))
return false;
try
if (pt.Info.CanWrite)
{
if (pt.Info.CanWrite)
pt.Info.SetValue(resource, DC.CastConvert(value, pt.Info.PropertyType));
}
catch(Exception ex)
{
//Console.WriteLine(resource.ToString() + " " + name);
Global.Log(ex);
try
{
loading = true;
pt.Info.SetValue(res, DC.CastConvert(value, pt.Info.PropertyType));
}
catch (Exception ex)
{
//Console.WriteLine(resource.ToString() + " " + name);
Global.Log(ex);
}
loading = false;
}
SetAge(pt.Index, age);
SetModificationDate(pt.Index, modificationDate);
@ -359,16 +381,19 @@ namespace Esiur.Resource
foreach (var pt in template.Properties)
{
/*
#if NETSTANDARD1_5
#if NETSTANDARD
var pi = resource.GetType().GetTypeInfo().GetProperty(pt.Name);
#else
var pi = resource.GetType().GetProperty(pt.Name);
#endif
*/
var rt = pt.Info.GetValue(resource, null);
props.Add(new PropertyValue(rt, ages[pt.Index], modificationDates[pt.Index]));
IResource res;
if (resource.TryGetTarget(out res))
{
var rt = pt.Info.GetValue(res, null);
props.Add(new PropertyValue(rt, ages[pt.Index], modificationDates[pt.Index]));
}
}
return props.ToArray();
@ -446,7 +471,7 @@ namespace Esiur.Resource
/// <returns></returns>
public bool IsStorable()
{
#if NETSTANDARD1_5
#if NETSTANDARD
var attrs = resource.GetType().GetTypeInfo().GetCustomAttributes(typeof(Storable), true).ToArray();
#else
var attrs = resource.GetType().GetCustomAttributes(typeof(Storable), true);
@ -458,22 +483,27 @@ namespace Esiur.Resource
internal void EmitModification(PropertyTemplate pt, object value)
{
instanceAge++;
var now = DateTime.UtcNow;
ages[pt.Index] = instanceAge;
modificationDates[pt.Index] = now;
if (pt.Storage == StorageMode.NonVolatile)
IResource res;
if (this.resource.TryGetTarget(out res))
{
store.Modify(resource, pt.Name, value, ages[pt.Index], now);
}
else if (pt.Storage == StorageMode.Recordable)
{
store.Record(resource, pt.Name, value, ages[pt.Index], now);
}
instanceAge++;
var now = DateTime.UtcNow;
ResourceModified?.Invoke(resource, pt.Name, value);
ages[pt.Index] = instanceAge;
modificationDates[pt.Index] = now;
if (pt.Storage == StorageMode.NonVolatile)
{
store.Modify(res, pt.Name, value, ages[pt.Index], now);
}
else if (pt.Storage == StorageMode.Recordable)
{
store.Record(res, pt.Name, value, ages[pt.Index], now);
}
ResourceModified?.Invoke(res, pt.Name, value);
}
}
/// <summary>
@ -484,6 +514,9 @@ namespace Esiur.Resource
/// <param name="oldValue"></param>
public void Modified([CallerMemberName] string propertyName = "")
{
if (loading)
return;
object value;
if (GetPropertyValue(propertyName, out value))
{
@ -496,7 +529,12 @@ namespace Esiur.Resource
internal void EmitResourceEvent(object issuer, Session[] receivers, string name, object[] args)
{
ResourceEventOccurred?.Invoke(resource, issuer, receivers, name, args);
IResource res;
if (this.resource.TryGetTarget(out res))
{
ResourceEventOccurred?.Invoke(res, issuer, receivers, name, args);
}
}
/// <summary>
@ -508,7 +546,7 @@ namespace Esiur.Resource
public bool GetPropertyValue(string name, out object value)
{
/*
#if NETSTANDARD1_5
#if NETSTANDARD
PropertyInfo pi = resource.GetType().GetTypeInfo().GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
#else
@ -521,7 +559,7 @@ namespace Esiur.Resource
if (pt != null && pt.Info != null)
{
/*
#if NETSTANDARD1_5
#if NETSTANDARD
object[] ca = pi.GetCustomAttributes(typeof(ResourceProperty), false).ToArray();
#else
@ -537,7 +575,15 @@ namespace Esiur.Resource
}
*/
value = pt.Info.GetValue(resource, null);
IResource res;
if (resource.TryGetTarget(out res))
value = pt.Info.GetValue(res, null);
else
{
value = null;
return false;
}
return true;
}
@ -556,10 +602,7 @@ namespace Esiur.Resource
/// <summary>
/// List of parents.
/// </summary>
public AutoList<IResource, Instance> Parents
{
get { return parents; }
}
//public AutoList<IResource, Instance> Parents => parents;
/// <summary>
/// Store responsible for creating and keeping the resource.
@ -572,15 +615,54 @@ namespace Esiur.Resource
/// <summary>
/// List of children.
/// </summary>
public AutoList<IResource, Instance> Children
{
get { return children; }
}
// public AutoList<IResource, Instance> Children => children;
/// <summary>
/// The unique and permanent link to the resource.
/// </summary>
public string Link
{
get
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
if (res == res.Instance.store)
return name; // root store
else
return store.Link(res);
}
else
return null;
}
}
public AsyncBag<T> Children<T>(string name = null) where T : IResource
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
//if (!(store is null))
return store.Children<T>(res, name);
//else
// return (res as IStore).Children<T>(res, name);
}
else
return new AsyncBag<T>(null);
}
public AsyncBag<T> Parents<T>(string name = null) where T : IResource
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
return store.Parents<T>(res, name);
}
else
return new AsyncBag<T>(null);
}
/*
{
get
{
@ -607,6 +689,8 @@ namespace Esiur.Resource
}
}
}
*
*/
/// <summary>
/// Instance name.
@ -623,7 +707,16 @@ namespace Esiur.Resource
/// </summary>
public IResource Resource
{
get { return resource; }
get
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
return res;
}
else
return null;
}
}
/// <summary>
@ -658,11 +751,15 @@ namespace Esiur.Resource
/// <returns>Ruling.</returns>
public Ruling Applicable(Session session, ActionType action, MemberTemplate member, object inquirer = null)
{
foreach (IPermissionsManager manager in managers)
IResource res;
if (this.resource.TryGetTarget(out res))
{
var r = manager.Applicable(this.resource, session, action, member, inquirer);
if (r != Ruling.DontCare)
return r;
foreach (IPermissionsManager manager in managers)
{
var r = manager.Applicable(res, session, action, member, inquirer);
if (r != Ruling.DontCare)
return r;
}
}
return Ruling.DontCare;
@ -684,19 +781,19 @@ namespace Esiur.Resource
public Instance(uint id, string name, IResource resource, IStore store, ResourceTemplate customTemplate = null, ulong age = 0)
{
this.store = store;
this.resource = resource;
this.resource = new WeakReference<IResource>(resource);
this.id = id;
this.name = name;
this.instanceAge = age;
this.attributes = new KeyList<string, object>(this);
children = new AutoList<IResource, Instance>(this);
parents = new AutoList<IResource, Instance>(this);
//children = new AutoList<IResource, Instance>(this);
//parents = new AutoList<IResource, Instance>(this);
managers = new AutoList<IPermissionsManager, Instance>(this);
children.OnAdd += Children_OnAdd;
children.OnRemoved += Children_OnRemoved;
parents.OnAdd += Parents_OnAdd;
parents.OnRemoved += Parents_OnRemoved;
//children.OnAdd += Children_OnAdd;
//children.OnRemoved += Children_OnRemoved;
//parents.OnAdd += Parents_OnAdd;
//parents.OnRemoved += Parents_OnRemoved;
resource.OnDestroy += Resource_OnDestroy;
@ -715,7 +812,7 @@ namespace Esiur.Resource
// connect events
Type t = ResourceProxy.GetBaseType(resource);
#if NETSTANDARD1_5
#if NETSTANDARD
var events = t.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
#else
@ -783,7 +880,12 @@ namespace Esiur.Resource
}
}
private void Children_OnRemoved(Instance parent, IResource value)
//IQueryable<IResource> Children => store.GetChildren(this);
/*
* private void Children_OnRemoved(Instance parent, IResource value)
{
value.Instance.parents.Remove(resource);
}
@ -804,7 +906,7 @@ namespace Esiur.Resource
if (!value.Instance.children.Contains(resource))
value.Instance.children.Add(resource);
}
*/
private void Resource_OnDestroy(object sender)
{