使用 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 区域中加入如下格式的自定义配置信息

使用 NVelocity 解析 PowerDesigner 的cdm文件 comment line1
使用 NVelocity 解析 PowerDesigner 的cdm文件 comment line2
使用 NVelocity 解析 PowerDesigner 的cdm文件 使用 NVelocity 解析 PowerDesigner 的cdm文件
使用 NVelocity 解析 PowerDesigner 的cdm文件 comment line n
使用 NVelocity 解析 PowerDesigner 的cdm文件 [config]
使用 NVelocity 解析 PowerDesigner 的cdm文件 name1
=value1 // 注释
使用 NVelocity 解析 PowerDesigner 的cdm文件
 使用 NVelocity 解析 PowerDesigner 的cdm文件
使用 NVelocity 解析 PowerDesigner 的cdm文件 nameN
=valueN // 注释 N
使用 NVelocity 解析 PowerDesigner 的cdm文件


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

相关文章:

  • 2021-12-03
  • 2022-12-23
  • 2022-12-23
  • 2022-01-21
  • 2021-10-22
  • 2022-01-09
  • 2022-12-23
  • 2021-12-23
猜你喜欢
  • 2021-11-06
  • 2021-05-09
  • 2021-08-03
  • 2021-10-08
  • 2021-09-21
  • 2021-12-15
相关资源
相似解决方案