internal static CodeTypeReference GetArrayTypeReference(JsonSchema propertySchema, SchemaImplementationDetails details, INestedClassProvider internalClassProvider) { propertySchema.ThrowIfNull("propertySchema"); if (propertySchema.Type != JsonSchemaType.Array) { throw new ArgumentException("Must be of JsonSchemaType.Array", "propertySchema"); } var arrayItems = propertySchema.Items; if (arrayItems != null && arrayItems.Count == 1) { CodeTypeReference itemType = arrayItems[0].Id.IsNotNullOrEmpty() ? new CodeTypeReference(arrayItems[0].Id) : GetCodeType(arrayItems[0], details, internalClassProvider); logger.Debug("type for array {0}", itemType.BaseType); return new CodeTypeReference(typeof(IList<>)) { TypeArguments = { itemType } }; } logger.Warning("Found Array of unhandled type. {0}", propertySchema); return new CodeTypeReference(typeof(System.Collections.IList)); }
/// <summary> /// Returns a code type references for the specified json schema. /// Generates the appropriate references. /// </summary> internal static CodeTypeReference GetCodeType(JsonSchema propertySchema, SchemaImplementationDetails details, INestedClassProvider internalClassProvider) { propertySchema.ThrowIfNull("propertySchema"); internalClassProvider.ThrowIfNull("internalClassProvider"); if (propertySchema.Type.HasValue == false) { throw new NotSupportedException("propertySchema has no Type. " + propertySchema); } switch (propertySchema.Type.Value) { case JsonSchemaType.String: return new CodeTypeReference(typeof(string)); case JsonSchemaType.Integer: return new CodeTypeReference(typeof(long?)); case JsonSchemaType.Boolean: return new CodeTypeReference(typeof(bool?)); case JsonSchemaType.Float: return new CodeTypeReference(typeof(double?)); case JsonSchemaType.Array: return GetArrayTypeReference(propertySchema, details, internalClassProvider); case JsonSchemaType.Object: return GetObjectTypeReference(propertySchema, details, internalClassProvider); case JsonSchemaType.Any: return new CodeTypeReference(typeof(string)); default: logger.Warning( "Found currently unsupported type {0} as part of {1}", propertySchema.Type.Value, propertySchema); return new CodeTypeReference(typeof(object)); } }
internal IList<CodeMemberProperty> GenerateAllProperties(string name, JsonSchema schema, IDictionary<JsonSchema, SchemaImplementationDetails> implDetails, INestedClassProvider internalClassProvider, params string[] usedWordsInContext) { schema.ThrowIfNull("schema"); name.ThrowIfNullOrEmpty("name"); logger.Debug("Adding properties for {0}", name); var fields = new List<CodeMemberProperty>(); if (schema.Properties.IsNullOrEmpty()) { logger.Debug("No properties found for schema " + name); return fields; } IEnumerable<string> allUsedWordsInContext = usedWordsInContext.Concat(schema.Properties.Keys); int index = 0; foreach (var propertyPair in schema.Properties) { SchemaImplementationDetails details = implDetails[propertyPair.Value]; CodeMemberProperty property = GenerateProperty( propertyPair.Key, propertyPair.Value, details, index++, internalClassProvider, allUsedWordsInContext.Except(new[] { propertyPair.Key })); fields.Add(property); } return fields; }
internal IList<CodeMemberField> GenerateAllFields(string name, JsonSchema schema, IDictionary<JsonSchema, SchemaImplementationDetails> implDetails, INestedClassProvider internalClassProvider) { schema.ThrowIfNull("schema"); name.ThrowIfNull("name"); implDetails.ThrowIfNull("details"); internalClassProvider.ThrowIfNull("internalClassProvider"); var fields = new List<CodeMemberField>(); if (schema.Properties.IsNullOrEmpty()) { logger.Debug("No Properties found for " + name); return fields; } int index = 0; foreach (var propertyPair in schema.Properties) { SchemaImplementationDetails details = implDetails[propertyPair.Value]; fields.Add( GenerateField( propertyPair.Key, propertyPair.Value, details, index, internalClassProvider, schema.Properties.Keys.Without(propertyPair.Key))); index++; } return fields; }
public void DecorateInternalClass(CodeTypeDeclaration typeDeclaration, string name, JsonSchema schema, IDictionary<JsonSchema, SchemaImplementationDetails> implDetails, INestedClassProvider internalClassProvider) { typeDeclaration.ThrowIfNull("typeDeclaration"); schema.ThrowIfNull("schema"); implDetails.ThrowIfNull("details"); internalClassProvider.ThrowIfNull("internalClassProvider"); typeDeclaration.Comments.AddRange(CreateComment(schema)); }
public void DecorateInternalClass(CodeTypeDeclaration typeDeclaration, string name, JsonSchema schema, IDictionary<JsonSchema, SchemaImplementationDetails> implDetails, INestedClassProvider internalClassProvider) { typeDeclaration.ThrowIfNull("typeDeclaration"); schema.ThrowIfNull("schema"); implDetails.ThrowIfNull("details"); internalClassProvider.ThrowIfNull("internalClassProvider"); typeDeclaration.Members.AddRange( GenerateAllFields(name, schema, implDetails, internalClassProvider).ToArray()); }
internal void ImplementAdditionalProperties(CodeTypeDeclaration type, JsonSchema schema, IDictionary<JsonSchema, SchemaImplementationDetails> implDetails, INestedClassProvider internalClassProvider) { // Validate the input parameters. type.ThrowIfNull("type"); schema.ThrowIfNull("schema"); implDetails.ThrowIfNull("implDetails"); internalClassProvider.ThrowIfNull("internalClassProvider"); // Check if this decorator applies to the specified json schema. if (schema.AdditionalProperties == null) { return; } // Note/ToDo: Currently we only support AdditionalProperties for schemas // specifiying no normal properties, as these won't be used // by the newtonsoft json library if a dictionary is specified. if (schema.Properties != null && schema.Properties.Count > 0) { type.Comments.Add(new CodeCommentStatement("TODO: Add support for additionalProperties on schemas")); type.Comments.Add(new CodeCommentStatement(" which have normal properties defined.")); return; } // Generate the underlying type. SchemaImplementationDetails details = implDetails[schema]; CodeTypeReference underlyingTypeRef = SchemaDecoratorUtil.GetCodeType( schema.AdditionalProperties, details, internalClassProvider); // Add the base type reference. CodeTypeReference dictionaryRef = new CodeTypeReference(typeof(Dictionary<,>)); dictionaryRef.TypeArguments.Add(typeof(string)); dictionaryRef.TypeArguments.Add(underlyingTypeRef); type.BaseTypes.Add(dictionaryRef); }
internal void AddCommentsToAllProperties(string name, JsonSchema schema, CodeTypeDeclaration typeDeclaration) { schema.ThrowIfNull("schema"); name.ThrowIfNullOrEmpty("name"); typeDeclaration.ThrowIfNull("typeDeclaration"); logger.Debug("Adding attributes to properties for {0}", name); if (schema.Properties.IsNullOrEmpty()) { logger.Debug("No properties found for schema " + name); return; } int index = 0; foreach (var propertyPair in schema.Properties) { var schemaFieldName = propertyPair.Key; var propertyDefinition = SchemaUtil.FindCodePropertyForName( typeDeclaration, schemaFieldName, index++, schema.Properties.Keys); propertyDefinition.Comments.AddRange(CreateComment(propertyPair.Value)); } }
/// <summary> /// Resolves the current schema by using the specified schema /// </summary> /// <param name="schema"></param> public void Resolve(JsonSchema schema) { schema.ThrowIfNull("schema"); if (schema is FutureJsonSchema && ((FutureJsonSchema) schema).Resolved == false) { throw new ArgumentException("Schema given to resolve this future was an unresolved future.", "schema"); } if (schema is FutureJsonSchema) { throw new ArgumentException("Resolved schema cannot be a FutureJsonSchema", "schema"); } if (schema.Id != Id) { throw new ArgumentException( "schema", "Attempting to resolve a FutureSchema with incorrect id FutureId[" + Id + "] passedinId[" + schema.Id + "]"); } if (Resolved) { throw new InvalidOperationException("This FutureJsonSchema has already been resolved." + Id); } Resolved = true; AdditionalProperties = schema.AdditionalProperties; AllowAdditionalProperties = schema.AllowAdditionalProperties; Default = schema.Default; Description = schema.Description; Disallow = schema.Disallow; Enum = schema.Enum; Extends = schema.Extends; Format = schema.Format; Hidden = schema.Hidden; Id = schema.Id; Identity = schema.Identity; Items = schema.Items; Maximum = schema.Maximum; MaximumItems = schema.MaximumItems; MaximumLength = schema.MaximumLength; Minimum = schema.Minimum; MinimumItems = schema.MinimumItems; MinimumLength = schema.MinimumLength; Options = schema.Options; Pattern = schema.Pattern; Properties = schema.Properties; ReadOnly = schema.ReadOnly; Requires = schema.Requires; Title = schema.Title; Transient = schema.Transient; Type = schema.Type; // The Newtonsoft.Silverlight implementation does not contain all properties. // Only add them if we are using the regular Newtonsoft.dll #if !SILVERLIGHT Required = schema.Required; PatternProperties = schema.PatternProperties; ExclusiveMaximum = schema.ExclusiveMaximum; ExclusiveMinimum = schema.ExclusiveMinimum; DivisibleBy = schema.DivisibleBy; #endif }
internal CodeCommentStatementCollection CreateComment(JsonSchema schema) { schema.ThrowIfNull("schema"); return DecoratorUtil.CreateSummaryComment(schema.Description); }
/// <summary> /// Resolves/generates an object type reference for a schema. /// </summary> internal static CodeTypeReference GetObjectTypeReference(JsonSchema propertySchema, SchemaImplementationDetails details, INestedClassProvider internalClassProvider) { propertySchema.ThrowIfNull("propertySchema"); if (propertySchema.Type != JsonSchemaType.Object) { throw new ArgumentException("Must be of JsonSchemaType.Array", "propertySchema"); } if (propertySchema.Id.IsNotNullOrEmpty()) { logger.Debug("Found Object with id using type {0}", propertySchema.Id); return new CodeTypeReference(propertySchema.Id); } return internalClassProvider.GetClassName(propertySchema, details); }
internal CodeMemberProperty GenerateProperty(string name, JsonSchema propertySchema, SchemaImplementationDetails details, int index, INestedClassProvider internalClassProvider, IEnumerable<string> disallowedNames) { name.ThrowIfNullOrEmpty("name"); propertySchema.ThrowIfNull("propertySchema"); var ret = new CodeMemberProperty(); ret.Name = SchemaDecoratorUtil.GetPropertyName(name, disallowedNames); ret.Type = SchemaDecoratorUtil.GetCodeType(propertySchema, details, internalClassProvider); ret.Attributes = MemberAttributes.Public; ret.HasGet = true; var fieldReference = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), SchemaDecoratorUtil.GetFieldName(name, disallowedNames)); ret.GetStatements.Add(new CodeMethodReturnStatement(fieldReference)); ret.HasSet = true; var parameterReference = new CodeVariableReferenceExpression("value"); ret.SetStatements.Add(new CodeAssignStatement(fieldReference, parameterReference)); return ret; }
internal static SchemaImplementationDetails GetOrCreateDetails( IDictionary<JsonSchema, SchemaImplementationDetails> details, JsonSchema schema) { details.ThrowIfNull("details"); schema.ThrowIfNull("schema"); // If no implementation details have been added yet, create a new entry); if (!details.ContainsKey(schema)) { details.Add(schema, new SchemaImplementationDetails()); } return details[schema]; }
internal static void ProposeNameIfNecessary(IDictionary<JsonSchema, SchemaImplementationDetails> dictionary, string name, JsonSchema schema) { schema.ThrowIfNull("schema"); name.ThrowIfNull("name"); dictionary.ThrowIfNull("name"); if (schema.Id.IsNotNullOrEmpty()) { // Already has a name -> return. return; } SchemaImplementationDetails details = GetOrCreateDetails(dictionary, schema); if (string.IsNullOrEmpty(details.ProposedName)) { details.ProposedName = name; } }
internal CodeMemberField GenerateField(string name, JsonSchema propertySchema, SchemaImplementationDetails details, int index, INestedClassProvider internalClassProvider, IEnumerable<string> otherFieldNames) { name.ThrowIfNullOrEmpty("name"); propertySchema.ThrowIfNull("propertySchema"); internalClassProvider.ThrowIfNull("internalClassProvider"); details.ThrowIfNull("details"); var ret = new CodeMemberField( SchemaDecoratorUtil.GetCodeType(propertySchema, details, internalClassProvider), SchemaDecoratorUtil.GetFieldName(name, otherFieldNames)); ret.Attributes = MemberAttributes.Private; return ret; }
internal CodeTypeDeclaration GenerateNestedClass(JsonSchema schema, IDictionary<JsonSchema, SchemaImplementationDetails> detailCollection, int orderOfNestedClass) { schema.ThrowIfNull("schema"); string className = knownSubschemas[schema].ClassName; var typeDeclaration = new CodeTypeDeclaration(className); typeDeclaration.Attributes = MemberAttributes.Public; var nestedClassGenerator = new NestedClassGenerator( typeDeclaration, decorators, uniquefier + orderOfNestedClass + "_"); foreach (ISchemaDecorator schemaDecorator in decorators) { if (schemaDecorator is INestedClassSchemaDecorator) { logger.Debug( "Found IInternalClassSchemaDecorator {0} - decorating {1}", schemaDecorator, className); ((INestedClassSchemaDecorator) schemaDecorator).DecorateInternalClass( typeDeclaration, className, schema, detailCollection, nestedClassGenerator); } } nestedClassGenerator.GenerateNestedClasses(detailCollection); return typeDeclaration; }