private Lazy <IRelationMetadata> CreateRecursor(RelationMetadata metadata) { if (metadata.HasFlag(RelationMetadataFlags.Item)) { IRelationMetadata recursiveParent = this.GetRecursiveParent(metadata); if (recursiveParent != null) { string recursivePath = metadata.Notation.Path(recursiveParent.Identity.Name, metadata.Parent.Identity.Name); string otherPath = metadata.Notation.Combine(metadata.Identity.Name, recursivePath); MetadataIdentity otherId = metadata.Identity.Push(recursivePath); return(new Lazy <IRelationMetadata>(() => this.GetMetadata(metadata.Schema, otherId))); } } else if (metadata.Owner.Recursor != null) { IRelationContract contract = this.GetContract(metadata); if (contract != null && metadata.Owner.Type.Equals(contract.ItemType)) { return(new Lazy <IRelationMetadata>(() => metadata.Owner)); } } return(null); }
private RelationMetadata CreateItem(RelationMetadata parent) { if (parent.Owner.HasFlag(RelationMetadataFlags.Recursive)) { MemberInfo parentMember = parent.Owner.Parent?.Member; MemberInfo thisMember = parent.Member; if (parentMember != null && parentMember.Equals(thisMember)) { return(null); } } IRelationContract contract = this.GetContract(parent); if (contract == null) { return(null); } MetadataIdentity itemId = parent.Identity.Push(contract.ItemName ?? "Item"); RelationMetadata metadata = new RelationMetadata(parent.Schema, itemId) { Parent = parent, Type = contract.ItemType, Flags = RelationMetadataFlags.Item, ReadIndex = contract.ReadIndex, WriteIndex = contract.WriteIndex, Depth = parent.Depth + 1, }; metadata.Owner = metadata; metadata.Item = this.CreateItem(metadata); metadata.Properties = this.CreateLazy(() => this.CreateProperties(metadata)); metadata.Annotations = this.CreateAnnotations(metadata).ToList(); if (contract.ReadIndex != null) { metadata.Flags |= RelationMetadataFlags.Readable; } if (contract.WriteIndex != null) { metadata.Flags |= RelationMetadataFlags.Writable; } if (metadata.Item != null) { metadata.Flags |= RelationMetadataFlags.List; } return(metadata); }
private RelationMetadata CreateProperty(RelationMetadata parent, MemberInfo memberInfo) { MetadataIdentity propertyId = parent.Identity.Push(memberInfo.Name); RelationMetadata metadata = new RelationMetadata(parent.Schema, propertyId) { Type = this.GetMemberType(memberInfo), Parent = parent, Member = memberInfo, Owner = parent.Owner, Flags = RelationMetadataFlags.Property, Depth = parent.Depth, }; metadata.Item = this.CreateItem(metadata); metadata.Properties = this.CreateLazy(() => this.CreateProperties(metadata)); metadata.Annotations = this.CreateAnnotations(metadata).ToList(); if (metadata.Item != null) { metadata.Flags |= RelationMetadataFlags.List; } if (memberInfo is PropertyInfo pi) { if (pi.CanRead) { metadata.Flags |= RelationMetadataFlags.Readable; } if (pi.CanWrite) { metadata.Flags |= RelationMetadataFlags.Writable; } } else if (memberInfo is FieldInfo) { metadata.Flags |= RelationMetadataFlags.Readable | RelationMetadataFlags.Writable; } parent.Schema.AddMetadata <IRelationMetadata>(metadata); if (metadata.Item != null) { parent.Schema.AddMetadata <IRelationMetadata>(metadata.Item); } this.AddRecursors(metadata); return(metadata); }
private Schema CreateSchema(Type modelType) { Schema newSchema = new Schema(this, modelType); foreach (IMetadataBuilder builder in this) { MetadataIdentity newIdentity = new MetadataIdentity(newSchema, this.Notation.Model()); MetadataBuilderContext context = new MetadataBuilderContext(newIdentity, newSchema); builder.Initialize(context); } return(newSchema); }
private RelationMetadata CreateItem(IMetadataBuilderContext context, RelationMetadata parent) { IRelationListContract contract = this.GetListContract(parent); if (contract == null) { return(null); } MetadataIdentity itemId = parent.Identity.Child(contract.ItemName ?? "Item"); RelationMetadata metadata = new RelationMetadata(itemId) { Parent = parent, Type = contract.ItemType, Flags = RelationMetadataFlags.Item | RelationMetadataFlags.Property, ReadIndex = contract.ReadIndex, WriteIndex = contract.WriteIndex, }; metadata.MemberOf = metadata; metadata.Item = this.CreateItem(context, metadata); metadata.Properties = this.CreateLazy(() => this.CreateProperties(context, metadata)); metadata.Annotations = this.CreateAnnotations(metadata).ToList(); if (this.IsMetadataRecursive(metadata)) { metadata.Flags |= RelationMetadataFlags.Recursive; } if (contract.ReadIndex != null) { metadata.Flags |= RelationMetadataFlags.Readable; } if (contract.WriteIndex != null) { metadata.Flags |= RelationMetadataFlags.Writable; } if (metadata.Item != null) { metadata.Flags |= RelationMetadataFlags.List; } context.AddMetadata <IRelationMetadata>(metadata); return(metadata); }
private RelationMetadata CreateProperty(IMetadataBuilderContext context, RelationMetadata parent, MemberInfo memberInfo) { MetadataIdentity attributeId = parent.Identity.Child(memberInfo.Name); RelationMetadata metadata = new RelationMetadata(attributeId) { Type = this.GetMemberType(memberInfo), Parent = parent, Member = memberInfo, MemberOf = parent.MemberOf, Flags = RelationMetadataFlags.Property, }; metadata.Item = this.CreateItem(context, metadata); metadata.Properties = this.CreateLazy(() => this.CreateProperties(context, metadata)); metadata.Annotations = this.CreateAnnotations(metadata).ToList(); if (metadata.Item != null) { metadata.Flags |= RelationMetadataFlags.List; } if (this.IsMetadataRecursive(metadata)) { metadata.Flags |= RelationMetadataFlags.Recursive; } if (memberInfo is PropertyInfo pi) { if (pi.CanRead) { metadata.Flags |= RelationMetadataFlags.Readable; } if (pi.CanWrite) { metadata.Flags |= RelationMetadataFlags.Writable; } } else if (memberInfo is FieldInfo) { metadata.Flags |= RelationMetadataFlags.Readable | RelationMetadataFlags.Writable; } context.AddMetadata <IRelationMetadata>(metadata); return(metadata); }
private IRelationMetadata GetMetadata(IMetadataBuilderContext context, MetadataIdentity identity) { MetadataIdentity parentIdentity = identity.Parent(); IRelationMetadata parent = context.GetMetadata <IRelationMetadata>(parentIdentity.Name) ?? this.GetMetadata(context, parentIdentity); if (parent == null) { return(null); } else if (parent.Item != null && parent.Item.Identity.Equals(identity)) { return(parent.Item); } return(parent.Properties.FirstOrDefault(m => m.Identity.Equals(identity))); }
internal IRelationMetadata GetMetadata(Schema schema, MetadataIdentity identity) { MetadataIdentity parentIdentity = identity.Pop(); IRelationMetadata parent = schema.GetCachedMetadata <IRelationMetadata>(parentIdentity.Name) ?? this.GetMetadata(schema, parentIdentity); if (parent == null) { return(null); } else if (parent.Item != null && parent.Item.Identity.Equals(identity)) { return(parent.Item); } return(parent.Properties.FirstOrDefault(m => m.Identity.Equals(identity))); }
public static MetadataNotFoundException FromMetadata <TMetadata>(MetadataIdentity identity, string message = null, Exception innerException = null) where TMetadata : IMetadata { string fullMessage; if (identity != null) { fullMessage = $"Metadata of type '{typeof(TMetadata).GetSanitizedName()}' not found for property '{identity.Name}' in schema '{identity.Schema.Model.GetSanitizedFullName()}'."; } else { fullMessage = $"Metadata of type '{typeof(TMetadata).GetSanitizedName()}' not found."; } if (message != null || innerException?.Message != null) { fullMessage += $" {message}"; } return(new MetadataNotFoundException(fullMessage, innerException)); }
public TMetadata Lookup <TMetadata>(string name) where TMetadata : IMetadata { MetadataKey key = this.CreateKey <TMetadata>(name); ReaderWriterLockSlim slim = this.GetLock <TMetadata>(); try { slim.EnterReadLock(); if (this.entries.TryGetValue(key, out object value)) { return((TMetadata)value); } } catch (LockRecursionException ex) { throw MetadataBuilderException.NoRecursion <TMetadata>(name, ex); } finally { if (slim.IsReadLockHeld) { slim.ExitReadLock(); } } slim.EnterWriteLock(); try { MetadataIdentity identity = new MetadataIdentity(this, name); IRelationMetadata relation = this.GetCachedMetadata <IRelationMetadata>(name) ?? this.Store.RelationBuilder.GetMetadata(this, identity); if (relation == null) { return(default);
internal void Initialize(Schema schema, Type modelType) { MetadataIdentity identity = new MetadataIdentity(schema); RelationMetadata metadata = new RelationMetadata(schema, identity) { Flags = RelationMetadataFlags.Model | RelationMetadataFlags.Readable, Type = modelType, }; metadata.Owner = metadata; metadata.Properties = this.CreateLazy(() => this.CreateProperties(metadata)); metadata.Depth = 0; metadata.Annotations = this.CreateAnnotations(metadata).ToList(); metadata.Item = this.CreateItem(metadata); if (metadata.Item != null) { metadata.Flags |= RelationMetadataFlags.List; } schema.AddMetadata <IRelationMetadata>(metadata); }
public static MetadataKey FromIdentity <TMetadata>(MetadataIdentity identity) => new MetadataKey(typeof(TMetadata), identity.Name, identity.Schema.Notation.Comparer);
public RelationMetadata(MetadataIdentity identity) { this.Identity = identity ?? throw new ArgumentNullException(nameof(identity)); }
public MetadataBuilderContext(MetadataIdentity identity, Schema schema) { this.Identity = identity ?? throw new ArgumentNullException(nameof(identity)); this.Schema = schema ?? throw new ArgumentNullException(nameof(schema)); }
public RelationMetadata(Schema schema, MetadataIdentity identity) { this.Schema = schema ?? throw new ArgumentNullException(nameof(identity)); this.Notation = schema.Notation; this.Identity = identity ?? throw new ArgumentNullException(nameof(identity)); }