1 #region License 2 // Copyright (c) 2007 James Newton-King 3 // 4 // Permission is hereby granted, free of charge, to any person 5 // obtaining a copy of this software and associated documentation 6 // files (the "Software"), to deal in the Software without 7 // restriction, including without limitation the rights to use, 8 // copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the 10 // Software is furnished to do so, subject to the following 11 // conditions: 12 // 13 // The above copyright notice and this permission notice shall be 14 // included in all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 // OTHER DEALINGS IN THE SOFTWARE. 24 #endregion 25 26 using System; 27 using System.Collections.Generic; 28 using System.IO; 29 using Newtonsoft.Json.Linq; 30 using Newtonsoft.Json.Utilities; 31 using System.Globalization; 32 33 namespace Newtonsoft.Json.Schema 34 { 35 /// <summary> 36 /// An in-memory representation of a JSON Schema. 37 /// </summary> 38 public class JsonSchema 39 { 40 /// <summary> 41 /// Gets or sets the id. 42 /// </summary> 43 public string Id { get; set; } 44 /// <summary> 45 /// Gets or sets the title. 46 /// </summary> 47 public string Title { get; set; } 48 /// <summary> 49 /// Gets or sets whether the object is required. 50 /// </summary> 51 public bool? Required { get; set; } 52 /// <summary> 53 /// Gets or sets whether the object is read only. 54 /// </summary> 55 public bool? ReadOnly { get; set; } 56 /// <summary> 57 /// Gets or sets whether the object is visible to users. 58 /// </summary> 59 public bool? Hidden { get; set; } 60 /// <summary> 61 /// Gets or sets whether the object is transient. 62 /// </summary> 63 public bool? Transient { get; set; } 64 /// <summary> 65 /// Gets or sets the description of the object. 66 /// </summary> 67 public string Description { get; set; } 68 /// <summary> 69 /// Gets or sets the types of values allowed by the object. 70 /// </summary> 71 /// <value>The type.</value> 72 public JsonSchemaType? Type { get; set; } 73 /// <summary> 74 /// Gets or sets the pattern. 75 /// </summary> 76 /// <value>The pattern.</value> 77 public string Pattern { get; set; } 78 /// <summary> 79 /// Gets or sets the minimum length. 80 /// </summary> 81 /// <value>The minimum length.</value> 82 public int? MinimumLength { get; set; } 83 /// <summary> 84 /// Gets or sets the maximum length. 85 /// </summary> 86 /// <value>The maximum length.</value> 87 public int? MaximumLength { get; set; } 88 /// <summary> 89 /// Gets or sets a number that the value should be divisble by. 90 /// </summary> 91 /// <value>A number that the value should be divisble by.</value> 92 public double? DivisibleBy { get; set; } 93 /// <summary> 94 /// Gets or sets the minimum. 95 /// </summary> 96 /// <value>The minimum.</value> 97 public double? Minimum { get; set; } 98 /// <summary> 99 /// Gets or sets the maximum. 100 /// </summary> 101 /// <value>The maximum.</value> 102 public double? Maximum { get; set; } 103 /// <summary> 104 /// Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute. 105 /// </summary> 106 /// <value>A flag indicating whether the value can not equal the number defined by the "minimum" attribute.</value> 107 public bool? ExclusiveMinimum { get; set; } 108 /// <summary> 109 /// Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute. 110 /// </summary> 111 /// <value>A flag indicating whether the value can not equal the number defined by the "maximum" attribute.</value> 112 public bool? ExclusiveMaximum { get; set; } 113 /// <summary> 114 /// Gets or sets the minimum number of items. 115 /// </summary> 116 /// <value>The minimum number of items.</value> 117 public int? MinimumItems { get; set; } 118 /// <summary> 119 /// Gets or sets the maximum number of items. 120 /// </summary> 121 /// <value>The maximum number of items.</value> 122 public int? MaximumItems { get; set; } 123 /// <summary> 124 /// Gets or sets the <see cref="JsonSchema"/> of items. 125 /// </summary> 126 /// <value>The <see cref="JsonSchema"/> of items.</value> 127 public IList<JsonSchema> Items { get; set; } 128 /// <summary> 129 /// Gets or sets the <see cref="JsonSchema"/> of properties. 130 /// </summary> 131 /// <value>The <see cref="JsonSchema"/> of properties.</value> 132 public IDictionary<string, JsonSchema> Properties { get; set; } 133 /// <summary> 134 /// Gets or sets the <see cref="JsonSchema"/> of additional properties. 135 /// </summary> 136 /// <value>The <see cref="JsonSchema"/> of additional properties.</value> 137 public JsonSchema AdditionalProperties { get; set; } 138 /// <summary> 139 /// Gets or sets the pattern properties. 140 /// </summary> 141 /// <value>The pattern properties.</value> 142 public IDictionary<string, JsonSchema> PatternProperties { get; set; } 143 /// <summary> 144 /// Gets or sets a value indicating whether additional properties are allowed. 145 /// </summary> 146 /// <value> 147 /// <c>true</c> if additional properties are allowed; otherwise, <c>false</c>. 148 /// </value> 149 public bool AllowAdditionalProperties { get; set; } 150 /// <summary> 151 /// Gets or sets the required property if this property is present. 152 /// </summary> 153 /// <value>The required property if this property is present.</value> 154 public string Requires { get; set; } 155 /// <summary> 156 /// Gets or sets the identity. 157 /// </summary> 158 /// <value>The identity.</value> 159 public IList<string> Identity { get; set; } 160 /// <summary> 161 /// Gets or sets the a collection of valid enum values allowed. 162 /// </summary> 163 /// <value>A collection of valid enum values allowed.</value> 164 public IList<JToken> Enum { get; set; } 165 /// <summary> 166 /// Gets or sets a collection of options. 167 /// </summary> 168 /// <value>A collection of options.</value> 169 public IDictionary<JToken, string> Options { get; set; } 170 /// <summary> 171 /// Gets or sets disallowed types. 172 /// </summary> 173 /// <value>The disallow types.</value> 174 public JsonSchemaType? Disallow { get; set; } 175 /// <summary> 176 /// Gets or sets the default value. 177 /// </summary> 178 /// <value>The default value.</value> 179 public JToken Default { get; set; } 180 /// <summary> 181 /// Gets or sets the extend <see cref="JsonSchema"/>. 182 /// </summary> 183 /// <value>The extended <see cref="JsonSchema"/>.</value> 184 public JsonSchema Extends { get; set; } 185 /// <summary> 186 /// Gets or sets the format. 187 /// </summary> 188 /// <value>The format.</value> 189 public string Format { get; set; } 190 191 private readonly string _internalId = Guid.NewGuid().ToString("N"); 192 193 internal string InternalId 194 { 195 get { return _internalId; } 196 } 197 198 /// <summary> 199 /// Initializes a new instance of the <see cref="JsonSchema"/> class. 200 /// </summary> JsonSchema()201 public JsonSchema() 202 { 203 AllowAdditionalProperties = true; 204 } 205 206 /// <summary> 207 /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>. 208 /// </summary> 209 /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param> 210 /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns> Read(JsonReader reader)211 public static JsonSchema Read(JsonReader reader) 212 { 213 return Read(reader, new JsonSchemaResolver()); 214 } 215 216 /// <summary> 217 /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>. 218 /// </summary> 219 /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param> 220 /// <param name="resolver">The <see cref="JsonSchemaResolver"/> to use when resolving schema references.</param> 221 /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns> Read(JsonReader reader, JsonSchemaResolver resolver)222 public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver) 223 { 224 ValidationUtils.ArgumentNotNull(reader, "reader"); 225 ValidationUtils.ArgumentNotNull(resolver, "resolver"); 226 227 JsonSchemaBuilder builder = new JsonSchemaBuilder(resolver); 228 return builder.Parse(reader); 229 } 230 231 /// <summary> 232 /// Load a <see cref="JsonSchema"/> from a string that contains schema JSON. 233 /// </summary> 234 /// <param name="json">A <see cref="String"/> that contains JSON.</param> 235 /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns> Parse(string json)236 public static JsonSchema Parse(string json) 237 { 238 return Parse(json, new JsonSchemaResolver()); 239 } 240 241 /// <summary> 242 /// Parses the specified json. 243 /// </summary> 244 /// <param name="json">The json.</param> 245 /// <param name="resolver">The resolver.</param> 246 /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns> Parse(string json, JsonSchemaResolver resolver)247 public static JsonSchema Parse(string json, JsonSchemaResolver resolver) 248 { 249 ValidationUtils.ArgumentNotNull(json, "json"); 250 251 JsonReader reader = new JsonTextReader(new StringReader(json)); 252 253 return Read(reader, resolver); 254 } 255 256 /// <summary> 257 /// Writes this schema to a <see cref="JsonWriter"/>. 258 /// </summary> 259 /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param> WriteTo(JsonWriter writer)260 public void WriteTo(JsonWriter writer) 261 { 262 WriteTo(writer, new JsonSchemaResolver()); 263 } 264 265 /// <summary> 266 /// Writes this schema to a <see cref="JsonWriter"/> using the specified <see cref="JsonSchemaResolver"/>. 267 /// </summary> 268 /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param> 269 /// <param name="resolver">The resolver used.</param> WriteTo(JsonWriter writer, JsonSchemaResolver resolver)270 public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver) 271 { 272 ValidationUtils.ArgumentNotNull(writer, "writer"); 273 ValidationUtils.ArgumentNotNull(resolver, "resolver"); 274 275 JsonSchemaWriter schemaWriter = new JsonSchemaWriter(writer, resolver); 276 schemaWriter.WriteSchema(this); 277 } 278 279 /// <summary> 280 /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. 281 /// </summary> 282 /// <returns> 283 /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. 284 /// </returns> ToString()285 public override string ToString() 286 { 287 StringWriter writer = new StringWriter(CultureInfo.InvariantCulture); 288 JsonTextWriter jsonWriter = new JsonTextWriter(writer); 289 jsonWriter.Formatting = Formatting.Indented; 290 291 WriteTo(jsonWriter); 292 293 return writer.ToString(); 294 } 295 } 296 }