private static ApiPropertyConfiguration GetOrAddApiPropertyConfiguration(ApiMutableObjectType apiMutableObjectType,
                                                                                 Type clrDeclaringType,
                                                                                 string clrPropertyName,
                                                                                 Type clrPropertyType,
                                                                                 ApiPrecedenceLevel apiPrecedenceLevel,
                                                                                 ApiPrecedenceStack apiPrecedenceStack)
        {
            Contract.Requires(apiMutableObjectType != null);
            Contract.Requires(clrDeclaringType != null);
            Contract.Requires(clrPropertyName.SafeHasContent());
            Contract.Requires(clrPropertyType != null);
            Contract.Requires(apiPrecedenceStack != null);

            if (apiMutableObjectType.ApiPropertyConfigurationsIndex.TryGetValue(clrPropertyName, out var apiPropertyConfigurationIndex))
            {
                var apiPropertyConfigurationExisting = apiMutableObjectType.ApiPropertyConfigurations[apiPropertyConfigurationIndex];
                return(apiPropertyConfigurationExisting);
            }

            var apiPropertyConfigurationNew      = new ApiPropertyConfiguration(clrDeclaringType, clrPropertyName, clrPropertyType, apiPrecedenceStack);
            var apiPropertyConfigurationIndexNew = apiMutableObjectType.ApiPropertyConfigurationsIndex.Count;

            apiMutableObjectType.ApiPropertyConfigurations.Add(apiPropertyConfigurationNew);
            apiMutableObjectType.ApiPropertyConfigurationsIndex.Add(clrPropertyName, apiPropertyConfigurationIndexNew);

            ApiFrameworkLog.Trace($"Added {nameof(ApiProperty)} [{nameof(ApiProperty.ClrName)}={clrPropertyName}] at {apiPrecedenceLevel} Level".Indent(IndentConstants.ApiMutableObjectTypeModifier));

            return(apiPropertyConfigurationNew);
        }
Example #2
0
        private void HandleApiObjectTypeAttribute(IApiSchemaBuilder apiSchemaBuilder,
                                                  ApiConventionSettings apiConventionSettings,
                                                  ApiPrecedenceStack apiPrecedenceStack,
                                                  Type clrType)
        {
            Contract.Requires(apiSchemaBuilder != null);
            Contract.Requires(apiConventionSettings != null);
            Contract.Requires(clrType != null);

            var apiObjectTypeAttribute = (ApiObjectTypeAttribute)Attribute.GetCustomAttribute(clrType, typeof(ApiObjectTypeAttribute));

            if (apiObjectTypeAttribute == null)
            {
                return;
            }

            if (ClrTypeDiscoveryRules.CanAddApiObjectType(clrType) == false)
            {
                return;
            }

            var apiDiscoverySettings = apiConventionSettings.ApiDiscoverySettings;
            var apiAnnotationDiscoveryPredicateResult = apiDiscoverySettings.ApiAnnotationDiscoveryPredicate?.Invoke(clrType) ?? true;

            if (apiAnnotationDiscoveryPredicateResult == false)
            {
                return;
            }

            if (apiObjectTypeAttribute.Excluded)
            {
                apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
                apiSchemaBuilder.Exclude(clrType);
                apiPrecedenceStack.Pop();
                return;
            }

            IApiObjectTypeBuilder ApiObjectTypeConfiguration(IApiObjectTypeBuilder apiObjectTypeBuilder)
            {
                apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
                if (String.IsNullOrWhiteSpace(apiObjectTypeAttribute.Name) == false)
                {
                    apiObjectTypeBuilder.HasName(apiObjectTypeAttribute.Name);
                }

                if (String.IsNullOrWhiteSpace(apiObjectTypeAttribute.Description) == false)
                {
                    apiObjectTypeBuilder.HasDescription(apiObjectTypeAttribute.Description);
                }

                apiPrecedenceStack.Pop();

                return(apiObjectTypeBuilder);
            }

            apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
            apiSchemaBuilder.ApiObjectType(clrType, ApiObjectTypeConfiguration);
            apiPrecedenceStack.Pop();
        }
        internal ApiEnumerationTypeConfiguration(Type clrEnumerationType, ApiPrecedenceStack apiPrecedenceStack, ApiMutableFactory <ApiMutableSchema, ApiMutableEnumerationType> apiMutableEnumerationTypeFactory)
            : base(clrEnumerationType)
        {
            Contract.Requires(clrEnumerationType != null);
            Contract.Requires(apiPrecedenceStack != null);

            this.ApiPrecedenceStack = apiPrecedenceStack;
            this.ApiMutableEnumerationTypeFactory = apiMutableEnumerationTypeFactory;
        }
        // INTERNAL CONSTRUCTORS ////////////////////////////////////////////
        #region Constructors
        internal ApiEnumerationTypeConfiguration(Type clrEnumerationType, ApiPrecedenceStack apiPrecedenceStack)
            : base(clrEnumerationType)
        {
            Contract.Requires(clrEnumerationType != null);
            Contract.Requires(apiPrecedenceStack != null);

            this.ApiPrecedenceStack = apiPrecedenceStack;
            this.ApiMutableEnumerationTypeFactory = new ApiMutableFactory <ApiMutableSchema, ApiMutableEnumerationType>(this.CreateApiMutableEnumerationTypeFactory(clrEnumerationType), IndentConstants.ApiMutableEnumerationType);
        }
        // PRIVATE METHODS //////////////////////////////////////////////////
        #region Methods
        private static void HandleApiEnumerationValueAttribute(IApiEnumerationTypeBuilder apiEnumerationTypeBuilder,
                                                               ApiPrecedenceStack apiPrecedenceStack,
                                                               FieldInfo clrFieldInfo)
        {
            Contract.Requires(apiEnumerationTypeBuilder != null);
            Contract.Requires(apiPrecedenceStack != null);
            Contract.Requires(clrFieldInfo != null);

            var apiEnumerationValueAttribute = (ApiEnumerationValueAttribute)Attribute.GetCustomAttribute(clrFieldInfo, typeof(ApiEnumerationValueAttribute));

            if (apiEnumerationValueAttribute == null)
            {
                return;
            }

            IApiEnumerationValueBuilder ApiEnumerationValueConfiguration(IApiEnumerationValueBuilder apiEnumerationValueBuilder)
            {
                apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);

                var apiName = apiEnumerationValueAttribute.Name;

                if (apiName != null)
                {
                    apiEnumerationValueBuilder.HasName(apiName);
                }

                var apiDescription = apiEnumerationValueAttribute.Description;

                if (apiDescription != null)
                {
                    apiEnumerationValueBuilder.HasDescription(apiDescription);
                }

                apiPrecedenceStack.Pop();

                return(apiEnumerationValueBuilder);
            }

            var clrEnumerationType = apiEnumerationTypeBuilder.ClrType;
            var clrName            = clrFieldInfo.Name;
            var clrOrdinal         = (int)Enum.Parse(clrEnumerationType, clrName);

            apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
            apiEnumerationTypeBuilder.ApiEnumerationValue(clrName, clrOrdinal, ApiEnumerationValueConfiguration);
            apiPrecedenceStack.Pop();
        }
        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);
        }
Example #7
0
        private static void HandleApiRelationshipAttribute(IApiObjectTypeBuilder apiObjectTypeBuilder,
                                                           ApiPrecedenceStack apiPrecedenceStack,
                                                           PropertyInfo clrPropertyInfo)
        {
            Contract.Requires(apiObjectTypeBuilder != null);
            Contract.Requires(clrPropertyInfo != null);

            var apiRelationshipAttribute = Attribute.GetCustomAttribute(clrPropertyInfo, typeof(ApiRelationshipAttribute));

            if (apiRelationshipAttribute == null)
            {
                return;
            }

            var clrPropertyName = clrPropertyInfo.Name;
            var clrPropertyType = clrPropertyInfo.PropertyType;

            apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
            apiObjectTypeBuilder.ApiRelationship(clrPropertyName, clrPropertyType);
            apiPrecedenceStack.Pop();
        }
        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);
        }
        private static ApiTypeConfiguration CreateApiScalarTypeConfiguration(Type clrScalarType, ApiPrecedenceStack apiPrecedenceStack)
        {
            Contract.Requires(clrScalarType != null);
            Contract.Requires(apiPrecedenceStack != null);

            var apiScalarTypeConfiguration = ApiTypeConfigurationFactory.CreateApiTypeConfiguration <ApiTypeConfiguration>(clrScalarType, ApiScalarTypeConfigurationOpenGenericType, apiPrecedenceStack);

            return(apiScalarTypeConfiguration);
        }
        private static void AddMissingApiScalarTypes(ApiMutableSchema apiMutableSchema, ApiPrecedenceStack apiPrecedenceStack)
        {
            Contract.Requires(apiMutableSchema != null);
            Contract.Requires(apiPrecedenceStack != null);

            var clrExplicitScalarTypes = apiMutableSchema.ApiScalarTypeConfigurationDictionary
                                         .Keys
                                         .ToList();

            var clrMissingScalarTypes = new HashSet <Type>(apiMutableSchema.ClrImplicitScalarTypes);

            clrMissingScalarTypes.ExceptWith(clrExplicitScalarTypes);

            foreach (var clrMissingScalarType in clrMissingScalarTypes)
            {
                var apiMissingScalarTypeConfiguration = CreateApiScalarTypeConfiguration(clrMissingScalarType, apiPrecedenceStack);
                apiMutableSchema.ApiScalarTypeConfigurationDictionary.Add(clrMissingScalarType, apiMissingScalarTypeConfiguration);
            }
        }
Example #11
0
        // PRIVATE METHODS //////////////////////////////////////////////////
        #region Methods
        private static void HandleApiPropertyAttribute(IApiObjectTypeBuilder apiObjectTypeBuilder,
                                                       ApiPrecedenceStack apiPrecedenceStack,
                                                       PropertyInfo clrPropertyInfo)
        {
            Contract.Requires(apiObjectTypeBuilder != null);
            Contract.Requires(apiPrecedenceStack != null);
            Contract.Requires(clrPropertyInfo != null);

            var apiPropertyAttribute = (ApiPropertyAttribute)Attribute.GetCustomAttribute(clrPropertyInfo, typeof(ApiPropertyAttribute));

            if (apiPropertyAttribute == null)
            {
                return;
            }

            var clrPropertyName = clrPropertyInfo.Name;
            var clrPropertyType = clrPropertyInfo.PropertyType;

            if (apiPropertyAttribute.Excluded)
            {
                apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
                apiObjectTypeBuilder.Exclude(clrPropertyName);
                apiPrecedenceStack.Pop();
                return;
            }

            IApiPropertyBuilder ApiPropertyConfiguration(IApiPropertyBuilder apiPropertyBuilder)
            {
                apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
                if (String.IsNullOrWhiteSpace(apiPropertyAttribute.Name) == false)
                {
                    apiPropertyBuilder.HasName(apiPropertyAttribute.Name);
                }

                if (String.IsNullOrWhiteSpace(apiPropertyAttribute.Description) == false)
                {
                    apiPropertyBuilder.HasDescription(apiPropertyAttribute.Description);
                }

                if (apiPropertyAttribute.Required)
                {
                    apiPropertyBuilder.IsRequired();
                }

                // ReSharper disable once InvertIf
                if (apiPropertyAttribute.ItemRequired)
                {
                    IApiCollectionTypeBuilder ApiCollectionTypeConfiguration(IApiCollectionTypeBuilder apiCollectionTypeBuilder)
                    {
                        apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
                        apiCollectionTypeBuilder.ItemIsRequired();
                        apiPrecedenceStack.Pop();
                        return(apiCollectionTypeBuilder);
                    }

                    apiPropertyBuilder.ApiCollectionType(ApiCollectionTypeConfiguration);
                }

                apiPrecedenceStack.Pop();

                return(apiPropertyBuilder);
            }

            apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation);
            apiObjectTypeBuilder.ApiProperty(clrPropertyName, clrPropertyType, ApiPropertyConfiguration);
            apiPrecedenceStack.Pop();
        }
        private static ApiEnumerationValueConfiguration GetOrAddApiEnumerationValueConfiguration(ApiMutableEnumerationType apiMutableEnumerationType,
                                                                                                 string clrName,
                                                                                                 int clrOrdinal,
                                                                                                 ApiPrecedenceLevel apiPrecedenceLevel,
                                                                                                 ApiPrecedenceStack apiPrecedenceStack)
        {
            Contract.Requires(apiMutableEnumerationType != null);
            Contract.Requires(clrName.SafeHasContent());
            Contract.Requires(apiPrecedenceStack != null);

            if (apiMutableEnumerationType.ApiEnumerationValueConfigurations.TryGetValue(clrOrdinal, out var apiEnumerationValueConfigurationExisting))
            {
                return(apiEnumerationValueConfigurationExisting);
            }

            var apiEnumerationValueConfigurationNew = new ApiEnumerationValueConfiguration(clrName, clrOrdinal, apiPrecedenceStack);

            apiMutableEnumerationType.ApiEnumerationValueConfigurations.Add(clrOrdinal, apiEnumerationValueConfigurationNew);

            ApiFrameworkLog.Trace($"Added {nameof(ApiEnumerationValue)} [{nameof(ApiEnumerationValue.ClrName)}={clrName}] at {apiPrecedenceLevel} Level".Indent(IndentConstants.ApiMutableEnumerationTypeModifier));

            return(apiEnumerationValueConfigurationNew);
        }