Click here to Skip to main content
15,896,153 members
Articles / Programming Languages / XML

netTierGenerator

Rate me:
Please Sign up or sign in to vote.
4.81/5 (20 votes)
30 Nov 2008CPOL14 min read 67.7K   2.8K   108  
A 3-tier application framework and code generation tool - the way for rapid and effective development.
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using TierGenerator.Common.Util.Model;
using System.IO;
using TierGenerator.Common.Util.Settings;

namespace TierGenerator.Common.Util.Generate.XmlModel
{
    public class TierModelBuilder
    {
        #region Class Members
        private TierModelBuilder parentTierModelBuilder;
        private TierModel tierModel;
        #endregion

        public TierModelBuilder(TierGeneratorSettings _settings, string _tierXmlModelPath)
        {
            tierModel = new TierModel();

            TierModel.Solution = _settings.Solution;
            TierModel.ModelPath = _tierXmlModelPath;
            TierModel.Settings = _settings;
        }
        private TierModelBuilder(TierModelBuilder parentTierModelBuilder, TierGeneratorSettings _settings, string _tierXmlModelPath)
            : this(_settings, _tierXmlModelPath)
        {
            this.parentTierModelBuilder = parentTierModelBuilder;
        }

        #region Properties
        public TierModel TierModel
        {
            get { return tierModel; }
            set { tierModel = value; }
        }
        #endregion

        #region Public Methods
        public void Parse()
        {
            if (!File.Exists(TierModel.ModelPath))
            {
                throw new InvalidDataException(String.Format("File {0} does not exists.", TierModel.ModelPath));
            }

            XmlDocument doc = new XmlDocument();
            doc.Load(TierModel.ModelPath);

            XmlNode root = doc.DocumentElement;

            this.TierModel.XmlDocument = doc;
            this.TierModel.Namespace = root.Attributes["Namespace"].Value;
            this.TierModel.ServiceName = root.Attributes["ServiceName"].Value;

            this.ParseDeclaration();
            this.ParseInfoModel();
            this.ParseListItemModel();
            this.ParseIncludes();
            this.ParseUdf();
            this.Validate();
        }
        #endregion

        #region Helper Methods
        private void ParseDeclaration()
        {
            XmlNode root = TierModel.XmlDocument.DocumentElement;
            XmlNodeList declarationList = root.SelectNodes("/TierModel/Declare");

            foreach (XmlNode declarationNode in declarationList)
            {
                Declaration declaration = new Declaration();
                declaration.FullType = declarationNode.Attributes["Type"].Value;
                if (
                        declaration.FullType.StartsWith(String.Concat(this.TierModel.Solution, ".Common.Data")) ||
                        declaration.FullType.StartsWith(String.Concat(this.TierModel.Solution, ".Common.Exception")) ||
                        declaration.FullType.StartsWith(String.Concat(this.TierModel.Solution, ".Common.Util"))
                    )
                {
                    continue;
                }
                TierModel.DeclarationList.Add(declaration);
            }
        }
        private void ParseIncludes()
        {
            XmlNode root = TierModel.XmlDocument.DocumentElement;
            XmlNodeList includeList = root.SelectNodes("/TierModel/Include");

            foreach (XmlNode includeNode in includeList)
            {
                string path = includeNode.Attributes["Path"].Value;
                string type = includeNode.Attributes["Type"].Value;

                string xmlModelPath = Path.Combine(TierModel.Settings.TierModelPath, path);
                TierModelBuilder tmpTierModelBuilder = null;

                if (!this.TryGetParentFromPath(xmlModelPath, out tmpTierModelBuilder))
                {
                    tmpTierModelBuilder = new TierModelBuilder(this, TierModel.Settings, xmlModelPath);
                    tmpTierModelBuilder.Parse();
                }               

                IItem item = tmpTierModelBuilder.TierModel.GetItemInfoByName(type);
                if (item == null)
                {
                    item = tmpTierModelBuilder.TierModel.GetListItemByName(type);
                }

                Include include = new Include(item, tmpTierModelBuilder.TierModel.Namespace, tmpTierModelBuilder.TierModel.ServiceName, path, type);
                TierModel.IncludeList.Add(include);
            }
        }
        private void ParseInfoModel()
        {
            XmlNode root = TierModel.XmlDocument.DocumentElement;
            XmlNodeList infoModelList = root.SelectNodes("/TierModel/ItemModel");

            foreach (XmlNode itemNode in infoModelList)
            {
                ItemInfo itemInfo = new ItemInfo();

                itemInfo.ClassName = itemNode.Attributes["ClassName"].Value;
                itemInfo.DbTableName = itemNode.Attributes["DbTable"].Value;
                if (itemNode.Attributes["DbView"] != null)
                {
                    itemInfo.DbViewName = itemNode.Attributes["DbView"].Value;
                }
                if (itemNode.Attributes["Caching"] != null)
                {
                    itemInfo.AllowCaching = Boolean.Parse(itemNode.Attributes["Caching"].Value);
                }
                if (itemNode.Attributes["History"] != null)
                {
                    itemInfo.AllowHistory = Boolean.Parse(itemNode.Attributes["History"].Value);
                }
                if (itemNode.Attributes["Equatable"] != null)
                {
                    itemInfo.Equatable = Boolean.Parse(itemNode.Attributes["Equatable"].Value);
                }

                XmlNodeList keyNodeList = itemNode.SelectNodes("KeyProperty");
                if (keyNodeList.Count != 1)
                {
                    //throw new InvalidDataException(String.Format("{0} must have only one key property.", itemInfo.ClassName));
                }
                if (keyNodeList.Count > 0)
                {
                    itemInfo.ColumnList.Add(TierModelHelper.ParseColumn(this, keyNodeList[0]));
                }

                XmlNodeList propertyNodeList = itemNode.SelectNodes("Property");
                foreach (XmlNode propertyNode in propertyNodeList)
                {
                    itemInfo.ColumnList.Add(TierModelHelper.ParseColumn(this, propertyNode));
                }

                XmlNodeList selectNodeList = itemNode.SelectNodes("SelectMethod");
                XmlNodeList insertNodeList = itemNode.SelectNodes("InsertMethod");
                XmlNodeList updateNodeList = itemNode.SelectNodes("UpdateMethod");
                XmlNodeList deleteNodeList = itemNode.SelectNodes("DeleteMethod");
                if (selectNodeList.Count != 1)
                {
                    throw new InvalidDataException(String.Format("{0} must have only one select method declaration.", itemInfo.ClassName));
                }
                if (insertNodeList.Count != 1)
                {
                    throw new InvalidDataException(String.Format("{0} must have only one insert method declaration.", itemInfo.ClassName));
                }
                if (updateNodeList.Count != 1)
                {
                    throw new InvalidDataException(String.Format("{0} must have only one update method declaration.", itemInfo.ClassName));
                }
                if (deleteNodeList.Count != 1)
                {
                    throw new InvalidDataException(String.Format("{0} must have only one delete method declaration.", itemInfo.ClassName));
                }

                #region Parse Select Method
                itemInfo.SelectMethod.NeedToCreate = Convert.ToBoolean(selectNodeList[0].Attributes["NeedToCreate"].Value.ToLower());
                if (selectNodeList[0].Attributes["BllAccess"] != null)
                {
                    itemInfo.SelectMethod.BllAccess = Convert.ToBoolean(selectNodeList[0].Attributes["BllAccess"].Value.ToLower());
                }
                if (selectNodeList[0].Attributes["DalAccess"] != null)
                {
                    itemInfo.SelectMethod.DalAccess = Convert.ToBoolean(selectNodeList[0].Attributes["DalAccess"].Value.ToLower());
                }
                #endregion Parse Select Method

                #region Parse Insert Method
                itemInfo.InsertMethod.NeedToCreate = Convert.ToBoolean(insertNodeList[0].Attributes["NeedToCreate"].Value.ToLower());
                if (insertNodeList[0].Attributes["BllAccess"] != null)
                {
                    itemInfo.InsertMethod.BllAccess = Convert.ToBoolean(insertNodeList[0].Attributes["BllAccess"].Value.ToLower());
                }
                if (insertNodeList[0].Attributes["DalAccess"] != null)
                {
                    itemInfo.InsertMethod.DalAccess = Convert.ToBoolean(insertNodeList[0].Attributes["DalAccess"].Value.ToLower());
                }
                #endregion Parse Insert Method

                #region Parse Update Method
                itemInfo.UpdateMethod.NeedToCreate = Convert.ToBoolean(updateNodeList[0].Attributes["NeedToCreate"].Value.ToLower());
                if (updateNodeList[0].Attributes["BllAccess"] != null)
                {
                    itemInfo.UpdateMethod.BllAccess = Convert.ToBoolean(updateNodeList[0].Attributes["BllAccess"].Value.ToLower());
                }
                if (updateNodeList[0].Attributes["DalAccess"] != null)
                {
                    itemInfo.UpdateMethod.DalAccess = Convert.ToBoolean(updateNodeList[0].Attributes["DalAccess"].Value.ToLower());
                }
                #endregion Parse Update Method

                #region Parse Delete Method
                itemInfo.DeleteMethod.NeedToCreate = Convert.ToBoolean(deleteNodeList[0].Attributes["NeedToCreate"].Value.ToLower());
                if (deleteNodeList[0].Attributes["BllAccess"] != null)
                {
                    itemInfo.DeleteMethod.BllAccess = Convert.ToBoolean(deleteNodeList[0].Attributes["BllAccess"].Value.ToLower());
                }
                if (deleteNodeList[0].Attributes["DalAccess"] != null)
                {
                    itemInfo.DeleteMethod.DalAccess = Convert.ToBoolean(deleteNodeList[0].Attributes["DalAccess"].Value.ToLower());
                }
                #endregion Parse Delete Method

                TierModel.ItemInfoList.Add(itemInfo);
            }
        }
        private void ParseListItemModel()
        {
            XmlNode root = TierModel.XmlDocument.DocumentElement;
            XmlNodeList listItemModelList = root.SelectNodes("/TierModel/ListItemModel");

            foreach (XmlNode itemNode in listItemModelList)
            {
                ListItem listItem = new ListItem();

                listItem.ClassName = itemNode.Attributes["ClassName"].Value;
                listItem.DbViewName = itemNode.Attributes["DbView"].Value;

                XmlNodeList keyNodeList = itemNode.SelectNodes("KeyProperty");
                if (keyNodeList.Count != 1)
                {
                    throw new InvalidDataException(String.Format("{0} must have excatly one key property.", listItem.ClassName));
                }
                listItem.ColumnList.Add(TierModelHelper.ParseColumn(this, keyNodeList[0]));

                XmlNodeList propertyNodeList = itemNode.SelectNodes("Property");
                foreach (XmlNode propertyNode in propertyNodeList)
                {
                    listItem.ColumnList.Add(TierModelHelper.ParseColumn(this, propertyNode));
                }

                TierModel.ListItemList.Add(listItem);
            }
        }
        private void ParseUdf()
        {
            ParseSelectMethod();
            ParseUpdateMethod();
            ParseDeleteMethod();
        }
        private void ParseSelectMethod()
        {
            XmlNode root = TierModel.XmlDocument.DocumentElement;
            XmlNodeList selectMethodList = root.SelectNodes("/TierModel/SelectMethod");

            foreach (XmlNode udfNode in selectMethodList)
            {
                UdfInfo udf = new UdfInfo();

                udf.Name = udfNode.Attributes["Name"].Value;
                if (udfNode.Attributes["BllAccess"] != null)
                {
                    udf.BllAccess = Convert.ToBoolean(udfNode.Attributes["BllAccess"].Value);
                }
                if (udfNode.Attributes["DalAccess"] != null)
                {
                    udf.DalAccess = Convert.ToBoolean(udfNode.Attributes["DalAccess"].Value);
                }
                udf.Comment = udfNode.SelectSingleNode("Comment").InnerText;
                udf.SqlQuery = udfNode.SelectSingleNode("Sql").SelectSingleNode("Query").InnerText;

                XmlNodeList propertyNodeList = udfNode.SelectNodes("Property");
                foreach (XmlNode propertyNode in propertyNodeList)
                {
                    udf.ColumnList.Add(TierModelHelper.ParseColumn(this, propertyNode));
                }

                XmlNode returnNode = udfNode.SelectSingleNode("Return");
                udf.ReturnType = CSharpTypeHelper.GetCSharpTypeEnum(returnNode.Attributes["ReturnType"].Value);

                if (!CSharpTypeHelper.IsSimpleType(udf.ReturnType))
                {
                    if (returnNode.Attributes["Type"] != null)
                    {
                        udf.Type = returnNode.Attributes["Type"].Value;
                    }
                    else if (returnNode.Attributes["ReturnType"] != null)
                    {
                        udf.Type = returnNode.Attributes["ReturnType"].Value;
                    }
                }
                else if (udf.ReturnType == CSharpTypeEnum.ENUM)
                {
                    udf.Type = returnNode.Attributes["ReturnType"].Value;
                }

                TierModel.SelectMethodList.Add(udf);
            }
        }
        private void ParseUpdateMethod()
        {
            XmlNode root = TierModel.XmlDocument.DocumentElement;
            XmlNodeList selectMethodList = root.SelectNodes("/TierModel/UpdateMethod");

            foreach (XmlNode udfNode in selectMethodList)
            {
                UdfInfo udf = new UdfInfo();

                udf.Name = udfNode.Attributes["Name"].Value;
                if (udfNode.Attributes["BllAccess"] != null)
                {
                    udf.BllAccess = Convert.ToBoolean(udfNode.Attributes["BllAccess"].Value);
                }
                if (udfNode.Attributes["DalAccess"] != null)
                {
                    udf.DalAccess = Convert.ToBoolean(udfNode.Attributes["DalAccess"].Value);
                }
                udf.Comment = udfNode.SelectSingleNode("Comment").Value;
                udf.SqlQuery = udfNode.SelectSingleNode("Sql").SelectSingleNode("Query").InnerText;

                XmlNodeList propertyNodeList = udfNode.SelectNodes("Property");
                foreach (XmlNode propertyNode in propertyNodeList)
                {
                    udf.ColumnList.Add(TierModelHelper.ParseColumn(this, propertyNode));
                }

                TierModel.UpdateMethodList.Add(udf);
            }
        }
        private void ParseDeleteMethod()
        {
            XmlNode root = TierModel.XmlDocument.DocumentElement;
            XmlNodeList selectMethodList = root.SelectNodes("/TierModel/DeleteMethod");

            foreach (XmlNode udfNode in selectMethodList)
            {
                UdfInfo udf = new UdfInfo();

                udf.Name = udfNode.Attributes["Name"].Value;
                if (udfNode.Attributes["BllAccess"] != null)
                {
                    udf.BllAccess = Convert.ToBoolean(udfNode.Attributes["BllAccess"].Value);
                }
                if (udfNode.Attributes["DalAccess"] != null)
                {
                    udf.DalAccess = Convert.ToBoolean(udfNode.Attributes["DalAccess"].Value);
                }
                udf.Comment = udfNode.SelectSingleNode("Comment").Value;
                udf.SqlQuery = udfNode.SelectSingleNode("Sql").SelectSingleNode("Query").InnerText;

                XmlNodeList propertyNodeList = udfNode.SelectNodes("Property");
                foreach (XmlNode propertyNode in propertyNodeList)
                {
                    udf.ColumnList.Add(TierModelHelper.ParseColumn(this, propertyNode));
                }

                TierModel.DeleteMethodList.Add(udf);
            }
        }
        private void Validate()
        {
            #region Rule 1 - ListItemModel must not have blob fields
            foreach (ListItem listItem in TierModel.ListItemList)
            {
                foreach (ColumnInfo column in listItem.ColumnList)
                {
                    if (column.CSharpColumn.Type == CSharpTypeEnum.BLOB)
                    {
                        throw new InvalidDataException(string.Format("{0} ListItemModel must not have blob fields", listItem.ClassName));
                    }
                }
            }
            #endregion Rule 1 - ListItemModel must not have blob fields

            #region Rule 2 - Declarations with the same Short/Full Type is not allowed
            foreach (Declaration declaration in TierModel.DeclarationList)
            {
                foreach (Declaration declaration2 in TierModel.DeclarationList)
                {
                    if (ReferenceEquals(declaration, declaration2))
                    {
                        continue;
                    }

                    if (declaration.ShortType == declaration2.ShortType)
                    {
                        throw new InvalidDataException(string.Format("Declarations with the same name {0} is not allowed ListItemModel must not have blob fields", declaration.ShortType));
                    }
                    if (declaration.FullType == declaration2.FullType)
                    {
                        throw new InvalidDataException(string.Format("Declarations with the same name {0} is not allowed ListItemModel must not have blob fields", declaration.FullType));
                    }
                }
            }
            #endregion Rule 2 - Declarations with the same Short Type is not allowed

            #region Rule 3 - Include type is not in the Path
            foreach (Include include in TierModel.IncludeList)
            {
                if (include.Item == null)
                {
                    throw new InvalidDataException(string.Format("Include type {0} is not in the Path \"{1}\"", include.Type, include.Path));
                }
            }
            #endregion Rule 3 - Include type is not in the Path
        }
        private bool TryGetParentFromPath(string xmlModelPath, out TierModelBuilder parentTierModelBuilder)
        {
            parentTierModelBuilder = null;
            if (this.parentTierModelBuilder != null)
            {
                if (String.Compare(this.parentTierModelBuilder.TierModel.ModelPath, xmlModelPath, StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    parentTierModelBuilder = this.parentTierModelBuilder;
                    return true;
                }
                return this.parentTierModelBuilder.TryGetParentFromPath(xmlModelPath, out parentTierModelBuilder);
            }
            return false;
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions