Exemplo n.º 1
0
        /// <summary>
        /// Gets the schema for a given URI.
        /// </summary>
        /// <param name="uri">The schema URI to resolve.</param>
        /// <returns>The resolved schema.</returns>
        public override JSchema GetSchema(Uri uri)
        {
            foreach (KnownSchema knownSchema in _knownSchemas)
            {
                string uriText   = uri.ToString();
                string knownText = (knownSchema.Id != null) ? knownSchema.Id.ToString() : string.Empty;

                if (uriText == knownText)
                {
                    return(knownSchema.Schema);
                }

                if (uriText.StartsWith(knownText, StringComparison.Ordinal))
                {
                    string relative    = uriText.Substring(knownText.Length);
                    Uri    relativeUri = new Uri(relative, UriKind.RelativeOrAbsolute);

                    JSchemaReader resolverSchemaReader = new JSchemaReader(this)
                    {
                        RootSchema = knownSchema.Schema
                    };

                    JSchema subSchema = null;

                    SchemaDiscovery.FindSchema(s => subSchema = s, knownSchema.Schema, knownSchema.Id, relativeUri, resolverSchemaReader);

                    if (subSchema != null)
                    {
                        resolverSchemaReader.ResolveDeferedSchemas();

                        return(subSchema);
                    }
                }
            }

            if (_resolver != null)
            {
                return(_resolver.GetSchema(uri));
            }

            return(null);
        }
        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));
        }