예제 #1
0
 /// <summary>
 /// Contains all the references for the resource including all extension properties.
 /// </summary>
 /// <param name="resourceClassBase">Resource object</param>
 /// <returns></returns>
 public static IEnumerable <Reference> UnifiedReferences(this ResourceClassBase resourceClassBase)
 {
     return(resourceClassBase.References
            .Concat(resourceClassBase.ExtensionReferences()));
 }
예제 #2
0
 private static bool IsDefiningUniqueId(ResourceClassBase resourceClass, ResourceProperty property)
 {
     return(UniqueIdSpecification.IsUniqueId(property.PropertyName) &&
            PersonEntitySpecification.IsPersonEntity(resourceClass.Name));
 }
예제 #3
0
 public static bool IsAggregateReference(this ResourceClassBase resource)
 {
     return(resource.IsAggregateRoot() && !resource.IsDescriptorEntity());
 }
        public object FilteredDelegates(ResourceProfileData profileData, ResourceClassBase resourceClass)
        {
            var collectionPairs = Resources.GetMemberItemPairs(resourceClass, r => r?.Collections);

            if (!collectionPairs.Any())
            {
                return(ResourceRenderer.DoNotRenderProperty);
            }

            var toRender = new List <object>();

            //unfiltered objects
            toRender.AddRange(
                collectionPairs.Where(x => x.Current == null || !x.Current.ValueFilters.Any())
                .Select(
                    x => new
            {
                ItemTypeNamespacePrefix = x.Underlying.ItemType.GetNamespacePrefix(),
                ItemType     = x.Underlying.ItemType.Name,
                PropertyName = x.Underlying.ItemType.Name,
                ParentName   =
                    resourceClass.IsDerived && !resourceClass.IsDescriptorEntity()
                                    ? resourceClass.Entity.Aggregate.Name
                                    : x.Underlying.ParentFullName.Name,
                Standard = ResourceRenderer.DoRenderProperty
            }));

            // filtered objects
            toRender.AddRange(
                collectionPairs
                .Where(x => x.Current != null && x.Current.ValueFilters.Any())
                .OrderBy(x => x.Underlying.PropertyName)
                .Select(
                    x =>
                    new
            {
                ItemTypeNamespacePrefix = x.Underlying.ItemType.GetNamespacePrefix(),
                ItemType     = x.Underlying.ItemType.Name,
                PropertyName = x.Underlying.ItemType.Name,
                ParentName   =
                    resourceClass.IsDerived && !resourceClass.IsDescriptorEntity()
                                        ? resourceClass.Entity.Aggregate.Name
                                        : x.Underlying.ParentFullName.Name,
                FilteredValues = x.Current.ValueFilters
                                 .SelectMany(
                    y => y.Values.Select(
                        z => new
                {
                    FilteredPropertyName = y.PropertyName,
                    FilteredValue        = z,
                    NotFirst             = z != y.Values.First(),
                    IsIncluded           = y.FilterMode == ItemFilterMode.IncludeOnly,
                    IsLast = z == y.Values.Last()
                })),
                Filtered = ResourceRenderer.DoRenderProperty
            }));

            return(toRender.Any()
                ? toRender
                : ResourceRenderer.DoNotRenderProperty);
        }
        public object References(ResourceProfileData profileData, ResourceClassBase resource, TemplateContext TemplateContext)
        {
            var activeResource = profileData.GetProfileActiveResource(resource);

            var references = activeResource.References
                             .ToList();

            if (!references.Any(x => profileData.IsIncluded(resource, x)))
            {
                return(ResourceRenderer.DoNotRenderProperty);
            }

            if (activeResource.IsAggregateRoot() || !activeResource.HasBackReferences())
            {
                return(new
                {
                    Collections = references
                                  .Where(x => profileData.IsIncluded(resource, x))
                                  .OrderBy(x => x.PropertyName)
                                  .Select(
                        x =>
                    {
                        bool renderNamespace =
                            !(x.Association.IsSelfReferencing ||
                              x.Association.IsSelfReferencingManyToMany) ||
                            x.Association.OtherEntity.IsAbstract ||
                            !x.Association.OtherEntity.IsSameAggregate(
                                resource.Entity);

                        string referenceName = !renderNamespace
                                    ? x.ReferenceTypeName
                                    : $"{x.ReferencedResourceName}.{x.ReferencedResource.Entity.SchemaProperCaseName()}.{x.ReferenceTypeName}";

                        return new
                        {
                            Reference = new
                            {
                                ReferencedResourceName = x.ReferencedResourceName,
                                ReferenceTypeName =
                                    !x.ReferencedResource.Entity
                                    .IsExtensionEntity &&
                                    !x.ReferenceTypeName.Replace("Reference", string.Empty)
                                    .Equals(resource.Name) &&
                                    !x.ReferenceTypeName.Replace("Reference", string.Empty)
                                    .Equals((resource as ResourceChildItem)?.Parent.Name)
                                                ? $"{x.ReferencedResourceName}.{EdFiConventions.ProperCaseName}.{x.ReferenceTypeName}"
                                                : referenceName,
                                Name = x.ParentFullName.Name,

                                // using the property name so we do not break the data member contract
                                // from the original template.
                                JsonPropertyName = x.PropertyName.ToCamelCase(),
                                PropertyName = x.PropertyName,
                                PropertyFieldName = x.PropertyName.ToCamelCase(),
                                IsRequired = x.IsRequired,
                                IsIdentifying = x.Association.IsIdentifying
                            },
                            Standard = ResourceRenderer.DoRenderProperty
                        };
                    }
                        )
                                  .ToList()
                });
            }

            return(new
            {
                Collections = activeResource.References
                              .OrderBy(x => x.PropertyName)
                              .Select(
                    x => new
                {
                    Reference = new
                    {
                        ReferencedResourceName = x.ReferencedResourceName,
                        ReferenceTypeName = x.ReferenceTypeName,
                        Name = x.ParentFullName.Name,
                        JsonPropertyName = x.JsonPropertyName,
                        PropertyName = x.PropertyName,
                        PropertyFieldName = x.PropertyName.ToCamelCase(),
                        IsRequired = x.IsRequired,
                        IsIdentifying = x.Association.IsIdentifying,
                        BackReferenceType =
                            string.Format(
                                "{0}To{1}Reference",
                                x.Association.ThisEntity.Name,
                                x.Association.OtherEntity.Name)
                    },
                    Backref = ResourceRenderer.DoRenderProperty
                }
                    )
                              .ToList()
            });
        }
예제 #6
0
        private IEnumerable <PropertyData> CreateProperties(ResourceClassBase resourceClass)
        {
            var allPossibleProperties = resourceClass.FilterContext.UnfilteredResourceClass?.NonIdentifyingProperties ??
                                        resourceClass.NonIdentifyingProperties;

            var currentProperties = resourceClass.AllProperties;

            var propertyPairs =
                (from p in allPossibleProperties
                 join c in currentProperties on p.PropertyName equals c.PropertyName into leftJoin
                 from _c in leftJoin.DefaultIfEmpty()
                 where

                 // Non-identifying properties only
                 !p.IsIdentifying

                 // Exclude boilerplate "id" property
                 && !p.PropertyName.Equals("Id")

                 // Exclude inherited properties
                 && !p.IsInheritedProperty()
                 orderby p.PropertyName
                 select new
            {
                UnderlyingProperty = p,
                CurrentProperty = _c
            })
                .ToList();

            foreach (var propertyPair in propertyPairs)
            {
                // If the property was filtered out, then generate an explicit interface "Null" implementation only.
                if (propertyPair.CurrentProperty == null)
                {
                    yield return(PropertyData.CreateNullProperty(propertyPair.UnderlyingProperty));

                    continue;
                }

                var property = propertyPair.CurrentProperty;

                if (property.IsSynchronizable())
                {
                    if (resourceClass.IsDescriptorEntity())
                    {
                        if (!property.IsInheritedProperty())
                        {
                            yield return(AssembleDerivedProperty(property));
                        }
                    }
                    else if (property.IsDirectLookup)
                    {
                        yield return(PropertyData.CreateStandardProperty(property));
                    }
                    else
                    {
                        yield return
                            (property.HasAssociations()
                                ? PropertyData.CreateReferencedProperty(property)
                                : PropertyData.CreateStandardProperty(property));
                    }
                }
                else
                {
                    if (property.HasAssociations())
                    {
                        yield return(property.IsLookup
                            ? PropertyData.CreateStandardProperty(property)
                            : PropertyData.CreateReferencedProperty(property));
                    }
                    else
                    {
                        yield return(PropertyData.CreateStandardProperty(property));
                    }
                }
            }
        }
 public Schema GetEdFiExtensionBridgeSchema(ResourceClassBase resource, ISwaggerResourceContext resourceContext)
 {
     //No Extension bridge schema
     return(null);
 }
예제 #8
0
 /// <summary>
 /// Check if resource is a descriptor entity.
 /// </summary>
 /// <param name="resource"></param>
 /// <returns></returns>
 public static bool IsDescriptorEntity(this ResourceClassBase resource)
 {
     return(resource.Entity.IsDescriptorEntity);
 }
예제 #9
0
 /// <summary>
 /// Check if resource has any unified keys
 /// </summary>
 /// <param name="resource"></param>
 /// <returns></returns>
 public static bool HasUnifiedKeys(this ResourceClassBase resource)
 {
     return(resource.IdentifyingProperties.Any(x => x.IsUnified()));
 }
예제 #10
0
 /// <summary>
 /// Check if resource is a type entity.
 /// </summary>
 /// <param name="resource"></param>
 /// <returns></returns>
 public static bool IsTypeEntity(this ResourceClassBase resource)
 {
     return(resource.Entity.IsTypeEntity);
 }
예제 #11
0
 /// <summary>
 /// Check if resource is a base entity.
 /// </summary>
 /// <param name="resourceClassBase">Resource object</param>
 /// <returns></returns>
 public static bool IsBase(this ResourceClassBase resourceClassBase)
 {
     return(resourceClassBase.Entity != null && resourceClassBase.Entity.IsBase);
 }
예제 #12
0
 /// <summary>
 /// Check if resource is abstract.
 /// </summary>
 /// <param name="resourceClassBase">Resource object</param>
 /// <returns></returns>
 public static bool IsAbstract(this ResourceClassBase resourceClassBase)
 {
     return(resourceClassBase.Entity.IsAbstract);
 }
예제 #13
0
 /// <summary>
 /// Contains all the properties for the resource including all extension properties.
 /// </summary>
 /// <param name="resourceClassBase">Resource object</param>
 /// <returns></returns>
 public static IEnumerable <ResourceProperty> UnifiedAllProperties(this ResourceClassBase resourceClassBase)
 {
     return
         (resourceClassBase.AllProperties.Concat(resourceClassBase.GetAllExtensionProperties()));
 }
예제 #14
0
 /// <summary>
 /// Get properties that are defined on the entities underlying this resource.
 /// </summary>
 /// <param name="resourceClassBase"></param>
 /// <returns></returns>
 public static IEnumerable <ResourceProperty> GetLocalResourceProperties(
     this ResourceClassBase resourceClassBase)
 {
     return(resourceClassBase.Properties.Where(x => x.EntityProperty.IsLocallyDefined));
 }
예제 #15
0
        public object AssembleInheritedProperties(
            ResourceProfileData profileData,
            ResourceClassBase resource)
        {
            if (profileData == null)
            {
                throw new ArgumentNullException(nameof(profileData));
            }

            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            IList <ResourcePropertyData> includedProperties = null;

            if (profileData.HasProfile)
            {
                includedProperties = (resource.Name == profileData.SuppliedResource.Name
                        ? profileData.UnfilteredResource
                        : resource).InheritedProperties()
                                     .Where(x => !x.IsIdentifying && !x.PropertyName.Equals("Id"))
                                     .OrderBy(x => x.PropertyName)
                                     .Select(
                    x =>
                    new ResourcePropertyData
                {
                    Property           = x,
                    IsStandardProperty = !profileData.IsIncluded(resource, x)
                })
                                     .ToList();
            }
            else
            {
                includedProperties = resource.InheritedProperties()
                                     .OrderBy(x => x.PropertyName)
                                     .Where(x => !x.IsIdentifying && !x.PropertyName.Equals("Id"))
                                     .Select(
                    x => new ResourcePropertyData
                {
                    Property           = x,
                    IsStandardProperty = false
                })
                                     .ToList();
            }

            var propertiesToRender = new List <PropertyData>();

            if (resource.IsDescriptorEntity() &&
                resource.InheritedProperties()
                .Any(x => !x.IsIdentifying && !x.PropertyName.Equals("Id")))
            {
                propertiesToRender.AddRange(
                    includedProperties.Select(
                        x =>
                {
                    var propertyData = x.IsStandardProperty
                                ? PropertyData.CreateNullProperty(x.Property)
                                : PropertyData.CreateStandardProperty(x.Property);

                    propertyData[ResourceRenderer.MiscellaneousComment] = "// NOT in a reference, NOT a lookup column ";
                    return(propertyData);
                }));
            }
            else if (resource.IsDerived)
            {
                propertiesToRender.AddRange(
                    includedProperties.Select(
                        x => x.IsStandardProperty
                            ? PropertyData.CreateNullProperty(x.Property)
                            : PropertyData.CreateStandardProperty(x.Property)));
            }

            return(propertiesToRender.Any()
                ? new { Properties = CreatePropertyDtos(propertiesToRender) }
                : ResourceRenderer.DoNotRenderProperty);
        }
예제 #16
0
 /// <summary>
 /// Gets the parent for the resource.
 /// </summary>
 /// <param name="resource"></param>
 /// <returns></returns>
 public static Entity GetParent(this ResourceClassBase resource)
 {
     return(resource.Entity.Parent);
 }
예제 #17
0
        public object AssemblePrimaryKeys(
            ResourceProfileData profileData,
            ResourceClassBase resourceClass,
            TemplateContext templateContext)
        {
            if (profileData == null)
            {
                throw new ArgumentNullException(nameof(profileData));
            }

            if (resourceClass == null)
            {
                throw new ArgumentNullException(nameof(resourceClass));
            }

            if (templateContext == null)
            {
                throw new ArgumentNullException(nameof(templateContext));
            }

            var pks = new List <object>();

            var activeResource = profileData.GetProfileActiveResource(resourceClass);

            var filteredResource = profileData.GetContainedResource(resourceClass) ?? resourceClass;

            if (resourceClass is ResourceChildItem)
            {
                pks.Add(
                    new
                {
                    HasParent = ResourceRenderer.DoRenderProperty,
                    Property  = new
                    {
                        PropertyName =
                            resourceClass.GetResourceInterfaceName(
                                templateContext.GetSchemaProperCaseNameForResource(resourceClass),
                                templateContext.IsProfiles,
                                templateContext.IsExtension),
                        ReferencesWithUnifiedKey =
                            resourceClass.References
                            .Where(@ref => @ref.Properties.Any(rp => rp.IsUnified()))
                            .Select(@ref => new
                        {
                            ReferencePropertyName = @ref.PropertyName,
                            ReferenceFieldName    = @ref.PropertyName.ToCamelCase(),
                            UnifiedKeyProperties  = @ref.Properties
                                                    .Where(rp => rp.IsUnified())
                                                    .Select(rp => new
                            {
                                UnifiedKeyPropertyName = rp.PropertyName
                            })
                        })
                    }
                });
            }

            var props = new List <PropertyData>();

            foreach (var property in activeResource.AllProperties
                     .Where(x => x.IsIdentifying)
                     .OrderBy(x => x.PropertyName))
            {
                if (activeResource.IsDescriptorEntity())
                {
                    props.Add(PropertyData.CreateDerivedProperty(property));
                    continue;
                }

                if (activeResource.IsAggregateRoot())
                {
                    if (resourceClass.IsDerived)
                    {
                        props.Add(AssembleDerivedProperty(property));
                    }
                    else
                    {
                        props.Add(
                            property.IsPersonOrUsi() && !templateContext.IsExtension
                                ? PropertyData.CreateUsiPrimaryKey(property)
                                : property.HasAssociations() && !property.IsDirectLookup
                                    ? PropertyData.CreateReferencedProperty(property, resource: filteredResource)
                                    : PropertyData.CreateStandardProperty(property));
                    }
                }
                else
                {
                    // non aggregate root
                    if (activeResource.References.Any())
                    {
                        if (property.IsPersonOrUsi())
                        {
                            props.Add(PropertyData.CreateUsiPrimaryKey(property));
                            continue;
                        }

                        if (resourceClass.HasBackReferences() &&
                            resourceClass.BackReferencedProperties()
                            .Contains(property, ModelComparers.ResourcePropertyNameOnly))
                        {
                            continue;
                        }

                        props.Add(
                            property.HasAssociations() && !property.IsDirectLookup
                                ? PropertyData.CreateReferencedProperty(property)
                                : PropertyData.CreateStandardProperty(property));
                    }
                    else
                    {
                        props.Add(PropertyData.CreateStandardProperty(property));
                    }
                }
            }

            pks.AddRange(CreatePropertyDtos(props));

            return(pks.Any()
                ? new { Properties = pks }
                : ResourceRenderer.DoNotRenderProperty);
        }
예제 #18
0
 /// <summary>
 /// Check if resource is EdFi entity.
 /// </summary>
 /// <param name="resourceClassBase">Resource object</param>
 /// <returns></returns>
 public static bool IsEdFiResource(this ResourceClassBase resourceClassBase)
 {
     return(resourceClassBase.Entity != null && resourceClassBase.Entity.IsEdFiStandardEntity);
 }
예제 #19
0
        public static PropertyData CreateReferencedProperty(
            ResourceProperty property,
            string desc                = null,
            string className           = null,
            ResourceClassBase resource = null)
        {
            var propertyData = new PropertyData(property);

            var associations = resource == null || !resource.References.Any()
                ? property.EntityProperty.IncomingAssociations
                : resource.References.Where(
                r =>
                r.Properties.Contains(
                    property,
                    ModelComparers.ResourcePropertyNameOnly))
                               .Select(r => r.Association)
                               .ToList();

            // we want to prioritize identifiers that are not optional.
            var association =
                associations
                .OrderBy(x => x.ThisProperties.Any(y => y.PropertyType.IsNullable))
                .ThenBy(x => x.Name)
                .FirstOrDefault(
                    x => x.PropertyMappingByThisName.ContainsKey(property.PropertyName) ||
                    x.PropertyMappingByThisName.ContainsKey(property.EntityProperty.PropertyName));

            var parent = association != null
                ? association.PropertyMappingByThisName.ContainsKey(property.PropertyName)
                    ? association.PropertyMappingByThisName[property.PropertyName]
                         .OtherProperty
                    : association.PropertyMappingByThisName.ContainsKey(property.EntityProperty.PropertyName)
                        ? association.PropertyMappingByThisName[property.EntityProperty.PropertyName]
                         .OtherProperty
                        : null
                : null;

            string parentPropertyName = parent != null
                ? property.IsLookup
                    ? parent.PropertyName.TrimSuffix("Id")
                    : UniqueIdSpecification.GetUniqueIdPropertyName(parent.PropertyName)
                : property.ParentFullName.Name;

            propertyData[ResourceRenderer.ParentPropertyName] = UniqueIdSpecification.GetUniqueIdPropertyName(parentPropertyName);

            if (className != null)
            {
                propertyData[ResourceRenderer.ClassName] = className;
            }

            if (desc != null)
            {
                propertyData[ResourceRenderer.DescriptionOverride] = desc;
            }

            if (associations.Any())
            {
                propertyData.Associations.AddRange(associations);
            }

            if (property.IsLookup)
            {
                propertyData[ResourceRenderer.RenderType] = ResourceRenderer.RenderUnified;

                propertyData[ResourceRenderer.MiscellaneousComment] =
                    string.Format(
                        "// IS in a reference ({0}.{1}Id), IS a lookup column ",
                        className ?? property.EntityProperty.Entity.ResolvedEdFiEntityName(),
                        property.PropertyName);
            }
            else
            {
                propertyData[ResourceRenderer.MiscellaneousComment] = "// IS in a reference, NOT a lookup column ";
                propertyData[ResourceRenderer.RenderType]           = ResourceRenderer.RenderReferenced;
            }

            return(propertyData);
        }
예제 #20
0
 /// <summary>
 /// Determines if the resource can be extended using extensions.
 /// </summary>
 /// <param name="resource"></param>
 /// <returns></returns>
 public static bool IsExtendable(this ResourceClassBase resource)
 {
     return(resource.Entity?.IsExtendable() == true);
 }
        public object SynchronizationSourceSupport(
            ResourceProfileData profileData,
            ResourceClassBase resourceClass,
            TemplateContext TemplateContext)
        {
            var collectionPairs = Resources.GetMemberItemPairs(resourceClass, r => r?.Collections);

            var synchSupportCollections =
                collectionPairs.Select(
                    itemPair =>
            {
                bool isExcluded = itemPair.Current == null;

                return(new
                {
                    ParentName =
                        resourceClass.IsDerived
                                    ? resourceClass.Name
                                    : itemPair.Underlying.Parent.Name,
                    PropertyName = itemPair.Underlying.ItemType.PluralName,
                    IsExcluded = isExcluded
                });
            });

            // Properties
            var allPossibleProperties = resourceClass.FilterContext.UnfilteredResourceClass?.AllProperties ??
                                        resourceClass.AllProperties;

            var currentProperties = resourceClass.AllProperties;

            var propertyPairs =
                (from p in allPossibleProperties
                 join c in currentProperties on p.PropertyName equals c.PropertyName into leftJoin
                 from _c in leftJoin.DefaultIfEmpty()
                 where p.IsSynchronizable()
                 orderby p.PropertyName
                 select new
            {
                UnderlyingProperty = p,
                CurrentProperty = _c
            })
                .ToList();

            var synchSupportProperties =
                propertyPairs.Select(
                    x =>
            {
                bool isExcluded = x.CurrentProperty == null;

                return(new
                {
                    ParentName = x.UnderlyingProperty.Parent != null
                                    ? x.UnderlyingProperty.Parent.Name
                                    : resourceClass.Name,
                    PropertyName = x.UnderlyingProperty.PropertyName,
                    IsExcluded = isExcluded
                });
            })
                .ToList();

            // Embedded Objects
            var allPossibleEmbeddedObjects = resourceClass.FilterContext.UnfilteredResourceClass?.EmbeddedObjects ??
                                             resourceClass.EmbeddedObjects;

            var currentEmbeddedObjects = resourceClass.EmbeddedObjects;

            var embeddedObjectPairs =
                (from p in allPossibleEmbeddedObjects
                 join c in currentEmbeddedObjects on p.PropertyName equals c.PropertyName into leftJoin
                 from _c in leftJoin.DefaultIfEmpty()
                 orderby p.PropertyName
                 select new
            {
                UnderlyingEmbeddedObject = p,
                CurrentEmbeddedObject = _c
            })
                .ToList();

            var synchSupportEmbeddedObjects =
                embeddedObjectPairs.Select(
                    x => new
            {
                ParentName   = x.UnderlyingEmbeddedObject.Parent.Name,
                PropertyName = x.UnderlyingEmbeddedObject.PropertyName,
                IsExcluded   = x.CurrentEmbeddedObject == null
            });

            var synchSupportMembers =
                synchSupportCollections
                .Concat(synchSupportProperties)
                .Concat(synchSupportEmbeddedObjects)
                .ToList();

            if (!synchSupportMembers.Any())
            {
                return(ResourceRenderer.DoNotRenderProperty);
            }

            int horizontalSpaceAllocation = synchSupportMembers.Max(x => x.PropertyName.Length)
                                            + "IsSupported".Length + 1;

            return
                (synchSupportMembers
                 .OrderBy(x => x.PropertyName)
                 .Distinct()
                 .Select(
                     x =>
                     new
            {
                ParentName = x.ParentName,
                PropertyName = x.PropertyName,
                SourceSupport = string.Format("Is{0}Supported", x.PropertyName)
                                .PadRight(horizontalSpaceAllocation),
                IsExcluded = x.IsExcluded
            })
                 .ToList());
        }
예제 #22
0
 /// <summary>
 /// Indicates whether the supplied resource class was inherited as a child member of the resource root class' base class.
 /// </summary>
 /// <param name="resourceClass"></param>
 /// <returns></returns>
 public static bool IsInheritedChildItem(this ResourceClassBase resourceClass)
 {
     return((resourceClass as ResourceChildItem)?.IsInheritedChildItem == true);
 }
        public object CreatePutPostRequestValidator(
            ResourceProfileData profileData,
            ResourceClassBase resource,
            TemplateContext templateContext)
        {
            return(new PutPostRequestValidator
            {
                EntityName = resource.Name,
                Collections = resource.Collections
                              // TODO: Remove this filter with dynamic profiles
                              .Where(collection => !profileData.HasProfile || profileData.IsIncluded(resource, collection))
                              .Select(
                    collection => new PutPostRequestValidatorCollectionProperty
                {
                    PropertyName = collection.PropertyName,
                    PropertyFieldNamePrefix = collection.PropertyName.ToCamelCase(),
                    ItemTypeName = collection.ItemType.Name,
                    Namespace = collection.ParentFullName.Name != resource.Name
                                ? string.Format(
                        "{0}.{1}.{2}",
                        collection.ParentFullName.Name,
                        profileData.HasProfile ? resource.SchemaProperCaseName : resource.Entity.BaseEntity.SchemaProperCaseName(),
                        profileData.ProfilePropertyNamespaceSection)
                                : ResourceRenderer.DoNotRenderProperty
                }),
                HasProfileItemFilterValidations = profileData.HasProfile &&
                                                  profileData.IsWritable &&
                                                  profileData.HasFilteredCollection() &&
                                                  GetItemFilterValidations().Any(),
                ProfileItemFilterValidations = GetItemFilterValidations(),
                KeyUnificationValidations = new KeyUnificationValidation
                {
                    ResourceClassName = resource.Name,
                    ParentResourceClassName = (resource as ResourceChildItem)?.Parent.Name,
                    UnifiedProperties = resource.AllProperties
                                        // TODO: Remove this filter with dynamic profiles
                                        .Where(rp => !profileData.HasProfile || profileData.IsIncluded(resource, rp))
                                        .Where(rp => rp.IsUnified())
                                        .Select(rp => new UnifiedProperty
                    {
                        UnifiedPropertyName = rp.PropertyName,
                        UnifiedJsonPropertyName = rp.JsonPropertyName,
                        UnifiedCSharpPropertyType = rp.PropertyType.ToCSharp(),
                        UnifiedPropertyIsFromParent = rp.EntityProperty.IncomingAssociations
                                                      .Any(a => a.IsNavigable),
                        References = rp.EntityProperty.IncomingAssociations
                                     .Where(a => !a.IsNavigable && rp.Parent.ReferenceByName.ContainsKey(a.Name + "Reference"))
                                     .Select(a => new
                        {
                            Reference = rp.Parent.ReferenceByName[a.Name + "Reference"],
                            OtherEntityPropertyName = a.PropertyMappings.Where(pm => pm.ThisProperty.Equals(rp.EntityProperty)).Select(pm => pm.OtherProperty.PropertyName).Single(),
                        })
                                     // TODO: Remove this filter with dynamic profiles
                                     .Where(x => !profileData.HasProfile || profileData.IsIncluded(resource, x.Reference))
                                     .Select(x => new
                        {
                            Reference = x.Reference,
                            ReferenceProperty =
                                (x.Reference.ReferenceTypeProperties
                                 .SingleOrDefault(rtp => rtp.EntityProperty.PropertyName == x.OtherEntityPropertyName)
                                 // Deal with the special case of the re-pointing of the identifying property from USI to UniqueId in Person entities
                                 ?? x.Reference.ReferenceTypeProperties
                                 .Single(rtp => rtp.EntityProperty.PropertyName ==
                                         EdFi.Ods.Common.Specifications.UniqueIdSpecification.GetUniqueIdPropertyName(x.OtherEntityPropertyName)))
                        })
                                     .Select(x => new UnifiedReferenceProperty
                        {
                            ReferenceName = x.Reference.PropertyName,
                            ReferenceJsonName = x.Reference.JsonPropertyName,
                            ReferencePropertyName = x.ReferenceProperty.PropertyName,
                            ReferenceJsonPropertyName = x.ReferenceProperty.JsonPropertyName
                        })
                    })
                }
            });

            IEnumerable <ItemFilterValidation> GetItemFilterValidations()
            {
                return(resource.Collections
                       .Where(x => profileData.IsFilteredCollection(resource, x))
                       .OrderBy(x => x.PropertyName)
                       .SelectMany(
                           x => profileData.GetFilteredCollection(resource, x)
                           .ValueFilters
                           .Select(
                               y => new ItemFilterValidation
                {
                    PropertyName = x.PropertyName,
                    ValidatorName = x.ItemType.Name,
                    ValidatorPropertyName = y.PropertyName,
                    PropertyFieldName = x.ItemType.Name.ToCamelCase(),
                    Filters = string.Join(", ", y.Values.Select(s => string.Format("'{0}'", s))),
                    ProfileName = profileData.ProfileName
                })));
            }
        }
예제 #24
0
 /// <summary>
 /// Check if resource is the aggregate root.
 /// </summary>
 /// <param name="resource"></param>
 /// <returns></returns>
 public static bool IsAggregateRoot(this ResourceClassBase resource)
 {
     return(resource.Entity?.IsAggregateRoot == true);
 }
        public object OnDeserialize(ResourceProfileData profileData, ResourceClassBase resource, TemplateContext TemplateContext)
        {
            bool shouldRender = !(profileData.HasProfile && !profileData.HasNavigableChildren(resource));

            if (!profileData.HasProfile &&
                !(resource.Collections.Any() || !resource.IsAggregateRoot() && resource.HasBackReferences()))
            {
                shouldRender = false;
            }

            if (!shouldRender)
            {
                return(ResourceRenderer.DoNotRenderProperty);
            }

            if (resource.IsDerived && !resource.IsDescriptorEntity())
            {
                return(new
                {
                    Inherited = resource.Collections.Any(x => x.IsInherited)
                        ? ResourceRenderer.DoRenderProperty
                        : ResourceRenderer.DoNotRenderProperty,
                    InheritedCollections = resource.Collections.Where(x => x.IsInherited)
                                           .OrderBy(x => x.PropertyName)
                                           .Select(
                        x => new
                    {
                        PropertyFieldName =
                            x.ItemType.PluralName.ToCamelCase()
                    })
                                           .ToList(),
                    Standard = resource.Collections.Any(x => !x.IsInherited)
                        ? ResourceRenderer.DoRenderProperty
                        : ResourceRenderer.DoNotRenderProperty,
                    Collections = resource.Collections
                                  .Where(x => !x.IsInherited && TemplateContext.ShouldRenderEntity(x.ItemType.Entity))
                                  .OrderBy(x => x.PropertyName)
                                  .Select(
                        x => new
                    {
                        ItemType = x.ItemType.Name,
                        Collection = x.ItemType.PluralName,
                        PropertyName = x.PropertyName,

                        // using the property name so we do not break the data member contract
                        // from the original template.
                        JsonPropertyName = x.PropertyName
                                           .TrimPrefix(x.ParentFullName.Name)
                                           .ToCamelCase(),
                        PropertyFieldName = x.ItemType.PluralName.ToCamelCase(),
                        ParentName = x.ParentFullName.Name
                    })
                                  .ToList()
                });
            }

            if (resource.Collections.Any(c => profileData.IsIncluded(resource, c)) ||
                !resource.IsAggregateRoot() && resource.References.Any(x => profileData.IsIncluded(resource, x)))
            {
                return(new
                {
                    BackRef = !resource.IsAggregateRoot() && resource.HasBackReferences()
                        ? ResourceRenderer.DoRenderProperty
                        : ResourceRenderer.DoNotRenderProperty,
                    BackRefCollections = resource.References
                                         .Where(x => profileData.IsIncluded(resource, x))
                                         .OrderBy(x => x.PropertyName)
                                         .Select(
                        x => new
                    {
                        ReferenceTypeName = x.ReferenceTypeName,
                        PropertyFieldName = x.ReferenceTypeName.ToCamelCase()
                    })
                                         .ToList(),
                    Standard = resource.Collections.Any(x => !x.IsInherited)
                        ? ResourceRenderer.DoRenderProperty
                        : ResourceRenderer.DoNotRenderProperty,
                    Collections = resource.Collections
                                  .OrderBy(x => x.PropertyName)
                                  .Select(
                        x => new
                    {
                        ItemType = x.ItemType.Name,
                        Collection = x.ItemType.PluralName,
                        PropertyName = x.PropertyName,

                        // using the property name so we do not break the data member contract
                        // from the original template.
                        JsonPropertyName = x.PropertyName
                                           .TrimPrefix(x.ParentFullName.Name)
                                           .ToCamelCase(),
                        PropertyFieldName = x.ItemType.PluralName.ToCamelCase(),
                        ParentName = x.ParentFullName.Name
                    })
                                  .ToList(),
                    Inherited = resource.Collections.Any(x => x.IsInherited)
                        ? ResourceRenderer.DoRenderProperty
                        : ResourceRenderer.DoNotRenderProperty,
                    InheritedCollections = resource.Collections.Where(x => x.IsInherited)
                                           .OrderBy(x => x.PropertyName)
                                           .Select(x => new { PropertyFieldName = x.ItemType.PluralName.ToCamelCase() })
                                           .ToList()
                });
            }

            return(ResourceRenderer.DoNotRenderProperty);
        }
예제 #26
0
 /// <summary>
 ///     Check if resource is a lookup entity.
 /// </summary>
 /// <param name="resource"></param>
 /// <returns></returns>
 public static bool IsLookup(this ResourceClassBase resource)
 {
     return(resource.Entity?.IsLookup == true);
 }
예제 #27
0
        private object BuildMapper(ResourceClassBase resourceClass)
        {
            return(new
            {
                ModelName = resourceClass.Name,
                ModelParentName = resourceClass.Entity?.Parent?.Name ?? resourceClass.Name.TrimSuffix("Extension"),
                ExtensionName = TemplateContext.SchemaProperCaseName, IsEntityExtension = resourceClass.IsResourceExtensionClass,
                BaseClassName = resourceClass.Entity?.BaseEntity?.Name, AllowPrimaryKeyUpdates = resourceClass.Entity?.Identifier.IsUpdatable,
                AnnotatedLocalPrimaryKeyList = AnnotateLocalIdentifyingPropertyKeys(resourceClass.Entity), BackSynchedPrimaryKeyList =
                    resourceClass.IdentifyingProperties
                    .Where(p => !IsDefiningUniqueId(resourceClass, p))
                    .OrderBy(x => x.PropertyName)
                    .Select(
                        x => new
                {
                    CSharpSafePrimaryKeyName = x.PropertyName.MakeSafeForCSharpClass(resourceClass.Name)
                }),
                IsDerivedEntity = resourceClass.Entity?.IsDerived, BaseClassNonPkPropertyList = resourceClass.NonIdentifyingProperties
                                                                                                .Where(
                    p => p.IsInherited &&
                    p.IsSynchronizedProperty())
                                                                                                .OrderBy(p => p.PropertyName)
                                                                                                .Select(
                    p => new
                {
                    BasePropertyName =
                        p.PropertyName
                }),
                NonPrimaryKeyList = resourceClass.NonIdentifyingProperties
                                    .Where(p => !p.IsInherited && p.IsSynchronizedProperty())

                                    // Add mappings for UniqueId values defined on Person resources
                                    .Concat(resourceClass.IdentifyingProperties.Where(p => IsDefiningUniqueId(resourceClass, p)))
                                    .OrderBy(p => p.PropertyName)
                                    .Select(
                    p => new
                {
                    p.PropertyName, CSharpSafePropertyName =
                        p.PropertyName.MakeSafeForCSharpClass(resourceClass.Name)
                }),
                HasOneToOneRelationships = resourceClass.EmbeddedObjects.Any(), OneToOneClassList = resourceClass.EmbeddedObjects
                                                                                                    .Select(
                    x => new
                {
                    OtherClassName =
                        x.PropertyName
                }),
                BaseNavigableChildrenList = resourceClass.Collections
                                            .Where(c => c.IsInherited)
                                            .Select(
                    c => new
                {
                    OtherClassPlural = c.PropertyName, OtherClassSingular = c.ItemType.Name
                }),
                NavigableChildrenList = resourceClass.Collections
                                        .Where(c => !c.IsInherited)
                                        .Select(
                    c => new
                {
                    IsExtensionClass = resourceClass.IsResourceExtensionClass,
                    IsCollectionAggregateExtension = c.ItemType.Entity.IsAggregateExtensionTopLevelEntity,
                    ParentName = (resourceClass as ResourceChildItem)?.Parent.Name,
                    ChildClassPlural = c.PropertyName, ChildClassSingular = c.ItemType.Name
                }),

                // Only Ed-Fi Standard entities that are non-lookups can have extensions
                IsExtendable = resourceClass.IsEdFiStandardResource &&
                               !resourceClass.IsLookup() &&
                               !resourceClass.IsDescriptorEntity() &&
                               !resourceClass.IsAbstract(),
                IsBaseClassConcrete = IsBaseClassConcrete(resourceClass), IsBaseEntity = resourceClass.Entity?.IsBase,
                DerivedEntitiesList = BuildDerivedEntities(resourceClass), IsRootEntity = resourceClass is Resource, ContextualKeysList =
                    resourceClass.IdentifyingProperties
                    .OrderBy(p => p.PropertyName)
                    .Select(
                        p => new
                {
                    CSharpSafePropertyName = p.PropertyName.MakeSafeForCSharpClass(resourceClass.Name)
                }),
                SourceSupportPropertyList = BuildSourceSupportProperties(resourceClass), FilterDelegatePropertyList = resourceClass.Collections
                                                                                                                      .OrderBy(
                    c => c
                    .ItemType
                    .Name)
                                                                                                                      .Select(
                    c => new
                {
                    PropertyName
                        = c
                          .ItemType
                          .Name
                }),
                HasAggregateReferences =
                    resourceClass.Entity?.GetAssociationsToReferenceableAggregateRoots(includeInherited: true).Any(),
                AggregateReferences =
                    resourceClass.Entity?.GetAssociationsToReferenceableAggregateRoots(includeInherited: true)
                    .OrderBy(a => a.Name)
                    .Select(
                        a => new
                {
                    AggregateReferenceName = a.Name,
                    MappedReferenceDataHasDiscriminator = a.OtherEntity.HasDiscriminator()
                })
            });
        }
예제 #28
0
        public object AssembleIdentifiers(
            ResourceProfileData profileData,
            ResourceClassBase resource,
            AssociationView association = null)
        {
            if (profileData == null)
            {
                throw new ArgumentNullException(nameof(profileData));
            }

            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            if (!resource.IdentifyingProperties.Any() && association == null)
            {
                return(ResourceRenderer.DoNotRenderProperty);
            }

            IList <ResourceProperty> properties;

            var activeResource = profileData.GetProfileActiveResource(resource);

            if (resource.IsAggregateRoot())
            {
                properties = activeResource.IdentifyingProperties
                             .OrderBy(x => x.PropertyName)
                             .ToList();
            }
            else
            {
                if (association != null)
                {
                    properties = association.ThisProperties
                                 .Where(x => !(x.IsUnified && x.IsIdentifying))
                                 .Select(
                        x =>
                        association.PropertyMappingByThisName[x.PropertyName]
                        .OtherProperty
                        .ToResourceProperty(resource))
                                 .OrderBy(x => x.PropertyName)
                                 .ToList();
                }
                else
                {
                    properties = resource.IdentifyingProperties
                                 .Where(x => !x.EntityProperty.IsLocallyDefined)
                                 .OrderBy(x => x.PropertyName)
                                 .ToList();
                }
            }

            ResourceProperty first = properties.FirstOrDefault();
            ResourceProperty last  = properties.LastOrDefault();

            return(properties.Any()
                ? properties.Select(
                       y => new PropertyData(y)
            {
                IsFirstProperty = y == first,
                IsLastProperty = y == last
            }.Render())
                   .ToList()
                : ResourceRenderer.DoNotRenderProperty);
        }
예제 #29
0
 /// <summary>
 /// Helper method used to convert an EntityProperty to a ResourceProperty
 /// </summary>
 /// <param name="entityProperty">EntityProperty to convert</param>
 /// <param name="resourceClassBase">Resource object</param>
 /// <returns></returns>
 public static ResourceProperty ToResourceProperty(
     this EntityProperty entityProperty,
     ResourceClassBase resourceClassBase)
 {
     return(new ResourceProperty(resourceClassBase, entityProperty));
 }
예제 #30
0
        public static IList <HrefData> GetIdentifyingPropertiesWithAttributes(
            ResourceClassBase resource,
            AssociationView association)
        {
            return(resource.IdentifyingProperties
                   .Where(x => !x.IsLocallyDefined)
                   .Select(
                       x =>
            {
                string propertyName = x.IsLookup
                            ? x.PropertyName + "Id"
                            : x.PropertyName;

                if (association.PropertyMappingByThisName.ContainsKey(propertyName))
                {
                    // in the case where we have unified key and roles, we need to use the
                    // context of the call along with the destination

                    var otherResourceProperty = association.PropertyMappingByThisName[propertyName]
                                                .OtherProperty
                                                .ToResourceProperty(resource);

                    if (!x.HasAssociations())
                    {
                        return
                        new HrefData
                        {
                            Source = otherResourceProperty,
                            Target = otherResourceProperty,
                            IsUnified = x.IsUnified()
                        };
                    }

                    var context = resource.Context(x);

                    if (context != null)
                    {
                        return new HrefData
                        {
                            Source =
                                context.PropertyMappingByThisName[propertyName]
                                .OtherProperty
                                .ToResourceProperty(resource),
                            Target = otherResourceProperty,
                            IsUnified = x.IsUnified()
                        };
                    }

                    return
                    new HrefData
                    {
                        Source = otherResourceProperty,
                        Target = otherResourceProperty,
                        IsUnified = x.IsUnified()
                    };
                }

                return new HrefData
                {
                    Source = x,
                    Target = x,
                    IsUnified = x.IsUnified()
                };
            })
                   .ToList());
        }