JsonSchemaWriter
class JsonSchemaWriter
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Newtonsoft.Json.Schema
{
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
internal class JsonSchemaWriter
{
private readonly JsonWriter _writer;
private readonly JsonSchemaResolver _resolver;
public JsonSchemaWriter(JsonWriter writer, JsonSchemaResolver resolver)
{
ValidationUtils.ArgumentNotNull(writer, "writer");
_writer = writer;
_resolver = resolver;
}
private void ReferenceOrWriteSchema(JsonSchema schema)
{
if (schema.Id != null && _resolver.GetSchema(schema.Id) != null) {
_writer.WriteStartObject();
_writer.WritePropertyName("$ref");
_writer.WriteValue(schema.Id);
_writer.WriteEndObject();
} else
WriteSchema(schema);
}
public void WriteSchema(JsonSchema schema)
{
ValidationUtils.ArgumentNotNull(schema, "schema");
if (!_resolver.LoadedSchemas.Contains(schema))
_resolver.LoadedSchemas.Add(schema);
_writer.WriteStartObject();
WritePropertyIfNotNull(_writer, "id", schema.Id);
WritePropertyIfNotNull(_writer, "title", schema.Title);
WritePropertyIfNotNull(_writer, "description", schema.Description);
WritePropertyIfNotNull(_writer, "required", schema.Required);
WritePropertyIfNotNull(_writer, "readonly", schema.ReadOnly);
WritePropertyIfNotNull(_writer, "hidden", schema.Hidden);
WritePropertyIfNotNull(_writer, "transient", schema.Transient);
if (schema.Type.HasValue)
WriteType("type", _writer, schema.Type.GetValueOrDefault());
if (!schema.AllowAdditionalProperties) {
_writer.WritePropertyName("additionalProperties");
_writer.WriteValue(schema.AllowAdditionalProperties);
} else if (schema.AdditionalProperties != null) {
_writer.WritePropertyName("additionalProperties");
ReferenceOrWriteSchema(schema.AdditionalProperties);
}
if (!schema.AllowAdditionalItems) {
_writer.WritePropertyName("additionalItems");
_writer.WriteValue(schema.AllowAdditionalItems);
} else if (schema.AdditionalItems != null) {
_writer.WritePropertyName("additionalItems");
ReferenceOrWriteSchema(schema.AdditionalItems);
}
WriteSchemaDictionaryIfNotNull(_writer, "properties", schema.Properties);
WriteSchemaDictionaryIfNotNull(_writer, "patternProperties", schema.PatternProperties);
WriteItems(schema);
WritePropertyIfNotNull(_writer, "minimum", schema.Minimum);
WritePropertyIfNotNull(_writer, "maximum", schema.Maximum);
WritePropertyIfNotNull(_writer, "exclusiveMinimum", schema.ExclusiveMinimum);
WritePropertyIfNotNull(_writer, "exclusiveMaximum", schema.ExclusiveMaximum);
WritePropertyIfNotNull(_writer, "minLength", schema.MinimumLength);
WritePropertyIfNotNull(_writer, "maxLength", schema.MaximumLength);
WritePropertyIfNotNull(_writer, "minItems", schema.MinimumItems);
WritePropertyIfNotNull(_writer, "maxItems", schema.MaximumItems);
WritePropertyIfNotNull(_writer, "divisibleBy", schema.DivisibleBy);
WritePropertyIfNotNull(_writer, "format", schema.Format);
WritePropertyIfNotNull(_writer, "pattern", schema.Pattern);
if (schema.Enum != null) {
_writer.WritePropertyName("enum");
_writer.WriteStartArray();
foreach (JToken item in schema.Enum) {
item.WriteTo(_writer, Array.Empty<JsonConverter>());
}
_writer.WriteEndArray();
}
if (schema.Default != null) {
_writer.WritePropertyName("default");
schema.Default.WriteTo(_writer, Array.Empty<JsonConverter>());
}
if (schema.Disallow.HasValue)
WriteType("disallow", _writer, schema.Disallow.GetValueOrDefault());
if (schema.Extends != null && schema.Extends.Count > 0) {
_writer.WritePropertyName("extends");
if (schema.Extends.Count == 1)
ReferenceOrWriteSchema(schema.Extends[0]);
else {
_writer.WriteStartArray();
foreach (JsonSchema extend in schema.Extends) {
ReferenceOrWriteSchema(extend);
}
_writer.WriteEndArray();
}
}
_writer.WriteEndObject();
}
private void WriteSchemaDictionaryIfNotNull(JsonWriter writer, string propertyName, IDictionary<string, JsonSchema> properties)
{
if (properties != null) {
writer.WritePropertyName(propertyName);
writer.WriteStartObject();
foreach (KeyValuePair<string, JsonSchema> property in properties) {
writer.WritePropertyName(property.Key);
ReferenceOrWriteSchema(property.Value);
}
writer.WriteEndObject();
}
}
private void WriteItems(JsonSchema schema)
{
if (schema.Items != null || schema.PositionalItemsValidation) {
_writer.WritePropertyName("items");
if (!schema.PositionalItemsValidation) {
if (schema.Items != null && schema.Items.Count > 0)
ReferenceOrWriteSchema(schema.Items[0]);
else {
_writer.WriteStartObject();
_writer.WriteEndObject();
}
} else {
_writer.WriteStartArray();
if (schema.Items != null) {
foreach (JsonSchema item in schema.Items) {
ReferenceOrWriteSchema(item);
}
}
_writer.WriteEndArray();
}
}
}
private void WriteType(string propertyName, JsonWriter writer, JsonSchemaType type)
{
if (Enum.IsDefined(typeof(JsonSchemaType), type)) {
writer.WritePropertyName(propertyName);
writer.WriteValue(JsonSchemaBuilder.MapType(type));
} else {
IEnumerator<JsonSchemaType> enumerator = (from v in EnumUtils.GetFlagsValues(type)
where v != JsonSchemaType.None
select v).GetEnumerator();
if (enumerator.MoveNext()) {
writer.WritePropertyName(propertyName);
JsonSchemaType current = enumerator.Current;
if (enumerator.MoveNext()) {
writer.WriteStartArray();
writer.WriteValue(JsonSchemaBuilder.MapType(current));
do {
writer.WriteValue(JsonSchemaBuilder.MapType(enumerator.Current));
} while (enumerator.MoveNext());
writer.WriteEndArray();
} else
writer.WriteValue(JsonSchemaBuilder.MapType(current));
}
}
}
private void WritePropertyIfNotNull(JsonWriter writer, string propertyName, object value)
{
if (value != null) {
writer.WritePropertyName(propertyName);
writer.WriteValue(value);
}
}
}
}