AndroMDA鳥瞰

原文見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.
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章