/// <inheritdoc /> public IMetadataObject TryGetFromGitPath(string path) { if (path == null) { throw new ArgumentNullException(nameof(path)); } var chunks = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); IMetadataObject result = this; for (int i = 0; i < chunks.Length - 1 && result != null; i++) { var propertyInfo = result.DataAccessor.ChildProperties.FirstOrDefault( p => p.FolderName.Equals(chunks[i], StringComparison.OrdinalIgnoreCase)); if (propertyInfo == null) { return(null); } i++; if (i >= chunks.Length) { return(null); } var children = propertyInfo.Accessor(result); var guid = Guid.Parse(chunks[i]); result = children.FirstOrDefault(c => c.Id == guid); } return(result); }
/// <summary> /// Gets the folder path containing the data file for a node. /// </summary> /// <param name="source">The node.</param> /// <returns>A <see cref="string"/> value containing the path to the folder.</returns> internal static string GetFolderPath(this IMetadataObject source) { var result = new StringBuilder(); GetFolderPath(source, result); return(result.ToString()); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the method belongs to.</param> /// <param name="method">The CLR method the metadata should be provided for.</param> /// <param name="name">The name of the method; if <c>null</c>, the method's CLR name is used.</param> /// <param name="baseMethod">The overridden base method, if any.</param> internal MethodMetadata(IMetadataObject obj, MethodInfo method, string name = null, MethodMetadata baseMethod = null) { Requires.NotNull(obj, () => obj); Requires.NotNull(method, () => method); Requires.That(name == null || !String.IsNullOrWhiteSpace(name), () => name, "The name must be null or non-whitespace only."); Requires.That(baseMethod == null || method != baseMethod.MethodInfo, "A method cannot override itself."); Requires.That(baseMethod == null || obj == baseMethod._object, "The base method must belong to the same object."); Requires.That(baseMethod == null || baseMethod.OverridingMethod == null, "The base method has already been overridden."); _object = obj; Name = EscapeName(name ?? method.Name); MethodInfo = method; BaseMethod = baseMethod; if (baseMethod != null) baseMethod.OverridingMethod = this; var backingFieldAttribute = MethodInfo.GetCustomAttribute<BackingFieldAttribute>(); if (backingFieldAttribute != null) BackingField = backingFieldAttribute.GetFieldInfo(MethodInfo.DeclaringType); var behaviorAttribute = MethodInfo.GetCustomAttribute<IntendedBehaviorAttribute>(); if (behaviorAttribute != null) IntendedBehavior = behaviorAttribute.GetMethodInfo(MethodInfo.DeclaringType); if (backingFieldAttribute == null && behaviorAttribute == null) IntendedBehavior = MethodInfo; Behaviors = new MethodBehaviorCollection(obj, this); ImplementedMethods = DetermineImplementedInterfaceMethods().ToArray(); _methodBody = new Lazy<MethodBodyMetadata>(InitializeMethodBody); }
IMetadataObject DeepClone(IMetadataObject node, ProcessArgument processArgument, ChildChangesGetter childChangesGetter, Func <IMetadataObject, bool> mustForceVisit) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (processArgument == null) { throw new ArgumentNullException(nameof(processArgument)); } if (childChangesGetter == null) { throw new ArgumentNullException(nameof(childChangesGetter)); } if (mustForceVisit == null) { throw new ArgumentNullException(nameof(mustForceVisit)); } ILazyChildren ProcessChildren(ChildPropertyInfo childProperty, ILazyChildren children, IMetadataObject @new, IModelDataAccessor childDataAccessor) { var childChanges = childChangesGetter.Invoke(node, childProperty); return(children.Clone( forceVisit: mustForceVisit(children.Parent), update: n => DeepClone(n, processArgument, childChangesGetter, mustForceVisit), added: childChanges.Additions, deleted: childChanges.Deletions)); } return(node.DataAccessor.ConstructorParameterBinding.Cloner(node, processArgument, ProcessChildren)); }
static Regex GetChildPathRegex(IMetadataObject node, ChildPropertyInfo childProperty) { var path = node.GetFolderPath(); return(string.IsNullOrEmpty(path) ? new Regex($@"{childProperty.FolderName}/[\w-]+/{FileSystemStorage.DataFile}", RegexOptions.IgnoreCase) : new Regex($@"{path}/{childProperty.FolderName}/[\w-]+/{FileSystemStorage.DataFile}", RegexOptions.IgnoreCase)); }
/// <summary> /// Serializes the node into the <paramref name="stringBuilder"/>. /// </summary> /// <param name="source">The source.</param> /// <param name="stringBuilder">The string builder.</param> internal static void ToJson(this IMetadataObject source, StringBuilder stringBuilder) { stringBuilder.Clear(); using (var writer = new StringWriter(stringBuilder)) { _jsonSerializer.Serialize(writer, source); } }
static void UpdateNodeIfNeeded(IMetadataObject original, IMetadataObject @new, Stack<string> stack, IModelDataAccessor accessor, IList<MetadataTreeEntryChanges> changes) { if (accessor.ModifiableProperties.Any(p => !p.AreSame(original, @new))) { var path = stack.ToDataPath(); changes.Add(new MetadataTreeEntryChanges(path, ChangeKind.Modified, original, @new)); } }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the method belongs to.</param> /// <param name="method">The metadata of the method the behavior belongs to.</param> internal FaultInjection(IMetadataObject obj, MethodMetadata method) { Requires.NotNull(obj, () => obj); Requires.NotNull(method, () => method); _object = obj; Method = method; }
TLink GetValueFromFactory(IMetadataObject parent) { if (_factory == null) { throw new NotSupportedException("Factory cannot be null."); } return(_factory(parent) ?? throw new NotSupportedException(_nullReturnedValueExceptionMessage)); }
/// <summary> /// Gets an <see cref="IEnumerable{IMetadataObject}"/> containing all parents of this node. /// </summary> /// <param name="source">The source.</param> /// <returns>All parent nodes from nearest to farest.</returns> public static IEnumerable <IMetadataObject> Parents(this IMetadataObject source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } return(ParentsIterator(source)); }
public void LazyChildrenThrowsErrorIfLambdaReturnsNull(IMetadataObject parent) { // Act var sut = new LazyChildren <IMetadataObject>(_ => null); sut.AttachToParent(parent); // Assert Assert.Throws <NotSupportedException>(() => sut.GetEnumerator()); }
static IEnumerable <IMetadataObject> ParentsIterator(IMetadataObject source) { var node = source; while (node != null) { yield return(node); node = node.Parent; } }
/// <summary> /// Возвращает интерфейс объекта метаданных. /// </summary> /// <param name="metadataObject">Объект метаданных.</param> /// <returns></returns> protected IMetadataObject GetMetadataObject(T metadataObject) { //проверяем наличие определения интерфейса метаданных. this.TypeDefinition.CheckIsMetadataObject(); //получаем экземпляр информации о метаданных объекта. object metadataObj = metadataObject; IMetadataObject metadataObjInterface = (IMetadataObject)metadataObj; //возвращаем интерфейс метаданных. return(metadataObjInterface); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the action belongs to.</param> /// <param name="method">The CLR method the metadata should be provided for.</param> /// <param name="name">The name of the method; if <c>null</c>, the method's CLR name is used.</param> internal ActionMetadata(IMetadataObject obj, MethodInfo method, string name = null) : base(obj, method, name) { Requires.That(HasImplementation, () => method, "Transition actions must have an implementation."); Requires.That(!CanBeAffectedByFaultEffects, () => method, "Transition actions must not be sensitive to fault effects."); Requires.That(method.GetParameters().Length == 0, () => method, "A transition action cannot take any parameters."); Requires.That(method.ReturnType == typeof(void), () => method, "A transition action must not return a value."); _delegate = (Action)CreateDelegate(typeof(Action)); _transition = new Lazy<IEnumerable<TransitionMetadata>>( () => DeclaringObject.StateMachine.Transitions.Where(transition => transition.Action == this).ToArray()); }
void CompareNodeChildren(IMetadataObject original, IMetadataObject @new, IList<MetadataTreeEntryChanges> changes, Stack<string> stack, ChildPropertyInfo childProperty) { using (var enumerator = new TwoSequenceEnumerator<IMetadataObject>( childProperty.Accessor(original), childProperty.Accessor(@new))) { while (!enumerator.BothCompleted) { CompareNodeChildren(changes, stack, enumerator); } } }
/// <summary> /// Gets the path to the data file for a node. /// </summary> /// <param name="source">The node.</param> /// <returns>A <see cref="string"/> value containing the path to the data file.</returns> internal static string GetDataPath(this IMetadataObject source) { var result = new StringBuilder(); GetFolderPath(source, result); if (result.Length > 0) { result.Append('/'); } result.Append(FileSystemStorage.DataFile); return(result.ToString()); }
/// <summary> /// Flattens the specified source and its nested children. /// </summary> /// <param name="source">The source.</param> /// <returns>An enumerable containing the source and its nested children.</returns> internal static IEnumerable <IMetadataObject> Flatten(this IMetadataObject source) { yield return(source); foreach (var child in source.Children) { foreach (var flattened in child.Flatten()) { yield return(flattened); } } }
/// <summary> /// Initializes a new instance of the <see cref="MetadataTreeEntryChanges"/> class. /// </summary> /// <param name="path">The path.</param> /// <param name="status">The change type.</param> /// <param name="old">The old value.</param> /// <param name="new">The new value.</param> /// <exception cref="ArgumentNullException">old</exception> public MetadataTreeEntryChanges(string path, ChangeKind status, IMetadataObject old = null, IMetadataObject @new = null) { Path = path ?? throw new ArgumentNullException(nameof(path)); Status = status; if (old == null && @new == null) { throw new ArgumentNullException($"{nameof(old)} and {nameof(@new)}"); } Old = old; New = @new; }
/// <inheritdoc /> public void AttachToParent(IMetadataObject parent) { if (parent == null) { throw new ArgumentNullException(nameof(parent)); } if (Parent != null && Parent != parent) { throw new NotSupportedException("A single metadata object cannot be attached to two different parents."); } Parent = parent; }
void AttachChildrenToParentIfNeeded(IMetadataObject parent) { if (_parentAttachedInChildren || _children == null) { return; } foreach (var child in _children) { child.AttachToParent(parent); } _parentAttachedInChildren = true; }
internal static int GetHashCode(IMetadataObject metadataObject) { string text = string.Format(CultureInfo.InvariantCulture, AdomdUtils.MetadataHashCodeTemplate, new object[] { metadataObject.Connection.GetHashCode().ToString(CultureInfo.InvariantCulture), metadataObject.SessionId, metadataObject.Catalog, metadataObject.CubeName, metadataObject.Type.GetHashCode(), metadataObject.UniqueName }); return(text.GetHashCode()); }
object ProcessProperty(IMetadataObject node, string name, Type argumentType, object fallback) { var path = node.GetDataPath(); var propertyChange = _changes[path].FirstOrDefault(c => c.Property.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); if (propertyChange != null) { return(propertyChange.MergeValue.ToObject(argumentType, _serializer.Value)); } else { return(fallback is ICloneable cloneable?cloneable.Clone() : fallback); } }
/// <summary> /// Gets the root repository of the specified node. /// </summary> /// <param name="node">The node.</param> /// <returns>The root <see cref="IMetadataObject"/> instance.</returns> /// <exception cref="ArgumentNullException">node</exception> internal static IMetadataObject Root(this IMetadataObject node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } while (node.Parent != null) { node = node.Parent; } return(node); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the affected method belongs to.</param> /// <param name="affectedMethod">The metadata of the S# method that should be affected by the fault injector.</param> internal MethodBehaviorCollection(IMetadataObject obj, MethodMetadata affectedMethod) { Requires.NotNull(obj, () => obj); Requires.NotNull(affectedMethod, () => affectedMethod); _object = obj; AffectedMethod = affectedMethod; FaultEffects = Enumerable.Empty<FaultEffectMetadata>(); FaultInjections = Enumerable.Empty<FaultInjection>().ToArray(); // Create and inject the intended behavior now; we do that as early as possible so that all // methods can be called reliably in the model initialization phase IntendedBehavior = new IntendedBehavior(_object, affectedMethod); IntendedBehavior.Bind(); }
/// <summary> /// Gets whether two objects store the same value. /// </summary> /// <param name="old">The old.</param> /// <param name="new">The new.</param> /// <returns><code>true</code> is the objects contain the same property value.</returns> /// <exception cref="ArgumentNullException"> /// old /// or /// new /// </exception> public bool AreSame(IMetadataObject old, IMetadataObject @new) { if (old == null) { throw new ArgumentNullException(nameof(old)); } if (@new == null) { throw new ArgumentNullException(nameof(@new)); } var oldValue = Accessor(old); var newValue = Accessor(@new); return(oldValue == newValue || (oldValue?.Equals(newValue) ?? false)); }
/// <summary> /// Обновляет существующий объект в базе данных. /// </summary> /// <param name="metadataObject">Объект метаданных.</param> /// <returns></returns> protected bool UpdateObject(T metadataObject) { if (metadataObject == null) { throw new ArgumentNullException("metadataObject"); } string tableName = this.GetTableName(metadataObject); if (String.IsNullOrEmpty(tableName)) { throw new Exception(String.Format("Не удалось определить конечную таблицу для объекта {0} типа {1}", metadataObject.ToString(), metadataObject.GetType().Name)); } DBObjectDistributedTable table = this.MetadataAdapter.TableActivator.GetDistributedTable(this.DBSchemaAdapter, tableName); MetadataQueryBuilder queryBuilder = new MetadataQueryBuilder(table.TablePartition.Table, this.TypeDefinition); //приводим объект к типу метаданных. IMetadataObject metadata = this.GetMetadataObject(metadataObject); if (metadata.ID == 0) { throw new ArgumentNullException("metadata.ID", "Не передан идентификатор объекта."); } //формируем условие обновления объекта по идентификатору. string identityCondition = string.Format("[ID] = {1}", table.TablePartition.Table.IdentityColumn.Name, metadata.ID); //запрос обновления объекта метаданных. string updateQuery = @" {UpdateQuery} WHERE {IdentityCondition} SELECT @@ROWCOUNT" .ReplaceKey("UpdateQuery", queryBuilder.UpdateQuery) .ReplaceKey("IdentityCondition", identityCondition) ; //формируем параметры обновления, соответствующие значениям свойств объекта. DBCollection <SqlParameter> updateParams = this.CreateInsertParameters(metadataObject); //выполняем запрос. int affectedRowsCount = this.DataAdapter.GetScalarValue <int>(updateQuery, updateParams.ToArray()); return(affectedRowsCount > 0); }
void RemoveNode(IMetadataObject left, IList<MetadataTreeEntryChanges> changed, Stack<string> stack) { var path = stack.ToDataPath(); changed.Add(new MetadataTreeEntryChanges(path, ChangeKind.Deleted, old: left)); var dataAccessor = _modelDataProvider.Get(left.GetType()); foreach (var childProperty in dataAccessor.ChildProperties) { stack.Push(childProperty.Name); foreach (var child in left.Children) { stack.Push(child.Id.ToString()); RemoveNode(child, changed, stack); stack.Pop(); } stack.Pop(); } }
void CompareNode(IMetadataObject original, IMetadataObject @new, IList<MetadataTreeEntryChanges> changes, Stack<string> stack) { var accessor = _modelDataProvider.Get(original.GetType()); UpdateNodeIfNeeded(original, @new, stack, accessor, changes); foreach (var childProperty in accessor.ChildProperties) { if (!childProperty.ShouldVisitChildren(original) && !childProperty.ShouldVisitChildren(@new)) { // Do not visit children if they were not generated. // This means that they were not modified! continue; } stack.Push(childProperty.FolderName); CompareNodeChildren(original, @new, changes, stack, childProperty); stack.Pop(); } }
static void GetFolderPath(IMetadataObject node, StringBuilder builder) { if (node.Parent != null) { GetFolderPath(node.Parent, builder); var childProperty = node.Parent.DataAccessor.ChildProperties.Single(p => p.ItemType.IsInstanceOfType(node)); if (builder.Length > 0) { builder.Append('/'); } builder.Append(childProperty.Name); builder.Append('/'); } if (!(node is IObjectRepository)) { builder.Append(node.Id); } }
/// <inheritdoc /> public IMetadataObject With(IMetadataObject source, IPredicateReflector predicate) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); } var newInstance = DeepClone( source.Repository, predicate.ProcessArgument, predicate.GetChildChanges, n => n.IsParentOf(source)); return(newInstance.TryGetFromGitPath(source.GetDataPath())); }
IEnumerable <TChild> GetValueFromFactory(IMetadataObject parent) { if (_factory != null) { return(_factory(parent) ?? throw new NotSupportedException(_nullReturnedValueExceptionMessage)); } else if (_factoryWithRepo != null) { var objectRepository = (AbstractObjectRepository)parent.Repository; return(objectRepository._repositoryProvider.Execute( objectRepository._repositoryDescription, repository => { var nodes = _factoryWithRepo(parent, repository) ?? throw new NotSupportedException(_nullReturnedValueExceptionMessage); return nodes.Cast <TChild>(); })); } throw new NotSupportedException("Factory cannot be null."); }
/// <inheritdoc/> public object ProcessArgument(IMetadataObject instance, string name, Type argumentType, object fallback = null) { if (instance == null) { throw new ArgumentNullException(nameof(instance)); } if (name == null) { throw new ArgumentNullException(nameof(name)); } if (argumentType == null) { throw new ArgumentNullException(nameof(argumentType)); } var matchingPredicate = _reflectors.FirstOrDefault(r => r.Instance == instance); if (matchingPredicate != null) { return(matchingPredicate.ProcessArgument(instance, name, argumentType, fallback)); } return(fallback is ICloneable cloneable?cloneable.Clone() : fallback); }
/// <summary> /// Determines whether this node is a parent of the specified instance. /// </summary> /// <param name="source">The source.</param> /// <param name="instance">The instance.</param> /// <returns> /// <c>true</c> if the node is a parent of the specified instance; otherwise, <c>false</c>. /// </returns> public static bool IsParentOf(this IMetadataObject source, IMetadataObject instance) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (instance == null) { throw new ArgumentNullException(nameof(instance)); } var node = instance.Parent; while (node != null) { if (node == source) { return(true); } node = node.Parent; } return(false); }
/// <summary> /// Обновляет существующий объект в базе данных. /// </summary> /// <param name="metadataObject">Объект метаданных.</param> /// <returns></returns> protected bool UpdateObject(T metadataObject) { if (metadataObject == null) { throw new ArgumentNullException("metadataObject"); } //приводим объект к типу метаданных. IMetadataObject metadata = this.GetMetadataObject(metadataObject); if (metadata.ID == 0) { throw new ArgumentNullException("metadata.ID", "Не передан идентификатор объекта."); } //формируем условие обновления объекта по идентификатору. string identityCondition = string.Format("[ID] = {1}", this.IdentityColumn.Name, metadata.ID); //запрос обновления объекта метаданных. string updateQuery = @" {UpdateQuery} WHERE {IdentityCondition} SELECT @@ROWCOUNT" .ReplaceKey("UpdateQuery", this.UpdateQuery) .ReplaceKey("IdentityCondition", identityCondition) ; //формируем параметры обновления, соответствующие значениям свойств объекта. DBCollection <SqlParameter> updateParams = this.CreateInsertParameters(metadataObject); //выполняем запрос. int affectedRowsCount = this.DataAdapter.GetScalarValue <int>(updateQuery, updateParams.ToArray()); return(affectedRowsCount > 0); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The <see cref="IMetadataObject" /> the exception should be raised for.</param> /// <param name="message">The message giving further details about the exception.</param> public MetadataException(IMetadataObject obj, string message) : base(String.Format("{0} The 'Object' property contains the metadata object the exception was raised for.", message)) { Requires.NotNull(obj, () => obj); Object = obj; }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the method belongs to.</param> /// <param name="method">The metadata of the method the fault injection belongs to.</param> /// <param name="faultEffect">The fault effect that should be injected deterministically.</param> public DeterministicFaultInjection(IMetadataObject obj, MethodMetadata method, FaultEffectMetadata faultEffect) : base(obj, method) { Requires.NotNull(faultEffect, () => faultEffect); FaultEffect = faultEffect; }
public void AddMetadataObject(IMetadataObject metadataObject, Action<int> SetAddObjectId) { this._ServiceProxy.BeginAddMetadataObject(metadataObject, delegate(IAsyncResult ar) { int objectId = this._ServiceProxy.EndAddMetadataObject(ar); SetAddObjectId(objectId); }, null); }
public VmQuotationBase(IMetadataObject metadataObject) : base(metadataObject) { }
public VmBase(IMetadataObject metadataObject) { this._MetadataObject = metadataObject; }