Exemplo n.º 1
0
        /// <summary>
        /// Generates the project code module for this
        /// </summary>
        public ProjectCode GenerateCode()
        {
            var code = new ProjectCode(Name);

            //Rename any class called "_globals" with an extra underscore.
            if (Namespaces["@"].FindIndex(x => x.Name == "_globals") != -1)
            {
                Namespaces["@"].First(x => x.Name == "_globals").Name += "_";
            }

            //Add the root address as a class called "_globals".
            var globalModule = new ClassModule("_globals");

            globalModule.StaticFields.Add(new Static("RootURL", "string")
            {
                Value = "@\"" + RootURL + "\""
            });
            Namespaces["@"].Add(globalModule);


            //Loop over namespaces for generation.
            foreach (var ns in Namespaces)
            {
                //Correct any collisions in this namespace.
                foreach (var module in ns.Value)
                {
                    while (ns.Value.FindAll(x => x.Name == module.Name).Count > 1)
                    {
                        module.Name += "_";
                    }
                }

                //Generate code for the namespace.
                string thisNamespaceFull = (ns.Key == "@") ? Name : Name + "." + ns.Key;
                foreach (var module in ns.Value)
                {
                    code.Files.Add(new ProjectFileInfo()
                    {
                        ClassName = module.Name,
                        Namespace = ns.Key
                    }, module.GenerateCode(thisNamespaceFull, Name + ".Data"));
                }
            }

            return(code);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Derives a C# class module from a JObject.
        /// </summary>
        public static ClassModule FromJObject(JObject jobj, string name)
        {
            //Create ClassModule.
            var module = new ClassModule(name);

            //If the name or JObject is null, invalid.
            if (jobj == null)
            {
                Logger.Write("[ERR] - Invalid JSON data given to create a class module from, no data. ('" + name + "')", 1);
                return(null);
            }
            if (name == null)
            {
                Logger.Write("[ERR] - No name provided for creating returned data from a route. ('" + name + "')", 1);
                return(null);
            }

            //Is the name a reserved word?
            while (module.Name.IsReservedWord())
            {
                //Stick underscores on it.
                module.Name += "_";
            }

            //Create the class module.
            foreach (var prop in jobj.Properties())
            {
                var field = GenerateField(name, prop.Name, prop.Value);
                if (field.Name.ToUpper() == module.Name.ToUpper())
                {
                    //Naming conflict between module and field, rename module with extra "_".
                    module.Name += "_";
                }
                module.Fields.Add(field);
            }

            return(module);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Run the currently set up instance of Burrito.
        /// </summary>
        public static int Run()
        {
            //Try and deserialize the schema.
            APISchema schema;

            try
            {
                schema = JsonConvert.DeserializeObject <APISchema>(File.ReadAllText(APISchemaPath));
            }
            catch (Exception e)
            {
                Logger.Write("[ERR] - Failed to load API schema, '" + e.Message + "'.", 1);
                return(0);
            }

            //All relevant properties exist?
            if (schema.Sections == null || schema.Name == null || schema.RootPath == null)
            {
                Logger.Write("[ERR] - Required chema property missing (one of 'name', 'root' or 'sections').", 1);
                return(0);
            }

            //Valid schema name?
            if (!Regex.IsMatch(schema.Name, "^[A-Za-z0-9_]+$"))
            {
                Logger.Write("[ERR] - Invalid schema name given. Must only be alphanumeric or underscores.", 1);
                return(0);
            }

            //If the root path doesn't end with a "/", add it on.
            if (!schema.RootPath.EndsWith("/"))
            {
                schema.RootPath += "/";
            }

            //Create a project module with the given schema and namespaces.
            Project = new ProjectModule(schema.Name, schema.RootPath);
            Project.AddNamespace("Data");
            Project.AddNamespace("@");
            Project.Namespaces["Data"].Add(new ClassModule("_empty"));

            //Check all the sections in the schema have unique names.
            var sectionNames = new List <string>();

            foreach (var module in schema.Sections)
            {
                if (sectionNames.Contains(module.Name))
                {
                    Logger.Write("[ERR] - Duplicate section name '" + module.Name + "' detected.", 1);
                    return(0);
                }
                sectionNames.Add(module.Name);
            }

            //Loop through the routes and generate code modules for each of them.
            foreach (var module in schema.Sections)
            {
                var moduleClass = new ClassModule(module.Name);
                foreach (var route in module.Routes)
                {
                    //Check whether the route has valid properties.
                    if (!route.Validate())
                    {
                        return(0);
                    }

                    //What method does this route use?
                    switch (route.HTTPMethod)
                    {
                    case null:
                        Logger.Write("[ERR] - No HTTP method defined for route '" + route.RelativeURL + "'.", 1);
                        return(0);

                    case "GET":
                    case "get":
                        //Figure out a data type from the API endpoint (if possible).
                        bool isList        = false;
                        var  classReturned = DataTypeCreator.DeriveFromRoute(schema.RootPath, route, ref isList);
                        if (classReturned == null)
                        {
                            break;
                        }

                        //Add class.
                        Project.Namespaces["Data"].Add(classReturned);

                        //Add the method.
                        moduleClass.Methods.Add(new GETMethodModule()
                        {
                            Async            = route.Async,
                            Route            = route.RelativeURL,
                            RouteParams      = route.GetRouteVariables(),
                            XMLSummary       = route.GetSummary(),
                            Name             = route.GetMethodName(),
                            ReceivedDataType = classReturned,
                            ReturnsList      = isList
                        });
                        break;

                    case "POST":
                    case "post":
                        //Figure out a data type it should receive.
                        bool returnsList       = false;
                        var  postClassReturned = DataTypeCreator.DeriveFromRoute(schema.RootPath, route, ref returnsList, route.ExampleData);
                        if (postClassReturned == null)
                        {
                            break;
                        }

                        //Figure out the data type is should send.
                        if (route.ExampleData == null)
                        {
                            Logger.Write("[ERR] - Cannot implement POST route '" + route.RelativeURL + "' without example data to send.", 1);
                            break;
                        }
                        if (route.SentDataName == null)
                        {
                            Logger.Write("[ERR] - Sent data name not set for POST route '" + route.RelativeURL + "', skipping.", 1);
                            break;
                        }
                        var postClass = DataTypeCreator.FromJObject(route.ExampleData, route.SentDataName);
                        if (postClass == null)
                        {
                            break;
                        }

                        //Add classes.
                        Project.Namespaces["Data"].Add(postClassReturned);
                        Project.Namespaces["Data"].Add(postClass);

                        //Add the method.
                        moduleClass.Methods.Add(new POSTMethodModule()
                        {
                            Async            = route.Async,
                            Route            = route.RelativeURL,
                            XMLSummary       = route.GetSummary(),
                            RouteParams      = route.GetRouteVariables(),
                            SentDataType     = postClass,
                            ReceivedDataType = postClassReturned,
                            Name             = route.GetMethodName(),
                            ReturnsList      = returnsList
                        });
                        break;
                    }
                }

                //Add the class to root namespace.
                Project.Namespaces["@"].Add(moduleClass);
            }

            //All classes generated, generate code for the project.
            ProjectCode code = Project.GenerateCode();

            //Decide what to do with it.
            if (CompileMode)
            {
                code.CompileToDLL(GenerationPath);
            }
            else
            {
                try
                {
                    code.CompileToProject(GenerationPath);
                }
                catch (Exception e)
                {
                    Logger.Write("[ERR] - Error writing project to disk: '" + e.Message + "'.", 1);
                }
            }

            //If a NuSpec needs to be generated, do it now.
            if (GenerateNuspec)
            {
                code.GenerateNuspec(GenerationPath);
            }

            return(code.Files.Count);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Generates a field to use in a generated class.
        /// </summary>
        private static Field GenerateField(string rootName, string name, JToken value)
        {
            switch (value.Type)
            {
            //array
            case JTokenType.Array:
                //How long is the array?
                var arr = (JArray)value;
                if (arr.Count == 0)
                {
                    Logger.Write("[WARN] - Cannot generate a type from an empty array. Leaving an empty list type here. ('" + name + "')", 2);
                    return(new Field(name, ClassModule.Empty()));
                }

                //generate field
                var subObjField = GenerateField(rootName, name, arr[0]);
                subObjField.IsList = true;

                //return field
                return(subObjField);

            //object (new class)
            case JTokenType.Object:
                //generate type.
                var subObjType = FromJObject((JObject)value, rootName + "_" + name);
                while (BurritoAPI.Project.Namespaces["Data"].FindIndex(x => x.Name == subObjType.Name) != -1)
                {
                    subObjType.Name += "_";
                }
                BurritoAPI.Project.Namespaces["Data"].Add(subObjType);

                //add field.
                return(new Field(name, subObjType.Name));

            //raw values
            case JTokenType.Boolean:
                return(new Field(name, "bool"));

            case JTokenType.Bytes:
                return(new Field(name, "byte[]"));

            case JTokenType.Date:
                return(new Field(name, "DateTime"));

            case JTokenType.Float:
                return(new Field(name, "float"));

            case JTokenType.Guid:
                return(new Field(name, "Guid"));

            case JTokenType.Integer:
                return(new Field(name, "int"));

            case JTokenType.String:
                return(new Field(name, "string"));

            case JTokenType.Null:
                Logger.Write("[WARN] - Null type in JSON at property '" + name + "', assumed as an object. ('" + name + "')", 2);
                return(new Field(name, "object "));

            default:
                Logger.Write("[WARN] - Unsupported type in JSON to create a class from: '" + value.Type.ToString() + "' for generated data class '" + name + "'. Skipped property.", 2);
                return(null);
            }
        }