public void GenerateFieldTest()
        {
            var schema      = new JsonSchema();
            var decorator   = new StandardPropertyFieldDecorator();
            var implDetails = new SchemaImplementationDetails();

            schema.Type = JsonSchemaType.String;
            CodeMemberField generatedField = decorator.GenerateField(
                "normalName", schema, implDetails, 1, internalClassProvider, Enumerable.Empty <string>());

            Assert.NotNull(generatedField);
            Assert.AreEqual(typeof(string).FullName, generatedField.Type.BaseType);
            Assert.AreEqual("_normalName", generatedField.Name);
            Assert.AreEqual(MemberAttributes.Private, generatedField.Attributes);

            schema.Type    = JsonSchemaType.Boolean;
            generatedField = decorator.GenerateField(
                "public", schema, implDetails, 2, internalClassProvider, Enumerable.Empty <string>());

            Assert.NotNull(generatedField);
            Assert.AreEqual(typeof(Nullable <>).FullName, generatedField.Type.BaseType);
            Assert.AreEqual(typeof(bool).FullName, generatedField.Type.TypeArguments[0].BaseType);
            Assert.AreEqual("_public", generatedField.Name);
            Assert.AreEqual(MemberAttributes.Private, generatedField.Attributes);

            generatedField = decorator.GenerateField(
                "UPPERCASE", schema, implDetails, 2, internalClassProvider, Enumerable.Empty <string>());

            Assert.NotNull(generatedField);
            Assert.AreEqual("_UPPERCASE", generatedField.Name);
        }
Exemplo n.º 2
0
        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 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);
        }
        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)));
        }
        public void DecorateClassTest()
        {
            // Init required vars.
            var decorator   = new ResponseInterfaceDecorator();
            var declaration = new CodeTypeDeclaration();
            var schema      = new MockSchema {
                SchemaDetails = new JsonSchema()
            };
            var internalClassProvider = new ObjectInternalClassProvider();
            var implDetails           = new Dictionary <JsonSchema, SchemaImplementationDetails>();

            implDetails.Add(schema.SchemaDetails, new SchemaImplementationDetails());

            // Test edge cases.
            Assert.Throws(
                typeof(ArgumentNullException),
                () => decorator.DecorateClass(null, schema, implDetails, internalClassProvider));
            Assert.Throws(
                typeof(ArgumentNullException),
                () => decorator.DecorateClass(declaration, null, implDetails, internalClassProvider));
            Assert.Throws(
                typeof(ArgumentNullException),
                () => decorator.DecorateClass(declaration, schema, null, internalClassProvider));

            decorator.DecorateClass(declaration, schema, implDetails, internalClassProvider);
            Assert.AreEqual(0, declaration.BaseTypes.Count);
            Assert.AreEqual(0, declaration.Members.Count);

            // Test simple functionality.
            var details = new SchemaImplementationDetails {
                IsMethodResult = true
            };

            implDetails = new Dictionary <JsonSchema, SchemaImplementationDetails>
            {
                { schema.SchemaDetails, details }
            };

            decorator.DecorateClass(declaration, schema, implDetails, internalClassProvider);

            Assert.AreEqual(1, declaration.BaseTypes.Count);
            Assert.AreEqual(2, declaration.Members.Count); // 1 property with a field.

            // Test with already existing e-tag field.
            declaration = new CodeTypeDeclaration();
            declaration.Members.Add(new CodeMemberProperty()
            {
                Name = "ETag"
            });
            decorator.DecorateClass(declaration, schema, implDetails, internalClassProvider);

            Assert.AreEqual(1, declaration.BaseTypes.Count);
            Assert.AreEqual(1, declaration.Members.Count);
        }
        /// <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));
        }
Exemplo n.º 7
0
        public void DecorateInternalClass(CodeTypeDeclaration typeDeclaration,
                                          string name,
                                          JsonSchema schema,
                                          IDictionary <JsonSchema, SchemaImplementationDetails> implDetails,
                                          INestedClassProvider internalClassProvider)
        {
            typeDeclaration.ThrowIfNull("typeDeclatation");
            schema.ThrowIfNull("schema");
            implDetails.ThrowIfNull("details");
            internalClassProvider.ThrowIfNull("internalClassProvider");

            SchemaImplementationDetails details = implDetails[schema];

            typeDeclaration.Members.AddRange(
                GenerateAllProperties(name, schema, implDetails, internalClassProvider,
                                      typeDeclaration.Name)
                .ToArray());
        }
Exemplo n.º 8
0
            public void GetClassNameWithDetailsCollisionsTest()
            {
                var empty = new List <ISchemaDecorator>(0);
                var decl  = new CodeTypeDeclaration()
                {
                    Name = "Top"
                };
                var gen = new SchemaGenerator.NestedClassGenerator(decl, empty, "1_");

                var schema1 = new JsonSchema();
                var schema2 = new JsonSchema();
                var details = new SchemaImplementationDetails()
                {
                    ProposedName = "TestClass"
                };

                Assert.AreEqual("Top.TestClass", gen.GetClassName(schema1, details).BaseType);
                Assert.AreNotEqual("Top.TestClass", gen.GetClassName(schema2, details).BaseType);
            }
        public void DecorateClass(CodeTypeDeclaration typeDeclaration,
                                  ISchema schema,
                                  IDictionary <JsonSchema, SchemaImplementationDetails> implDetails,
                                  INestedClassProvider internalClassProvider)
        {
            typeDeclaration.ThrowIfNull("typeDeclaration");
            schema.ThrowIfNull("schema");
            implDetails.ThrowIfNull("implDetails");

            SchemaImplementationDetails details = implDetails[schema.SchemaDetails];

            // If this method is refered as a result directly, add an inheritance to IResponse and implement
            // the interface
            if (details.IsMethodResult)
            {
                logger.Debug("Applying decorator to schema " + schema.Name);
                typeDeclaration.BaseTypes.Add(GetIResponseBaseType());
                typeDeclaration.Members.AddRange(CreateETagProperty(typeDeclaration));
            }
        }
        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);
        }
        /// <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)));
            }
        }
Exemplo n.º 12
0
        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 }));

                foreach (var decorator in propertyDecorators)
                {
                    decorator.DecorateProperty(property, propertyPair);
                }

                fields.Add(property);
            }
            return(fields);
        }
Exemplo n.º 13
0
        public void DecorateClass(CodeTypeDeclaration typeDeclaration,
                                  ISchema schema,
                                  IDictionary <JsonSchema, SchemaImplementationDetails> implDetails,
                                  INestedClassProvider internalClassProvider)
        {
            typeDeclaration.ThrowIfNull("typeDeclaration");
            schema.ThrowIfNull("schema");
            implDetails.ThrowIfNull("implDetails");
            internalClassProvider.ThrowIfNull("internalClassProvider");

            JsonSchema details = schema.SchemaDetails;

            details.ThrowIfNull("schemaDetails");

            // Check if this decorator can be applied to the schema);
            if (details.Type != JsonSchemaType.Array)
            {
                return;
            }

            if (details.Items == null || details.Items.Count != 1)
            {
                logger.Warning("Found array scheme of unhandled type. {0}", details);
                return; // not supported
            }

            // Generate or find the nested type
            JsonSchema itemScheme = details.Items[0];
            SchemaImplementationDetails implDetail = implDetails[itemScheme];

            implDetail.ProposedName = "Entry"; // Change the name to a custom one.
            CodeTypeReference item = SchemaDecoratorUtil.GetCodeType(itemScheme, implDetail, internalClassProvider);

            // Insert the base type before any interface declaration
            typeDeclaration.BaseTypes.Insert(0, new CodeTypeReference(typeof(List <>))
            {
                TypeArguments = { item }
            });
        }
        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);
        }
Exemplo n.º 15
0
 public CodeTypeReference GetClassName(JsonSchema definition, SchemaImplementationDetails details)
 {
     return(new CodeTypeReference(typeof(object)));
 }