private void Push(JsonSchema value) { _currentSchema = value; _stack.Add(value); _resolver.LoadedSchemas.Add(value); _documentSchemas.Add(value.Location, value); }
private JsonSchema Pop() { JsonSchema poppedSchema = _currentSchema; _stack.RemoveAt(_stack.Count - 1); _currentSchema = _stack.LastOrDefault(); return poppedSchema; }
public TypeSchema(Type type, JsonSchema schema) { ValidationUtils.ArgumentNotNull(type, "type"); ValidationUtils.ArgumentNotNull(schema, "schema"); Type = type; Schema = schema; }
/// <summary> /// Determines whether the <see cref="JToken"/> is valid. /// </summary> /// <param name="source">The source <see cref="JToken"/> to test.</param> /// <param name="schema">The schema to test with.</param> /// <param name="errorMessages">When this method returns, contains any error messages generated while validating. </param> /// <returns> /// <c>true</c> if the specified <see cref="JToken"/> is valid; otherwise, <c>false</c>. /// </returns> public static bool IsValid(this JToken source, JsonSchema schema, out IList<string> errorMessages) { IList<string> errors = new List<string>(); source.Validate(schema, (sender, args) => errors.Add(args.Message)); errorMessages = errors; return (errorMessages.Count == 0); }
public JsonSchemaNode(JsonSchema schema) { Schemas = new ReadOnlyCollection<JsonSchema>(new[] { schema }); Properties = new Dictionary<string, JsonSchemaNode>(); PatternProperties = new Dictionary<string, JsonSchemaNode>(); Items = new List<JsonSchemaNode>(); Id = GetId(Schemas); }
public JsonSchemaModel Build(JsonSchema schema) { _nodes = new JsonSchemaNodeCollection(); _node = AddSchema(null, schema); _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>(); JsonSchemaModel model = BuildNodeModel(_node); return model; }
private JsonSchemaNode(JsonSchemaNode source, JsonSchema schema) { Schemas = new ReadOnlyCollection<JsonSchema>(source.Schemas.Union(new[] { schema }).ToList()); Properties = new Dictionary<string, JsonSchemaNode>(source.Properties); PatternProperties = new Dictionary<string, JsonSchemaNode>(source.PatternProperties); Items = new List<JsonSchemaNode>(source.Items); AdditionalProperties = source.AdditionalProperties; AdditionalItems = source.AdditionalItems; Id = GetId(Schemas); }
public JsonSchemaNode AddSchema(JsonSchemaNode existingNode, JsonSchema schema) { string newId; if (existingNode != null) { if (existingNode.Schemas.Contains(schema)) return existingNode; newId = JsonSchemaNode.GetId(existingNode.Schemas.Union(new[] { schema })); } else { newId = JsonSchemaNode.GetId(new[] { schema }); } if (_nodes.Contains(newId)) return _nodes[newId]; JsonSchemaNode currentNode = (existingNode != null) ? existingNode.Combine(schema) : new JsonSchemaNode(schema); _nodes.Add(currentNode); AddProperties(schema.Properties, currentNode.Properties); AddProperties(schema.PatternProperties, currentNode.PatternProperties); if (schema.Items != null) { for (int i = 0; i < schema.Items.Count; i++) { AddItem(currentNode, i, schema.Items[i]); } } if (schema.AdditionalItems != null) AddAdditionalItems(currentNode, schema.AdditionalItems); if (schema.AdditionalProperties != null) AddAdditionalProperties(currentNode, schema.AdditionalProperties); if (schema.Extends != null) { foreach (JsonSchema jsonSchema in schema.Extends) { currentNode = AddSchema(currentNode, jsonSchema); } } return currentNode; }
private void ReferenceOrWriteSchema(JsonSchema schema) { if (schema.Id != null && _resolver.GetSchema(schema.Id) != null) { _writer.WriteStartObject(); _writer.WritePropertyName(JsonTypeReflector.RefPropertyName); _writer.WriteValue(schema.Id); _writer.WriteEndObject(); } else { WriteSchema(schema); } }
private static void Combine(JsonSchemaModel model, JsonSchema schema) { // Version 3 of the Draft JSON Schema has the default value of Not Required model.Required = model.Required || (schema.Required ?? false); model.Type = model.Type & (schema.Type ?? JsonSchemaType.Any); model.MinimumLength = MathUtils.Max(model.MinimumLength, schema.MinimumLength); model.MaximumLength = MathUtils.Min(model.MaximumLength, schema.MaximumLength); // not sure what is the best way to combine divisibleBy model.DivisibleBy = MathUtils.Max(model.DivisibleBy, schema.DivisibleBy); model.Minimum = MathUtils.Max(model.Minimum, schema.Minimum); model.Maximum = MathUtils.Max(model.Maximum, schema.Maximum); model.ExclusiveMinimum = model.ExclusiveMinimum || (schema.ExclusiveMinimum ?? false); model.ExclusiveMaximum = model.ExclusiveMaximum || (schema.ExclusiveMaximum ?? false); model.MinimumItems = MathUtils.Max(model.MinimumItems, schema.MinimumItems); model.MaximumItems = MathUtils.Min(model.MaximumItems, schema.MaximumItems); model.PositionalItemsValidation = model.PositionalItemsValidation || schema.PositionalItemsValidation; model.AllowAdditionalProperties = model.AllowAdditionalProperties && schema.AllowAdditionalProperties; model.AllowAdditionalItems = model.AllowAdditionalItems && schema.AllowAdditionalItems; model.UniqueItems = model.UniqueItems || schema.UniqueItems; if (schema.Enum != null) { if (model.Enum == null) model.Enum = new List<JToken>(); model.Enum.AddRangeDistinct(schema.Enum, JToken.EqualityComparer); } model.Disallow = model.Disallow | (schema.Disallow ?? JsonSchemaType.None); if (schema.Pattern != null) { if (model.Patterns == null) model.Patterns = new List<string>(); model.Patterns.AddDistinct(schema.Pattern); } }
/// <summary> /// Validates the specified <see cref="JToken"/>. /// </summary> /// <param name="source">The source <see cref="JToken"/> to test.</param> /// <param name="schema">The schema to test with.</param> /// <param name="validationEventHandler">The validation event handler.</param> public static void Validate(this JToken source, JsonSchema schema, ValidationEventHandler validationEventHandler) { ValidationUtils.ArgumentNotNull(source, "source"); ValidationUtils.ArgumentNotNull(schema, "schema"); using (JsonValidatingReader reader = new JsonValidatingReader(source.CreateReader())) { reader.Schema = schema; if (validationEventHandler != null) reader.ValidationEventHandler += validationEventHandler; while (reader.Read()) { } } }
/// <summary> /// Validates the specified <see cref="JToken"/>. /// </summary> /// <param name="source">The source <see cref="JToken"/> to test.</param> /// <param name="schema">The schema to test with.</param> public static void Validate(this JToken source, JsonSchema schema) { source.Validate(schema, null); }
public JsonSchemaNode Combine(JsonSchema schema) { return new JsonSchemaNode(this, schema); }
/// <summary> /// Determines whether the <see cref="JToken"/> is valid. /// </summary> /// <param name="source">The source <see cref="JToken"/> to test.</param> /// <param name="schema">The schema to test with.</param> /// <returns> /// <c>true</c> if the specified <see cref="JToken"/> is valid; otherwise, <c>false</c>. /// </returns> public static bool IsValid(this JToken source, JsonSchema schema) { bool valid = true; source.Validate(schema, (sender, args) => { valid = false; }); return valid; }
public void WriteSchema(JsonSchema schema) { ValidationUtils.ArgumentNotNull(schema, "schema"); if (!_resolver.LoadedSchemas.Contains(schema)) _resolver.LoadedSchemas.Add(schema); _writer.WriteStartObject(); WritePropertyIfNotNull(_writer, JsonSchemaConstants.IdPropertyName, schema.Id); WritePropertyIfNotNull(_writer, JsonSchemaConstants.TitlePropertyName, schema.Title); WritePropertyIfNotNull(_writer, JsonSchemaConstants.DescriptionPropertyName, schema.Description); WritePropertyIfNotNull(_writer, JsonSchemaConstants.RequiredPropertyName, schema.Required); WritePropertyIfNotNull(_writer, JsonSchemaConstants.ReadOnlyPropertyName, schema.ReadOnly); WritePropertyIfNotNull(_writer, JsonSchemaConstants.HiddenPropertyName, schema.Hidden); WritePropertyIfNotNull(_writer, JsonSchemaConstants.TransientPropertyName, schema.Transient); if (schema.Type != null) WriteType(JsonSchemaConstants.TypePropertyName, _writer, schema.Type.Value); if (!schema.AllowAdditionalProperties) { _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName); _writer.WriteValue(schema.AllowAdditionalProperties); } else { if (schema.AdditionalProperties != null) { _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName); ReferenceOrWriteSchema(schema.AdditionalProperties); } } if (!schema.AllowAdditionalItems) { _writer.WritePropertyName(JsonSchemaConstants.AdditionalItemsPropertyName); _writer.WriteValue(schema.AllowAdditionalItems); } else { if (schema.AdditionalItems != null) { _writer.WritePropertyName(JsonSchemaConstants.AdditionalItemsPropertyName); ReferenceOrWriteSchema(schema.AdditionalItems); } } WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PropertiesPropertyName, schema.Properties); WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PatternPropertiesPropertyName, schema.PatternProperties); WriteItems(schema); WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumPropertyName, schema.Minimum); WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumPropertyName, schema.Maximum); WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMinimumPropertyName, schema.ExclusiveMinimum); WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMaximumPropertyName, schema.ExclusiveMaximum); WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumLengthPropertyName, schema.MinimumLength); WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumLengthPropertyName, schema.MaximumLength); WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumItemsPropertyName, schema.MinimumItems); WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumItemsPropertyName, schema.MaximumItems); WritePropertyIfNotNull(_writer, JsonSchemaConstants.DivisibleByPropertyName, schema.DivisibleBy); WritePropertyIfNotNull(_writer, JsonSchemaConstants.FormatPropertyName, schema.Format); WritePropertyIfNotNull(_writer, JsonSchemaConstants.PatternPropertyName, schema.Pattern); if (schema.Enum != null) { _writer.WritePropertyName(JsonSchemaConstants.EnumPropertyName); _writer.WriteStartArray(); foreach (JToken token in schema.Enum) { token.WriteTo(_writer); } _writer.WriteEndArray(); } if (schema.Default != null) { _writer.WritePropertyName(JsonSchemaConstants.DefaultPropertyName); schema.Default.WriteTo(_writer); } if (schema.Disallow != null) WriteType(JsonSchemaConstants.DisallowPropertyName, _writer, schema.Disallow.Value); if (schema.Extends != null && schema.Extends.Count > 0) { _writer.WritePropertyName(JsonSchemaConstants.ExtendsPropertyName); if (schema.Extends.Count == 1) { ReferenceOrWriteSchema(schema.Extends[0]); } else { _writer.WriteStartArray(); foreach (JsonSchema jsonSchema in schema.Extends) { ReferenceOrWriteSchema(jsonSchema); } _writer.WriteEndArray(); } } _writer.WriteEndObject(); }
private void WriteItems(JsonSchema schema) { if (schema.Items == null && !schema.PositionalItemsValidation) return; _writer.WritePropertyName(JsonSchemaConstants.ItemsPropertyName); if (!schema.PositionalItemsValidation) { if (schema.Items != null && schema.Items.Count > 0) { ReferenceOrWriteSchema(schema.Items[0]); } else { _writer.WriteStartObject(); _writer.WriteEndObject(); } return; } _writer.WriteStartArray(); if (schema.Items != null) { foreach (JsonSchema itemSchema in schema.Items) { ReferenceOrWriteSchema(itemSchema); } } _writer.WriteEndArray(); }
private JsonSchema ResolveReferences(JsonSchema schema) { if (schema.DeferredReference != null) { string reference = schema.DeferredReference; bool locationReference = (reference.StartsWith("#", StringComparison.Ordinal)); if (locationReference) reference = UnescapeReference(reference); JsonSchema resolvedSchema = _resolver.GetSchema(reference); if (resolvedSchema == null) { if (locationReference) { string[] escapedParts = schema.DeferredReference.TrimStart('#').Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); JToken currentToken = _rootSchema; foreach (string escapedPart in escapedParts) { string part = UnescapeReference(escapedPart); if (currentToken.Type == JTokenType.Object) { currentToken = currentToken[part]; } else if (currentToken.Type == JTokenType.Array || currentToken.Type == JTokenType.Constructor) { int index; if (int.TryParse(part, out index) && index >= 0 && index < currentToken.Count()) currentToken = currentToken[index]; else currentToken = null; } if (currentToken == null) break; } if (currentToken != null) resolvedSchema = BuildSchema(currentToken); } if (resolvedSchema == null) throw new JsonException("Could not resolve schema reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, schema.DeferredReference)); } schema = resolvedSchema; } if (schema.ReferencesResolved) return schema; schema.ReferencesResolved = true; if (schema.Extends != null) { for (int i = 0; i < schema.Extends.Count; i++) { schema.Extends[i] = ResolveReferences(schema.Extends[i]); } } if (schema.Items != null) { for (int i = 0; i < schema.Items.Count; i++) { schema.Items[i] = ResolveReferences(schema.Items[i]); } } if (schema.AdditionalItems != null) schema.AdditionalItems = ResolveReferences(schema.AdditionalItems); if (schema.PatternProperties != null) { foreach (KeyValuePair<string, JsonSchema> patternProperty in schema.PatternProperties.ToList()) { schema.PatternProperties[patternProperty.Key] = ResolveReferences(patternProperty.Value); } } if (schema.Properties != null) { foreach (KeyValuePair<string, JsonSchema> property in schema.Properties.ToList()) { schema.Properties[property.Key] = ResolveReferences(property.Value); } } if (schema.AdditionalProperties != null) schema.AdditionalProperties = ResolveReferences(schema.AdditionalProperties); return schema; }
private void Push(TypeSchema typeSchema) { _currentSchema = typeSchema.Schema; _stack.Add(typeSchema); _resolver.LoadedSchemas.Add(typeSchema.Schema); }
private TypeSchema Pop() { TypeSchema popped = _stack[_stack.Count - 1]; _stack.RemoveAt(_stack.Count - 1); TypeSchema newValue = _stack.LastOrDefault(); if (newValue != null) { _currentSchema = newValue.Schema; } else { _currentSchema = null; } return popped; }
private JsonSchema BuildSchema(JToken token) { JObject schemaObject = token as JObject; if (schemaObject == null) throw JsonException.Create(token, token.Path, "Expected object while parsing schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); JToken referenceToken; if (schemaObject.TryGetValue(JsonTypeReflector.RefPropertyName, out referenceToken)) { JsonSchema deferredSchema = new JsonSchema(); deferredSchema.DeferredReference = (string)referenceToken; return deferredSchema; } string location = token.Path.Replace(".", "/").Replace("[", "/").Replace("]", string.Empty); if (!string.IsNullOrEmpty(location)) location = "/" + location; location = "#" + location; JsonSchema existingSchema; if (_documentSchemas.TryGetValue(location, out existingSchema)) return existingSchema; Push(new JsonSchema { Location = location }); ProcessSchemaProperties(schemaObject); return Pop(); }
public void AddProperty(IDictionary<string, JsonSchemaNode> target, string propertyName, JsonSchema schema) { JsonSchemaNode propertyNode; target.TryGetValue(propertyName, out propertyNode); target[propertyName] = AddSchema(propertyNode, schema); }
public void AddAdditionalItems(JsonSchemaNode parentNode, JsonSchema schema) { parentNode.AdditionalItems = AddSchema(parentNode.AdditionalItems, schema); }
public void AddAdditionalProperties(JsonSchemaNode parentNode, JsonSchema schema) { parentNode.AdditionalProperties = AddSchema(parentNode.AdditionalProperties, schema); }
public void AddItem(JsonSchemaNode parentNode, int index, JsonSchema schema) { JsonSchemaNode existingItemNode = (parentNode.Items.Count > index) ? parentNode.Items[index] : null; JsonSchemaNode newItemNode = AddSchema(existingItemNode, schema); if (!(parentNode.Items.Count > index)) { parentNode.Items.Add(newItemNode); } else { parentNode.Items[index] = newItemNode; } }