Ejemplo n.º 1
0
        private void ReadTokenArray(JsonReader reader, string name, ref List <JToken> values)
        {
            EnsureToken(reader, name, JsonToken.StartArray);

            if (values == null)
            {
                values = new List <JToken>();
            }

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonToken.Comment:
                    // nom nom nom
                    break;

                case JsonToken.EndArray:
                    return;

                default:
                    JToken t = JToken.ReadFrom(reader);

                    values.Add(t);
                    break;
                }
            }

            throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading '{0}'.".FormatWith(CultureInfo.InvariantCulture, name));
        }
Ejemplo n.º 2
0
        private void PopulateSchemaArray(JsonReader reader, string name, List <JSchema> schemas)
        {
            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonToken.StartObject:
                    int itemCount = schemas.Count;
                    LoadAndSetSchema(reader, s => SetAtIndex(schemas, itemCount, s));
                    break;

                case JsonToken.Comment:
                    // nom nom nom
                    break;

                case JsonToken.EndArray:
                    return;

                default:
                    throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token when reading schemas: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
                }
            }

            throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading schemas for '{0}'.".FormatWith(CultureInfo.InvariantCulture, name));
        }
Ejemplo n.º 3
0
        private void ReadStringArray(JsonReader reader, string name, out List <string> values)
        {
            values = new List <string>();

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonToken.String:
                    values.Add((string)reader.Value);
                    break;

                case JsonToken.Comment:
                    // nom nom nom
                    break;

                case JsonToken.EndArray:
                    return;

                default:
                    throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token when reading '{0}': {1}".FormatWith(CultureInfo.InvariantCulture, name, reader.TokenType));
                }
            }

            throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading '{0}'.".FormatWith(CultureInfo.InvariantCulture, name));
        }
        internal JSchema ReadRoot(JsonReader reader, bool resolveDeferedSchemas = true)
        {
            if (reader.TokenType == JsonToken.None || reader.TokenType == JsonToken.Comment)
            {
                if (!reader.Read())
                {
                    throw JSchemaReaderException.Create(reader, _baseUri, "Error reading schema from JsonReader.");
                }
            }

            if (reader.TokenType != JsonToken.StartObject)
            {
                throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token encountered when reading schema. Expected StartObject, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
            }

            RootSchema = new JSchema();

            LoadAndSetSchema(reader, s =>
            {
                RootSchema = s;

                if (s.BaseUri != null)
                {
                    Cache[s.BaseUri] = s;
                }
            }, true);

            if (resolveDeferedSchemas)
            {
                ResolveDeferedSchemas();
            }

            return(RootSchema);
        }
Ejemplo n.º 5
0
        private Uri ResolveSchemaReference(JSchema schema)
        {
            Uri resolvedReference = null;

            foreach (JSchema s in _schemaStack.Reverse())
            {
                Uri part = s.Id;

                if (part != null)
                {
                    if (resolvedReference == null)
                    {
                        resolvedReference = part;
                    }
                    else
                    {
                        resolvedReference = SchemaDiscovery.ResolveSchemaId(resolvedReference, part);
                    }
                }
            }

            try
            {
                resolvedReference = SchemaDiscovery.ResolveSchemaId(resolvedReference, schema.Reference);
            }
            catch (Exception ex)
            {
                string message = "Error resolving schema reference '{0}' in the scope '{1}'. The resolved reference must be a valid URI.".FormatWith(CultureInfo.InvariantCulture, schema.Reference, resolvedReference);
                throw JSchemaReaderException.Create(schema, _baseUri, schema.Path, message, ex);
            }

            return(resolvedReference);
        }
Ejemplo n.º 6
0
        private Dictionary <string, JSchema> ReadProperties(JsonReader reader)
        {
            EnsureToken(reader, Constants.PropertyNames.Properties, JsonToken.StartObject);

            Dictionary <string, JSchema> properties = new Dictionary <string, JSchema>();

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonToken.PropertyName:
                    string name = (string)reader.Value;

                    EnsureToken(reader, name, JsonToken.StartObject);

                    // use last schema for duplicates
                    // will this cause issues with a previously deferred schemas?
                    LoadAndSetSchema(reader, s => properties[name] = s);
                    break;

                case JsonToken.Comment:
                    // nom, nom
                    break;

                case JsonToken.EndObject:
                    return(properties);

                default:
                    throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token when reading properties: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
                }
            }

            throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading schema properties.");
        }
Ejemplo n.º 7
0
 private void RaiseSchemaValidationError(object sender, SchemaValidationEventArgs e)
 {
     throw JSchemaReaderException.Create(
               (JsonReader)sender,
               _baseUri,
               "Validation error raised by version schema '{0}': {1}".FormatWith(CultureInfo.InvariantCulture, _schemaVersionUri, e.ValidationError.Message),
               JSchemaValidationException.Create(e.ValidationError));
 }
Ejemplo n.º 8
0
        private void EnsureToken(JsonReader reader, string name, List <JsonToken> tokenTypes)
        {
            EnsureRead(reader, name);

            if (!tokenTypes.Contains(reader.TokenType))
            {
                throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token encountered when reading value for '{0}'. Expected {1}, got {2}.".FormatWith(CultureInfo.InvariantCulture, name, StringHelpers.Join(", ", tokenTypes), reader.TokenType));
            }
        }
Ejemplo n.º 9
0
        private void EnsureToken(JsonReader reader, string name, JsonToken tokenType)
        {
            EnsureRead(reader, name);

            if (reader.TokenType != tokenType)
            {
                throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token encountered when reading value for '{0}'. Expected {1}, got {2}.".FormatWith(CultureInfo.InvariantCulture, name, tokenType, reader.TokenType));
            }
        }
Ejemplo n.º 10
0
        private void ReadDependencies(JsonReader reader, JSchema schema)
        {
            EnsureToken(reader, Constants.PropertyNames.Dependencies, JsonToken.StartObject);

            Dictionary <string, object> dependencies = new Dictionary <string, object>();

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonToken.PropertyName:
                    string name = (string)reader.Value;

                    EnsureToken(reader, name, Constants.DependencyTokens);

                    // use last dependency when duplicates are defined
                    if (reader.TokenType == JsonToken.StartObject)
                    {
                        LoadAndSetSchema(reader, s => dependencies[name] = s);
                    }
                    else if (reader.TokenType == JsonToken.StartArray)
                    {
                        List <string> l;
                        ReadStringArray(reader, name, out l);
                        dependencies[name] = l;
                    }
                    else
                    {
                        EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3);

                        dependencies[name] = new List <string>
                        {
                            (string)reader.Value
                        };
                    }
                    break;

                case JsonToken.Comment:
                    // nom, nom
                    break;

                case JsonToken.EndObject:
                    schema._dependencies = dependencies;
                    return;

                default:
                    throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token when reading dependencies: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
                }
            }

            throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading dependencies.");
        }
Ejemplo n.º 11
0
        private void EnsureRead(JsonReader reader, string name)
        {
            // read to the next non-comment
            while (reader.Read())
            {
                if (reader.TokenType != JsonToken.Comment)
                {
                    return;
                }
            }

            throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading value for '{0}'.".FormatWith(CultureInfo.InvariantCulture, name));
        }
Ejemplo n.º 12
0
        private Uri ReadUri(JsonReader reader, string name)
        {
            EnsureToken(reader, name, JsonToken.String);
            string id = (string)reader.Value;

            try
            {
                return(new Uri(id, UriKind.RelativeOrAbsolute));
            }
            catch (Exception ex)
            {
                throw JSchemaReaderException.Create(reader, _baseUri, "Error parsing id '{0}'. Id must be a valid URI.".FormatWith(CultureInfo.InvariantCulture, id), ex);
            }
        }
Ejemplo n.º 13
0
        public void ResolveDeferedSchemas()
        {
            if (_deferedSchemas.Count > 0)
            {
                List <DeferedSchema> resolvedDeferedSchemas = new List <DeferedSchema>();

                int initialCount = _deferedSchemas.Count;

                int i = 0;
                // note that defered schemas could be added while resolving
                while (_deferedSchemas.Count > 0)
                {
                    DeferedSchema deferedSchema = _deferedSchemas[0];

                    ResolveDeferedSchema(deferedSchema);

                    resolvedDeferedSchemas.Add(deferedSchema);
                    _deferedSchemas.Remove(deferedSchema);

                    if (!deferedSchema.Success && i >= initialCount)
                    {
                        // if schema resolved to another reference and that reference has already not be resolved then fail
                        // probably a circular reference
                        for (int j = initialCount; j < resolvedDeferedSchemas.Count; j++)
                        {
                            DeferedSchema resolvedSchema = resolvedDeferedSchemas[j];
                            if (deferedSchema != resolvedSchema && deferedSchema.ResolvedReference.ToString() == resolvedSchema.ResolvedReference.ToString())
                            {
                                throw JSchemaReaderException.Create(resolvedSchema.ReferenceSchema, _baseUri, resolvedSchema.ReferenceSchema.Path, "Could not resolve schema reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, deferedSchema.ResolvedReference));
                            }
                        }
                    }
                    i++;
                }

                foreach (DeferedSchema resolvedDeferedSchema in resolvedDeferedSchemas)
                {
                    if (!resolvedDeferedSchema.Success)
                    {
                        throw JSchemaReaderException.Create(resolvedDeferedSchema.ReferenceSchema, _baseUri, resolvedDeferedSchema.ReferenceSchema.Path, "Could not resolve schema reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, resolvedDeferedSchema.ResolvedReference));
                    }
                }
            }
        }
Ejemplo n.º 14
0
        private void ResolveDeferedSchema(DeferedSchema deferedSchema)
        {
            Uri reference = deferedSchema.ResolvedReference;

            bool found = SchemaDiscovery.FindSchema(s =>
            {
                // additional json copied to referenced schema
                // kind of hacky
                if (deferedSchema.ReferenceSchema._extensionData != null)
                {
                    foreach (KeyValuePair <string, JToken> keyValuePair in deferedSchema.ReferenceSchema._extensionData.ToList())
                    {
                        s.ExtensionData[keyValuePair.Key] = keyValuePair.Value;
                    }
                }

                deferedSchema.SetResolvedSchema(s);
            }, RootSchema, RootSchema.Id, reference, this, ref _schemaDiscovery);

            if (found)
            {
                return;
            }

            JSchema resolvedSchema;

            try
            {
                resolvedSchema = ResolvedSchema(deferedSchema.ReferenceSchema.Reference, deferedSchema.ResolvedReference);
            }
            catch (Exception ex)
            {
                throw JSchemaReaderException.Create(deferedSchema.ReferenceSchema, _baseUri, deferedSchema.ReferenceSchema.Path, "Error when resolving schema reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, deferedSchema.ReferenceSchema.Reference), ex);
            }

            if (resolvedSchema != null)
            {
                deferedSchema.SetResolvedSchema(resolvedSchema);
                return;
            }

            throw JSchemaReaderException.Create(deferedSchema.ReferenceSchema, _baseUri, deferedSchema.ReferenceSchema.Path, "Could not resolve schema reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, deferedSchema.ResolvedReference));
        }
Ejemplo n.º 15
0
        private void ReadExtends(JsonReader reader, JSchema schema)
        {
            EnsureRead(reader, Constants.PropertyNames.Extends);
            EnsureList(ref schema._allOf);

            switch (reader.TokenType)
            {
            case JsonToken.StartObject:
                int index = schema._allOf.Count;
                LoadAndSetSchema(reader, s => SetAtIndex(schema._allOf, index, s));
                break;

            case JsonToken.StartArray:
                PopulateSchemaArray(reader, Constants.PropertyNames.Extends, schema._allOf);
                break;

            default:
                throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token when reading '{0}': {1}".FormatWith(CultureInfo.InvariantCulture, Constants.PropertyNames.Extends, reader.TokenType));
            }
        }
Ejemplo n.º 16
0
        internal JSchemaType?MapType(JsonReader reader)
        {
            string typeName = (string)reader.Value;

            JSchemaType mappedType;

            if (!Constants.JSchemaTypeMapping.TryGetValue(typeName, out mappedType))
            {
                if (EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                {
                    if (typeName == Constants.Types.Any)
                    {
                        return(null);
                    }
                }

                throw JSchemaReaderException.Create(reader, _baseUri, "Invalid JSON schema type: {0}".FormatWith(CultureInfo.InvariantCulture, typeName));
            }

            return(mappedType);
        }
Ejemplo n.º 17
0
        private void ReadItems(JsonReader reader, JSchema schema)
        {
            EnsureRead(reader, Constants.PropertyNames.Items);
            EnsureList(ref schema._items);

            switch (reader.TokenType)
            {
            case JsonToken.StartObject:
                LoadAndSetSchema(reader, s => SetAtIndex(schema._items, 0, s));
                schema.ItemsPositionValidation = false;
                break;

            case JsonToken.StartArray:
                PopulateSchemaArray(reader, Constants.PropertyNames.Items, schema._items);
                schema.ItemsPositionValidation = true;
                break;

            default:
                throw JSchemaReaderException.Create(reader, _baseUri, "Expected array or JSON schema object for '{0}', got {1}.".FormatWith(CultureInfo.InvariantCulture, Constants.PropertyNames.Items, reader.TokenType));
            }
        }
Ejemplo n.º 18
0
        private void ReadExtensionData(JsonReader reader, JSchema schema, string name)
        {
            if (!reader.Read())
            {
                throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading schema.");
            }

            JToken t;

            if (reader is JTokenReader)
            {
                t = ((JTokenReader)reader).CurrentToken;
                reader.Skip();
            }
            else
            {
                string basePath = reader.Path;
                t = JToken.ReadFrom(reader);
                t.AddAnnotation(new JTokenPathAnnotation(basePath));
            }

            schema.ExtensionData[name] = t;
        }
Ejemplo n.º 19
0
        private void ReadRequired(JsonReader reader, JSchema schema)
        {
            EnsureRead(reader, Constants.PropertyNames.Required);

            if (reader.TokenType == JsonToken.Boolean)
            {
                if (!EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                {
                    throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token encountered when reading value for 'required'. Expected StartArray, got Boolean.");
                }

                schema.DeprecatedRequired = (bool)reader.Value;
            }
            else
            {
                if (!EnsureVersion(SchemaVersion.Draft4))
                {
                    throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token encountered when reading value for 'required'. Expected Boolean, got StartArray.");
                }

                ReadStringArray(reader, Constants.PropertyNames.Required, out schema._required);
            }
        }
Ejemplo n.º 20
0
        private void ReadSchemaProperties(JsonReader reader, bool isRoot, JSchema schema)
        {
            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonToken.PropertyName:
                    ProcessSchemaName(ref reader, isRoot, schema, (string)reader.Value);
                    break;

                case JsonToken.Comment:
                    // nom, nom
                    break;

                case JsonToken.EndObject:
                    return;

                default:
                    throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token when reading schema: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
                }
            }

            throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading schema.");
        }
Ejemplo n.º 21
0
        private void ProcessSchemaName(ref JsonReader reader, bool isRoot, JSchema schema, string name)
        {
            switch (name)
            {
            case Constants.PropertyNames.Id:
                schema.Id = ReadUri(reader, name);
                break;

            case Constants.PropertyNames.Ref:
                schema.Reference = ReadUri(reader, name);
                break;

            case Constants.PropertyNames.Properties:
                schema._properties = ReadProperties(reader);

                // add schemas with deprecated required flag to new required array
                foreach (KeyValuePair <string, JSchema> schemaProperty in schema.Properties)
                {
                    if (schemaProperty.Value.DeprecatedRequired)
                    {
                        if (!schema.Required.Contains(schemaProperty.Key))
                        {
                            schema.Required.Add(schemaProperty.Key);
                        }
                    }
                }
                break;

            case Constants.PropertyNames.Items:
                ReadItems(reader, schema);
                break;

            case Constants.PropertyNames.Type:
            {
                object typeResult = ReadType(reader, name);
                if (typeResult is JSchemaType)
                {
                    schema.Type = (JSchemaType)typeResult;
                }
                else
                {
                    schema._anyOf = (List <JSchema>)typeResult;
                }
                break;
            }

            case Constants.PropertyNames.AnyOf:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    ReadSchemaArray(reader, name, out schema._anyOf);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.AllOf:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    ReadSchemaArray(reader, name, out schema._allOf);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.OneOf:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    ReadSchemaArray(reader, name, out schema._oneOf);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.Not:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    ReadSchema(reader, name, s => schema.Not = s);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.Title:
                schema.Title = ReadString(reader, name);
                break;

            case Constants.PropertyNames.Description:
                schema.Description = ReadString(reader, name);
                break;

            case Constants.PropertyNames.Format:
                schema.Format = ReadString(reader, name);
                break;

            case Constants.PropertyNames.AdditionalProperties:
                ReadAdditionalProperties(reader, schema);
                break;

            case Constants.PropertyNames.AdditionalItems:
                ReadAdditionalItems(reader, schema);
                break;

            case Constants.PropertyNames.PatternProperties:
                schema._patternProperties = ReadProperties(reader);
                break;

            case Constants.PropertyNames.Required:
                ReadRequired(reader, schema);
                break;

            case Constants.PropertyNames.Dependencies:
                ReadDependencies(reader, schema);
                break;

            case Constants.PropertyNames.Minimum:
                schema.Minimum = ReadDouble(reader, name);
                break;

            case Constants.PropertyNames.Maximum:
                schema.Maximum = ReadDouble(reader, name);
                break;

            case Constants.PropertyNames.ExclusiveMinimum:
                schema.ExclusiveMinimum = ReadBoolean(reader, name);
                break;

            case Constants.PropertyNames.ExclusiveMaximum:
                schema.ExclusiveMaximum = ReadBoolean(reader, name);
                break;

            case Constants.PropertyNames.MaximumLength:
                schema.MaximumLength = ReadInteger(reader, name);
                break;

            case Constants.PropertyNames.MinimumLength:
                schema.MinimumLength = ReadInteger(reader, name);
                break;

            case Constants.PropertyNames.MaximumItems:
                schema.MaximumItems = ReadInteger(reader, name);
                break;

            case Constants.PropertyNames.MinimumItems:
                schema.MinimumItems = ReadInteger(reader, name);
                break;

            case Constants.PropertyNames.MaximumProperties:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    schema.MaximumProperties = ReadInteger(reader, name);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.MinimumProperties:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    schema.MinimumProperties = ReadInteger(reader, name);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.DivisibleBy:
                if (EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                {
                    schema.MultipleOf = ReadDouble(reader, name);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.MultipleOf:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    schema.MultipleOf = ReadDouble(reader, name);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.Disallow:
            {
                if (EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                {
                    if (schema.Not == null)
                    {
                        schema.Not = new JSchema();
                    }

                    object disallowResult = ReadType(reader, name);
                    if (disallowResult is JSchemaType)
                    {
                        JSchemaType type = schema.Not.Type ?? JSchemaType.None;
                        schema.Not.Type = type | (JSchemaType)disallowResult;
                    }
                    else
                    {
                        schema.Not._anyOf = (List <JSchema>)disallowResult;
                    }
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;
            }

            case Constants.PropertyNames.Pattern:
                schema.Pattern = ReadString(reader, name);

                if (_validationErrors != null)
                {
                    Regex  patternRegex;
                    string errorMessage;
                    if (!schema.TryGetPatternRegex(out patternRegex, out errorMessage))
                    {
                        ValidationError error = ValidationError.CreateValidationError("Could not parse regex pattern '{0}'. Regex parser error: {1}".FormatWith(CultureInfo.InvariantCulture, schema.Pattern, errorMessage), ErrorType.Pattern, schema, null, schema.Pattern, null, schema, schema.Path);
                        _validationErrors.Add(error);
                    }
                }
                break;

            case Constants.PropertyNames.Enum:
                ReadTokenArray(reader, name, ref schema._enum);
                if (schema._enum.Count == 0)
                {
                    throw JSchemaReaderException.Create(reader, _baseUri, "Enum array must have at least one value.");
                }
                break;

            case Constants.PropertyNames.Extends:
                if (EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                {
                    ReadExtends(reader, schema);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.UniqueItems:
                schema.UniqueItems = ReadBoolean(reader, name);
                break;

            case Constants.PropertyNames.Default:
                EnsureRead(reader, Constants.PropertyNames.Default);
                schema.Default = JToken.ReadFrom(reader);
                break;

            default:
                if (isRoot && name == Constants.PropertyNames.Schema)
                {
                    if (!reader.Read())
                    {
                        throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading schema.");
                    }

                    if (reader.TokenType != JsonToken.String)
                    {
                        throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token encountered when reading value for '$schema'. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
                    }

                    _schemaVersionUri = new Uri((string)reader.Value, UriKind.RelativeOrAbsolute);

#if !PORTABLE
                    string tempUriText = _schemaVersionUri.OriginalString.ToLower(CultureInfo.InvariantCulture);
#else
                    string tempUriText = _schemaVersionUri.OriginalString.ToLower();
#endif

                    Uri tempUri = new Uri(tempUriText, UriKind.RelativeOrAbsolute);
                    if (tempUri == Constants.SchemaVersions.Draft3)
                    {
                        _schemaVersion = SchemaVersion.Draft3;
                    }
                    else if (tempUri == Constants.SchemaVersions.Draft4)
                    {
                        _schemaVersion = SchemaVersion.Draft4;
                    }

                    if (_validateSchema)
                    {
                        if (_schemaVersion == SchemaVersion.Draft3)
                        {
                            _validatingSchema = SpecSchemaCache.Get("schema-draft-v3.json");
                        }
                        else if (_schemaVersion == SchemaVersion.Draft4)
                        {
                            _validatingSchema = SpecSchemaCache.Get("schema-draft-v4.json");
                        }
                        else
                        {
                            if (!_schemaVersionUri.IsAbsoluteUri)
                            {
                                throw JSchemaReaderException.Create(reader, _baseUri, "Schema version identifier '{0}' is not an absolute URI.".FormatWith(CultureInfo.InvariantCulture, _schemaVersionUri.OriginalString));
                            }

                            _validatingSchema = ResolvedSchema(_schemaVersionUri, _schemaVersionUri);

                            if (_validatingSchema == null)
                            {
                                throw JSchemaReaderException.Create(reader, _baseUri, "Could not resolve schema version identifier '{0}'.".FormatWith(CultureInfo.InvariantCulture, _schemaVersionUri.OriginalString));
                            }
                        }

                        JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);
                        validatingReader.Schema = _validatingSchema;
                        // push state that we're already inside an object
                        validatingReader.Validator.ValidateCurrentToken(JsonToken.StartObject, null, 0);
                        validatingReader.ValidationEventHandler += RaiseSchemaValidationError;

                        reader = validatingReader;
                    }
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;
            }
        }
Ejemplo n.º 22
0
        private object ReadType(JsonReader reader, string name)
        {
            EnsureRead(reader, name);

            List <JSchemaType> types       = new List <JSchemaType>();
            List <JSchema>     typeSchemas = null;
            bool isAny = false;

            switch (reader.TokenType)
            {
            case JsonToken.String:
                return(MapType(reader));

            case JsonToken.StartArray:
                while (reader.Read())
                {
                    switch (reader.TokenType)
                    {
                    case JsonToken.String:
                        JSchemaType?t = MapType(reader);

                        if (t == null)
                        {
                            isAny = true;
                        }
                        else
                        {
                            if (typeSchemas != null)
                            {
                                typeSchemas.Add(new JSchema {
                                    Type = t
                                });
                            }
                            else
                            {
                                types.Add(t.Value);
                            }
                        }
                        break;

                    case JsonToken.Comment:
                        // nom nom nom
                        break;

                    case JsonToken.EndArray:
                        // type of "any" removes all other type constraints
                        if (isAny)
                        {
                            return(null);
                        }

                        if (typeSchemas != null)
                        {
                            return(typeSchemas);
                        }

                        JSchemaType finalType = JSchemaType.None;
                        foreach (JSchemaType type in types)
                        {
                            finalType = finalType | type;
                        }

                        return(finalType);

                    default:
                        if (EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                        {
                            if (typeSchemas == null)
                            {
                                typeSchemas = new List <JSchema>();
                                foreach (JSchemaType type in types)
                                {
                                    typeSchemas.Add(new JSchema
                                    {
                                        Type = type
                                    });
                                }
                                types = null;
                            }
                            int            count = typeSchemas.Count;
                            List <JSchema> l     = typeSchemas;
                            LoadAndSetSchema(reader, s => SetAtIndex(l, count, s));
                        }
                        else
                        {
                            throw JSchemaReaderException.Create(reader, _baseUri, "Expected string token for type, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
                        }
                        break;
                    }
                }
                break;

            default:
                throw JSchemaReaderException.Create(reader, _baseUri, "Expected array or string for '{0}', got {1}.".FormatWith(CultureInfo.InvariantCulture, Constants.PropertyNames.Type, reader.TokenType));
            }

            throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading schema type.");
        }