一种基于MDA的分布式对象模型框架代码生成方法
2014-03-25张森邓磊吴健朱明洁
张森, 邓磊, 吴健, 朱明洁
(1.西北工业大学 计算机学院, 陕西 西安 710072; 2.中航工业西安飞机设计研究所, 陕西 西安 710089)
分布式对象模型是分布式技术和面向对象技术结合的产物,它是对分布式系统的业务处理进行抽象来构造出的一组相关模型。这些模型通过接口来实现客户程序和分布式中间件的相互通信,具有可重用性、平台无关性等优点。分布式对象模型框架代码是分布式对象模型在具体平台上的体现,提供具体平台上的分布式对象发布订阅和远程方法访问等服务。文献[1]描述了一种基于模板的代码自动生成方法,该方法有效解决了人工编写分布式对象模型框架代码工作量大、错误率高的问题,大大提高了软件开发的速度和质量。然而代码生成的规则都是在程序中硬编码实现的,可扩展性和可维护性较差。
MDA(model driven architecture,模型驱动架构)是由OMG(object management group,对象管理组织)于2001年提出来的一种软件开发框架。该框架以模型为核心,并将模型贯穿于整个软件开发过程之中。它根据软件开发的不同阶段将模型分为PIM(platform independent model,平台无关模型)、PSM(platform specific model ,平台相关模型)和代码3种。在MDA中,软件开发过程由对软件系统的建模行为驱动[2],首先要建立能够描述系统全部业务的、与具体平台无关的PIM。然后制定PIM到具体平台的PSM的模型转换规则,并通过这些规则将PIM转换成一个或多个PSM。最后根据具体平台的代码生成技术将PSM转换成相应平台的程序代码。本文结合一种典型的分布式对象模型框架需求,改进了现有的基于模板技术的代码生成技术,提出了一种基于MDA的代码生成方法,有效提高了分布式对象模型框架代码生成系统的可扩展性和可维护性。
1 基于模板技术的模型框架代码生成
分布式对象模型框架代码生成系统的作用是将用户编写的分布式对象模型描述VDL文件,通过解析,生成分布式模型框架代码。该系统主要分为3个部分:模型解析、代码生成和驱动引擎,如图1所示。
模型解析的功能是以动态链接库的形式提供一组API,以供驱动引擎调用。此API实现了对用户给出的分布式对象模型描述VDL文件的解析,并将解析结果组织、记录在一个中间表示数据结构(IR)中。该部分包括词法分析和语法分析模块。词法分析模块从VDL文件中分离出VDL的单词。语法分析是通过YACC(yet another compiler compiler)工具生成的VDL语法分析器来完成对VDL语法分析处理的。语法分析的过程会依照语义的描述来完成中间表示数据的记录。语法分析过程中会通过2条途径报告VDL语法错误。一条途径是当输入VDL文件不符合VDL文法规定时,直接报告错误。此类错误一旦出现,就退出编译过程。另一条途径是在语义处理过程中检查并报告与上下文有关的错误。
图1 基于模板技术的代码生成框架
代码生成的任务是以动态链接库的形式提供一组API,以供驱动引擎调用,并生成适配于分布式中间件的对象模型框架代码。该框架代码主要包括2部分。一部分是CORBA(TAO)的IDL代码,IDL代码最终交由TAO的IDL编译器进行编译生成Skeleton和Stub的C++代码,这部分代码主要完成VDO远程方法访问的功能。另一部分是C++代码,此部分代码会与分布式中间件协同,以实现分布式对象VDO的状态发布/订阅功能。
由于分布式中间件的协同代码具有很多的共性,不同的VDL对应的协同代码的差异性信息在VDL文件中均已定义,故采取模板的技术对分布式中间件协同代码进行生成。
系统首先将同一类分布式对象的中间件协同代码做成模板的形式,其中不变部分以源代码的方式直接给出;可变部分以标签的形式给出。其次,根据具体的分布式对象的信息来生成各个标签的内容。最后,替换模板中的所有标签,并输出替换标签后的模板,即生成中间件协同代码。
驱动引擎的任务是读取用户输入的分布式对象模型VDL描述文件,调用模型解析部分的API,生成中间表示数据结构IR。然后扫描该IR,并调用代码生成部分提供的API,自动生成分布式对象模型代码。
由上述生成方案可以看出,代码生成规则都是事先在程序中通过硬编码设定的,一旦生成规则发生改变或者生成另一种平台的模型框架代码,则开发人员将重新修改原来的程序代码,可扩展性和可维护性较差。
2 基于MDA的分布式对象模型框架代码生成方法
本文结合分布式对象模型框架需求和MDA思想,提出了一种新的代码生成方法。主要包括:PIM建立、PIM到PSM的转换和PSM到代码的生成3个部分。PIM建立部分主要完成分布式对象PIM的建立,然后将其描述成XML文件。PIM到PSM的转换部分以PIM描述XML文件为输入,结合PIM和PSM元模型之间的转换规则来转换成PSM,并将其描述为XML文件。PSM到代码的生成部分以PSM描述XML文件为输入,采用XSLT技术来完成代码的生成。系统架构如图2所示。
图2 基于MDA的代码生成架构图
2.1 分布式对象PIM
分布式对象PIM的描述有2种方式:①VDL描述。VDL是一种专门为描述分布式对象而设计的语言,该语言类似于IDL语言,具有很高的灵活性。②Ecore描述。Ecore是EMF(eclipse model framework,Eclipse模型框架)的元元模型,是UML的一个子集。开发人员可以使用EMF中的Ecore树形样本编辑器快速方便地建立分布式对象Ecore模型。然而,尽管它们均能详细地描述分布式系统的对象信息,但是却无法作为MDA中PIM到PSM映射转换的输入。为此,本文采用XML文件作为系统的标准描述文件。对于VDL描述文件,则需要进行词法分析和语法分析,将解析出的模型信息表述为XML文件。而对于Ecore描述,则可以使用标准XMI将Ecore表示的模型信息串行化成XML文件。以localclass对象模型Person为例,该对象具有2个属性:①公有的name属性,其类型为string。②只读的age属性,其类型为short。其XML描述为:
xmlns:xmi=http://www.omg.org/XMI xmlns:vdl="platform:/resource/VdlModelRefactoring/MetaModel/Vdl.ecore" name="Person">
2.2 分布式对象PSM
分布式对象模型代码主要实现分布式对象的远程方法访问和发布订阅功能。远程方法访问是借助CORBA来实现的,系统首先要生成IDL代码,然后经过IDL编译器编译形成Skeleton和Stub的C++代码。因此需要将PIM转换成CORBA平台的IDL-PSM模型。而发布订阅功能是单独用C++语言设计实现的,所以还需要转换成C++平台的C++-PSM模型。为了PSM模型到代码的生成,所以PSM模型也采用XML进行描述。还以localclass对象模型Person为例,该对象会映射到一个C++平台的class模型。该模型主要包含了Person模型对应的属性的get/set方法。根据Person模型属性的修饰符不同,其转换方法也不同。对于公有属性,转换后class模型含有get/set方法。对于只读属性,转换后只有get方法,而没有set方法。其XML描述为:
xmlns:xmi=http://www.omg.org/XMI xmlns:cpsm="platform:/resource/VdlModelRefactoring/MetaModel/CPsm.ecore" name="Person">
2.3 分布式对象PIM到PSM的转换
模型转换是MDA中的关键部分。MDA中PIM到PSM的转换是基于转换规则来进行转换的。为了使转换规则的定义标准化,OMG开发了一组编写转换规则定义的标准语言QVT(query/view/transformation)。而ATL(atlas transformation language,Atlas转换语言)是ATLAS研究组开发出来的一种模型转换语言。该语言是EMF下的一种语言,符合OMG的QVT标准,可以将一组模型转换成一种或多种目标模型。ATL的模型转换规则定义在转换模型所在层的上一层。如果转换的模型处于M1模型层,那么模型转换规则定义在M2元模型层。所以开发人员首先要设计PIM和PSM的元模型,然后再制定相应的转换规则,才能将输入的PIM自动转换成PSM。
以localclass对象模型到C++平台的class模型的转换为例,首先要定义localclass对象模型和C++平台的class模型的元模型。元模型如图3所示:
图3 localclass元模型和class元模型
然后定义localclass元模型到class元模型转换的规则,如下所示:
rule Root {
from
s : VDL!localclass
to
t : CPSM!class(
name <-s.name,
func <-
s.attr->select(e|e.modifier=′public′)->collect(e|thisModule.functionset(e)),
func <- s.attr->collect(e|thisModule.functionget(e))
)
}
lazy rule functionset {
from
c : VDL!attribute
to
m : CPSM!function(
rettype <-′void′,
name <-′set_′+c.name,
param <-
thisModule.parameter(c)
)
}
lazy rule functionget {
from
c : VDL!attribute
to
m: CPSM!function(
rettype <- c.type,
name <-′get_′+c.name
)
}
lazy rule parameter {
from
s : VDL!attribute
to
t : CPSM!parameter(
type <- s.type,
name <- s.name
)
}
其中,Root规则段定义了PIM元模型中locaclass模型到PSM元模型中class模型的映射。首先将localclass模型中的name属性原封不动地转成class模型的name属性,然后将localclass模型中的attr属性转换成function模型。对于公有的attr才能转换成set方法的function模型。functionset和functionget规则段定义了PIM元模型中attribute模型到PSM元模型中function模型的映射。functionset规则产生set方法,functionget规则产生get方法。对于set方法function模型中的返回值类型rettype为void类型,方法名name由字符串"set_"和属性名拼接而成。参数param由规则parameter来产生。而对于get方法function模型中的返回值类型rettype为属性的类型,方法名name由字符串"get_"和属性名拼接而成。paramter规则段定义了PIM元模型中attribute模型到PSM元模型中parameter模型的映射。该规则将attribute模型的属性type和name对应映射到了parameter模型的属性type和name。
2.4 分布式对象PSM到代码的生成
分布式对象模型代码的生成主要完成从PSM模型到代码的生成。该部分以PSM模型描述XML文件为输入,并从中解析出模型信息,然后结合代码模板生成具体平台的模型代码。由于分布式对象模型代码具有很大的共性,并可以将其编写成XSLT模板,并且代码的动态部分信息是由XML文件描述的,所以代码生成可以采用XSLT/XML技术来生成模型代码。
XSLT代表eXtensible Stylesheet
Language:Transformations(扩展样式表语言:转换),是一种用来将一个XML文档的结构进行转换的语言[3]。它可以将XML文档转换为其他基于文本格式的文档,也可以转换成另一种XML文档。以Person模型为例,其xslt转换代码为:
encoding="ISO-8859-1"?>
xmlns:cpsm="platform:/resource/VdlMod elRefactoring/MetaModel/CPsm.ecore" xmlns:xsl="http://www.w3.org/1999/XSL/ Transform"> #include disable-output-escaping="yes">< ext>string disable-output-escaping="yes">> ext> using namespace std; class select="/cpsm:class/@name"/> { public: ); };
其中,
3 结 论
本系统架构已经在虚拟试验分布式对象框架代码生成系统中得到应用。采用该系统架构,开发人员可以方便地修改模型、转换规则和XSLT模板来调整模型代码的生成,极大地缩短了开发人员的工作量,有效提升了系统开发的效率,提高了可扩展性、可维护性和可移植性。
参考文献:
[1] 肖寒. J2EE平台下代码自动生成技术研究[J]. 电脑知识与技术,2009,5(20):5421-5422,5434
Xiao Han. Study of Code Generation Technology Based on J2EE Platform[J]. Computer Knowledge and Technology, 2009,5(20):5421-5422,5434 (in Chinese)
[2] Anneke Kleppe, Jos Warmer, Wim Bast. 解析MDA[M]. 鲍志云,译. 北京: 人民邮电出版社,2004
Anneke Kleppe, Jos Warmer, Wim Bast. MDA Analysis[M]. Bao Zhiyun, Translator. Beijing: Posts& Telecom Press, 2004 (in Chinese)
[3] Michael Kay. XSLT程序员参考手册[M]. 朱冬东,吕俊辉,李玫,译. 北京: 机械工业出社,2002
Michael Kay. XSLT Programmer′s Reference[M]. Zhu Dongdong, Lü Junhui, Li Mei, Translator. Beijing: China Machine Press,2002 (in Chinese)
[4] 曾一,许林,黄兴砚,王翠钦. 一种结合MDA的高阶模型转换方法[J]. 计算机应用研究, 2012,29(12):4584-4588
Zeng Yi, Xu Lin, Huang Xingyan, Wang Cuiqin. Method of Higher-Order Model Transformation Combined with MDA[J]. Application Research of Computers, 2012,29(12):4584-4588 (in Chinese)
[5] 赵远东,王云华. 基于J2EE平台的MDA模型驱动架构技术[J]. 电脑知识与技术, 2010,6(25):7017-7018,7043
Zhao Yuandong,Wang Yunhua. Model Driven Architecture Based on J2EE System[J]. Computer Knowledge and Technology, 2010,6(25):7017-7018,7043 (in Chinese)
[6] 於良伟,袁泉,霍剑青,王晓蒲. 基于XML和XSLT的模型驱动构架[J]. 计算机工程, 2010,36(6):49-51
Yu Liangwei,Yuan Quan, Huo Jianqing, Wang Xiaopu. Model Driven Architecture Based on XML and XSLT[J]. Computer Engineering, 2010,36(6):49-51 (in Chinese)
[7] 杨美荣,史建锋,李明星. 基于MDA的代码生成器设计与实现[J]. 计算机工程, 2009,35(12):47-49,53
Yang Meirong, Shi Jianfeng, Li Mingxing. Design and Implementation of Code Generator Based on MDA[J]. Computer Engineering, 2009,35(12):47-49,53 (in Chinese)
[8] Mhamed Rahmouni, Samir Mbarki. MDA-Based ATL Transformation to Generate MVC 2 Web Models[J]. International Journal of Computer Science & Information Technology, 2011,3(4):57-70