aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Utilities/Tango.DBObservablesGenerator.CLI/ObservablesGenerator.cs
blob: 208adf63f6267aa434b75faf577e6274733f787f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
/* Generated from: StubGPIOReadBitRequest.proto */

#ifndef PROTOBUF_C_StubGPIOReadBitRequest_2eproto__INCLUDED
#define PROTOBUF_C_StubGPIOReadBitRequest_2eproto__INCLUDED

#include <protobuf-c/protobuf-c.h>

PROTOBUF_C__BEGIN_DECLS

#if PROTOBUF_C_VERSION_NUMBER < 1003000
# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
#elif 1003000 < PROTOBUF_C_MIN_COMPILER_VERSION
# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
#endif


typedef struct _StubGPIOReadBitRequest StubGPIOReadBitRequest;


/* --- enums --- */


/* --- messages --- */

struct  _StubGPIOReadBitRequest
{
  ProtobufCMessage base;
  char *portid;
  protobuf_c_boolean has_pinid;
  uint32_t pinid;
  protobuf_c_boolean has_polling;
  protobuf_c_boolean polling;
  protobuf_c_boolean has_pollexpvalue;
  protobuf_c_boolean pollexpvalue;
};
#define STUB_GPIOREAD_BIT_REQUEST__INIT \
 { PROTOBUF_C_MESSAGE_INIT (&stub_gpioread_bit_request__descriptor) \
    , NULL, 0, 0, 0, 0, 0, 0 }


/* StubGPIOReadBitRequest methods */
void   stub_gpioread_bit_request__init
                     (StubGPIOReadBitRequest         *message);
size_t stub_gpioread_bit_request__get_packed_size
                     (const StubGPIOReadBitRequest   *message);
size_t stub_gpioread_bit_request__pack
                     (const StubGPIOReadBitRequest   *message,
                      uint8_t             *out);
size_t stub_gpioread_bit_request__pack_to_buffer
                     (const StubGPIOReadBitRequest   *message,
                      ProtobufCBuffer     *buffer);
StubGPIOReadBitRequest *
       stub_gpioread_bit_request__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data);
void   stub_gpioread_bit_request__free_unpacked
                     (StubGPIOReadBitRequest *message,
                      ProtobufCAllocator *allocator);
/* --- per-message closures --- */

typedef void (*StubGPIOReadBitRequest_Closure)
                 (const StubGPIOReadBitRequest *message,
                  void *closure_data);

/* --- services --- */


/* --- descriptors --- */

extern const ProtobufCMessageDescriptor stub_gpioread_bit_request__descriptor;

PROTOBUF_C__END_DECLS


#endif  /* PROTOBUF_C_StubGPIOReadBitRequest_2eproto__INCLUDED */
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Tango.CodeGeneration;
using Tango.DAL.Remote.DB;
using Tango.Settings;
using Humanizer;
using System.Globalization;
using Tango.Core;
using System.Data;
using System.Diagnostics;
using static Tango.Core.Components.DataBaseDescriptionsHelper;
using System.Threading;
using Newtonsoft.Json;

namespace Tango.DBObservablesGenerator.CLI
{
    /// <summary>
    /// Generates observable entities code files.
    /// </summary>
    public class ObservablesGenerator
    {
        /// <summary>
        /// Generates C# code files.
        /// </summary>
        /// <param name="targetPath">The target path.</param>
        public void GenerateCSharp(String targetPath)
        {
            List<DbDescription> dbDescriptions = new List<DbDescription>();
            List<ForeignKeyDescription> foreign_keys = new List<ForeignKeyDescription>();

            //Get column descriptions...
            using (RemoteDB db = new RemoteDB(SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource))
            {
                db.Configuration.LazyLoadingEnabled = false;
                db.Database.Connection.Open();

                dbDescriptions = Core.Components.DataBaseDescriptionsHelper.GetDescriptions(db.Database.Connection);
                foreign_keys = Core.Components.DataBaseDescriptionsHelper.GetForeignKeys(db.Database.Connection);
            }

            //Generate Entities and DTOs...
            foreach (var table in typeof(RemoteDB).GetProperties().Where(x => typeof(IEnumerable).IsAssignableFrom(x.PropertyType)))
            {
                Console.WriteLine("Generating table '" + table + "'...");

                String table_description = null;
                var db_des = dbDescriptions.FirstOrDefault(x => x.TableName == table.Name);

                if (db_des != null && !String.IsNullOrWhiteSpace(db_des.TableDescription))
                {
                    table_description = db_des.TableDescription;
                }

                EntityCodeFile codeFile = new EntityCodeFile((table.Name == "TECH_VALVES" ? "TechValve" : DalNameToStandardName(table.Name).SingularizeMVC()) + "Base")
                {
                    EntityName = table.Name.SingularizeMVC(),
                    TableName = table.Name,
                    Description = table_description,
                };

                EntityDTOCodeFile dtoCodeBase = new EntityDTOCodeFile();
                dtoCodeBase.Name = codeFile.Name.Replace("Base", "DTOBase");
                dtoCodeBase.Description = codeFile.Description;
                dtoCodeBase.ObservableType = codeFile.Name.Replace("Base", "");
                dtoCodeBase.InheritedType = dtoCodeBase.Name.Replace("Base", "");

                List<String> guessed_keys = table.PropertyType.GenericTypeArguments.First().GetProperties().Skip(3).Where(x => x.PropertyType == typeof(String)).Where(x => x.Name.ToLower().Contains("guid")).Select(x => DalNameToStandardName(x.Name).SingularizeMVC().Replace("Guid", "")).OrderBy(x => x).ToList();

                List<String> foreignKeys = foreign_keys.Where(x => x.TableName == table.Name).Select(x => DalNameToStandardName(x.ColumnName).SingularizeMVC().Replace("Guid", "")).OrderBy(x => x).ToList();

                String t_name = table.Name;

                if (guessed_keys.Count != foreignKeys.Count)
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;

                    Console.WriteLine($"Suspicious entry at {table.Name}.");
                    for (int i = 0; i < Math.Max(guessed_keys.Count, foreignKeys.Count); i++)
                    {
                        if (i < guessed_keys.Count)
                        {
                            Console.Write(guessed_keys[i]);
                        }

                        Console.Write(" <=> ");

                        if (i < foreignKeys.Count)
                        {
                            Console.Write(foreignKeys[i]);
                        }

                        Console.WriteLine();
                    }

                    Console.ForegroundColor = ConsoleColor.Gray;

                    Thread.Sleep(2000);
                }

                foreach (var field in table.PropertyType.GenericTypeArguments.First().GetProperties().Skip(3))
                {
                    EntityCodeFileField codeField = new EntityCodeFileField();
                    codeField.FieldName = field.Name;
                    codeField.Name = DalNameToStandardName(field.Name);
                    codeField.Description = field.Name.Replace("_", " ").ToLower();

                    String column_description = null;
                    var column_des = dbDescriptions.FirstOrDefault(x => x.TableName == table.Name && x.ColumnName == field.Name);

                    if (column_des != null)
                    {
                        column_description = column_des.ColumnDescription;
                    }

                    if (column_description != null)
                    {
                        DbPropertyExtensionModel dbPropertyExtensionModel = null;

                        try
                        {
                            dbPropertyExtensionModel = JsonConvert.DeserializeObject<DbPropertyExtensionModel>(column_description, new JsonSerializerSettings()
                            {
                                NullValueHandling = NullValueHandling.Ignore,
                                MissingMemberHandling = MissingMemberHandling.Ignore,
                            });
                        }
                        catch { }

                        if (dbPropertyExtensionModel != null)
                        {
                            codeField.PropertyExtension = dbPropertyExtensionModel;

                            if (dbPropertyExtensionModel.Description != null)
                            {
                                codeField.DbDescription = dbPropertyExtensionModel.Description.ToLines().Select(x => "/// " + x).Join(Environment.NewLine);
                            }
                        }
                        else
                        {
                            codeField.DbDescription = column_description.ToLines().Select(x => "/// " + x).Join(Environment.NewLine);
                        }
                    }

                    if (field.PropertyType.IsGenericType)
                    {
                        if (field.PropertyType == typeof(Nullable<DateTime>))
                        {
                            codeField.Type = String.Format("Nullable<{0}>", "DateTime");
                        }
                        else if (field.PropertyType == typeof(Nullable<Int32>))
                        {
                            codeField.Type = String.Format("Nullable<{0}>", "Int32");
                        }
                        else if (field.PropertyType == typeof(Nullable<Double>))
                        {
                            codeField.Type = String.Format("Nullable<{0}>", "Double");
                        }
                        else
                        {
                            codeField.Type = String.Format("SynchronizedObservableCollection<{0}>", DalNameToStandardName(field.PropertyType.GenericTypeArguments.Single().Name).SingularizeMVC());
                            codeField.Construct = true;
                        }
                    }
                    else
                    {
                        if (field.PropertyType.IsClass && field.PropertyType != typeof(String) && field.PropertyType != typeof(byte[]))
                        {
                            codeField.Type = DalNameToStandardName(field.PropertyType.Name).SingularizeMVC();
                            codeField.Name = codeField.Type;
                            codeField.XmlIgnore = true;

                            var fk = foreignKeys.FirstOrDefault(x => x.Contains(codeField.Name));

                            if (fk != null)
                            {
                                codeField.Name = fk;
                                foreignKeys.Remove(fk);
                            }

                            codeField.Complex = true;
                        }
                        else
                        {
                            codeField.Type = field.PropertyType.Name;

                            if (foreignKeys.Contains(codeField.Name.Replace("Guid", "")))
                            {
                                codeField.IsForeignKey = true;
                                codeField.ForeignKeyName = codeField.Name.Replace("Guid", "");
                            }
                        }
                    }
                    codeFile.Fields.Add(codeField);

                    if (field.PropertyType.IsPrimitive || field.PropertyType.IsValueType || field.PropertyType == typeof(String) || field.PropertyType == typeof(byte[]))
                    {
                        dtoCodeBase.Properties.Add(new Property()
                        {
                            Type = codeField.Type,
                            Name = codeField.Name,
                            Description = codeField.Description,
                        });
                    }
                }

                String code = codeFile.GenerateCode();

                String entitiesPath = Path.Combine(targetPath, "Entities");
                Directory.CreateDirectory(entitiesPath);
                File.WriteAllText(Path.Combine(entitiesPath, codeFile.Name + ".cs"), code);

                if (!File.Exists(Path.Combine(entitiesPath, codeFile.Name + ".cs")))
                {
                    EntityInheritedCodeFile inherited = new EntityInheritedCodeFile(codeFile.Name.Replace("Base", ""), codeFile.Name);
                    String inheritedCode = inherited.GenerateCode();
                    File.WriteAllText(Path.Combine(entitiesPath, inherited.Name + ".cs"), inheritedCode);
                }

                if (dtoCodeBase.Name != "SysdiagramDTOBase")
                {
                    String dtoCode = dtoCodeBase.GenerateCode();
                    String dtoPath = Path.Combine(targetPath, "DTO");
                    Directory.CreateDirectory(dtoPath);
                    File.WriteAllText(Path.Combine(dtoPath, dtoCodeBase.Name + ".cs"), dtoCode);

                    String inheritedName = dtoCodeBase.Name.Replace("Base", "");

                    if (!File.Exists(Path.Combine(dtoPath, inheritedName + ".cs")))
                    {
                        EntityInheritedDTOCodeFile inherited = new EntityInheritedDTOCodeFile(inheritedName, dtoCodeBase.Name);
                        String inheritedCode = inherited.GenerateCode();
                        File.WriteAllText(Path.Combine(dtoPath, inherited.Name + ".cs"), inheritedCode);
                    }
                }
            }
            //Generate Entities...

            //Generate Enumerations...
            using (RemoteDB db = new RemoteDB(SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource))
            {
                foreach (var tableProp in db.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.PropertyType.IsGenericTypeAndNotNullable()))
                {
                    try
                    {
                        var a = tableProp.PropertyType.GenericTypeArguments.FirstOrDefault();
                        var codeProp = tableProp.PropertyType.GenericTypeArguments.First().GetProperty("CODE");
                        var nameProp = tableProp.PropertyType.GenericTypeArguments.First().GetProperty("NAME");
                        var descriptionProp = tableProp.PropertyType.GenericTypeArguments.First().GetProperty("DESCRIPTION");

                        if (codeProp != null && nameProp != null)
                        {
                            EnumerationFile enumFile = new EnumerationFile();
                            enumFile.Name = DalNameToStandardName(tableProp.Name);

                            Console.WriteLine("Generating enumeration '" + enumFile.Name + "'...");

                            foreach (var row in tableProp.GetValue(db) as IEnumerable)
                            {
                                EnumerationField field = new EnumerationField();
                                field.Name = nameProp.GetValue(row).ToString().Replace(" ", "");
                                field.Value = (int)codeProp.GetValue(row);

                                if (descriptionProp != null)
                                {
                                    field.Description = descriptionProp.GetValue(row).ToStringSafe();
                                }
                                else
                                {
                                    field.Description = nameProp.GetValue(row).ToString();
                                }
                                enumFile.Fields.Add(field);
                            }

                            String enumerationsPath = Path.Combine(targetPath, "Enumerations");
                            Directory.CreateDirectory(enumerationsPath);
                            String code = enumFile.GenerateCode();
                            File.WriteAllText(Path.Combine(enumerationsPath, enumFile.Name + ".cs"), code);
                        }
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }
            //Generate Enumerations...

            //Generate Observables Adapter Extensions...

            Console.WriteLine("Generating Observables Adapter...");

            ObservablesAdapterFile adapterFile = new ObservablesAdapterFile();
            adapterFile.Name = "ObservablesEntitiesAdapter";

            foreach (var table in typeof(RemoteDB).GetProperties().Where(x => typeof(IEnumerable).IsAssignableFrom(x.PropertyType)))
            {
                String tName = table.PropertyType.GenericTypeArguments.Single().Name;

                adapterFile.Properties.Add(new Property()
                {
                    Name = DalNameToStandardName(table.Name),
                    Type = String.Format("ObservableCollection<{0}>", tName == "TECH_VALVES" ? "TechValve" : DalNameToStandardName(tName).SingularizeMVC()),
                });
            }

            String adapterCode = adapterFile.GenerateCode();
            File.WriteAllText(Path.Combine(targetPath, "ObservablesEntitiesAdapterExtension.cs"), adapterCode);
            //Generate Observables Adapter Extensions...


            //Generate Observables Static Collections...

            Console.WriteLine("Generating Observables Static Collections...");

            ObservablesStaticCollectionsFile collectionsFile = new ObservablesStaticCollectionsFile();
            collectionsFile.Name = "ObservablesStaticCollections";

            foreach (var table in typeof(RemoteDB).GetProperties().Where(x => typeof(IEnumerable).IsAssignableFrom(x.PropertyType)))
            {
                String tName = table.PropertyType.GenericTypeArguments.Single().Name;

                collectionsFile.Properties.Add(new Property()
                {
                    Name = DalNameToStandardName(table.Name),
                    Type = String.Format("ObservableCollection<{0}>", tName == "TECH_VALVES" ? "TechValve" : DalNameToStandardName(tName).SingularizeMVC()),
                });
            }

            String collectionsCode = collectionsFile.GenerateCode();
            File.WriteAllText(Path.Combine(targetPath, "ObservablesStaticCollectionsExtension.cs"), collectionsCode);
            //Generate Observables Static Collections...


            //Generate Observables Context

            Console.WriteLine("Generating Observables DB Context...");

            ObservablesContextCodeFile contextFile = new ObservablesContextCodeFile();
            contextFile.Name = "ObservablesContext";

            foreach (var table in typeof(RemoteDB).GetProperties().Where(x => typeof(IEnumerable).IsAssignableFrom(x.PropertyType)))
            {
                String tName = table.PropertyType.GenericTypeArguments.Single().Name;

                contextFile.Properties.Add(new Property()
                {
                    Name = DalNameToStandardName(table.Name),
                    Type = String.Format("DbSet<{0}>", tName == "TECH_VALVES" ? "TechValve" : DalNameToStandardName(tName).SingularizeMVC()),
                });
            }
            String contextCode = contextFile.GenerateCode();
            File.WriteAllText(Path.Combine(targetPath, "ObservablesContext.cs"), contextCode);
            //Generate Observables Context
        }

        /// <summary>
        /// Generates Java code files.
        /// </summary>
        /// <param name="targetPath">The target path.</param>
        public void GenerateJava(String targetPath)
        {
            //Generate Entities...
            foreach (var table in typeof(RemoteDB).GetProperties().Where(x => typeof(IEnumerable).IsAssignableFrom(x.PropertyType)))
            {
                EntityCodeFileJava codeFile = new EntityCodeFileJava(DalNameToStandardName(table.Name).Singularize(false) + "Base")
                {
                    EntityName = table.Name.Singularize(false),
                    TableName = table.Name,
                };

                EntityCodeFileJavaExtension extensionCodeFile = new EntityCodeFileJavaExtension(DalNameToStandardName(table.Name).Singularize(false), codeFile.Name)
                {
                    TableName = table.Name
                };

                foreach (var field in table.PropertyType.GenericTypeArguments.First().GetProperties().Skip(3).Where(x => !x.Name.Contains("GUID")))
                {
                    String name = field.Name;

                    if (name.ToLower().StartsWith("set_"))
                    {
                        name = name.Remove(0, 4);
                    }

                    EntityCodeFileField codeField = new EntityCodeFileField();
                    codeField.FieldName = field.Name;
                    codeField.Name = DalNameToStandardName(name);
                    codeField.Description = FirstCharacterToLower(DalNameToStandardName(name));


                    if (field.PropertyType.IsGenericTypeAndNotNullable())
                    {
                        continue;
                    }
                    else
                    {
                        if (field.PropertyType.IsClass && field.PropertyType != typeof(String) && field.PropertyType != typeof(Byte[]))
                        {
                            codeField.Type = DalNameToStandardName(field.PropertyType.Name).Singularize(false);
                            codeField.Construct = true;
                            codeField.FieldName = codeField.FieldName.Singularize(false).ToUpper();
                            codeField.Description = codeField.Description.Singularize(false);
                            codeField.Name = codeField.Type;
                        }
                        else if (field.PropertyType == typeof(Byte[]) || field.PropertyType == typeof(Boolean) || field.PropertyType == typeof(Double))
                        {
                            codeField.Type = field.PropertyType.Name.ToLower();
                        }
                        else
                        {
                            codeField.Type = field.PropertyType.Name == "Int32" ? "int" : field.PropertyType.Name;
                        }
                    }

                    codeFile.Fields.Add(codeField);
                }

                codeFile.IndentResult = false;
                extensionCodeFile.IndentResult = false;
                String code = codeFile.GenerateCode();
                String extensionCode = extensionCodeFile.GenerateCode();

                String entitiesPath = Path.Combine(targetPath, "entities");
                Directory.CreateDirectory(entitiesPath);
                File.WriteAllText(Path.Combine(entitiesPath, codeFile.Name + ".java"), code);

                String extensionCodeFilePath = Path.Combine(entitiesPath, extensionCodeFile.Name + ".java");

                if (!File.Exists(extensionCodeFilePath))
                {
                    File.WriteAllText(extensionCodeFilePath, extensionCode);
                }
            }
            //Generate Entities...

            //Generate Enumerations...
            using (RemoteDB db = new RemoteDB(SettingsManager.Default.GetOrCreate<CoreSettings>().DataSource))
            {
                foreach (var tableProp in db.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.PropertyType.IsGenericTypeAndNotNullable()))
                {
                    try
                    {
                        var a = tableProp.PropertyType.GenericTypeArguments.FirstOrDefault();
                        var codeProp = tableProp.PropertyType.GenericTypeArguments.First().GetProperty("CODE");
                        var nameProp = tableProp.PropertyType.GenericTypeArguments.First().GetProperty("NAME");
                        var descriptionProp = tableProp.PropertyType.GenericTypeArguments.First().GetProperty("DESCRIPTION");

                        if (codeProp != null && nameProp != null)
                        {
                            EnumerationFileJava enumFile = new EnumerationFileJava();
                            enumFile.Name = DalNameToStandardName(tableProp.Name);

                            foreach (var row in tableProp.GetValue(db) as IEnumerable)
                            {
                                EnumerationField field = new EnumerationField();
                                field.Name = nameProp.GetValue(row).ToString().Replace(" ", "");
                                field.Value = (int)codeProp.GetValue(row);

                                if (descriptionProp != null)
                                {
                                    field.Description = descriptionProp.GetValue(row).ToString();
                                }
                                else
                                {
                                    field.Description = nameProp.GetValue(row).ToString();
                                }
                                enumFile.Fields.Add(field);
                            }

                            String enumerationsPath = Path.Combine(targetPath, "enumerations");
                            Directory.CreateDirectory(enumerationsPath);
                            String code = enumFile.GenerateCode();
                            File.WriteAllText(Path.Combine(enumerationsPath, enumFile.Name + ".java"), code);
                        }
                    }
                    catch { }
                }
            }
            //Generate Enumerations...

            //Generate DAO...
            TangoDAOJavaFile daoFile = new TangoDAOJavaFile();
            daoFile.Name = "TangoDAO";

            foreach (var table in typeof(RemoteDB).GetProperties().Where(x => typeof(IEnumerable).IsAssignableFrom(x.PropertyType)))
            {
                daoFile.Entities.Add(new TangoDAOJavaFile.TangoDAOEntity()
                {
                    Name = DalNameToStandardName(table.Name).Singularize(false),
                    TableName = DalNameToStandardName(table.Name),
                });
            }

            String daoCode = daoFile.GenerateCode();
            String daoFolder = Path.Combine(targetPath, "dao");
            Directory.CreateDirectory(daoFolder);
            File.WriteAllText(Path.Combine(daoFolder, "TangoDAO.java"), daoCode);
            //Generate DAO...
        }

        /// <summary>
        /// Lower case the first character of a string.
        /// </summary>
        /// <param name="str">The string.</param>
        /// <returns></returns>
        private static string FirstCharacterToLower(string str)
        {
            if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
                return str;

            return Char.ToLowerInvariant(str[0]) + str.Substring(1);
        }

        /// <summary>
        /// Converts the specified database conventional name to the observables conventional name.
        /// </summary>
        /// <param name="dalName">DAL name.</param>
        /// <returns></returns>
        private static String DalNameToStandardName(String dalName)
        {
            return String.Join("", dalName.Split('_').Select(x => ToTitleCase(x)));
        }

        /// <summary>
        /// Converts the specified text to title case.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        private static string ToTitleCase(string text)
        {
            return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text.ToLower());
        }
    }
}