You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
7.1 KiB

  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. using System;
  26. using System.Collections.Generic;
  27. #if NET20
  28. using Newtonsoft.Json.Utilities.LinqBridge;
  29. #else
  30. using System.Linq;
  31. #endif
  32. namespace Newtonsoft.Json.Schema
  33. {
  34. [Obsolete("JSON Schema validation has been moved to its own package. See http://www.newtonsoft.com/jsonschema for more details.")]
  35. internal class JsonSchemaModelBuilder
  36. {
  37. private JsonSchemaNodeCollection _nodes = new JsonSchemaNodeCollection();
  38. private Dictionary<JsonSchemaNode, JsonSchemaModel> _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>();
  39. private JsonSchemaNode _node;
  40. public JsonSchemaModel Build(JsonSchema schema)
  41. {
  42. _nodes = new JsonSchemaNodeCollection();
  43. _node = AddSchema(null, schema);
  44. _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>();
  45. JsonSchemaModel model = BuildNodeModel(_node);
  46. return model;
  47. }
  48. public JsonSchemaNode AddSchema(JsonSchemaNode existingNode, JsonSchema schema)
  49. {
  50. string newId;
  51. if (existingNode != null)
  52. {
  53. if (existingNode.Schemas.Contains(schema))
  54. {
  55. return existingNode;
  56. }
  57. newId = JsonSchemaNode.GetId(existingNode.Schemas.Union(new[] { schema }));
  58. }
  59. else
  60. {
  61. newId = JsonSchemaNode.GetId(new[] { schema });
  62. }
  63. if (_nodes.Contains(newId))
  64. {
  65. return _nodes[newId];
  66. }
  67. JsonSchemaNode currentNode = (existingNode != null)
  68. ? existingNode.Combine(schema)
  69. : new JsonSchemaNode(schema);
  70. _nodes.Add(currentNode);
  71. AddProperties(schema.Properties, currentNode.Properties);
  72. AddProperties(schema.PatternProperties, currentNode.PatternProperties);
  73. if (schema.Items != null)
  74. {
  75. for (int i = 0; i < schema.Items.Count; i++)
  76. {
  77. AddItem(currentNode, i, schema.Items[i]);
  78. }
  79. }
  80. if (schema.AdditionalItems != null)
  81. {
  82. AddAdditionalItems(currentNode, schema.AdditionalItems);
  83. }
  84. if (schema.AdditionalProperties != null)
  85. {
  86. AddAdditionalProperties(currentNode, schema.AdditionalProperties);
  87. }
  88. if (schema.Extends != null)
  89. {
  90. foreach (JsonSchema jsonSchema in schema.Extends)
  91. {
  92. currentNode = AddSchema(currentNode, jsonSchema);
  93. }
  94. }
  95. return currentNode;
  96. }
  97. public void AddProperties(IDictionary<string, JsonSchema> source, IDictionary<string, JsonSchemaNode> target)
  98. {
  99. if (source != null)
  100. {
  101. foreach (KeyValuePair<string, JsonSchema> property in source)
  102. {
  103. AddProperty(target, property.Key, property.Value);
  104. }
  105. }
  106. }
  107. public void AddProperty(IDictionary<string, JsonSchemaNode> target, string propertyName, JsonSchema schema)
  108. {
  109. JsonSchemaNode propertyNode;
  110. target.TryGetValue(propertyName, out propertyNode);
  111. target[propertyName] = AddSchema(propertyNode, schema);
  112. }
  113. public void AddItem(JsonSchemaNode parentNode, int index, JsonSchema schema)
  114. {
  115. JsonSchemaNode existingItemNode = (parentNode.Items.Count > index)
  116. ? parentNode.Items[index]
  117. : null;
  118. JsonSchemaNode newItemNode = AddSchema(existingItemNode, schema);
  119. if (!(parentNode.Items.Count > index))
  120. {
  121. parentNode.Items.Add(newItemNode);
  122. }
  123. else
  124. {
  125. parentNode.Items[index] = newItemNode;
  126. }
  127. }
  128. public void AddAdditionalProperties(JsonSchemaNode parentNode, JsonSchema schema)
  129. {
  130. parentNode.AdditionalProperties = AddSchema(parentNode.AdditionalProperties, schema);
  131. }
  132. public void AddAdditionalItems(JsonSchemaNode parentNode, JsonSchema schema)
  133. {
  134. parentNode.AdditionalItems = AddSchema(parentNode.AdditionalItems, schema);
  135. }
  136. private JsonSchemaModel BuildNodeModel(JsonSchemaNode node)
  137. {
  138. JsonSchemaModel model;
  139. if (_nodeModels.TryGetValue(node, out model))
  140. {
  141. return model;
  142. }
  143. model = JsonSchemaModel.Create(node.Schemas);
  144. _nodeModels[node] = model;
  145. foreach (KeyValuePair<string, JsonSchemaNode> property in node.Properties)
  146. {
  147. if (model.Properties == null)
  148. {
  149. model.Properties = new Dictionary<string, JsonSchemaModel>();
  150. }
  151. model.Properties[property.Key] = BuildNodeModel(property.Value);
  152. }
  153. foreach (KeyValuePair<string, JsonSchemaNode> property in node.PatternProperties)
  154. {
  155. if (model.PatternProperties == null)
  156. {
  157. model.PatternProperties = new Dictionary<string, JsonSchemaModel>();
  158. }
  159. model.PatternProperties[property.Key] = BuildNodeModel(property.Value);
  160. }
  161. foreach (JsonSchemaNode t in node.Items)
  162. {
  163. if (model.Items == null)
  164. {
  165. model.Items = new List<JsonSchemaModel>();
  166. }
  167. model.Items.Add(BuildNodeModel(t));
  168. }
  169. if (node.AdditionalProperties != null)
  170. {
  171. model.AdditionalProperties = BuildNodeModel(node.AdditionalProperties);
  172. }
  173. if (node.AdditionalItems != null)
  174. {
  175. model.AdditionalItems = BuildNodeModel(node.AdditionalItems);
  176. }
  177. return model;
  178. }
  179. }
  180. }