2
0
mirror of https://github.com/esiur/esiur-dart.git synced 2025-05-06 12:02:57 +00:00
This commit is contained in:
Ahmed Zamil 2021-02-20 00:10:06 +03:00
parent 4c36f591da
commit cb8e6d5430
9 changed files with 637 additions and 681 deletions

View File

@ -1,27 +1,24 @@
import 'ExceptionCode.dart'; import 'ExceptionCode.dart';
import 'ErrorType.dart'; import 'ErrorType.dart';
class AsyncException implements Exception class AsyncException implements Exception {
{
final ErrorType type; final ErrorType type;
final int code; final int code;
final String message; final String message;
AsyncException(this.type, this.code, this.message) AsyncException(this.type, this.code, this.message) {}
{
} static toAsyncException(Exception ex) {
return ex is AsyncException
static toAsyncException(Exception ex) ? ex
{
return ex is AsyncException ? ex
: new AsyncException(ErrorType.Exception, 0, ex.toString()); : new AsyncException(ErrorType.Exception, 0, ex.toString());
} }
String errMsg() { String errMsg() {
if (type == ErrorType.Management) if (type == ErrorType.Management)
return ExceptionCode.values.elementAt(code).toString() + ": " + (message ?? ""); return ExceptionCode.values.elementAt(code).toString() +
": " +
(message ?? "");
else else
return code.toString() + ": " + message; return code.toString() + ": " + message;
} }

View File

@ -89,6 +89,10 @@ class AsyncReply<T> implements Future<T>
{ {
_errorCallbacks.add((ex)=>onError()); _errorCallbacks.add((ex)=>onError());
} }
else if (onError is Function(Object, StackTrace))
{
_errorCallbacks.add((ex)=>onError(ex, null));
}
} }
@ -169,10 +173,17 @@ class AsyncReply<T> implements Future<T>
if (_resultReady) if (_resultReady)
return; return;
if (exception is AsyncException)
_exception = exception;
else
_exception = AsyncException.toAsyncException(exception); _exception = AsyncException.toAsyncException(exception);
///lock (callbacksLock) ///lock (callbacksLock)
//{ //{
if (this._errorCallbacks.length == 0)
throw _exception;
else
_errorCallbacks.forEach((x) { _errorCallbacks.forEach((x) {
x(_exception); x(_exception);
}); });

View File

@ -916,12 +916,12 @@ class DistributedConnection extends NetworkConnection with IStore
/// </summary> /// </summary>
/// <param name="resource">Resource.</param> /// <param name="resource">Resource.</param>
/// <returns></returns> /// <returns></returns>
bool put(IResource resource) AsyncReply<bool> put(IResource resource)
{ {
if (Codec.isLocalResource(resource, this)) if (Codec.isLocalResource(resource, this))
_resources.add((resource as DistributedResource).id, resource); _resources.add((resource as DistributedResource).id, resource);
// else .. put it in the server.... // else .. put it in the server....
return true; return AsyncReply.ready(true);
} }

View File

@ -33,9 +33,7 @@ import '../../Data/Codec.dart';
import './DistributedConnection.dart'; import './DistributedConnection.dart';
import '../Packets/IIPPacketAction.dart'; import '../Packets/IIPPacketAction.dart';
class DistributedResource extends IResource class DistributedResource extends IResource {
{
int _instanceId; int _instanceId;
DistributedConnection _connection; DistributedConnection _connection;
@ -46,8 +44,8 @@ class DistributedResource extends IResource
List _properties; List _properties;
bool _destroyed = false; bool _destroyed = false;
List<KeyValuePair<int, dynamic>> _queued_updates =
List<KeyValuePair<int, dynamic>> _queued_updates =List<KeyValuePair<int, dynamic>>(); List<KeyValuePair<int, dynamic>>();
/// <summary> /// <summary>
/// Connection responsible for the distributed resource. /// Connection responsible for the distributed resource.
@ -69,19 +67,19 @@ class DistributedResource extends IResource
bool get suspended => _suspended; bool get suspended => _suspended;
bool _suspended = true; bool _suspended = true;
AsyncReply<bool> trigger(ResourceTrigger trigger) => AsyncReply.ready(true);
/// <summary> /// <summary>
/// IDestructible interface. /// IDestructible interface.
/// </summary> /// </summary>
void destroy() void destroy() {
{
_destroyed = true; _destroyed = true;
_attached = false; _attached = false;
_connection.sendDetachRequest(_instanceId); _connection.sendDetachRequest(_instanceId);
emitArgs("destroy", [this]); emitArgs("destroy", [this]);
} }
void suspend() void suspend() {
{
_suspended = true; _suspended = true;
_attached = false; _attached = false;
} }
@ -96,7 +94,6 @@ class DistributedResource extends IResource
/// </summary> /// </summary>
bool get attached => _attached; bool get attached => _attached;
// public DistributedResourceStack Stack // public DistributedResourceStack Stack
//{ //{
// get { return stack; } // get { return stack; }
@ -109,8 +106,8 @@ class DistributedResource extends IResource
/// <param name="template">Resource template.</param> /// <param name="template">Resource template.</param>
/// <param name="instanceId">Instance Id given by the other end.</param> /// <param name="instanceId">Instance Id given by the other end.</param>
/// <param name="age">Resource age.</param> /// <param name="age">Resource age.</param>
DistributedResource(DistributedConnection connection, int instanceId, int age, String link) DistributedResource(
{ DistributedConnection connection, int instanceId, int age, String link) {
this._link = link; this._link = link;
this._connection = connection; this._connection = connection;
this._instanceId = instanceId; this._instanceId = instanceId;
@ -125,32 +122,27 @@ class DistributedResource extends IResource
/// Export all properties with ResourceProperty attributed as bytes array. /// Export all properties with ResourceProperty attributed as bytes array.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
List<PropertyValue> serialize() List<PropertyValue> serialize() {
{
var props = new List<PropertyValue>(_properties.length); var props = new List<PropertyValue>(_properties.length);
for (var i = 0; i < _properties.length; i++) for (var i = 0; i < _properties.length; i++)
props[i] = new PropertyValue(_properties[i], instance.getAge(i), instance.getModificationDate(i)); props[i] = new PropertyValue(
_properties[i], instance.getAge(i), instance.getModificationDate(i));
return props; return props;
} }
bool attach(List<PropertyValue> properties) bool attach(List<PropertyValue> properties) {
{
if (_attached) if (_attached)
return false; return false;
else else {
{
_suspended = false; _suspended = false;
_properties = new List(properties.length); // object[properties.Length]; _properties = new List(properties.length); // object[properties.Length];
//_events = new DistributedResourceEvent[Instance.Template.Events.Length]; //_events = new DistributedResourceEvent[Instance.Template.Events.Length];
for (var i = 0; i < properties.length; i++) for (var i = 0; i < properties.length; i++) {
{
instance.setAge(i, properties[i].age); instance.setAge(i, properties[i].age);
instance.setModificationDate(i, properties[i].date); instance.setModificationDate(i, properties[i].date);
_properties[i] = properties[i].value; _properties[i] = properties[i].value;
@ -164,21 +156,18 @@ class DistributedResource extends IResource
_attached = true; _attached = true;
if (_queued_updates.length > 0) if (_queued_updates.length > 0) {
{ _queued_updates
_queued_updates.forEach((kv)=>updatePropertyByIndex(kv.key, kv.value)); .forEach((kv) => updatePropertyByIndex(kv.key, kv.value));
_queued_updates.clear(); _queued_updates.clear();
} }
} }
return true; return true;
} }
void emitEventByIndex(int index, List<dynamic> args) void emitEventByIndex(int index, List<dynamic> args) {
{
// neglect events when the object is not yet attached // neglect events when the object is not yet attached
if (!_attached) if (!_attached) return;
return;
var et = instance.template.getEventTemplateByIndex(index); var et = instance.template.getEventTemplateByIndex(index);
//events[index]?.Invoke(this, args); //events[index]?.Invoke(this, args);
@ -187,54 +176,39 @@ class DistributedResource extends IResource
instance.emitResourceEvent(null, null, et.name, args); instance.emitResourceEvent(null, null, et.name, args);
} }
AsyncReply<dynamic> invokeByNamedArguments(int index, Structure namedArgs) AsyncReply<dynamic> invokeByNamedArguments(int index, Structure namedArgs) {
{ if (_destroyed) throw new Exception("Trying to access destroyed object");
if (_destroyed)
throw new Exception("Trying to access destroyed object");
if (_suspended) if (_suspended) throw new Exception("Trying to access suspended object");
throw new Exception("Trying to access suspended object");
if (index >= instance.template.functions.length) if (index >= instance.template.functions.length)
throw new Exception("Function index is incorrect"); throw new Exception("Function index is incorrect");
return connection.sendInvokeByNamedArguments(_instanceId, index, namedArgs); return connection.sendInvokeByNamedArguments(_instanceId, index, namedArgs);
} }
AsyncReply<dynamic> invokeByArrayArguments(int index, List<dynamic> args) {
if (_destroyed) throw new Exception("Trying to access destroyed object");
if (_suspended) throw new Exception("Trying to access suspended object");
AsyncReply<dynamic> invokeByArrayArguments(int index, List<dynamic> args)
{
if (_destroyed)
throw new Exception("Trying to access destroyed object");
if (_suspended)
throw new Exception("Trying to access suspended object");
if (index >= instance.template.functions.length) if (index >= instance.template.functions.length)
throw new Exception("Function index is incorrect"); throw new Exception("Function index is incorrect");
return connection.sendInvokeByArrayArguments(_instanceId, index, args); return connection.sendInvokeByArrayArguments(_instanceId, index, args);
} }
operator [](String index) operator [](String index) {
{
var pt = instance.template.getPropertyTemplateByName(index); var pt = instance.template.getPropertyTemplateByName(index);
if (pt != null) if (pt != null) return get(pt.index);
return get(pt.index);
} }
operator []=(String index, value) operator []=(String index, value) {
{
var pt = instance.template.getPropertyTemplateByName(index); var pt = instance.template.getPropertyTemplateByName(index);
if (pt != null) if (pt != null) set(pt.index, value);
set(pt.index, value);
} }
String _getMemberName(Symbol symbol) String _getMemberName(Symbol symbol) {
{
var memberName = symbol.toString(); var memberName = symbol.toString();
if (memberName.endsWith("=\")")) if (memberName.endsWith("=\")"))
return memberName.substring(8, memberName.length - 3); return memberName.substring(8, memberName.length - 3);
@ -243,47 +217,35 @@ class DistributedResource extends IResource
} }
@override //overring noSuchMethod @override //overring noSuchMethod
noSuchMethod(Invocation invocation) noSuchMethod(Invocation invocation) {
{
var memberName = _getMemberName(invocation.memberName); var memberName = _getMemberName(invocation.memberName);
if (invocation.isMethod) if (invocation.isMethod) {
{
var ft = instance.template.getFunctionTemplateByName(memberName); var ft = instance.template.getFunctionTemplateByName(memberName);
if (_attached && ft!=null) if (_attached && ft != null) {
{ if (invocation.namedArguments.length > 0) {
if (invocation.namedArguments.length > 0)
{
var namedArgs = new Structure(); var namedArgs = new Structure();
for (var p in invocation.namedArguments.keys) for (var p in invocation.namedArguments.keys)
namedArgs[_getMemberName(p)] = invocation.namedArguments[p]; namedArgs[_getMemberName(p)] = invocation.namedArguments[p];
return invokeByNamedArguments(ft.index, namedArgs); return invokeByNamedArguments(ft.index, namedArgs);
} } else {
else return invokeByArrayArguments(
{ ft.index, invocation.positionalArguments);
return invokeByArrayArguments(ft.index, invocation.positionalArguments);
} }
} }
} } else if (invocation.isSetter) {
else if (invocation.isSetter)
{
var pt = instance.template.getPropertyTemplateByName(memberName); var pt = instance.template.getPropertyTemplateByName(memberName);
if (pt != null) if (pt != null) {
{
set(pt.index, invocation.positionalArguments[0]); set(pt.index, invocation.positionalArguments[0]);
return true; return true;
} }
} } else if (invocation.isGetter) {
else if (invocation.isGetter)
{
var pt = instance.template.getPropertyTemplateByName(memberName); var pt = instance.template.getPropertyTemplateByName(memberName);
if (pt != null) if (pt != null) {
{
return get(pt.index); return get(pt.index);
} }
} }
@ -291,29 +253,20 @@ class DistributedResource extends IResource
return null; return null;
} }
/// <summary> /// <summary>
/// Get a property value. /// Get a property value.
/// </summary> /// </summary>
/// <param name="index">Zero-based property index.</param> /// <param name="index">Zero-based property index.</param>
/// <returns>Value</returns> /// <returns>Value</returns>
get(int index) get(int index) {
{ if (index >= _properties.length) return null;
if (index >= _properties.length)
return null;
return _properties[index]; return _properties[index];
} }
void updatePropertyByIndex(int index, dynamic value) {
void updatePropertyByIndex(int index, dynamic value) if (!_attached) {
{
if (!_attached)
{
_queued_updates.add(KeyValuePair(index, value)); _queued_updates.add(KeyValuePair(index, value));
} } else {
else
{
var pt = instance.template.getPropertyTemplateByIndex(index); var pt = instance.template.getPropertyTemplateByIndex(index);
_properties[index] = value; _properties[index] = value;
instance.emitModification(pt, value); instance.emitModification(pt, value);
@ -326,21 +279,19 @@ class DistributedResource extends IResource
/// <param name="index">Zero-based property index.</param> /// <param name="index">Zero-based property index.</param>
/// <param name="value">Value</param> /// <param name="value">Value</param>
/// <returns>Indicator when the property is set.</returns> /// <returns>Indicator when the property is set.</returns>
AsyncReply<dynamic> set(int index, dynamic value) AsyncReply<dynamic> set(int index, dynamic value) {
{ if (index >= _properties.length) return null;
if (index >= _properties.length)
return null;
var reply = new AsyncReply<dynamic>(); var reply = new AsyncReply<dynamic>();
var parameters = Codec.compose(value, connection); var parameters = Codec.compose(value, connection);
connection.sendRequest(IIPPacketAction.SetProperty) connection
.sendRequest(IIPPacketAction.SetProperty)
.addUint32(_instanceId) .addUint32(_instanceId)
.addUint8(index) .addUint8(index)
.addDC(parameters) .addDC(parameters)
.done() .done()
.then((res) .then((res) {
{
// not really needed, server will always send property modified, // not really needed, server will always send property modified,
// this only happens if the programmer forgot to emit in property setter // this only happens if the programmer forgot to emit in property setter
_properties[index] = value; _properties[index] = value;
@ -349,6 +300,4 @@ class DistributedResource extends IResource
return reply; return reply;
} }
} }

View File

@ -231,8 +231,8 @@ class IIPAuthPacket
} }
else if (command == IIPAuthPacketCommand.Acknowledge) else if (command == IIPAuthPacketCommand.Acknowledge)
{ {
remoteMethod = ((data[offset] >> 4) & 0x3); remoteMethod = AuthenticationMethod.values[ ((data[offset] >> 4) & 0x3)];
localMethod = ((data[offset] >> 2) & 0x3); localMethod = AuthenticationMethod.values[ ((data[offset] >> 2) & 0x3)];
var encrypt = ((data[offset++] & 0x2) == 0x2); var encrypt = ((data[offset++] & 0x2) == 0x2);
if (_notEnough(offset, ends, 1)) if (_notEnough(offset, ends, 1))

View File

@ -35,12 +35,11 @@ abstract class IStore implements IResource
{ {
AsyncReply<IResource> get(String path); AsyncReply<IResource> get(String path);
AsyncReply<IResource> retrieve(int iid); AsyncReply<IResource> retrieve(int iid);
bool put(IResource resource); AsyncReply<bool> put(IResource resource);
String link(IResource resource); String link(IResource resource);
bool record(IResource resource, String propertyName, dynamic value, int age, DateTime dateTime); bool record(IResource resource, String propertyName, dynamic value, int age, DateTime dateTime);
bool modify(IResource resource, String propertyName, dynamic value, int age, DateTime dateTime); bool modify(IResource resource, String propertyName, dynamic value, int age, DateTime dateTime);
bool remove(IResource resource); bool remove(IResource resource);
AsyncReply<KeyList<PropertyTemplate, List<PropertyValue>>> getRecord(IResource resource, DateTime fromDate, DateTime toDate); AsyncReply<KeyList<PropertyTemplate, List<PropertyValue>>> getRecord(IResource resource, DateTime fromDate, DateTime toDate);
} }

View File

@ -38,14 +38,14 @@ import 'ResourceTrigger.dart';
import '../Net/IIP/DistributedConnection.dart'; import '../Net/IIP/DistributedConnection.dart';
// Centeral Resource Issuer // Centeral Resource Issuer
class Warehouse class Warehouse {
{ static AutoList<IResource, Instance> _stores =
static AutoList<IResource, Instance> _stores = new AutoList<IResource, Instance>(null); new AutoList<IResource, Instance>(null);
static Map<int, IResource> _resources = new Map<int, IResource>(); static Map<int, IResource> _resources = new Map<int, IResource>();
static int resourceCounter = 0; static int resourceCounter = 0;
static KeyList<Guid, ResourceTemplate> _templates = new KeyList<Guid, ResourceTemplate>(); static KeyList<Guid, ResourceTemplate> _templates =
new KeyList<Guid, ResourceTemplate>();
//public delegate void StoreConnectedEvent(IStore store, string name); //public delegate void StoreConnectedEvent(IStore store, string name);
//public delegate void StoreDisconnectedEvent(IStore store); //public delegate void StoreDisconnectedEvent(IStore store);
@ -55,7 +55,8 @@ class Warehouse
static bool _warehouseIsOpen = false; static bool _warehouseIsOpen = false;
static KeyList<String, IStore Function()> protocols = _getSupportedProtocols(); static KeyList<String, AsyncReply<IStore> Function(String, dynamic)>
protocols = _getSupportedProtocols();
static final _urlRegex = RegExp(r'^(?:([^\s|:]*):\/\/([^\/]*)\/?(.*))'); static final _urlRegex = RegExp(r'^(?:([^\s|:]*):\/\/([^\/]*)\/?(.*))');
@ -64,11 +65,8 @@ class Warehouse
/// </summary> /// </summary>
/// <param name="name">Store instance name</param> /// <param name="name">Store instance name</param>
/// <returns></returns> /// <returns></returns>
static IStore getStore(String name) static IStore getStore(String name) {
{ for (var s in _stores) if (s.instance.name == name) return s;
for(var s in _stores)
if (s.instance.name == name)
return s;
return null; return null;
} }
@ -77,8 +75,7 @@ class Warehouse
/// </summary> /// </summary>
/// <param name="id">Instance Id</param> /// <param name="id">Instance Id</param>
/// <returns></returns> /// <returns></returns>
static AsyncReply<IResource> getById(int id) static AsyncReply<IResource> getById(int id) {
{
if (_resources.containsKey(id)) if (_resources.containsKey(id))
return new AsyncReply<IResource>.ready(_resources[id]); return new AsyncReply<IResource>.ready(_resources[id]);
else else
@ -90,24 +87,17 @@ class Warehouse
/// This function issues the initialize trigger to all stores and resources. /// This function issues the initialize trigger to all stores and resources.
/// </summary> /// </summary>
/// <returns>True, if no problem occurred.</returns> /// <returns>True, if no problem occurred.</returns>
static AsyncReply<bool> open() static AsyncReply<bool> open() {
{
var bag = new AsyncBag<bool>(); var bag = new AsyncBag<bool>();
for (var s in _stores) bag.add(s.trigger(ResourceTrigger.Initialize));
for(var s in _stores)
bag.add(s.trigger(ResourceTrigger.Initialize));
bag.seal(); bag.seal();
var rt = new AsyncReply<bool>(); var rt = new AsyncReply<bool>();
bag.then((x) bag.then((x) {
{
for (var b in x) for (var b in x)
if (!b) if (!b) {
{
rt.trigger(false); rt.trigger(false);
return; return;
} }
@ -118,11 +108,9 @@ class Warehouse
rBag.seal(); rBag.seal();
rBag.then((y) rBag.then((y) {
{
for (var b in y) for (var b in y)
if (!b) if (!b) {
{
rt.trigger(false); rt.trigger(false);
return; return;
} }
@ -130,7 +118,6 @@ class Warehouse
rt.trigger(true); rt.trigger(true);
_warehouseIsOpen = true; _warehouseIsOpen = true;
}); });
}); });
return rt; return rt;
@ -141,17 +128,14 @@ class Warehouse
/// This function issues terminate trigger to all resources and stores. /// This function issues terminate trigger to all resources and stores.
/// </summary> /// </summary>
/// <returns>True, if no problem occurred.</returns> /// <returns>True, if no problem occurred.</returns>
static AsyncReply<bool> close() static AsyncReply<bool> close() {
{
var bag = new AsyncBag<bool>(); var bag = new AsyncBag<bool>();
for (var resource in _resources.values) for (var resource in _resources.values)
if (!(resource is IStore)) if (!(resource is IStore))
bag.add(resource.trigger(ResourceTrigger.Terminate)); bag.add(resource.trigger(ResourceTrigger.Terminate));
for (var s in _stores) for (var s in _stores) bag.add(s.trigger(ResourceTrigger.Terminate));
bag.add(s.trigger(ResourceTrigger.Terminate));
for (var resource in _resources.values) for (var resource in _resources.values)
if (!(resource is IStore)) if (!(resource is IStore))
@ -163,11 +147,9 @@ class Warehouse
bag.seal(); bag.seal();
var rt = new AsyncReply<bool>(); var rt = new AsyncReply<bool>();
bag.then((x) bag.then((x) {
{
for (var b in x) for (var b in x)
if (!b) if (!b) {
{
rt.trigger(false); rt.trigger(false);
return; return;
} }
@ -178,22 +160,17 @@ class Warehouse
return rt; return rt;
} }
static List<IResource> qureyIn(
static List<IResource> qureyIn(List<String> path, int index, AutoList<IResource, Instance> resources) List<String> path, int index, AutoList<IResource, Instance> resources) {
{
var rt = new List<IResource>(); var rt = new List<IResource>();
if (index == path.length - 1) if (index == path.length - 1) {
{
if (path[index] == "") if (path[index] == "")
for (var child in resources) for (var child in resources) rt.add(child);
rt.add(child);
else else
for (var child in resources) for (var child in resources)
if (child.instance.name == path[index]) if (child.instance.name == path[index]) rt.add(child);
rt.add(child); } else
}
else
for (var child in resources) for (var child in resources)
if (child.instance.name == path[index]) if (child.instance.name == path[index])
rt.addAll(qureyIn(path, index + 1, child.instance.children)); rt.addAll(qureyIn(path, index + 1, child.instance.children));
@ -201,28 +178,18 @@ class Warehouse
return rt; return rt;
} }
static AsyncReply<List<IResource>> query(String path) static AsyncReply<List<IResource>> query(String path) {
{ if (path == null || path == "") {
if (path == null || path == "")
{
var roots = _stores.where((s) => s.instance.parents.length == 0).toList(); var roots = _stores.where((s) => s.instance.parents.length == 0).toList();
return new AsyncReply<List<IResource>>.ready(roots); return new AsyncReply<List<IResource>>.ready(roots);
} } else {
else
{
var rt = new AsyncReply<List<IResource>>(); var rt = new AsyncReply<List<IResource>>();
get(path).then((x) get(path).then((x) {
{
var p = path.split('/'); var p = path.split('/');
if (x == null) if (x == null) {
{
rt.trigger(qureyIn(p, 0, _stores)); rt.trigger(qureyIn(p, 0, _stores));
} } else {
else
{
var ar = qureyIn(p, 0, _stores).where((r) => r != x).toList(); var ar = qureyIn(p, 0, _stores).where((r) => r != x).toList();
ar.insert(0, x); ar.insert(0, x);
rt.trigger(ar); rt.trigger(ar);
@ -230,9 +197,7 @@ class Warehouse
}); });
return rt; return rt;
} }
} }
/// <summary> /// <summary>
@ -241,47 +206,48 @@ class Warehouse
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
/// <returns>Resource instance.</returns> /// <returns>Resource instance.</returns>
static AsyncReply<dynamic> get(String path, [attributes = null, IResource parent = null, IPermissionsManager manager = null]) static AsyncReply<dynamic> get(String path,
{ [attributes = null,
var rt = new AsyncReply<IResource>(); IResource parent = null,
IPermissionsManager manager = null]) {
var rt = AsyncReply<IResource>();
// Should we create a new store ? // Should we create a new store ?
if (_urlRegex.hasMatch(path)) if (_urlRegex.hasMatch(path)) {
{
var url = _urlRegex.allMatches(path).first; var url = _urlRegex.allMatches(path).first;
if (protocols.containsKey(url[1])) if (protocols.containsKey(url[1])) {
{
var handler = protocols[url[1]]; var handler = protocols[url[1]];
var store = handler(); var getFromStore = () {
put(store, url[2], null, parent, null, 0, manager, attributes); handler(url[2], attributes).then<IStore>((store) {
store.trigger(ResourceTrigger.Open).then<dynamic>((x)
{
_warehouseIsOpen = true;
if (url[3].length > 0 && url[3] != "") if (url[3].length > 0 && url[3] != "")
store.get(url[3]).then<dynamic>((r) store.get(url[3]).then<dynamic>((r) {
{
rt.trigger(r); rt.trigger(r);
}).error((e) => rt.triggerError(e)); }).error((e) => rt.triggerError(e));
else else
rt.trigger(store); rt.trigger(store);
}).error((e) }).error((e) {
{
rt.triggerError(e); rt.triggerError(e);
Warehouse.remove(store); //Warehouse.remove(store);
}); });
};
if (!_warehouseIsOpen)
open().then((v) {
if (v)
getFromStore();
else
rt.trigger(null);
});
else
getFromStore();
return rt; return rt;
} }
} }
query(path).then((rs) {
query(path).then((rs)
{
if (rs != null && rs.length > 0) if (rs != null && rs.length > 0)
rt.trigger(rs[0]); rt.trigger(rs[0]);
else else
@ -290,7 +256,6 @@ class Warehouse
return rt; return rt;
/* /*
var p = path.split('/'); var p = path.split('/');
IResource res; IResource res;
@ -368,45 +333,86 @@ class Warehouse
/// <param name="name">Resource name.</param> /// <param name="name">Resource name.</param>
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param> /// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param> /// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
static void put(IResource resource, String name, [IStore store = null, IResource parent = null, ResourceTemplate customTemplate = null, int age = 0, IPermissionsManager manager = null, attributes = null]) static AsyncReply<bool> put(IResource resource, String name,
{ [IStore store = null,
resource.instance = new Instance(resourceCounter++, name, resource, store, customTemplate, age); IResource parent = null,
ResourceTemplate customTemplate = null,
int age = 0,
IPermissionsManager manager = null,
attributes = null]) {
var rt = AsyncReply<bool>();
resource.instance = new Instance(
resourceCounter++, name, resource, store, customTemplate, age);
if (attributes != null) if (attributes != null)
resource.instance.setAttributes(Structure.fromMap(attributes)); resource.instance.setAttributes(Structure.fromMap(attributes));
if (manager != null) if (manager != null) resource.instance.managers.add(manager);
resource.instance.managers.add(manager);
if (store == parent) if (store == parent) parent = null;
parent = null;
if (parent == null) if (parent == null) {
{ if (!(resource is IStore)) store.instance.children.add(resource);
if (!(resource is IStore)) } else
store.instance.children.add(resource);
}
else
parent.instance.children.add(resource); parent.instance.children.add(resource);
var initResource = () {
if (resource is IStore)
{
_stores.add(resource);
//StoreConnected?.Invoke(resource as IStore, name);
}
else
store.put(resource);
_resources[resource.instance.id] = resource; _resources[resource.instance.id] = resource;
if (_warehouseIsOpen) if (_warehouseIsOpen) {
resource.trigger(ResourceTrigger.Initialize); resource.trigger(ResourceTrigger.Initialize).then<dynamic>((value) {
if (resource is IStore)
resource.trigger(ResourceTrigger.Open).then<dynamic>((value) {
rt.trigger(value);
}).error((ex) => rt.triggerError(ex));
else
rt.trigger(value);
}).error((ex) => rt.triggerError(ex));
}
};
if (resource is IStore) {
_stores.add(resource);
initResource();
} else {
store.put(resource).then<dynamic>((value) {
if (value)
initResource();
else
rt.trigger(false);
}).error((ex) => rt.triggerError(ex));
} }
static T New<T extends IResource>(String name, [IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null]) return rt;
{ }
static AsyncReply<T> New<T extends IResource>(T resource, String name,
[IStore store = null,
IResource parent = null,
IPermissionsManager manager = null,
attributes = null,
properties = null]) {
if (properties != null) {
dynamic d = resource;
for (var i = 0; i < properties.length; i++)
d[properties.keys.elementAt(i)] = properties.at(i);
//setProperty(resource, properties.keys.elementAt(i), properties.at(i));
}
var rt = AsyncReply<T>();
put(resource, name, store, parent, null, 0, manager, attributes)
.then<bool>((value) {
if (value)
rt.trigger(resource);
else
rt.trigger(null);
}).error((ex) => rt.triggerError(ex));
return rt;
/* /*
var type = ResourceProxy.GetProxy<T>(); var type = ResourceProxy.GetProxy<T>();
var res = Activator.CreateInstance(type) as IResource; var res = Activator.CreateInstance(type) as IResource;
@ -419,24 +425,20 @@ class Warehouse
/// Put a resource template in the templates warehouse. /// Put a resource template in the templates warehouse.
/// </summary> /// </summary>
/// <param name="template">Resource template.</param> /// <param name="template">Resource template.</param>
static void putTemplate(ResourceTemplate template) static void putTemplate(ResourceTemplate template) {
{
if (!_templates.containsKey(template.classId)) if (!_templates.containsKey(template.classId))
_templates.add(template.classId, template); _templates.add(template.classId, template);
} }
/// <summary> /// <summary>
/// Get a template by type from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse. /// Get a template by type from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
/// </summary> /// </summary>
/// <param name="type">.Net type.</param> /// <param name="type">.Net type.</param>
/// <returns>Resource template.</returns> /// <returns>Resource template.</returns>
static ResourceTemplate getTemplateByType(Type type) static ResourceTemplate getTemplateByType(Type type) {
{
// loaded ? // loaded ?
for (var t in _templates.values) for (var t in _templates.values)
if (t.className == type.toString()) if (t.className == type.toString()) return t;
return t;
var template = new ResourceTemplate.fromType(type); var template = new ResourceTemplate.fromType(type);
_templates.add(template.classId, template); _templates.add(template.classId, template);
@ -449,8 +451,7 @@ class Warehouse
/// </summary> /// </summary>
/// <param name="classId">Class Id.</param> /// <param name="classId">Class Id.</param>
/// <returns>Resource template.</returns> /// <returns>Resource template.</returns>
static AsyncReply<ResourceTemplate> getTemplateByClassId(Guid classId) static AsyncReply<ResourceTemplate> getTemplateByClassId(Guid classId) {
{
if (_templates.containsKey(classId)) if (_templates.containsKey(classId))
return new AsyncReply<ResourceTemplate>.ready(_templates[classId]); return new AsyncReply<ResourceTemplate>.ready(_templates[classId]);
return null; return null;
@ -461,8 +462,7 @@ class Warehouse
/// </summary> /// </summary>
/// <param name="className">Class name.</param> /// <param name="className">Class name.</param>
/// <returns>Resource template.</returns> /// <returns>Resource template.</returns>
static AsyncReply<ResourceTemplate> getTemplateByClassName(String className) static AsyncReply<ResourceTemplate> getTemplateByClassName(String className) {
{
for (var t in _templates.values) for (var t in _templates.values)
if (t.className == className) if (t.className == className)
return new AsyncReply<ResourceTemplate>.ready(t); return new AsyncReply<ResourceTemplate>.ready(t);
@ -470,25 +470,21 @@ class Warehouse
return null; return null;
} }
static bool remove(IResource resource) static bool remove(IResource resource) {
{ if (resource.instance == null) return false;
if (resource.instance == null)
return false;
if (_resources.containsKey(resource.instance.id)) if (_resources.containsKey(resource.instance.id))
_resources.remove(resource.instance.id); _resources.remove(resource.instance.id);
else else
return false; return false;
if (resource is IStore) if (resource is IStore) {
{
_stores.remove(resource); _stores.remove(resource);
// remove all objects associated with the store // remove all objects associated with the store
var toBeRemoved = _resources.values.where((x) => x.instance.store == resource); var toBeRemoved =
for (var o in toBeRemoved) _resources.values.where((x) => x.instance.store == resource);
remove(o); for (var o in toBeRemoved) remove(o);
// StoreDisconnected?.Invoke(resource as IStore); // StoreDisconnected?.Invoke(resource as IStore);
} }
@ -501,12 +497,14 @@ class Warehouse
return true; return true;
} }
static KeyList<String, AsyncReply<IStore> Function(String, dynamic)>
static KeyList<String, IStore Function()> _getSupportedProtocols() _getSupportedProtocols() {
{ var rt =
var rt = new KeyList<String, IStore Function()>(); new KeyList<String, AsyncReply<IStore> Function(String, dynamic)>();
rt.add("iip", () => new DistributedConnection()); rt.add(
"iip",
(String name, attributes) => Warehouse.New<DistributedConnection>(
DistributedConnection(), name, null, null, null, attributes));
return rt; return rt;
} }
} }

View File

@ -1,9 +1,10 @@
name: esiur name: esiur
description: Distributed Object Framework. description: Distributed Object Framework.
version: 1.2.4 version: 1.2.6
# author: Ahmed Zamil <ahmed@dijlh.com> # author: Ahmed Zamil <ahmed@dijlh.com>
homepage: https://github.com/esiur/esiur-dart homepage: https://github.com/esiur/esiur-dart
environment: environment:
sdk: ">=2.1.0 <3.0.0" sdk: ">=2.1.0 <3.0.0"

View File

@ -3,13 +3,14 @@ import 'package:esiur/esiur.dart';
import 'dart:io'; import 'dart:io';
main() async { main() async {
test("Connect to server", () async { try {
// // // connect to the server var x = await Warehouse.get("iip://localhost:5070/sys/cp",
var x = await Warehouse.get("iip://localhost:5000/sys/su",
{"username": "admin", "password": "1234", "domain": "example.com"}); {"username": "admin", "password": "1234", "domain": "example.com"});
print(x); print(x);
}); } catch (ex) {
print("Error occured");
print(ex);
}
} }
// describe object // describe object