/// <summary> /// Get the type of the schema. If it is an array, get the array type. /// </summary> /// <param name="schema">The JSON schema.</param> /// <param name="ns">The namespace.</param> /// <returns>The type of the schema.</returns> public static Type GetType(JsonSchema schema, string ns = "") { string toRet = DEFAULT_TYPE; var builder = new TypeBuilderHelper(ns); // Set the type to the type if it is not an array if (!IsArray(schema)) { if (schema.Title != null) { return builder.GetCustomType(schema.Title, true); } if (schema.Type != null) { toRet = TypeUtils.GetPrimitiveTypeAsString(schema.Type); } } else { // Set the type to the title if it exists if (schema.Title != null) { return builder.GetCustomType(schema.Title, true); } if (schema.Items != null && schema.Items.Count > 0) { // Set the type to the title of the items if (schema.Items[0].Title != null) { return builder.GetCustomType(schema.Items[0].Title, true); } // Set the type to the type of the items if (schema.Items[0].Type != null) { toRet = TypeUtils.GetPrimitiveTypeAsString(schema.Items[0].Type); } } } return Type.GetType(toRet, true); }
private JsonSchemaWrapper ResolveSchemaHelper(Uri curr, Uri parent, string data) { var definition = new { csharpType = string.Empty, csharpInterfaces = new string[] { }, properties = new Dictionary<string, JObject>() }; var deserialized = JsonConvert.DeserializeAnonymousType(data, definition); var dependencies = new List<JsonSchemaWrapper>(); MatchCollection matches = Regex.Matches(data, @"\""\$ref\""\s*:\s*\""(.*.json)\"""); foreach (Match match in matches) { // Get the full path to the file, and change the reference to match var currPath = new Uri(match.Groups[1].Value, UriKind.RelativeOrAbsolute); var currUri = IoUtils.GetAbsoluteUri(parent, currPath, true); JsonSchemaWrapper schema; if (!_schemas.ContainsKey(currUri)) { schema = ResolveSchemaHelper(parent, currUri); _schemas.Add(currUri, schema); } else { schema = _schemas[currUri]; } // Add schema to dependencies dependencies.Add(schema); } // Go through properties to see if there needs to be more resolving if (deserialized != null && deserialized.properties != null) { foreach (var s in deserialized.properties) { var properties = s.Value.Properties(); // Check that the property also has a top level key called properties or items foreach (var prop in properties) { var isProp = prop.Name.Equals("properties"); var isItem = prop.Name.Equals("items"); // TODO ehhhh let's avoid hardcoding this if (isProp || (isItem && prop.Value.ToString().Contains("\"properties\""))) { var propData = isProp ? s.Value.ToString() : prop.Value.ToString(); // Create dummy internal Uri var dummyUri = new Uri(new Uri(curr + "/"), s.Key); JsonSchemaWrapper schema = ResolveSchemaHelper(dummyUri, curr, propData); if (!_schemas.ContainsKey(dummyUri)) { _schemas.Add(dummyUri, schema); } } } } } // Set up schema and wrapper to return JsonSchema parsed; try { parsed = JsonSchema.Parse(StandardizeReferences(parent, data), _resolver); } catch (Exception) { _log.Error("Could not parse the schema: " + curr + "\nMake sure your schema is compatible." + "Examine the stack trace below."); throw; } parsed.Id = curr.ToString(); parsed.Title = parsed.Title.SanitizeIdentifier(); var toReturn = new JsonSchemaWrapper(parsed) { Namespace = _ns, Dependencies = dependencies }; // If csharpType is specified if (deserialized != null && !string.IsNullOrEmpty(deserialized.csharpType)) { // Create directories and set namespace int lastIndex = deserialized.csharpType.LastIndexOf('.'); string cType = deserialized.csharpType.Substring(lastIndex == -1 ? 0 : lastIndex + 1); toReturn.Namespace = deserialized.csharpType.Substring(0, lastIndex); toReturn.Schema.Title = cType; if (_createDirs) { IoUtils.CreateDirectoryFromNamespace(_baseDir, toReturn.Namespace); } } // If csharpInterfaces is specified if (deserialized != null && deserialized.csharpInterfaces != null) { foreach (string s in deserialized.csharpInterfaces) { // Try to resolve the type Type t = Type.GetType(s, false); // If type cannot be found, create a new type if (t == null) { var builder = new TypeBuilderHelper(toReturn.Namespace); t = builder.GetCustomType(s, !s.Contains(".")); } toReturn.Interfaces.Add(t); } } return toReturn; }