private JSchemaGenerationProvider ResolveTypeProvider(Type nonNullableType, JsonProperty memberProperty) { JSchemaGenerationProviderAttribute providerAttribute = null; if (memberProperty != null && memberProperty.AttributeProvider != null) { providerAttribute = (JSchemaGenerationProviderAttribute)memberProperty.AttributeProvider.GetAttributes(typeof(JSchemaGenerationProviderAttribute), true).SingleOrDefault(); } if (providerAttribute == null) { providerAttribute = ReflectionUtils.GetAttribute <JSchemaGenerationProviderAttribute>(nonNullableType, true); if (providerAttribute == null) { return(null); } } JSchemaGenerationProvider provider = (JSchemaGenerationProvider)Activator.CreateInstance(providerAttribute.ProviderType, providerAttribute.ProviderParameters); return(provider); }
private JSchema GenerateInternal(Type type, Required valueRequired, JsonProperty memberProperty, JsonContainerContract container) { ValidationUtils.ArgumentNotNull(type, "type"); Type nonNullableType = ReflectionUtils.IsNullableType(type) ? Nullable.GetUnderlyingType(type) : type; Uri resolvedId = GetTypeId(nonNullableType, false); Uri explicitId = GetTypeId(nonNullableType, true); if (resolvedId != null) { JSchema resolvedSchema = _resolver.GetSchema(resolvedId); if (resolvedSchema != null) { // resolved schema is not null but referencing member allows nulls // change resolved schema to allow nulls. hacky but what are ya gonna do? if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JSchemaType.Null)) { resolvedSchema.Type |= JSchemaType.Null; } return(resolvedSchema); } } JsonContract contract = ContractResolver.ResolveContract(type); var key = CreateKey(valueRequired, memberProperty, contract); switch (contract.ContractType) { case JsonContractType.Object: case JsonContractType.Array: case JsonContractType.Dictionary: TypeSchema typeSchema = _typeSchemas.SingleOrDefault(s => s.Key.Equals(key)); if (typeSchema != null) { return(typeSchema.Schema); } break; } JSchema schema = null; JSchemaGenerationProvider provider = ResolveTypeProvider(nonNullableType, memberProperty); if (provider != null) { JSchemaTypeGenerationContext context = new JSchemaTypeGenerationContext(type, valueRequired, memberProperty, container, this); schema = provider.GetSchema(context); if (schema == null) { throw new JsonException("Could not get schema for type '{0}' from provider '{1}'.".FormatWith(CultureInfo.InvariantCulture, type.FullName, provider.GetType().FullName)); } } if (_generationProviders != null) { JSchemaTypeGenerationContext context = new JSchemaTypeGenerationContext(type, valueRequired, memberProperty, container, this); foreach (JSchemaGenerationProvider generationProvider in _generationProviders) { schema = generationProvider.GetSchema(context); } } if (schema != null) { _typeSchemas.Add(new TypeSchema(key, schema)); return(schema); } schema = new JSchema(); if (explicitId != null) { schema.Id = explicitId; } switch (contract.ContractType) { case JsonContractType.Object: case JsonContractType.Array: case JsonContractType.Dictionary: _typeSchemas.Add(new TypeSchema(key, schema)); break; } return(PopulateSchema(schema, contract, memberProperty, valueRequired)); }