/// <summary> /// /// </summary> /// <param name="Element"></param> /// <param name="Resolver"></param> private void Traverse(JObject Element, ReferenceResolver Resolver) { //Has a reference if (Element.ContainsKey("$ref")) { this.ResolveRef(Element, Resolver); } var Names = new List <String>(Element.Count); foreach (KeyValuePair <String, JToken> Child in Element) { Names.Add(Child.Key); } for (Int32 I = 0; I < Names.Count; I++) { JToken Item = Element[Names[I]]; if (Item is JObject JChild) { this.Traverse(JChild, Resolver); } else if (Item is JArray A) { this.Traverse(A, Resolver); } } }
/// <summary> /// /// </summary> public ReferenceResolver(String BasePath, ReferenceResolver Parent = null) { if (!BasePath.EndsWith("/")) { BasePath += "/"; } this._Basepath = new Uri(BasePath); this._Definitions = new Dictionary <String, JToken>(); this._ReferenceConverter = new Dictionary <String, String>(); if (Parent != null) { foreach (KeyValuePair <String, String> Item in Parent._ReferenceConverter) { this._ReferenceConverter[Item.Key] = Item.Value; } foreach (KeyValuePair <String, JToken> Item in Parent._Definitions) { this._Definitions[Item.Key] = null; } } this.References = new List <JToken>(); }
/// <summary> /// /// </summary> /// <param name="Schema"></param> public void DefinitionSimplfier(JObject Schema) { Console.WriteLine("Simplyfing definitions"); var Definitions = (JObject)Schema["definitions"]; var Names = new List <String>(Definitions.Count); foreach (KeyValuePair <String, JToken> Child in Definitions) { Names.Add(Child.Key); } UInt32 Count = 0; var Data = new List <ReplaceData>(); var NewDefinitions = new JObject(); foreach (String Name in Names) { var Item = (JObject)Definitions[Name]; String NewName = ReferenceResolver.CreateName(Count); ++Count; //Replace the definition with a shorter one NewDefinitions[NewName] = Item; Data.Add(new ReplaceData("#/definitions/" + Name, "#/definitions/" + NewName)); } Schema["definitions"] = NewDefinitions; this.ReplaceDefinition(Schema, Data); }
/// <summary> /// /// </summary> /// <param name="Elements"></param> /// <param name="Resolver"></param> private void Traverse(JArray Elements, ReferenceResolver Resolver) { foreach (JToken Item in Elements) { if (Item is JObject JChild) { this.Traverse(JChild, Resolver); } else if (Item is JArray A) { this.Traverse(A, Resolver); } } }
/// <summary> /// /// </summary> /// <param name="Doc"></param> /// <param name="Filepath"></param> /// <param name="Parent"></param> /// <returns></returns> internal ReferenceResolver InternalResolve(JObject Doc, String Filepath, ReferenceResolver Parent = null) { var Resolver = new ReferenceResolver(Directory.GetParent(Filepath).FullName, Parent); //Check if definitions object exists, else add it if (Doc.ContainsKey(this._DefinitionsName)) { foreach (KeyValuePair <String, JToken> Item in (JObject)Doc[this._DefinitionsName]) { Resolver._Definitions[Item.Key] = Item.Value; } } else { Doc.Add(this._DefinitionsName, new JObject()); } //Traverse all the elements looking for $ref, and resolve them this.Traverse(Doc, Resolver); //If larger then 0 make sure its present in the document if (Resolver._Definitions.Count > 0) { var Definitions = (JObject)Doc[this._DefinitionsName]; foreach (KeyValuePair <String, JToken> Item in Resolver._Definitions) { if (Item.Value == null) { continue; } JToken Current = Item.Value.DeepClone(); Definitions[Item.Key] = Current; } } //this.DefinitionSimplfier(Doc); return(Resolver); }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="referenceData"></param> internal void Inherit(String name, JObject referenceData, ReferenceResolver Child) { //Transfer references this.References.AddRange(Child.References); //Transfers reference converters data foreach (KeyValuePair <String, String> Item in Child._ReferenceConverter) { this._ReferenceConverter[Item.Key] = Item.Value; } foreach (KeyValuePair <String, JToken> Item in Child._Definitions) { if (Item.Value != null) { this._Definitions[Item.Key] = Item.Value; } } //Copy over definitions if (referenceData.ContainsKey("definitions")) { JToken definitions = referenceData["definitions"]; if (definitions is JObject ODefinitions) { foreach (KeyValuePair <String, JToken> Item in ODefinitions) { this._Definitions[Item.Key] = Item.Value.DeepClone(); } } referenceData.Remove("definitions"); } referenceData.Remove("$id"); referenceData.Remove("$schema"); //move schema into definitions this._Definitions[name] = referenceData; }
/// <summary> /// /// </summary> /// <param name="Element"></param> /// <param name="Resolver"></param> private void ResolveRef(JObject Element, ReferenceResolver Resolver) { String Reference; Resolver.References.Add(Element); if (Element is JObject OElement) { Reference = OElement["$ref"].Value <String>(); } else { Reference = Element["$ref"].Value <String>(); } if (Reference[0] == '#') { return; } if (Reference.StartsWith("./")) { Reference = Reference[2..];