zoukankan      html  css  js  c++  java
  • 使用 NVelocity 解析 PowerDesigner 的cdm文件

    使用 NVelocity 解析 PowerDesigner 的cdm文件

    使用powerdesign来进行数据库设计应该是设计者的首选了,而且现在的powerdesign做得越来越好,新版的11已经开始可以把实体和需求一一对应了。powerdesign本身还能够支持数据库的创建和修改,如果oom的话也可以生成代码,并且其本身可以支持在cdm,oom,pdm格式之间的相互转换。但是在实际应用中,远远不够。因为很多程序员自己做了很多的架构和规范,powerdesign内置的单一功能的代码生成已经远远不能满足实际使用中的需求。比如想用 hibernate/NHibernate 的朋友们想直接生成 .hbm.xml 文件的话,常规方法只能够是先创建数据库,然后用hbm自己的工具反向生成代码。实际使用中,常常因为实体间多对多的关系,hbm生成的配置文件还要进行修改之后才能使用。

    本人也在实际工作中遇到了同样的问题,所以把以前的几个工具综合起来,最终采用了NVelocity(http://sourceforge.net/projects/nvelocity/)来做实际的代码转换工作,我自己编了一个对cdm文件的解释器,提供给NVelocity。然后NVelocity装入我们编写的模版文件,解释并生成代码。
    具体NVelocity模版怎么编写,大家可以参考http://jakarta.apache.org/velocity/中的user guide(英文)。另外我提供的工程中还会有一个测试用的小模版,基本的技巧都用到了,也可以作为参考。

    我export给NVelocity的入口变量是 $pdm,是一个 PDM 的实例。其中涉及到的各个类的可用成员和解释如下所示。
    其中 xxxCollection 都是一个 IList 派生的类型。

    另外,这里支持在 对象的 Comment 区域中加入如下格式的自定义配置信息

     comment line1
     comment line2
     
     comment line n
     [config]
     name1
    =value1 // 注释
     
     nameN
    =valueN // 注释 N


    从 $pdm 中可以引用到如下的对象:

    class PDM    // 系统的总入口,对应一个pdm文件的所有内容
        NamespaceCollection Namespaces    // pdm中所有的Package
        EntityCollection Entities         // pdm中所有的Entity,
        DomainCollection Domains          // pdm中所有的Domain
        DataItemCollection DataItems      // pdm中所有的DataItem
        string CreatePDMName(string name, int count)    // 为了方便生成 pdm 的重复名字生成逻辑(属性级),
                                          
    // 比如 GroupId,Gro_GroupId,Gro_GroupId1等等
        string CreateUniqueName(string name, int count) // 为了方便生成类一级的重复名字
        
    class Namespace // 对应一个 Package 
        EntityCollection Entities        // 该Package中的所有Entity
        DataItemCollection DataItems     // 该 Package中的所有 DataItem
        RelationshipCollection Relationships     // 该Package中的所有Relationship
        InheritanceCollection Inheritances  // 所有 Package 中的继承关系
        string Id           // Package 的 id
        string ObjectId     // Package 的 GUID
        string Name         // 中文名称,以下所有的 Name 都是相同含义
        string Code         // 代码名称,
        PDM Owner           // 对 PDM 的反向引用
        Comment Comment     // Comment内容中"[config]"标志之前的内容
        string GetConfigValue(string name)    // 从配置中获取name对应的value,如果不存在则返回空字符串(String.Empty)
        
    class Entity    // 实体
        AttributeCollection Attributes  // 实体中所有的字段
        Index PrimaryIndex              // 主索引
        IndexCollection Indexs          // 其他索引
        DataItemCollection DataItems    // 实体中引用到的 DataItem,应该看作字段类型而不是字段
        RelationLinkCollection Relation // 本实体需要关注的RelationLink,是经过处理了的Relationship
        RelationLinkCollection AllRelationships // 和本实体相关的所有的 Relationship
        InheritanceCollection Base  // 所有实体相关的基类继承关系
        InheritanceCollection Derives  // 所有实体相关的派生类继承关系
        bool Generated  // 是否要处理
        string Id        // 同上类
        string ObjectId 
        
    string Name 
        
    string Code 
        Namespace Owner 
        Comment Comment  
    // Comment内容中"[config]"标志之前的内容
        string GetConfigValue(string name)    // 从配置中获取name对应的value,如果不存在则返回空字符串(String.Empty)
        ArrayList GetBaseList() // 获取所有的基类实体列表
        ArrayList GetDeriveList() // 获取本实体所有的派生类实体列表
        
    class DataItem        // 数据项
        string Id         // 同上类
        string ObjectId 
        
    string Name 
        
    string Code 
        
    int Length  // 数据项的长度
        DataTypeInfo DataType // 数据的类型,比如 VA50,I 等等
        Domain Domain         // 数据类型相关的 Domain 
        Namespace Owner 
        Comment Comment 
        
    string GetConfigValue(string name)
        
    class Attribute        // Entity 的字段
        string Name
        
    string Code
        DataTypeInfo DataType    
        
    bool CodeExistInBase // 相同代码的Attribute是否存在于所属实体的基类中
        bool CodeExistInDerives // 相同代码的Attribute是否存在于所属实体的派生类中
        DataItem DataItem
        IndexCollection Indexs 
    // Attribute 参与的索引集合
        Entity Owner 
        
    string Id 
        
    string ObjectId 
        
    bool Mandatory     // 是否必须字段
        Comment Comment    // Comment内容中"[config]"标志之前的内容
        string GetConfigValue(string name) // 从配置中获取name对应的value,如果不存在则返回空字符串(String.Empty)
        
    class Relationship    // 关系
        Entity Object1    
        Entity Object2
        RelationshipEntity RelationEntity 
    // 为了方便生成中间表,特意把多对多关系的内容提到这里
                                          
    // 请使用 Pd_NameExt/Pd_NameExts 来获取中间表的字段名
        string Id 
        
    string ObjectId 
        
    string Name 
        
    string Code 
        
    string DominantRole     // 主导方,=A表示Object2要引用Object1,
                                
    // =B则反之,为""则表示都需要,已经处理在 RelationLink 中了,不需要再自行处理
        string DependentRole    // 依赖于哪一方,A表示Object1引用Object2,B反之,为""则都需要
                                
    // 同样已经处理在 RelationLink 中了,不需要自行处理
        Namespace Owner 
        Comment Comment         
    // Comment内容中"[config]"标志之前的内容
        string GetConfigValue(string name)    // 从配置中获取name对应的value,如果不存在则返回空字符串(String.Empty)

    class RelationLink    // 经过处理之后的关系,包含在 Entity.Relation 中,是单方关系
        Relationship Relationship     // 相关的Relationship
        Entity Owner  // 关系的拥有者
        Entity Entity   // 关系引用的 Entity
        string Role     // 关系的名称
        Cardinality Cardinality  // 所属Entity和本关系引用的Entity之间的对应关系 1:1,1:n等等
        Cardinality ReverseCardinality     // 本关系引用的Entity和所属Entity之间的对应关系 1:1,1:n等等
        bool IsMultiMulti   // 本关系是否多对多关系
        RelationLink Pair   // 如果是成对的关系,则指向关系的另一头
        string Pd_Name      // powerdesign生成的数据库字段名,如引用的Entity有复合主键,则应用Pd_Names
                            
    // 如果是多对多关系的话,本名字保持原始引用名,需要用生成名请参考Pd_NameExt,
        string[] Pd_Names   // 复合主键对应的名称
        string UniqueCode   // 为了方便处理而生成的实体中唯一的对象名称
        int UniqueSeed  // 生成UniqueCode和Pd_Name时候使用的count参数
        string GetConfigValue(string name)

    class RelationshipEntity // 多对多关系的中间实体
        Relationship Owner   // 所属的关系
        string Name 
        
    string Code 
        RelationLinkCollection Fields 
    // 实体包含的所有内容
        string GetConfigValue(string name) // 获取相关的relationship中的配置信息
        
    class Cardinality    // 对应关系,比如 1:n
        string Min       // 
        string Max
        
    class Index        // 索引
        AttributeCollection Attributes     // 索引包含的字段
        Entity Owner 
        
    string Id 
        
    string ObjectId 
        
    string Name 
        
    string Code 
        Comment Comment    
    // 注释
        string GetConfigValue(string name)    // 获取配置值

    class Inheritance // 继承关系描述
        Entity Parent // 继承关系中的基类实体
        EntityCollection Children // 继承关系中的派生类实体
        bool InheritAll // 是否继承基类中所有内容
        bool MutuallyExclusive // 对应pd中同名参数
        Comment Comment  // 关系的注释说明
        Namespace Owner  // 关系所属的命名空间
        string Id  // 
        string ObjectId  // 
        string Name  // 
        string Code  // 
        string GetConfigValue(string name) // 获取关系中的配置参数

    class Comment      // 注释
        string Text    // 注释的全文本,包含回车换行符
        string[] Lines // 注释的分行文本,不含回车换行符
        
    class Domain    // Domain,对应 SQL SERVER 中的 User Type 类型
        string Id 
        
    string ObjectId 
        
    string Name 
        
    string Code 
        DataTypeInfo DataType 
        
    int Length       // 数据类型的长度
        string LowValue  // 取值定义的下限
        string HighValue // 取值定义的上限
        string DefaultValue   // 默认值
        ValuePair[] ValueList // 合法值列表,类似于 enum
        Comment Comment  // 注释
        string GetConfigValue(string name)    // 获取配置值
        
    class ValuePair      // Domain 中合法值的信息,类似于enum
        string Value     // 值
        string Caption   // 值的名字
        
    class DataTypeInfo 
        
    string Type  // 把DataType中的类似 VA50 中的长度之前的类型,比如 VA
        int Length   // 数据类型的长度

    class Helper
        
    string Char(int ascii) // 把 ascii 字符变换为对应的字符
        int Ascii(string ch) // 获取字符的ascii码
        string UpCase(string text) // 大写字符串
        string LowerCase(string text) // 小写字符串
        string Trim(string text) // 消除字符串前后空白字符
        bool IsBlankString(string text) // 判断是否空白字符串
        string[] Split(string text, string splitters) // 切割字符串,splitters中所有字符作为切割标记



    目前经过改进,已经可以支持xml格式的脚本,定义请参考代码中的xsd文件,也支持visual studio 2003工程文件属性中的custom tool,只要运行一下regist.bat,就支持名字为PDMGenerator的自定义工具在编译时进行文件的转换工作。

    工程代码请到https://files.cnblogs.com/BigTall/pd-map.zip 。

    在使用中会出现 NVelocity 的bug:
    1。模版文件中的中文不能输出
    2。在 #set($var = "this is 'my \"$baby\"' lover!") 对于连续的引号中的引号处理不正确。

    -----------------
    2005-5-16 更新
        1。给所有的Entity,DataItem,Domain,Attribute,Relationship都加上配置功能
        2。修正DataType的类型从string到DataTypeInfo
        3。增加RelationshipEntity的实现
        4。修正UniqueCode的实现算法

    2005-5-31 更新
        1。加入inheritance的支持
        2。加入支持新的xml格式的脚本文件,以及支持代码库文件
        3。支持Visual Studio 2003的custom tool功能,使用PDMGenerate的名字就可以支持编译时转换
        4。增加$Helper输出符号,支持简单字符串处理功能,同时规避NVelocity已知错误
       

  • 相关阅读:
    在ubuntu中安装photoshop cs6
    技术博客链接及相关资料
    VIM中括号的自动补全与删除
    ubuntu,jdk安装成功后,点击eclipse,提示信息A Java RunTime Environment (JRE) or Java Development Kit (JDK)
    系统安装
    css实现上下左右布局
    html+css实现选项卡功能
    jsp出现错误can not find the tag directory /web-inf/tags
    数据库类型空间效率探索(二)
    数据库类型空间效率探索(一)
  • 原文地址:https://www.cnblogs.com/BigTall/p/146979.html
Copyright © 2011-2022 走看看