Пример #1
0
 public FieldInfo(IJsonClassGeneratorConfig generator, string jsonMemberName, JsonType type, bool usePascalCase, IList<object> Examples)
 {
     this.generator = generator;
     this.JsonMemberName = jsonMemberName;
     this.MemberName = jsonMemberName;
     if (usePascalCase) MemberName = JsonClassGenerator.ToTitleCase(MemberName);
     this.Type = type;
     this.Examples = Examples;
 }
Пример #2
0
        public static JsonType GetCommonType(IJsonClassGeneratorConfig generator, JToken[] tokens)
        {

            if (tokens.Length == 0) return new JsonType(generator, JsonTypeEnum.NonConstrained);

            var common = new JsonType(generator, tokens[0]).MaybeMakeNullable(generator);

            for (int i = 1; i < tokens.Length; i++)
            {
                var current = new JsonType(generator, tokens[i]);
                common = common.GetCommonType(current);
            }

            return common;

        }
Пример #3
0
        private void GenerateClass(JObject[] examples, JsonType type)
        {
            var jsonFields = new Dictionary<string, JsonType>();
            var fieldExamples = new Dictionary<string, IList<object>>();

            var first = true;

            foreach (var obj in examples)
            {
                foreach (var prop in obj.Properties())
                {
                    JsonType fieldType;
                    var currentType = new JsonType(this, prop.Value);
                    var propName = prop.Name;
                    if (jsonFields.TryGetValue(propName, out fieldType))
                    {

                        var commonType = fieldType.GetCommonType(currentType);

                        jsonFields[propName] = commonType;
                    }
                    else
                    {
                        var commonType = currentType;
                        if (first) commonType = commonType.MaybeMakeNullable(this);
                        else commonType = commonType.GetCommonType(JsonType.GetNull(this));
                        jsonFields.Add(propName, commonType);
                        fieldExamples[propName] = new List<object>();
                    }
                    var fe = fieldExamples[propName];
                    var val = prop.Value;
                    if (val.Type == JTokenType.Null || val.Type == JTokenType.Undefined)
                    {
                        if (!fe.Contains(null))
                        {
                            fe.Insert(0, null);
                        }
                    }
                    else
                    {
                        var v = val.Type == JTokenType.Array || val.Type == JTokenType.Object ? val : val.Value<object>();
                        if (!fe.Any(x => v.Equals(x)))
                            fe.Add(v);
                    }
                }
                first = false;
            }

            if (UseNestedClasses)
            {
                foreach (var field in jsonFields)
                {
                    Names.Add(field.Key.ToLower());
                }
            }

            foreach (var field in jsonFields)
            {
                var fieldType = field.Value;
                if (fieldType.Type == JsonTypeEnum.Object)
                {
                    var subexamples = new List<JObject>(examples.Length);
                    foreach (var obj in examples)
                    {
                        JToken value;
                        if (obj.TryGetValue(field.Key, out value))
                        {
                            if (value.Type == JTokenType.Object)
                            {
                                subexamples.Add((JObject)value);
                            }
                        }
                    }

                    fieldType.AssignName(CreateUniqueClassName(field.Key));
                    GenerateClass(subexamples.ToArray(), fieldType);
                }

                if (fieldType.InternalType != null && fieldType.InternalType.Type == JsonTypeEnum.Object)
                {
                    var subexamples = new List<JObject>(examples.Length);
                    foreach (var obj in examples)
                    {
                        JToken value;
                        if (obj.TryGetValue(field.Key, out value))
                        {
                            if (value.Type == JTokenType.Array)
                            {
                                foreach (var item in (JArray)value)
                                {
                                    if (!(item is JObject)) throw new NotSupportedException("Arrays of non-objects are not supported yet.");
                                    subexamples.Add((JObject)item);
                                }

                            }
                            else if (value.Type == JTokenType.Object)
                            {
                                foreach (var item in (JObject)value)
                                {
                                    if (!(item.Value is JObject)) throw new NotSupportedException("Arrays of non-objects are not supported yet.");

                                    subexamples.Add((JObject)item.Value);
                                }
                            }
                        }
                    }

                    field.Value.InternalType.AssignName(CreateUniqueClassNameFromPlural(field.Key));
                    GenerateClass(subexamples.ToArray(), field.Value.InternalType);
                }
            }

            type.Fields = jsonFields.Select(x => new FieldInfo(this, x.Key, x.Value, UsePascalCase, fieldExamples[x.Key])).ToArray();

            Types.Add(type);
        }
Пример #4
0
        public void GenerateClasses()
        {
            if (CodeWriter == null) CodeWriter = new CSharpCodeWriter();
            if (ExplicitDeserialization && !(CodeWriter is CSharpCodeWriter)) throw new ArgumentException("Explicit deserialization is obsolete and is only supported by the C# provider.");

            if (used) throw new InvalidOperationException("This instance of JsonClassGenerator has already been used. Please create a new instance.");
            used = true;

            var writeToDisk = TargetFolder != null;
            if (writeToDisk && !Directory.Exists(TargetFolder)) Directory.CreateDirectory(TargetFolder);

            JObject[] examples;
            var example = Example.StartsWith("HTTP/") ? Example.Substring(Example.IndexOf("\r\n\r\n")) : Example;
            using (var sr = new StringReader(example))
            using (var reader = new JsonTextReader(sr))
            {
                var json = JToken.ReadFrom(reader);
                if (json is JArray)
                {
                    examples = ((JArray)json).Cast<JObject>().ToArray();
                }
                else if (json is JObject)
                {
                    examples = new[] { (JObject)json };
                }
                else
                {
                    throw new Exception("Sample JSON must be either a JSON array, or a JSON object.");
                }
            }

            Types = new List<JsonType>();
            Names.Add(MainClass);
            var rootType = new JsonType(this, examples[0]);
            rootType.IsRoot = true;
            rootType.AssignName(MainClass);
            GenerateClass(examples, rootType);

            if (writeToDisk)
            {

                var parentFolder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                if (writeToDisk && !NoHelperClass && ExplicitDeserialization) File.WriteAllBytes(Path.Combine(TargetFolder, "JsonClassHelper.cs"), Properties.Resources.JsonClassHelper);
                if (SingleFile)
                {
                    WriteClassesToFile(Path.Combine(TargetFolder, MainClass + CodeWriter.FileExtension), Types);
                }
                else
                {

                    foreach (var type in Types)
                    {
                        var folder = TargetFolder;
                        if (!UseNestedClasses && !type.IsRoot && SecondaryNamespace != null)
                        {
                            var s = SecondaryNamespace;
                            if (s.StartsWith(Namespace + ".")) s = s.Substring(Namespace.Length + 1);
                            folder = Path.Combine(folder, s);
                            Directory.CreateDirectory(folder);
                        }
                        WriteClassesToFile(Path.Combine(folder, (UseNestedClasses && !type.IsRoot ? MainClass + "." : string.Empty) + type.AssignedName + CodeWriter.FileExtension), new[] { type });
                    }
                }
            }
            else if (OutputStream != null)
            {
                WriteClassesToFile(OutputStream, Types);
            }
        }
        public JsonType GetCommonType(JsonType type2)
        {
            var commonType = GetCommonTypeEnum(this.Type, type2.Type);

            if (commonType == JsonTypeEnum.Array)
            {
                if (type2.Type == JsonTypeEnum.NullableSomething) return this;
                if (this.Type == JsonTypeEnum.NullableSomething) return type2;
                var commonInternalType = InternalType.GetCommonType(type2.InternalType).MaybeMakeNullable(_generator);
                if (commonInternalType != InternalType) return new JsonType(_generator, JsonTypeEnum.Array) { InternalType = commonInternalType };
            }

            //if (commonType == JsonTypeEnum.Dictionary)
            //{
            //    var commonInternalType = InternalType.GetCommonType(type2.InternalType);
            //    if (commonInternalType != InternalType) return new JsonType(JsonTypeEnum.Dictionary) { InternalType = commonInternalType };
            //}

            if (this.Type == commonType) return this;
            return new JsonType(_generator, commonType).MaybeMakeNullable(_generator);
        }
Пример #6
0
        private JsonTypeEnum GetCommonTypeEnum(JsonTypeEnum type1, JsonType type2json)
        {
            if (type2json == null)
            {
                return(type1);
            }

            var type2 = type2json.Type;

            if (type1 == JsonTypeEnum.NonConstrained)
            {
                return(type2);
            }
            if (type2 == JsonTypeEnum.NonConstrained)
            {
                return(type1);
            }

            switch (type1)
            {
            case JsonTypeEnum.Boolean:
                if (IsNull(type2))
                {
                    return(JsonTypeEnum.NullableBoolean);
                }
                if (type2 == JsonTypeEnum.Boolean)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.NullableBoolean:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Boolean)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.Integer:
                if (IsNull(type2))
                {
                    return(JsonTypeEnum.NullableInteger);
                }
                if (type2 == JsonTypeEnum.Float)
                {
                    return(JsonTypeEnum.Float);
                }
                if (type2 == JsonTypeEnum.Long)
                {
                    return(JsonTypeEnum.Long);
                }
                if (type2 == JsonTypeEnum.Integer)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.NullableInteger:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Float)
                {
                    return(JsonTypeEnum.NullableFloat);
                }
                if (type2 == JsonTypeEnum.Long)
                {
                    return(JsonTypeEnum.NullableLong);
                }
                if (type2 == JsonTypeEnum.Integer)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.Float:
                if (IsNull(type2))
                {
                    return(JsonTypeEnum.NullableFloat);
                }
                if (type2 == JsonTypeEnum.Float)
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Integer)
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Long)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.NullableFloat:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Float)
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Integer)
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Long)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.Long:
                if (IsNull(type2))
                {
                    return(JsonTypeEnum.NullableLong);
                }
                if (type2 == JsonTypeEnum.Float)
                {
                    return(JsonTypeEnum.Float);
                }
                if (type2 == JsonTypeEnum.Integer)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.NullableLong:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Float)
                {
                    return(JsonTypeEnum.NullableFloat);
                }
                if (type2 == JsonTypeEnum.Integer)
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Long)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.Date:
                if (IsNull(type2))
                {
                    return(JsonTypeEnum.NullableDate);
                }
                if (type2 == JsonTypeEnum.Date)
                {
                    return(JsonTypeEnum.Date);
                }
                break;

            case JsonTypeEnum.NullableDate:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Date)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.NullableSomething:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.String)
                {
                    return(JsonTypeEnum.String);
                }
                if (type2 == JsonTypeEnum.Integer)
                {
                    return(JsonTypeEnum.NullableInteger);
                }
                if (type2 == JsonTypeEnum.Float)
                {
                    return(JsonTypeEnum.NullableFloat);
                }
                if (type2 == JsonTypeEnum.Long)
                {
                    return(JsonTypeEnum.NullableLong);
                }
                if (type2 == JsonTypeEnum.Boolean)
                {
                    return(JsonTypeEnum.NullableBoolean);
                }
                if (type2 == JsonTypeEnum.Date)
                {
                    return(JsonTypeEnum.NullableDate);
                }
                if (type2 == JsonTypeEnum.Array)
                {
                    return(JsonTypeEnum.Array);
                }
                if (type2 == JsonTypeEnum.Object)
                {
                    return(JsonTypeEnum.Object);
                }
                break;

            case JsonTypeEnum.Object:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Object)
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Dictionary)
                {
                    throw new ArgumentException();
                }
                break;

            case JsonTypeEnum.Dictionary:
                throw new ArgumentException();

            //if (IsNull(type2)) return type1;
            //if (type2 == JsonTypeEnum.Object) return type1;
            //if (type2 == JsonTypeEnum.Dictionary) return type1;
            //  break;
            case JsonTypeEnum.Array:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.Array)
                {
                    return(type1);
                }
                break;

            case JsonTypeEnum.String:
                if (IsNull(type2))
                {
                    return(type1);
                }
                if (type2 == JsonTypeEnum.String)
                {
                    return(type1);
                }
                break;
            }

            return(JsonTypeEnum.Anything);
        }
Пример #7
0
        public void GenerateClasses()
        {
            if (CodeWriter == null)
            {
                CodeWriter = new CSharpCodeWriter();
            }
            if (ExplicitDeserialization && !(CodeWriter is CSharpCodeWriter))
            {
                throw new ArgumentException("Explicit deserialization is obsolete and is only supported by the C# provider.");
            }

            if (used)
            {
                throw new InvalidOperationException("This instance of JsonClassGenerator has already been used. Please create a new instance.");
            }
            used = true;


            var writeToDisk = TargetFolder != null;

            if (writeToDisk && !Directory.Exists(TargetFolder))
            {
                Directory.CreateDirectory(TargetFolder);
            }


            JObject[] examples;
            var       example = Example.StartsWith("HTTP/") ? Example.Substring(Example.IndexOf("\r\n\r\n")) : Example;

            using (var sr = new StringReader(example))
                using (var reader = new JsonTextReader(sr))
                {
                    var json = JToken.ReadFrom(reader);
                    if (json is JArray)
                    {
                        examples = ((JArray)json).Cast <JObject>().ToArray();
                    }
                    else if (json is JObject)
                    {
                        examples = new[] { (JObject)json };
                    }
                    else
                    {
                        throw new Exception("Sample JSON must be either a JSON array, or a JSON object.");
                    }
                }


            Types = new List <JsonType>();
            Names.Add(MainClass);
            var rootType = new JsonType(this, examples[0]);

            rootType.IsRoot = true;
            rootType.AssignName(MainClass);
            GenerateClass(examples, rootType);

            if (writeToDisk)
            {
                var parentFolder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                if (writeToDisk && !NoHelperClass && ExplicitDeserialization)
                {
                    File.WriteAllText(Path.Combine(TargetFolder, "JsonClassHelper.cs"), NFinalCompiler.Json.JsonClassGeneratorLib.Resource.JsonClassHelper);
                }
                if (SingleFile)
                {
                    WriteClassesToFile(Path.Combine(TargetFolder, MainClass + CodeWriter.FileExtension), Types);
                }
                else
                {
                    foreach (var type in Types)
                    {
                        var folder = TargetFolder;
                        if (!UseNestedClasses && !type.IsRoot && SecondaryNamespace != null)
                        {
                            var s = SecondaryNamespace;
                            if (s.StartsWith(Namespace + "."))
                            {
                                s = s.Substring(Namespace.Length + 1);
                            }
                            folder = Path.Combine(folder, s);
                            Directory.CreateDirectory(folder);
                        }
                        WriteClassesToFile(Path.Combine(folder, (UseNestedClasses && !type.IsRoot ? MainClass + "." : string.Empty) + type.AssignedName + CodeWriter.FileExtension), new[] { type });
                    }
                }
            }
            else if (OutputStream != null)
            {
                WriteClassesToFile(OutputStream, Types);
            }
        }
Пример #8
0
        private void GenerateClass(JObject[] examples, JsonType type)
        {
            var jsonFields    = new Dictionary <string, JsonType>();
            var fieldExamples = new Dictionary <string, IList <object> >();

            var first = true;

            foreach (var obj in examples)
            {
                foreach (var prop in obj.Properties())
                {
                    JsonType fieldType;
                    var      currentType = new JsonType(this, prop.Value);
                    var      propName    = prop.Name;
                    if (jsonFields.TryGetValue(propName, out fieldType))
                    {
                        var commonType = fieldType.GetCommonType(currentType);

                        jsonFields[propName] = commonType;
                    }
                    else
                    {
                        var commonType = currentType;
                        if (first)
                        {
                            commonType = commonType.MaybeMakeNullable(this);
                        }
                        else
                        {
                            commonType = commonType.GetCommonType(JsonType.GetNull(this));
                        }
                        jsonFields.Add(propName, commonType);
                        fieldExamples[propName] = new List <object>();
                    }
                    var fe  = fieldExamples[propName];
                    var val = prop.Value;
                    if (val.Type == JTokenType.Null || val.Type == JTokenType.Undefined)
                    {
                        if (!fe.Contains(null))
                        {
                            fe.Insert(0, null);
                        }
                    }
                    else
                    {
                        var v = val.Type == JTokenType.Array || val.Type == JTokenType.Object ? val : val.Value <object>();
                        if (!fe.Any(x => v.Equals(x)))
                        {
                            fe.Add(v);
                        }
                    }
                }
                first = false;
            }

            if (UseNestedClasses)
            {
                foreach (var field in jsonFields)
                {
                    Names.Add(field.Key.ToLower());
                }
            }

            foreach (var field in jsonFields)
            {
                var fieldType = field.Value;
                if (fieldType.Type == JsonTypeEnum.Object)
                {
                    var subexamples = new List <JObject>(examples.Length);
                    foreach (var obj in examples)
                    {
                        JToken value;
                        if (obj.TryGetValue(field.Key, out value))
                        {
                            if (value.Type == JTokenType.Object)
                            {
                                subexamples.Add((JObject)value);
                            }
                        }
                    }

                    fieldType.AssignName(CreateUniqueClassName(field.Key));
                    GenerateClass(subexamples.ToArray(), fieldType);
                }

                if (fieldType.InternalType != null && fieldType.InternalType.Type == JsonTypeEnum.Object)
                {
                    var subexamples = new List <JObject>(examples.Length);
                    foreach (var obj in examples)
                    {
                        JToken value;
                        if (obj.TryGetValue(field.Key, out value))
                        {
                            if (value.Type == JTokenType.Array)
                            {
                                foreach (var item in (JArray)value)
                                {
                                    if (!(item is JObject))
                                    {
                                        throw new NotSupportedException("Arrays of non-objects are not supported yet.");
                                    }
                                    subexamples.Add((JObject)item);
                                }
                            }
                            else if (value.Type == JTokenType.Object)
                            {
                                foreach (var item in (JObject)value)
                                {
                                    if (!(item.Value is JObject))
                                    {
                                        throw new NotSupportedException("Arrays of non-objects are not supported yet.");
                                    }

                                    subexamples.Add((JObject)item.Value);
                                }
                            }
                        }
                    }

                    field.Value.InternalType.AssignName(CreateUniqueClassNameFromPlural(field.Key));
                    GenerateClass(subexamples.ToArray(), field.Value.InternalType);
                }
            }

            type.Fields = jsonFields.Select(x => new FieldInfo(this, x.Key, x.Value, UsePascalCase, fieldExamples[x.Key])).ToArray();

            Types.Add(type);
        }