private object CreateResourceClass(ResourceProfileData profileData, ResourceClassBase resourceClass) { // NOTE model matching if (resourceClass.IsAbstract()) { return(new { ResourceReference = new { ReferenceName = resourceClass.Name, ReferenceIdentifiers = _resourcePropertyRenderer.AssembleIdentifiers(profileData, resourceClass), Href = AssembleHref(profileData, resourceClass), HasDiscriminator = resourceClass.HasDiscriminator() }, ShouldRenderClass = false, HasDiscriminator = resourceClass.HasDiscriminator() }); } var parentResource = (resourceClass as ResourceChildItem)?.Parent; // NOTE model matching if (parentResource != null && parentResource.IsAbstract() && parentResource.Entity?.IsSameAggregate(resourceClass.Entity) != true) { return(new { ShouldRenderClass = false }); } object putPostRequestValidator = _resourceCollectionRenderer.CreatePutPostRequestValidator(profileData, resourceClass, TemplateContext); // Contextual parent handling var resourceAsChildItem = resourceClass as ResourceChildItem; var contextualParent = GetContextualParent(resourceAsChildItem, profileData); var parentProperCaseSchemaName = contextualParent?.ResourceModel.SchemaNameMapProvider .GetSchemaMapByPhysicalName(contextualParent.FullName.Schema) .ProperCaseName; var collections = _resourceCollectionRenderer.Collections(profileData, resourceClass, TemplateContext); return(new { ShouldRenderClass = true, ResourceReference = resourceClass.IsAggregateReference() ? new { ReferenceName = resourceClass.Name, ReferenceIdentifiers = _resourcePropertyRenderer .AssembleIdentifiers(profileData, resourceClass), Href = AssembleHref(profileData, resourceClass) } : ResourceRenderer.DoNotRenderProperty, ContextSpecificResourceReferences = CreateContextSpecificResourceReferences(profileData, resourceClass), ClassName = resourceClass.Name, EntityName = resourceClass.Name, Constructor = AssembleConstructor(profileData, resourceClass), HasCollections = ((IList)collections).Count > 0, Collections = collections, Identifiers = _resourcePropertyRenderer.AssemblePrimaryKeys(profileData, resourceClass, TemplateContext), NonIdentifiers = _resourcePropertyRenderer.AssembleProperties(resourceClass), InheritedProperties = _resourcePropertyRenderer.AssembleInheritedProperties(profileData, resourceClass), InheritedCollections = _resourceCollectionRenderer.InheritedCollections(profileData, resourceClass, TemplateContext), OnDeserialize = _resourceCollectionRenderer.OnDeserialize(profileData, resourceClass, TemplateContext), Guid = resourceClass.IsAggregateRoot() ? new { ResourceName = resourceClass.Name, GuidConverterTypeName = "GuidConverter" } : ResourceRenderer.DoNotRenderProperty, NavigableOneToOnes = _resourceCollectionRenderer.NavigableOneToOnes(profileData, resourceClass), InheritedNavigableOneToOnes = _resourceCollectionRenderer.InheritedNavigableOneToOnes(profileData, resourceClass), SynchronizationSourceSupport = _resourceCollectionRenderer .SynchronizationSourceSupport(profileData, resourceClass, TemplateContext), Versioning = resourceClass.IsAggregateRoot() ? ResourceRenderer.DoRenderProperty : ResourceRenderer.DoNotRenderProperty, References = _resourceCollectionRenderer.References(profileData, resourceClass, TemplateContext), FQName = resourceClass.FullName, IsAbstract = resourceClass.IsAbstract(), IsAggregateRoot = resourceClass.IsAggregateRoot(), DerivedName = resourceClass.IsDerived ? $@", {EdFiConventions.BuildNamespace( Namespaces.Entities.Common.RelativeNamespace, resourceClass.Entity.BaseEntity.SchemaProperCaseName()) }.I{resourceClass.Entity.BaseEntity.Name}" : ResourceRenderer.DoNotRenderProperty, ParentName = contextualParent?.Name, ParentFieldName = contextualParent?.Name.ToCamelCase(), InterfaceParentFieldName = contextualParent?.Name, ParentNamespacePrefix = parentProperCaseSchemaName == null ? null : $"{Namespaces.Entities.Common.RelativeNamespace}.{parentProperCaseSchemaName}.", IsBaseClassConcrete = resourceClass.Entity != null && resourceClass.Entity.IsDerived && resourceClass.Entity.BaseEntity != null && !resourceClass.Entity.BaseEntity.IsAbstractRequiringNoCompositeId(), DerivedBaseTypeName = resourceClass.IsDerived && resourceClass.Entity != null ? resourceClass.Entity.BaseEntity?.Name : ResourceRenderer.DoNotRenderProperty, FilteredDelegates = _resourceCollectionRenderer.FilteredDelegates(profileData, resourceClass), ShouldRenderValidator = putPostRequestValidator != ResourceRenderer.DoNotRenderProperty, Validator = putPostRequestValidator, IsExtendable = resourceClass.IsExtendable(), IsProfileProject = TemplateContext.IsProfiles, HasSupportedExtensions = profileData.SuppliedResource.Extensions.Any(), SupportedExtensions = profileData.SuppliedResource.Extensions .Select(e => new { ExtensionName = TemplateContext.GetSchemaProperCaseNameForExtension(e) }), IsEdFiResource = resourceClass.IsEdFiResource(), NamespacePrefix = resourceClass.GetNamespacePrefix(), HasDiscriminator = resourceClass.HasDiscriminator(), // Foreign Key Discriminators should not have any profile applied to this, as this data is required for links ResourceReferences = CreateResourceReferences(resourceClass) }); }
private object CreateContextSpecificResourceReferences(ResourceProfileData profileData, ResourceClassBase resource) { if (resource.IsAggregateRoot() || !resource.HasBackReferences()) { return(ResourceRenderer.DoNotRenderProperty); } var externalAssociations = resource.ExternalReferenceAssociations() .ToList(); var refs = externalAssociations.Select( av => new { ContextSpecificResourceReference = new { NamespacePrefix = resource.GetNamespacePrefix(), ReferenceName = string.Format( "{0}To{1}", av.ThisEntity.Name, av.OtherEntity.Name), // Leaving this member definition inline as this entire method // is to be deprecated in the future. ContextualReferenceIdentifier = av.ThisProperties .Where(p => (p.IsUnified && p.IsIdentifying)) .Select( p => av.PropertyMappingByThisName[p.PropertyName] .OtherProperty .ToResourceProperty(resource)) .OrderBy(p => p.PropertyName) .Select(p => new { PropertyName = p.PropertyName, JsonPropertyName = p.JsonPropertyName, PropertyType = p.PropertyType.ToCSharp(), // Use GetLineage to build the property path, in reverse order, skipping the first since that's the BackReference itself PropertyPathToRoot = "BackReference." + string.Join(".", ((ResourceChildItem)resource).GetLineage().Reverse().Skip(1).Select(l => l.Name)) }), ReferenceIdentifiers = _resourcePropertyRenderer.AssembleIdentifiers( profileData, resource, av), Href = AssembleHref(profileData, resource, av), HasDiscriminator = av.OtherEntity.HasDiscriminator(), ThisEntityName = av.ThisEntity.Name, OtherEntityName = av.OtherEntity.Name, BackReference = string.Format( "backreference.{0}.", (resource as ResourceChildItem)?.Parent.Name), ReferenceFullyDefined = _resourcePropertyRenderer .AssembleReferenceFullyDefined( resource, av) } } ) .ToList(); return(refs); }