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已知错误
       

  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/BigTall/p/146979.html
Copyright © 2011-2022 走看看