public void ProcessPath( Resource startingResource, string pathName, string pathExpression, Action <ResourceProperty, string> processPropertyCallback = null, Action <Reference, string> processReferenceCallback = null, Action <Collection, string> processCollectionCallback = null, Action <LinkedCollection, string> processLinkedCollectionCallback = null, Action <EmbeddedObject, string> processEmbeddedObjectCallback = null) { var resourceModel = startingResource.ResourceModel; string[] pathParts = pathExpression.Split( new[] { "->", "." }, StringSplitOptions.None); ResourceClassBase currentFilterModel = startingResource; foreach (string part in pathParts) { ResourceMemberBase member; // TODO: Embedded convention - reference properties end with "Reference" suffix if (!currentFilterModel.MemberByName.TryGetValue(part, out member) && !currentFilterModel.MemberByName.TryGetValue(part.EnsureSuffixApplied("Reference"), out member)) { throw new Exception( string.Format( "Unable to find member '{0}' on resource class '{1}' for path '{2}' using path expression '{3}'.", part, currentFilterModel.Name, string.IsNullOrEmpty(pathName) ? "(unspecifed)" : pathName, pathExpression)); } var property = member as ResourceProperty; if (property != null) { if (processPropertyCallback != null) { processPropertyCallback(property, part); } break; } var reference = member as Reference; if (reference != null) { // TODO: Embedded convention - reference properties end with "Reference" suffix if (processReferenceCallback != null) { processReferenceCallback(reference, part.EnsureSuffixApplied("Reference")); } currentFilterModel = resourceModel.GetResourceByFullName(reference.ReferencedResource.Entity.FullName); continue; } var linkedCollection = member as LinkedCollection; if (linkedCollection != null) { if (processLinkedCollectionCallback != null) { processLinkedCollectionCallback(linkedCollection, part); } currentFilterModel = resourceModel.GetResourceByFullName(linkedCollection.Association.OtherEntity.FullName); continue; } var collection = member as Collection; if (collection != null) { if (processCollectionCallback != null) { processCollectionCallback(collection, part); } currentFilterModel = collection.ItemType; continue; } var embeddedObject = member as EmbeddedObject; if (embeddedObject != null) { if (processEmbeddedObjectCallback != null) { processEmbeddedObjectCallback(embeddedObject, part); } currentFilterModel = embeddedObject.ObjectType; continue; } throw new NotSupportedException( string.Format( "Filter join implementation does not support resource model type '{0}'.", member.GetType() .FullName)); } }
public EmbeddedObject(ResourceClassBase resourceClass, ResourceChildItem objectType, string displayName) : base(resourceClass, displayName, displayName.ToCamelCase()) { ObjectType = objectType; }
public Reference(ResourceClassBase resourceClass, AssociationView association) : this(resourceClass, association, association.Name + "Reference") { }
public Collection(ResourceClassBase resourceClass, ResourceChildItem itemType, AssociationView association, string memberDisplayName) : base(resourceClass, memberDisplayName, memberDisplayName.ToCamelCase()) { ItemType = itemType; Association = association; }
public IMemberFilter GetMemberFilter(ResourceClassBase resourceClass, XElement definition) { string memberSelectionMode = definition.AttributeValue("memberSelection"); // TODO: Embedded rule - Profiles always include PK properties var identifyingPropertyNames = resourceClass.IdentifyingProperties.Select(p => p.PropertyName); var identifyingReferences = resourceClass.References.Where(r => r.Association.IsIdentifying) .Select(r => r.PropertyName); var baseMemberNames = definition .Elements() .Where(e => ProfileDefinitionMemberElementNames.Contains(e.Name.ToString())) .Select(e => e.AttributeValue("name")) .Where(n => !string.IsNullOrEmpty(n)); var extensionNames = definition .Elements("Extension") .Select(e => e.AttributeValue("name")) .Where(n => !string.IsNullOrEmpty(n) && resourceClass.ResourceModel.SchemaNameMapProvider != null) .Select( x => resourceClass.ResourceModel.SchemaNameMapProvider.GetSchemaMapByLogicalName(x) .ProperCaseName) .ToArray(); var extensionMembers = definition .Descendants("Property") .Select(e => e.AttributeValue("name")) .Where(n => !string.IsNullOrEmpty(n)) .ToArray(); IMemberFilter memberFilter; switch (memberSelectionMode) { case "IncludeAll": memberFilter = new IncludeAllMemberFilter(); break; case "IncludeOnly": var includedMemberNames = identifyingPropertyNames.Concat(identifyingReferences) .Concat(baseMemberNames) .ToArray(); // Expand filter to include UniqueId versions on names alongside USI names var includedUsiExpansionNames = includedMemberNames .Where(n => n.EndsWith("USI")) .Select(n => n.Replace("USI", "UniqueId")); memberFilter = new IncludeOnlyMemberFilter( includedMemberNames.Concat(includedUsiExpansionNames) .Concat(extensionMembers) .ToArray(), extensionNames); break; case "ExcludeOnly": var excludedMemberNames = baseMemberNames .ToArray(); var excludedUsiExpansionNames = excludedMemberNames .Where(n => n.EndsWith("USI")) .Select(n => n.Replace("USI", "UniqueId")); memberFilter = new ExcludeOnlyMemberFilter( excludedMemberNames .Concat(excludedUsiExpansionNames) .Except(identifyingPropertyNames) // Don't let identifying properties be excluded. .Except(identifyingReferences) // Don't let identifying references be excluded. .Concat(extensionMembers) .ToArray(), extensionNames); break; default: throw new NotImplementedException( string.Format("Member selection mode '{0}' is not supported.", memberSelectionMode)); } return(memberFilter); }