Example #1
0
        internal override IApiType CreateApiType(ApiMutableType apiMutableType, ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableType != null);
            Contract.Requires(apiSchemaProxy != null);

            var apiMutableCollectionType = (ApiMutableCollectionType)apiMutableType;

            var apiCollectionType = CreateApiCollectionType(apiMutableCollectionType, apiSchemaProxy);

            return(apiCollectionType);
        }
Example #2
0
        internal override IApiType CreateApiType(ApiMutableType apiMutableType, ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableType != null);
            Contract.Requires(apiSchemaProxy != null);

            var apiMutableScalarType = (ApiMutableScalarType)apiMutableType;

            var apiScalarType = CreateApiScalarType(apiMutableScalarType);

            ApiFrameworkLog.Debug($"Created {apiScalarType}".Indent(IndentConstants.ApiScalarType));

            return(apiScalarType);
        }
Example #3
0
        public IApiCollectionType Create(ApiMutableSchema apiMutableSchema, ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableSchema != null);
            Contract.Requires(apiSchemaProxy != null);

            var apiMutableCollectionType = this.CreateApiMutableType(apiMutableSchema);

            var apiCollectionType = (IApiCollectionType)this.CreateApiType(apiMutableCollectionType, apiSchemaProxy);

            ApiFrameworkLog.Debug($"Created {apiCollectionType}".Indent(IndentConstants.ApiCollectionType));

            return(apiCollectionType);
        }
Example #4
0
        private static IApiProperty CreateApiProperty(ApiMutableObjectType apiMutableObjectType,
                                                      ApiMutableProperty apiMutableProperty,
                                                      ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableObjectType != null);
            Contract.Requires(apiMutableProperty != null);
            Contract.Requires(apiSchemaProxy != null);

            var apiMutableSchema = apiMutableProperty.ApiMutableSchema;
            var apiName          = apiMutableProperty.ApiName;
            var apiDescription   = apiMutableProperty.ApiDescription;
            var apiTypeKind      = apiMutableProperty.ApiTypeKind;
            var apiTypeModifiers = apiMutableProperty.ApiTypeModifiers;
            var clrName          = apiMutableProperty.ClrName;
            var clrType          = apiMutableProperty.ClrType;

            switch (apiTypeKind)
            {
            case ApiTypeKind.Enumeration:
            {
                apiMutableSchema.AddClrImplicitEnumerationType(clrType);
                break;
            }

            case ApiTypeKind.Collection:
            {
                // Create the known concrete API collection type.
                var apiCollectionTypeConfiguration = apiMutableProperty.ApiCollectionTypeConfiguration;
                var apiCollectionType = apiCollectionTypeConfiguration.Create(apiMutableSchema, apiSchemaProxy);
                return(ApiTypeFactory.CreateApiProperty(apiName, apiDescription, apiCollectionType, apiTypeModifiers, clrName));
            }

            case ApiTypeKind.Scalar:
            {
                apiMutableSchema.AddClrImplicitScalarType(clrType);
                break;
            }
            }

            // API identity properties will always be required.
            var clrIdentityPropertyName = apiMutableObjectType?.ClrIdentityProperty?.ClrPropertyName;

            if (clrName == clrIdentityPropertyName)
            {
                apiTypeModifiers |= ApiTypeModifiers.Required;
            }

            var apiTypeResolver = new ApiSchemaProxyTypeResolver(apiSchemaProxy, apiTypeKind, clrType);

            return(ApiTypeFactory.CreateApiProperty(apiName, apiDescription, apiTypeResolver, apiTypeModifiers, clrName));
        }
        private static IEnumerable <IApiObjectType> CreateApiObjectTypes(ApiMutableSchema apiMutableSchema,
                                                                         ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableSchema != null);
            Contract.Requires(apiSchemaProxy != null);

            ApiFrameworkLog.Debug($"Creating {nameof(ApiObjectType)}s".Indent(IndentConstants.ApiObjectTypes));

            var apiObjectTypeConfigurations = apiMutableSchema.ApiObjectTypeConfigurationDictionary
                                              .Values
                                              .ToList();
            var clrExcludedObjectTypes = apiMutableSchema.ClrExcludedObjectTypes;
            var apiObjectTypes         = CreateApiTypes <IApiObjectType>(apiMutableSchema, apiSchemaProxy, apiObjectTypeConfigurations, clrExcludedObjectTypes);

            ApiFrameworkLog.Debug($"Created {nameof(ApiObjectType)}s".Indent(IndentConstants.ApiObjectTypes));

            return(apiObjectTypes);
        }
        private static IApiSchema CreateApiSchema(ApiMutableSchema apiMutableSchema,
                                                  ApiPrecedenceStack apiPrecedenceStack)
        {
            Contract.Requires(apiMutableSchema != null);
            Contract.Requires(apiPrecedenceStack != null);

            var apiSchemaProxy = new ApiSchemaProxy();

            // Create API object types before other API types so implicit primitive property types (enums, scalars, etc.) are added to the mutable schema object.
            var apiObjectTypes      = CreateApiObjectTypes(apiMutableSchema, apiSchemaProxy);
            var apiEnumerationTypes = CreateApiEnumerationTypes(apiMutableSchema, apiPrecedenceStack, apiSchemaProxy);
            var apiScalarTypes      = CreateApiScalarTypes(apiMutableSchema, apiPrecedenceStack, apiSchemaProxy);

            var apiSchemaName = apiMutableSchema.ApiName;
            var apiSchema     = ApiTypeFactory.CreateApiSchema(apiSchemaName, apiEnumerationTypes, apiObjectTypes, apiScalarTypes);

            apiSchemaProxy.Initialize(apiSchema);

            return(apiSchema);
        }
        private static IEnumerable <TApiType> CreateApiTypes <TApiType>(ApiMutableSchema apiMutableSchema,
                                                                        ApiSchemaProxy apiSchemaProxy,
                                                                        IReadOnlyCollection <ApiTypeConfiguration> apiTypeConfigurations,
                                                                        ISet <Type> clrExcludedTypes)
            where TApiType : IApiNamedType
        {
            Contract.Requires(apiMutableSchema != null);
            Contract.Requires(apiSchemaProxy != null);
            Contract.Requires(apiTypeConfigurations != null);
            Contract.Requires(clrExcludedTypes != null);

            var apiTypeConfigurationsQuery = apiTypeConfigurations.AsEnumerable();

            if (clrExcludedTypes.Any())
            {
                var clrIncludedTypes = new HashSet <Type>(apiTypeConfigurations.Select(x => x.ClrType));
                clrIncludedTypes.ExceptWith(clrExcludedTypes);

                apiTypeConfigurationsQuery = apiTypeConfigurationsQuery.Where(x => clrIncludedTypes.Contains(x.ClrType));
            }

            var apiTypes = apiTypeConfigurationsQuery.Select(x =>
            {
                var apiMutableType = x.CreateApiMutableType(apiMutableSchema);
                var tuple          = new Tuple <ApiTypeConfiguration, ApiMutableType>(x, apiMutableType);
                return(tuple);
            })
                           .ToList()
                           .Select(tuple =>
            {
                var apiTypeConfiguration = tuple.Item1;
                var apiMutableType       = tuple.Item2;
                var apiType = apiTypeConfiguration.CreateApiType(apiMutableType, apiSchemaProxy);
                return(apiType);
            })
                           .Cast <TApiType>()
                           .OrderBy(x => x.ApiName)
                           .ToList();

            return(apiTypes);
        }
        private static IEnumerable <IApiEnumerationType> CreateApiEnumerationTypes(ApiMutableSchema apiMutableSchema,
                                                                                   ApiPrecedenceStack apiPrecedenceStack,
                                                                                   ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableSchema != null);
            Contract.Requires(apiPrecedenceStack != null);

            ApiFrameworkLog.Debug($"Creating {nameof(ApiEnumerationType)}s".Indent(IndentConstants.ApiEnumerationTypes));

            RemoveUnusedApiEnumerationTypes(apiMutableSchema);
            AddMissingApiEnumerationTypes(apiMutableSchema, apiPrecedenceStack);

            var apiEnumerationTypeConfigurations = apiMutableSchema.ApiEnumerationTypeConfigurationDictionary
                                                   .Values
                                                   .ToList();
            var clrExcludedEnumerationTypes = apiMutableSchema.ClrExcludedEnumerationTypes;
            var apiEnumerationTypes         = CreateApiTypes <IApiEnumerationType>(apiMutableSchema, apiSchemaProxy, apiEnumerationTypeConfigurations, clrExcludedEnumerationTypes);

            ApiFrameworkLog.Debug($"Created {nameof(ApiEnumerationType)}s".Indent(IndentConstants.ApiEnumerationTypes));

            return(apiEnumerationTypes);
        }
Example #9
0
        public IApiProperty CreateApiProperty(ApiMutableSchema apiMutableSchema, ApiMutableObjectType apiMutableObjectType, ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableSchema != null);
            Contract.Requires(apiMutableObjectType != null);
            Contract.Requires(apiSchemaProxy != null);

            var apiMutableProperty = this.ApiMutablePropertyFactory.Create(apiMutableSchema);

            var apiProperty = CreateApiProperty(apiMutableObjectType, apiMutableProperty, apiSchemaProxy);

            ApiFrameworkLog.Debug($"Created {apiProperty}".Indent(IndentConstants.ApiProperty));

            return(apiProperty);
        }
Example #10
0
        private static IApiCollectionType CreateApiCollectionType(ApiMutableCollectionType apiMutableCollectionType, ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableCollectionType != null);
            Contract.Requires(apiSchemaProxy != null);

            var apiMutableSchema     = apiMutableCollectionType.ApiMutableSchema;
            var apiItemTypeKind      = apiMutableCollectionType.ApiItemTypeKind;
            var apiItemTypeModifiers = apiMutableCollectionType.ApiItemTypeModifiers;
            var clrItemType          = apiMutableCollectionType.ClrItemType;

            switch (apiItemTypeKind)
            {
            case ApiTypeKind.Scalar:
            {
                apiMutableSchema.AddClrImplicitScalarType(clrItemType);
                break;
            }

            case ApiTypeKind.Enumeration:
            {
                apiMutableSchema.AddClrImplicitEnumerationType(clrItemType);
                break;
            }
            }

            var apiItemTypeResolver = new ApiSchemaProxyTypeResolver(apiSchemaProxy, apiItemTypeKind, clrItemType);
            var apiCollectionType   = ApiTypeFactory.CreateApiCollectionType(apiItemTypeResolver, apiItemTypeModifiers);

            return(apiCollectionType);
        }
 internal abstract IApiType CreateApiType(ApiMutableType apiMutableType, ApiSchemaProxy apiSchemaProxy);
        // ReSharper disable once ReturnTypeCanBeEnumerable.Local
        private static IReadOnlyCollection <IApiRelationship> CreateApiRelationships(ApiMutableObjectType apiMutableObjectType,
                                                                                     ApiSchemaProxy apiSchemaProxy,
                                                                                     IEnumerable <IApiProperty> apiProperties,
                                                                                     IApiIdentity apiIdentity)
        {
            Contract.Requires(apiMutableObjectType != null);
            Contract.Requires(apiSchemaProxy != null);
            Contract.Requires(apiProperties != null);

            // If this API object type has no identity, it may not contain any relationships.
            if (apiIdentity == null)
            {
                return(null);
            }

            var apiMutableSchema = apiMutableObjectType.ApiMutableSchema;
            var clrRelationshipPropertyCollection = apiMutableObjectType.ClrRelationshipPropertyCollection;
            var apiRelationships = clrRelationshipPropertyCollection
                                   .Where(x =>
            {
                // Can not create an API relationship if the related API object type does not have identity (must be an API resource type).
                var clrPropertyType     = x.ClrPropertyType;
                var apiPropertyTypeKind = clrPropertyType.GetApiTypeKind(out var clrPropertyItemType);
                switch (apiPropertyTypeKind)
                {
                case ApiTypeKind.Object:
                    {
                        var isApiResourceType = apiMutableSchema.ClrResourceTypes.Contains(clrPropertyType);
                        if (!isApiResourceType)
                        {
                            return(false);
                        }

                        break;
                    }

                case ApiTypeKind.Collection:
                    {
                        var apiItemTypeKind = clrPropertyItemType.GetApiTypeKind();
                        switch (apiItemTypeKind)
                        {
                        case ApiTypeKind.Collection:
                            {
                                // Unable to handle collections within collections.
                                var message = $"Unable to create API relationship for an API property [{nameof(x.ClrPropertyName)}={x.ClrPropertyName}] that contains collections within collections";
                                throw new ApiSchemaException(message);
                            }
                        }

                        var isApiResourceType = apiMutableSchema.ClrResourceTypes.Contains(clrPropertyItemType);
                        if (!isApiResourceType)
                        {
                            return(false);
                        }

                        break;
                    }

                default:
                    {
                        return(false);
                    }
                }

                return(true);
            })
                                   .Select(x =>
            {
                var clrPropertyName     = x.ClrPropertyName;
                var clrPropertyType     = x.ClrPropertyType;
                var apiProperty         = apiProperties.Single(y => y.ClrName == clrPropertyName);
                var apiPropertyTypeKind = clrPropertyType.GetApiTypeKind(out var clrPropertyItemType);

                ApiRelationshipCardinality apiCardinality;
                Type clrType;
                switch (apiPropertyTypeKind)
                {
                case ApiTypeKind.Object:
                    {
                        apiCardinality = ApiRelationshipCardinality.ToOne;
                        clrType        = clrPropertyType;
                        break;
                    }

                case ApiTypeKind.Collection:
                    {
                        apiCardinality = ApiRelationshipCardinality.ToMany;
                        clrType        = clrPropertyItemType;
                        break;
                    }

                default:
                    {
                        throw new ArgumentOutOfRangeException();
                    }
                }

                var apiRelatedTypeResolver = new ApiSchemaProxyTypeResolver(apiSchemaProxy, ApiTypeKind.Object, clrType);
                var apiRelationship        = ApiTypeFactory.CreateApiRelationship(apiProperty, apiCardinality, apiRelatedTypeResolver);

                return(apiRelationship);
            })
                                   .ToList();

            foreach (var apiRelationship in apiRelationships)
            {
                ApiFrameworkLog.Debug($"Created {apiRelationship}".Indent(IndentConstants.ApiMutableObjectTypeRelationship));
            }

            return(apiRelationships);
        }
        private static IReadOnlyCollection <IApiProperty> CreateApiProperties(ApiMutableObjectType apiMutableObjectType, ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableObjectType != null);
            Contract.Requires(apiSchemaProxy != null);

            // Create an ApiPropertyConfiguration query (LINQ to Objects).
            var apiMutableSchema               = apiMutableObjectType.ApiMutableSchema;
            var apiPropertyConfigurations      = apiMutableObjectType.ApiPropertyConfigurations;
            var apiPropertyConfigurationsQuery = apiPropertyConfigurations.AsEnumerable();

            // Enhance query to remove explicit (by name) excluded properties for this API object type.
            var clrExplicitExcludedPropertyNames = apiMutableObjectType.ClrExcludedPropertyNames;

            if (clrExplicitExcludedPropertyNames.Any())
            {
                var clrExplicitIncludedPropertyNames = apiPropertyConfigurations.Select(x => x.ClrName)
                                                       .ToList();
                var clrExplicitIncludedPropertyNameHashSet = new HashSet <string>(clrExplicitIncludedPropertyNames);
                clrExplicitIncludedPropertyNameHashSet.ExceptWith(clrExplicitExcludedPropertyNames);

                apiPropertyConfigurationsQuery = apiPropertyConfigurationsQuery.Where(x => clrExplicitIncludedPropertyNameHashSet.Contains(x.ClrName));
            }

            // Enhance query to remove implicit (by type) excluded properties for this API object type.
            var clrExcludedTypes = apiMutableSchema.ClrExcludedTypes;

            if (clrExcludedTypes.Any())
            {
                var clrImplicitExcludedPropertyNameHashSet =
                    apiPropertyConfigurations
                    .Where(x =>
                {
                    var clrLeafType = x.ClrType.GetClrLeafType();
                    return(clrExcludedTypes.Contains(clrLeafType));
                })
                    .Select(x => x.ClrName)
                    .ToList();

                var clrImplicitIncludedPropertyNames = apiPropertyConfigurations.Select(x => x.ClrName)
                                                       .ToList();
                var clrImplicitIncludedPropertyNameHashSet = new HashSet <string>(clrImplicitIncludedPropertyNames);
                clrImplicitIncludedPropertyNameHashSet.ExceptWith(clrImplicitExcludedPropertyNameHashSet);

                apiPropertyConfigurationsQuery = apiPropertyConfigurationsQuery.Where(x => clrImplicitIncludedPropertyNameHashSet.Contains(x.ClrName));
            }

            // Execute query to create API property objects for this API object type.
            var apiProperties = apiPropertyConfigurationsQuery.Select(x => x.CreateApiProperty(apiMutableSchema,
                                                                                               apiMutableObjectType,
                                                                                               apiSchemaProxy))
                                .ToList();

            return(apiProperties);
        }
        private static IApiObjectType CreateApiObjectType(ApiMutableObjectType apiMutableObjectType, ApiSchemaProxy apiSchemaProxy)
        {
            Contract.Requires(apiMutableObjectType != null);
            Contract.Requires(apiSchemaProxy != null);

            var apiName          = apiMutableObjectType.ApiName;
            var apiDescription   = apiMutableObjectType.ApiDescription;
            var apiProperties    = CreateApiProperties(apiMutableObjectType, apiSchemaProxy);
            var apiIdentity      = CreateApiIdentity(apiMutableObjectType, apiProperties);
            var apiRelationships = CreateApiRelationships(apiMutableObjectType, apiSchemaProxy, apiProperties, apiIdentity);
            var clrObjectType    = apiMutableObjectType.ClrObjectType;
            var apiObjectType    = ApiTypeFactory.CreateApiObjectType(apiName, apiDescription, apiProperties, apiIdentity, apiRelationships, clrObjectType);

            return(apiObjectType);
        }