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 /// <para> 37 /// An in-memory representation of a JSON Schema. 38 /// </para> 39 /// <note type="caution"> 40 /// JSON Schema validation has been moved to its own package. See <see href="http://www.newtonsoft.com/jsonschema">http://www.newtonsoft.com/jsonschema</see> for more details. 41 /// </note> 42 /// </summary> 43 [Obsolete("JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details.")] 44 public class JsonSchema 45 { 46 /// <summary> 47 /// Gets or sets the id. 48 /// </summary> 49 public string Id { get; set; } 50 51 /// <summary> 52 /// Gets or sets the title. 53 /// </summary> 54 public string Title { get; set; } 55 56 /// <summary> 57 /// Gets or sets whether the object is required. 58 /// </summary> 59 public bool? Required { get; set; } 60 61 /// <summary> 62 /// Gets or sets whether the object is read only. 63 /// </summary> 64 public bool? ReadOnly { get; set; } 65 66 /// <summary> 67 /// Gets or sets whether the object is visible to users. 68 /// </summary> 69 public bool? Hidden { get; set; } 70 71 /// <summary> 72 /// Gets or sets whether the object is transient. 73 /// </summary> 74 public bool? Transient { get; set; } 75 76 /// <summary> 77 /// Gets or sets the description of the object. 78 /// </summary> 79 public string Description { get; set; } 80 81 /// <summary> 82 /// Gets or sets the types of values allowed by the object. 83 /// </summary> 84 /// <value>The type.</value> 85 public JsonSchemaType? Type { get; set; } 86 87 /// <summary> 88 /// Gets or sets the pattern. 89 /// </summary> 90 /// <value>The pattern.</value> 91 public string Pattern { get; set; } 92 93 /// <summary> 94 /// Gets or sets the minimum length. 95 /// </summary> 96 /// <value>The minimum length.</value> 97 public int? MinimumLength { get; set; } 98 99 /// <summary> 100 /// Gets or sets the maximum length. 101 /// </summary> 102 /// <value>The maximum length.</value> 103 public int? MaximumLength { get; set; } 104 105 /// <summary> 106 /// Gets or sets a number that the value should be divisble by. 107 /// </summary> 108 /// <value>A number that the value should be divisble by.</value> 109 public double? DivisibleBy { get; set; } 110 111 /// <summary> 112 /// Gets or sets the minimum. 113 /// </summary> 114 /// <value>The minimum.</value> 115 public double? Minimum { get; set; } 116 117 /// <summary> 118 /// Gets or sets the maximum. 119 /// </summary> 120 /// <value>The maximum.</value> 121 public double? Maximum { get; set; } 122 123 /// <summary> 124 /// Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute. 125 /// </summary> 126 /// <value>A flag indicating whether the value can not equal the number defined by the "minimum" attribute.</value> 127 public bool? ExclusiveMinimum { get; set; } 128 129 /// <summary> 130 /// Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute. 131 /// </summary> 132 /// <value>A flag indicating whether the value can not equal the number defined by the "maximum" attribute.</value> 133 public bool? ExclusiveMaximum { get; set; } 134 135 /// <summary> 136 /// Gets or sets the minimum number of items. 137 /// </summary> 138 /// <value>The minimum number of items.</value> 139 public int? MinimumItems { get; set; } 140 141 /// <summary> 142 /// Gets or sets the maximum number of items. 143 /// </summary> 144 /// <value>The maximum number of items.</value> 145 public int? MaximumItems { get; set; } 146 147 /// <summary> 148 /// Gets or sets the <see cref="JsonSchema"/> of items. 149 /// </summary> 150 /// <value>The <see cref="JsonSchema"/> of items.</value> 151 public IList<JsonSchema> Items { get; set; } 152 153 /// <summary> 154 /// Gets or sets a value indicating whether items in an array are validated using the <see cref="JsonSchema"/> instance at their array position from <see cref="JsonSchema.Items"/>. 155 /// </summary> 156 /// <value> 157 /// <c>true</c> if items are validated using their array position; otherwise, <c>false</c>. 158 /// </value> 159 public bool PositionalItemsValidation { get; set; } 160 161 /// <summary> 162 /// Gets or sets the <see cref="JsonSchema"/> of additional items. 163 /// </summary> 164 /// <value>The <see cref="JsonSchema"/> of additional items.</value> 165 public JsonSchema AdditionalItems { get; set; } 166 167 /// <summary> 168 /// Gets or sets a value indicating whether additional items are allowed. 169 /// </summary> 170 /// <value> 171 /// <c>true</c> if additional items are allowed; otherwise, <c>false</c>. 172 /// </value> 173 public bool AllowAdditionalItems { get; set; } 174 175 /// <summary> 176 /// Gets or sets whether the array items must be unique. 177 /// </summary> 178 public bool UniqueItems { get; set; } 179 180 /// <summary> 181 /// Gets or sets the <see cref="JsonSchema"/> of properties. 182 /// </summary> 183 /// <value>The <see cref="JsonSchema"/> of properties.</value> 184 public IDictionary<string, JsonSchema> Properties { get; set; } 185 186 /// <summary> 187 /// Gets or sets the <see cref="JsonSchema"/> of additional properties. 188 /// </summary> 189 /// <value>The <see cref="JsonSchema"/> of additional properties.</value> 190 public JsonSchema AdditionalProperties { get; set; } 191 192 /// <summary> 193 /// Gets or sets the pattern properties. 194 /// </summary> 195 /// <value>The pattern properties.</value> 196 public IDictionary<string, JsonSchema> PatternProperties { get; set; } 197 198 /// <summary> 199 /// Gets or sets a value indicating whether additional properties are allowed. 200 /// </summary> 201 /// <value> 202 /// <c>true</c> if additional properties are allowed; otherwise, <c>false</c>. 203 /// </value> 204 public bool AllowAdditionalProperties { get; set; } 205 206 /// <summary> 207 /// Gets or sets the required property if this property is present. 208 /// </summary> 209 /// <value>The required property if this property is present.</value> 210 public string Requires { get; set; } 211 212 /// <summary> 213 /// Gets or sets the a collection of valid enum values allowed. 214 /// </summary> 215 /// <value>A collection of valid enum values allowed.</value> 216 public IList<JToken> Enum { get; set; } 217 218 /// <summary> 219 /// Gets or sets disallowed types. 220 /// </summary> 221 /// <value>The disallow types.</value> 222 public JsonSchemaType? Disallow { get; set; } 223 224 /// <summary> 225 /// Gets or sets the default value. 226 /// </summary> 227 /// <value>The default value.</value> 228 public JToken Default { get; set; } 229 230 /// <summary> 231 /// Gets or sets the collection of <see cref="JsonSchema"/> that this schema extends. 232 /// </summary> 233 /// <value>The collection of <see cref="JsonSchema"/> that this schema extends.</value> 234 public IList<JsonSchema> Extends { get; set; } 235 236 /// <summary> 237 /// Gets or sets the format. 238 /// </summary> 239 /// <value>The format.</value> 240 public string Format { get; set; } 241 242 internal string Location { get; set; } 243 244 private readonly string _internalId = Guid.NewGuid().ToString("N"); 245 246 internal string InternalId 247 { 248 get { return _internalId; } 249 } 250 251 // if this is set then this schema instance is just a deferred reference 252 // and will be replaced when the schema reference is resolved 253 internal string DeferredReference { get; set; } 254 internal bool ReferencesResolved { get; set; } 255 256 /// <summary> 257 /// Initializes a new instance of the <see cref="JsonSchema"/> class. 258 /// </summary> JsonSchema()259 public JsonSchema() 260 { 261 AllowAdditionalProperties = true; 262 AllowAdditionalItems = true; 263 } 264 265 /// <summary> 266 /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>. 267 /// </summary> 268 /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param> 269 /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns> Read(JsonReader reader)270 public static JsonSchema Read(JsonReader reader) 271 { 272 return Read(reader, new JsonSchemaResolver()); 273 } 274 275 /// <summary> 276 /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>. 277 /// </summary> 278 /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param> 279 /// <param name="resolver">The <see cref="JsonSchemaResolver"/> to use when resolving schema references.</param> 280 /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns> Read(JsonReader reader, JsonSchemaResolver resolver)281 public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver) 282 { 283 ValidationUtils.ArgumentNotNull(reader, nameof(reader)); 284 ValidationUtils.ArgumentNotNull(resolver, nameof(resolver)); 285 286 JsonSchemaBuilder builder = new JsonSchemaBuilder(resolver); 287 return builder.Read(reader); 288 } 289 290 /// <summary> 291 /// Load a <see cref="JsonSchema"/> from a string that contains schema JSON. 292 /// </summary> 293 /// <param name="json">A <see cref="String"/> that contains JSON.</param> 294 /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns> Parse(string json)295 public static JsonSchema Parse(string json) 296 { 297 return Parse(json, new JsonSchemaResolver()); 298 } 299 300 /// <summary> 301 /// Parses the specified json. 302 /// </summary> 303 /// <param name="json">The json.</param> 304 /// <param name="resolver">The resolver.</param> 305 /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns> Parse(string json, JsonSchemaResolver resolver)306 public static JsonSchema Parse(string json, JsonSchemaResolver resolver) 307 { 308 ValidationUtils.ArgumentNotNull(json, nameof(json)); 309 310 using (JsonReader reader = new JsonTextReader(new StringReader(json))) 311 { 312 return Read(reader, resolver); 313 } 314 } 315 316 /// <summary> 317 /// Writes this schema to a <see cref="JsonWriter"/>. 318 /// </summary> 319 /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param> WriteTo(JsonWriter writer)320 public void WriteTo(JsonWriter writer) 321 { 322 WriteTo(writer, new JsonSchemaResolver()); 323 } 324 325 /// <summary> 326 /// Writes this schema to a <see cref="JsonWriter"/> using the specified <see cref="JsonSchemaResolver"/>. 327 /// </summary> 328 /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param> 329 /// <param name="resolver">The resolver used.</param> WriteTo(JsonWriter writer, JsonSchemaResolver resolver)330 public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver) 331 { 332 ValidationUtils.ArgumentNotNull(writer, nameof(writer)); 333 ValidationUtils.ArgumentNotNull(resolver, nameof(resolver)); 334 335 JsonSchemaWriter schemaWriter = new JsonSchemaWriter(writer, resolver); 336 schemaWriter.WriteSchema(this); 337 } 338 339 /// <summary> 340 /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. 341 /// </summary> 342 /// <returns> 343 /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>. 344 /// </returns> ToString()345 public override string ToString() 346 { 347 StringWriter writer = new StringWriter(CultureInfo.InvariantCulture); 348 JsonTextWriter jsonWriter = new JsonTextWriter(writer); 349 jsonWriter.Formatting = Formatting.Indented; 350 351 WriteTo(jsonWriter); 352 353 return writer.ToString(); 354 } 355 } 356 }