现在的位置: 首页 > 综合 > 正文

AndroMDA鸟瞰

2013年08月30日 ⁄ 综合 ⁄ 共 10547字 ⁄ 字号 评论关闭

原文见AndroMDA官方网

  

系统概况
AndroMDA是一种代码生成工具,输入UML模型,产生源代码。通过使用一系列的模版文件(可以自定义),AndroMDA可以把UML模型产生任何程序语言的源代码。缺省的模版文件将产生Java代码(J2EE代码)。
 
在AndroMDA系统中,使用两种主要的组件:
 
AndroMDA代码生成引擎。
Apache项目构建和管理系统Maven
 
AndroMDA代码生成器实际上是个普通的代码生成引擎。这个引擎是个包含代码模块的平台,这些代码模块称为cartridge,由这些代码模块来负责具体的代码生成。AndroMDA模块是一个包含源代码模版文件和jar文件形式的Java帮助类(称为Metafacade)的集合。现在已经有一些模块了,你可以把这些模块放到引擎下,来产生代码。这些模块可以产生针对于不同流行开源框架的Java代码(例如Spring,Hibernate,J2EE)。当然引擎还支持其它模块。你可以自己编写模块(至少在理论上),从UML模型产生各种代码。
 
Maven实际上是个可选组件。AndroMDA引擎可以直接从命令行,IDE,或者构建脚本(例如Ant)调用。然而,Maven插件的存在大大简化了使用AndroMDA的过程。如果你不是尽力把AndroMDA整合到已经存在的项目中,那么强力推荐使用Maven来调用AndroMDA。这是一种获得AndroMDA服务的正常途径。
 
项目开发周期
以下是一个典型的AndroMDA项目的开发过程(Java)。
1. 使用命令maven andromdapp:generate创建一个新项目目录(这个命令调用了maven的app generator插件);
2. 配置这个项目来满足你的需要;
3. 使用MagicDraw来编辑<projectDir>/mda/src/uml/<projectName>Model.xmi文件,这个文件就是我们应用的模型;
4. 在你的项目根目录下,调用以下任何一个命令来产生代码:
 maven mda 从模型(重新)产生代码
 maven install从模型(重新)产生代码,包含数据库的schema文件,接着构建所有的源模块
 maven create-schema 假如你正在使用AndroMDA来产生你的持久层(例如Hibernate或者Spring),这个命令将在数据库中安装SQL DDL。这个命令会假设你已经创建了DDL文件(使用maven install)
5 在<projectDir>/core/src/java目录下,处理一下需要手动编写的代码;
6 编译和测试你的代码;
7 假如你的项目变化了,重新定义UML模型,重新从第三步开始;
 
创建新项目
要创建一个项目,首先把命令行的目录切换到要创建项目的父目录,执行命令maven andromdapp:generate,当被问到使用一个名称(没有任何空格)来作为项目ID时,你输入的名称将作为项目的名称。例如假如在/myProjects目录下,你产生一个项目,它的ID是myDemo,那么你项目的根目录将是/myProjects/myDemo
 
项目目录结构
通过maven app generation 插件产生的项目目录结构如下:
<projectDir>/mda/src
这个目录存放UML模型文件。
<projectDir>/mda/conf
这个目录存放AndroMDA引擎配置文件。
<projectDir>/core/target
这个目录是代码生成器存放大部分代码的地方,SQL Schema文件也存放在这里。Java源文件存放在src/子目录下,你可以学习这些代码,但是你不能修改它们,因为在下次重新生成代码时,这些文件会被覆盖。
<projectDir>/core/src
这个目录存放需要手动修改的代码,这个目录中的文件在以后的代码生成中不会被覆盖。
 
AndroMDA配置
AndroMDA最后是由andromda.xml中的配置信息来驱动的。假如使用maven app generator插件产生的项目,这个文件在<projectDir>/mda/conf/目录下,这个文件包含UML模型文件的名字和不同的AndroMDA模块的配置。(这些配置在namespaces中互相隔离)。
假如使用maven app generator插件产生的项目,andromda.xml文件中的许多配置值实际上都由Maven的构建属性来代理。
<projectDir>project.properties包含Maven属性将被传给andromda.xml,这其中包含例如JDBC配置信息,数据库方言等。
<projectDir>build.properties包含Maven属性。
 
创建你的UML模型
理论上,AndroMDA可以使用任何UML建模工具产生的uml文件作为生成代码的起点,这些UML模型应该符合xmi文件格式。
 
为了节省你的工作量,强力推荐使用MagicDraw。
 
AndroMDA代码生成是由UML版型来驱动的。AndroMDA引擎在解析你的UML模型时,首先按照版型来寻找类,如果它发现它可以识别的版型,适当的模块就被调用来为这个类产生代码,什么类型的版型可以被识别取决于AndorMDA使用的模块。
 
在MDA中,一个主要的概念是PIM(Platform Independent Model)。许多UML工具被设计来产生Java代码,因此它们在定义模型时,使用Java数据类型来作为缺省类型,这破环了PIM概念。UMLMDA期望UML模型包含通用的数据类型(尤其是UML数据类型)。
 
为了简化建模(确保适当的UML数据类型和版型可以被使用)AndroMDA UML Profile已经被开发出来了,它能被当作你模型的一部分。这个Profile文件被命名为 andromda-profile-XXX.xml.zip (XXX是你使用AndroMDA的版本号)。这个profile包含所有的UML数据类型,版型和AndroMDA的所有模块。任何一个新的UML模型都应该首先把这个文件导入到你的项目中去(如果使用MagicDraw,可以通过菜单File_Use Profile/Module来导入)。
 
假如你的项目是通过Maven app generation插件产生的,预先产生的项目模型文件< projectDir >/mda/src/uml/< projectName >Model.xmi 已经包含了这个profile了。.
这个profile文件可以在 AndroMDA < sourceDir >/etc/profile/target 的子目录下找到。 通常,使用MagicDraw 打开一个UML文件,它将让你指定这个文件的位置。从 AndroMDA原目录下,复制这个文件到MagicDraw's profile 目录下 ( /Program Files/Magic Draw UML/profiles on a Windows XP installation) ,可以使MagicDraw 在本地找到这个profile文件。
 
AndroMDA如何产生代码
接下来介绍通过AndroMDA 引擎产生代码的过程。
 
项目需要的所有模块都被引擎导入。
接下来,引擎解析UML模型的xmi文件,创建模型的对象树,这个对象树将被引擎和模块使用。除了对象树之外,辅助类(称为Metafacades)被创建来简化模块的工作。
引擎转换对象树,查找它可以识别版型的类。
对于每个类,相应的模块将被用来产生代码。模型中的每个类可能产生多个源代码文件:对每个类模块中的多个模板可能用来产生代码;同时对每个类多个模块可能被用来产生代码。模块中的缺省模板可能被使用,或者自定义的模板被使用,这完全取决于你的配置。
对于模型中的每个类,第四步将被重复。
Loading the Cartridges to use
当AndroMDA引擎开始工作时,它首先导入和激活它将要使用的模块。对于每一个将被使用的模块,模块的jar文件必须:
 
在AndroMDA引擎的Java CLASSPATH中
在andromda.xml 配置文件中,通过引用它的命名空间被激活。
如果使用Maven插件,那么把模块放到引擎的 CLASSPATH中,修改 < projectDir >/mda/project.xml 文件,在<dependencies> 部分增加对模块的 <dependency>。
如果使用Maven插件, andromda.xml配置文件在< projectDir >/mda/conf 目录下。这个文件包含一个或者多个 <namespace>标签来激活模块。
 
导入 UML 模型
就像有一个标准的对象模型来解析XML文件(DOM)和这个DOM API的Java实现(例如Apache's Xerces), 也有个标准的对象模型来解析存贮在UML模型中的元数据。这个标准的解析UML元数据对象模型称为Meta Object Facility (MOF). Java对这个API的一个实现是Netbeans' MDR (MetaData Repository).AndroMDA引擎使用Netbeans MDR来解析UML模型。
 
The act of generating code from the UML model requires some computation not easily handled by the simple scripting capabilities found in the template engine used by AndroMDA. Things such as traversing the MDR looking for relationships among classes, testing for certain conditions in the model, formulating identifier names and package names based on attributes found in the UML model - these all require computation handled easier in Java code. To simplify the source code templates, the Facade design pattern is used to create helper classes that shield the complexities of the MDR from the template. These helper classes are called Metafacades (for meta data facades). Each cartridge used by the AndroMDA engine usually contains its own set of Metafacades to aid in platform specific code generation. It is the engine's responsibility to instantiate these Metafacades for use by the source code templates.
 
Matching Stereotypes to Cartridges
初始化之后, AndroMDA引擎解析UML模型,寻找特定版型的类.当它找到一个它可以识别的版型(或者更准确的说,是cartridge可以识别的版型),适当的cartridge(s)会被调用来产生代码.
 
cartridge实际上是个JAR文件.在这个JAR文件中有一个文件/META-INF/andromda/cartridge.xml. 这个文件被称为Cartridge Descriptor. 在Cartridge Descriptor中, there are <template> tags that specify the code generation templates available from the Cartridge. Inside each <template> tag is a <modelElements> tag. This <modelElements> node will contain one or more <modelElement> nodes. Each <modelElement> is used to specify (among other things) the stereotype the template maps to. This specification is done in one of two ways:
 
直接用<modelElement>元素的stereotype属性. The value of the stereotype attribute specifies the stereotype the template maps to.
间接地用<type>元素. The <type> node specifies the name of the Metafacade class the template uses. The Metafacade's definition, in turn, contains a definition of the stereotype the Metafacade maps to. The Metafacade's definition is found in the Metafacade Descriptor - a file in the cartridge .JAR file named /META-INF/andromda-metafacades.xml . The Metafacade Descriptor contains <metafacade> tags for each metafacade used by the cartridge. Each <metafacade> tag in turn contains a <stereotype> tag which defines the name of the stereotype the metafacade maps to.
Generating code from templates
一旦AndroMDA引擎从UML模型中识别出一个类并且和相应的cartridge匹配, 适当的templates会被调用来产生代码.
 
缺省情况下, AndroMDA使用Velocity template引擎来产生代码.当然也可以使用其它的template引擎,但是事实上, Velocity已经做了很多工作.
To see all of the templates available from a particular cartridge, examine the contents of the cartridge's Cartridge Descriptor file ( /META-INF/andromda/cartridge.xml) . This file can be found in one of two places:
 
inside of the cartridge .JAR file itself
if it is part of the default AndroMDA source distribution, in the /src/META-INF/andromda sub-directory of the cartridge's source directory ( < androMDASourceDir >/cartridges/< nameOfCartridge > )
Each template available for use in the cartridge is defined in a <template> node inside the Cartridge Descriptor. The <template> node contains several pieces of important information:
 
path属性指定template文件在cartridge .jar文件中的完整路径
The outlet attribute specifies (indirectly) the sub-directory where the source file will be written to. An outlet is a conceptual name assigned to a sub-directory. It is actually the name of a property found in the cartridge's namespace in the andromda.xml configuration file. For example, an outlet named config-files would mean there is a namespace property named config-files in andromda.xml that specifies the sub-directory where all configuration files are to be written to.
overwrite属性指定template在生成代码时是否会覆盖以前生成的代码. 一般的,需要手动修改的代码这个属性设置为false and will have a different outlet than code that does not require hand modification.
<modelElements>标签定义了template使用的Metafacade. The variable attribute of the <modelElements> tag defines the name of the instance variable to be used by the template. That template variable will be an instance of the specified Metafacade.
The <modelElements> tag of a <template> definition contains a <modelElement> tag, which may in turn contain a <type> tag. The <type> tag specifies the Metafacade class that the template will use. The <type> tag may optionally contain <property> tags. These <property> tags are used for conditional code generation. If a value is specified for a property, that property must match that value for template code to be saved to disk. If the <property> tag does not contain a value, then that property simply must be defined. The property might be a namespace property defined in the andromda.xml config file (to allow for the code generation to be defined at configuration time). The property may instead be a property set by the template after it has run. This allows the template itself to determine if code should be generated at run-time.
For more information on how cartridges work in general, see the cartridge index page
 
自定义代码生成
有两种方法来自定义代码生成过程.
 
Override a template from a pre-existing cartridge with a custom version
Customize the entire cartridge, re-compiling the .JAR file
Write your own cartridge from scratch.
 
Overriding a cartridge's default template(s)
The simplest way to customize code generation is to slightly modify or simply re-write one or two templates in an existing cartridge. Assuming a particular cartridge does mostly what you are looking for, but you need to change or extend its functionality, you can instruct the AndroMDA engine to use your template rather than the one from the cartridge's .JAR file.
 
locate the original template file you wish to modify. These files can be found in the /templates sub-directory of the cartridge's .JAR file. If you have the AndroMDA source distribution installed on your machine, you can also find them in the /src/templates sub-directory of the of the cartridge's source directory ( < androMDASourceDir >/cartridges/< nameOfCartridge > ).
Copy the desired files to your project directory. If your project conforms to the standard project structure using the Maven plug-ins, the best place to put your copy is in the /mda/src directory of your project (such as < projectDir >/mda/src/customTemplates /). Since you may override templates from more than one cartridge, it is also a good idea to further segregate each cartridge into its own sub-directory. Finally, it is important you honor the template structure found in the cartridge. So, to override the hibernate.hbm.xml.vsl template for version 3, place a copy of that file in the sub-directory < projectDir >mda/src/customTemplates/andromda-hibernate/templates/hibernate3 .
In the cartridge's <namespace> entry in the andromda.xml configuration file, specify a mergeLocation property. For our example Hibernate template overwrite, we would make the following addition in the andromda.xml file:
<namespace name="hibernate">
   ...
   <properties>
      ...
      <property name= "mergeLocation">${maven.src.dir}/customTemplates/andromda-hibernate </property>
      ...
   </properties>
   ...
</namespace>When you specify a mergeLocation property, the AndroMDA engine will first look in your mergeLocation directory when looking for a particular template file. If it does not find it, it will fall back on the cartridge's .JAR file.
See Overriding cartridge resources at overriding cartridge resources for more details.
 
自定义已存在的cartridges
AndroMDA标准的cartridges可以被修改和扩展 if you need more control than a simple template override can provide. The source directory for a cartridge comes with the AndroMDA source distribution. The cartridge's root directory is < androMDASourceDir >/cartridges/< nameOfCartridge > . All the source files are located under that directory. From the cartridge root directory, the command maven install will re-build and re-package the cartridge.
 
从头创建cartridges
完整的cartridges也能被开发.cartridge开发最困难的方面是可能需要自定义Metafacades.令人感到欣慰的是AndroMDA可以被用来开发metafacades.你可以用MagicDraw来为你的metafacade建模,接下来让AndroMDA产生metafacade代码e.
 
 
 
 
【上篇】
【下篇】

抱歉!评论已关闭.