/// <summary> /// Adds imports for attributes and lists. /// </summary> /// <param name="schema">The schema to import from.</param> public void AddImportsFromSchema(JsonSchema schema) { // Arrays if (JsonSchemaUtils.IsArray(schema)) { AddImport("System.Collections.Generic"); } // MinValue | MaxValue if (schema.Minimum != null || schema.Maximum != null) { AddImport("Cvent.SchemaToPoco.Core.ValidationAttributes"); } // Required | StringLength | MinItems | MaxItems | Pattern if ((schema.Required != null && schema.Required.Value) || schema.MaximumLength != null || schema.MinimumLength != null || schema.MinimumItems != null || schema.MaximumItems != null || schema.Pattern != null) { AddImport("System.ComponentModel.DataAnnotations"); } }
/// <summary> /// Add all comments and attributes. /// </summary> /// <param name="schema">The JsonSchema.</param> /// <param name="type">Annotation type to generate.</param> public void Populate(JsonSchema schema, AttributeType type) { // Add description if (schema.Description != null) { AddComment(schema.Description); } // Add required attribute if (schema.Required != null && schema.Required.Value) { /*switch (type) * { * case AttributeType.SystemDefault: * AddAttribute("Required"); * break; * case AttributeType.JsonDotNet: * AddAttribute("JsonProperty", * new CodeAttributeArgument("Required", new CodeSnippetExpression("Required.Always"))); * break; * }*/ AddAttribute("Required"); } // Number only flags if (JsonSchemaUtils.IsNumber(schema)) { if (schema.Minimum != null) { if (schema.ExclusiveMinimum != null && schema.ExclusiveMinimum.Value) { AddAttribute("MinValue", (int)schema.Minimum.Value + 1); } else { AddAttribute("MinValue", (int)schema.Minimum.Value); } } if (schema.Maximum != null) { if (schema.ExclusiveMaximum != null && schema.ExclusiveMaximum.Value) { AddAttribute("MaxValue", (int)schema.Maximum.Value - 1); } else { AddAttribute("MaxValue", (int)schema.Maximum.Value); } } } // String only flags if (JsonSchemaUtils.IsString(schema)) { var args = new List <CodeAttributeArgument>(); bool flag = false; if (schema.MaximumLength != null) { args.Add(new CodeAttributeArgument(new CodePrimitiveExpression(schema.MaximumLength.Value))); flag = true; } if (schema.MinimumLength != null) { args.Add(new CodeAttributeArgument("MinimumLength", new CodePrimitiveExpression(schema.MinimumLength.Value))); flag = true; } if (flag) { AddAttribute("StringLength", args.ToArray()); } if (!String.IsNullOrEmpty(schema.Pattern)) { AddAttribute("RegularExpression", new CodeAttributeArgument(new CodeSnippetExpression(string.Format(@"@""{0}""", schema.Pattern.SanitizeRegex(true))))); } } // Array only flags if (JsonSchemaUtils.IsArray(schema)) { if (schema.MinimumItems != null) { AddAttribute("MinLength", schema.MinimumItems.Value); } if (schema.MaximumItems != null) { AddAttribute("MaxLength", schema.MaximumItems.Value); } } }
/// <summary> /// Main executor function. /// </summary> /// <returns>A CodeCompileUnit.</returns> public CodeCompileUnit Execute() { var codeCompileUnit = new CodeCompileUnit(); // Set namespace var nsWrap = new NamespaceWrapper(new CodeNamespace(_codeNamespace)); // Set class var codeClass = new CodeTypeDeclaration(_schemaDocument.Title) { Attributes = MemberAttributes.Public }; var clWrap = new ClassWrapper(codeClass); // Add imports for interfaces and dependencies nsWrap.AddImportsFromWrapper(_schemaWrapper); // Add comments and attributes for class if (!String.IsNullOrEmpty(_schemaDocument.Description)) { clWrap.AddComment(_schemaDocument.Description); } // Add extended class if (_schemaDocument.Extends != null && _schemaDocument.Extends.Count > 0) { clWrap.AddInterface(JsonSchemaUtils.GetType(_schemaDocument.Extends[0], _codeNamespace).Name); } // Add interfaces foreach (Type t in _schemaWrapper.Interfaces) { clWrap.AddInterface(t.Name); } // Add properties with getters/setters if (_schemaDocument.Properties != null) { foreach (var i in _schemaDocument.Properties) { JsonSchema schema = i.Value; // Sanitize inputs if (!String.IsNullOrEmpty(schema.Description)) { schema.Description = Regex.Unescape(schema.Description); } // If it is an enum var propertyName = i.Key.Capitalize(); if (schema.Enum != null) { var enumField = new CodeTypeDeclaration(propertyName); var enumWrap = new EnumWrapper(enumField); // Add comment if not null if (!String.IsNullOrEmpty(schema.Description)) { enumField.Comments.Add(new CodeCommentStatement(schema.Description)); } foreach (JToken j in schema.Enum) { enumWrap.AddMember(j.ToString().SanitizeIdentifier()); } // Add to namespace nsWrap.AddClass(enumWrap.Property); } else { // WARNING: This assumes the namespace of the property is the same as the parent. // This should not be a problem since imports are handled for all dependencies at the beginning. Type type = JsonSchemaUtils.GetType(schema, _codeNamespace); bool isCustomType = type.Namespace != null && type.Namespace.Equals(_codeNamespace); string strType = String.Empty; // Add imports nsWrap.AddImport(type.Namespace); nsWrap.AddImportsFromSchema(schema); // Get the property type if (isCustomType) { strType = JsonSchemaUtils.IsArray(schema) ? string.Format("{0}<{1}>", JsonSchemaUtils.GetArrayType(schema), type.Name) : type.Name; } else if (JsonSchemaUtils.IsArray(schema)) { strType = string.Format("{0}<{1}>", JsonSchemaUtils.GetArrayType(schema), new CSharpCodeProvider().GetTypeOutput(new CodeTypeReference(type))); } //var field = new CodeMemberField //{ // Attributes = MemberAttributes.Private, // Name = "_" + i.Key, // Type = // TypeUtils.IsPrimitive(type) && !JsonSchemaUtils.IsArray(schema) // ? new CodeTypeReference(type) // : new CodeTypeReference(strType) //}; //clWrap.Property.Members.Add(field); var property = CreateProperty(propertyName, TypeUtils.IsPrimitive(type) && !JsonSchemaUtils.IsArray(schema) ? new CodeTypeReference(type) : new CodeTypeReference(strType)); var prWrap = new PropertyWrapper(property); // Add comments and attributes prWrap.Populate(schema, _attributeType); // Add default, if any if (schema.Default != null) { clWrap.AddDefault(propertyName, property.Type, schema.Default.ToString()); } clWrap.Property.Members.Add(property); } } } // Add class to namespace nsWrap.AddClass(clWrap.Property); codeCompileUnit.Namespaces.Add(nsWrap.Namespace); return(codeCompileUnit); }