Sunteți pe pagina 1din 11

A Birds Eye view of AndroMDA

By Joel Kozikowski

The purpose of this document is to give a high level view of the entire AndroMDA
system so you can quickly get up to speed in using it. It is intended to be used
by an experienced developer (but new to AndroMDA) as a road map to find their
way around all of the components. It does not go into detail on any one aspect of
the system. Instead, it identifies common how does that work type questions,
and then points you to material for further study. A basic understanding of UML is
assumed. If you are completely new to UML, you may want to try one of the
numerous books on the subject before tackling AndroMDA. A good crash
course on UML can be found here:
http://bdn.borland.com/article/0,1410,31863,00.html

System overview
AndroMDA is a code generation tool that takes a UML model as input and
generates source code as output. Using a series of template files (which you can
customize if you wish), AndroMDA can produce source code from a UML model
in any programming language. Default templates exist to generate Java code
(and in particular J2EE code).
There are two primary components used in the AndroMDA system:
1. The AndroMDA code generation engine.
2. Apaches Maven project builder and management system.
The AndroMDA code generator is actually a generic code generation engine. The
engine is a platform that hosts code modules (called cartridges) that do the
actual code generation. An AndroMDA cartridge is a collection of source code
template files and Java helper classes (called Metafacades) packaged into a
.JAR file. There are a variety of pre-existing cartridges that you can plug in to
the engine to generate code a particular way. The pre-existing cartridges all
generate Java source code for various popular Open Source libraries (such as
Spring, Hibernate, and J2EE). The engine is not limited to these however. You
can write your own cartridges, and (at least in theory) generate code from UML
for any programming language.
An excellent explanation/demonstration of AndroMDAs capabilities can be found
in the HowTo guide explaining how to model using the Spring Cartridge. There,
you can see examples of a UML model, and the resulting Java source code (very
valuable to study). For more details, see http://www.andromda.org/andromdaspring-cartridge/howto1.html

Maven is actually an optional component. The AndroMDA engine could be


called directly from the command line, from within an IDE, or from a build script
(such as from within Ant). However, a series of Maven plug-ins already exist to
greatly simplify the process of using AndroMDA. Unless you are trying to
integrate AndroMDA into a pre-existing project, using Maven is highly
recommended. It is the normal way of accessing AndroMDA services.
If you are unfamiliar with Maven, learning it first (at least at the conceptual level)
is highly recommended. A good overview article of what Maven is and what it is
capable of can be found here: http://www.devx.com/java/Article/17204
For a complete list of articles you can use to familiarize yourself with Maven, see
http://maven.apache.org/reference/articles.html
For instructions on how to install the necessary components to get AndroMDA up
and running see http://www.andromda.org/starting.html

Project development cycle


The following is a typical AndroMDA projects development cycle (for Java).
Details for each step follow this section.
1. Create a new project directory using the command maven
andromdapp:generate (which calls a maven plug-in known as the
maven app generator plug-in).
2. Configure the generated project to fit your specific needs
3. Use MagicDraw to edit the file
<projectDir>/mda/src/uml/<projectName>Model.xmi. This file is where
you save your UML model.
4. Generate code by issuing one of the following commands from your
projects root directory:
a. maven mda (re)generates source code from the model
b. maven install (re)generates source code, including the database
schema files, then builds all source modules.
c. maven create-schema installs the SQL DDL to your database if
you are using AndroMDA to generate your persistence layer (such
as with Hibernate and/or Spring). This command assumes the DDL
file has already been created (using maven install)
5. Hand code any methods requiring manual implementation in the source
files found in <projectDir>/core/src/java.
6. Compile and test your code
7. As your project evolves, make refinements first to the UML model by restarting the process from step 3 above.
A complete list of Maven goals for your project that you may want to use for
step #4 above can be found in the file <projectDir>/readme.txt (which is
created by the app generator).

Creating a new project


To create a new project, first change to the desired PARENT directory of your
soon to be created project directory, and issue the maven
andromdapp:generate command. When asked for a project ID use a short
name (without any spaces) that will represent the sub-directorys name. For
example, if in the \myProjects directory you generate a project with the ID
myDemo, your projects root directory will be /myProjects/myDemo.
For more information, see
http://team.andromda.org/docs/starting.html#My_first_AndroMDA_project
as well as
http://www.andromda.org/maven-andromdapp-plugin/index.html

Project Directory Structure


The most significant sub-directories in the project structure created by the Maven
app generation plug-in are as follows:
<projectDir>/mda/src
Where the UML model file is located.
<projectDir>/mda/conf
Where the AndroMDA engine configuration file is located.
<projectDir>/core/target
Where the code generator places most of the resulting files. The SQL schema
files are found in this directory. Java source files are found in the src/ subdirectory. You may view this code for study, but do not make any modifications to
it, as it will be overwritten on subsequent runs of the code generator.
<projectDir>/core/src
Source files that require manual implementation go here. Files in this directory
will NOT be overwritten on subsequent runs of the code generator.
For a complete description of project sub-directories, see the file
<projectDir>/readme.txt

AndroMDA configuration
The AndroMDA engine is ultimately driven by the configuration information found
in the file andromda.xml. If using a project generated by the Maven app
generator plug-in, this file is located in the <projectDir>/mda/conf sub-directory.

This file contains, among other things, the name of the UML model file to be used
by the engine, as well as configuration settings for the various AndroMDA
Cartridges used by your project (these settings are segregated from each other
in sections called namespaces).
For general information about the configuration information found in
andromda.xml, see http://www.andromda.org/configuration.html
For information about cartridge specific configuration options, first go to the
AndroMDA Cartridge page (http://www.andromda.org/andromdacartridges/index.html), select the desired cartridge from the Available Cartridges
menu on the left, then select the Namespace option under the Documentation
menu.
If you used the Maven app generator (and subsequently use Maven to actually
build your project), many of the configuration values found in andromda.xml are
actually delegated up to Maven build properties.
The file <projectDir>project.properties contains Maven properties that are
passed down to andromda.xml (and other parts of the build scripts) that are
project wide settings (regardless of which developer is currently building the
system, and which version is being built). These include things such as JDBC
configuration settings, which database dialect you want Hibernate to use (e.g.
Hypersonic, mySQL, etc.).
The file <projectDir>build.properties contains Maven properties that are
specific to the version being built.
Maven build properties can also be overridden on a workstation (and/or
developer) by workstation basis. For more information about Maven build
properties in general, see http://maven.apache.org/reference/properties.html

Creating your UML Model


In theory, AndroMDA can use the output of any UML modeling tool as its starting
point for code generation, provided the UML modeling tool can output to the
Object Management Groups industry standard XML Metadata Interchange (XMI)
file format (see http://www.omg.org/technology/documents/formal/xmi.htm ).
In practice, you will save yourself a LOT of headache if you simply use
MagicDraw as your UML tool (a free community edition is available at
http://www.magicdraw.com). All of the developers on the AndroMDA team use
MagicDraw. All of the testing of the Cartridges is based on MagicDraw files. And
frankly, there seem to be some assumptions made in the AndroMDA code that
are based on MagicDraw (and its capabilities). For all intents and purposes,
AndroMDA only works with MagicDraw.

AndroMDA code generation is driven by UML stereotypes. In a nutshell, the


engine traverses your UML model, looking for classes tagged with a specific
stereotype. If it finds a stereotype it recognizes, the appropriate cartridge is
called to generate code for that class. Which stereotypes are recognized depend
on the AndroMDA Cartridge(s) being used. Stereotype recognition is case
sensitive.
A key concept in the Model Driven Architecture methodology is the idea of the
developer first creating a Platform Independent Model (the PIM) of the system.
By Platform Independent, that means a model devoid of any platform specific
items (such as a classs attribute defined using a Java data type like
java.lang.String). Many UML tools are designed to generate Java code, so they
use Java data types by default when modeling (violating the PIM concept).
AndroMDA expects UML models to contain generic data types (specifically, UML
data types).
To simplify modeling (insuring the proper UML data types and stereotypes are
used), the AndroMDA UML Profile has been developed which can (and really
must) be included as part of your model. The profile is named andromdaprofile-XXX.xml.zip (where XXX is the version of AndroMDA you are using).
The profile contains all of the UML data types, stereotypes, and tagged values
that are known to work with AndroMDA and all of its Cartridges. Any new UML
model should begin by importing this file into your project (with MagicDraw, this is
done by using the File_Use Profile/Module menu option). See
http://www.andromda.org/faq.html#profile-import for more information.
If your project was generated using the Maven app generation plug-in, the precreated project model file <projectDir>/mda/src/uml/<projectName>Model.xmi
will already have included this profile.
The profile file itself can be found in the AndroMDA source distribution in the
<sourceDir>/etc/profile/target sub-directory. Frequently, when opening a UML
file with MagicDraw, it will ask for you to specify the location of this file. Copying
the profile file from the AndroMDA source dir to MagicDraws profile directory
(/Program Files/Magic Draw UML/profiles on a Windows XP installation) will
allow MagicDraw to find the profile file on its own.
For general information on AndroMDA modeling, see
http://team.andromda.org/docs/modeling.html
For a tutorial on creating models that work with the Spring cartridge (the most
popular AndroMDA plug-in), see http://www.andromda.org/andromda-springcartridge/howto.html

For information about cartridge specific stereotypes and tagged values, first go to
the AndroMDA Cartridge page (http://www.andromda.org/andromdacartridges/index.html), select the desired cartridge from the Available Cartridges
menu on the left, and then select the Profile option on the left hand menu.
For more information on the Model Driven Architecture methodology in general,
see http://www.omg.org/mda/

How AndroMDA generates code


The following describes the process used by the AndroMDA engine to generate
code. Details of each step follow this section.
1. All of the cartridges that the project requires are loaded by the engine.
2. The engine then parses the UML models XMI file, creating an object tree
of the model for use by the engine and the cartridge templates. In addition
to the main object tree, helper classes (called Metafacades) are
created to simplify the work of the cartridge templates.
3. The engine traverses the object tree, looking for classes tagged with
stereotypes it recognizes
4. For each class located, the appropriate cartridge template(s) are identified
and dispatched to generate code. Multiple source code files may be
generated for each tagged class in the model: more than one template in
a given cartridge may generate code for any given class; more than one
cartridge may generate code for any given class. The default templates for
a cartridge may be used, or a customized version may be used,
depending on your configuration.
5. Step #4 is repeated for every class in the model.

Loading the Cartridges to use


When the AndroMDA engine is started, it first loads and activates the cartridges it
will use. For a particular cartridge to be used, the cartridge .JAR file must:
1. Be in the Java CLASSPATH of the AndroMDA engine
2. Be activated by referencing its namespace in the andromda.xml
configuration file.
To put the cartridge in the CLASSPATH of the engine if using the Maven plug-in,
modify the <projectDir>/mda/project.xml file and add a <dependency> for the
cartridge to the <dependencies> section. For more information, see Using a
cartridge at http://team.andromda.org/docs/andromda-cartridges/index.html
If using the Maven plug-in, the andromda.xml configuration file is located in the
<projectDir>/mda/conf directory. This file contains one or more <namespace>
tags to activate the cartridge(s).
For more information on configuring a cartridges namespace, see
http://team.andromda.org/docs/configuration.html#namespace

Loading the UML model


Just as there is a standardized object model to represent a parsed XML file (The
Document Object Model) and popular Java implementations of the DOM API
(such as Apaches Xerces), so is there a standardized object model for the
metadata stored in a UML model. The standardized object model that represents
UML metadata is called The Meta Object Facility (the MOF see
http://www.omg.org/mof). One Java implementation of this API is Netbeans
MDR (MetaData Repository see http://mdr.netbeans.org/). The AndroMDA
engine uses the Netbeans MDR to load the UML model into memory.
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 engines responsibility to instantiate these
Metafacades for use by the source code templates.
For more information about Metafacades, see
http://www.andromda.org/andromda-metafacades/index.html

Matching Stereotypes to Cartridges


After initializing, the AndroMDA engine traverses the UML model, looking for
classes marked with a specific stereotype. When it finds a stereotype it
recognizes (or more specifically, a stereotype that a cartridge is known to
recognize), the appropriate cartridge(s) is called to generate the code.
A cartridge is actually a .JAR file. In this .JAR file there is (amongst other things),
a file named /META-INF/andromda/cartridge.xml. This file is called the
Cartridge Descriptor. Inside the 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:

1. directly via an attribute of the <modelElement> tag named stereotype.


The value of the stereotype attribute specifies the stereotype the
template maps to.
2. indirectly via a <type>inner node. The <type> node specifies the
name of the Metafacade class the template uses. The Metafacades
definition, in turn, contains a definition of the stereotype the Metafacade
maps to. The Metafacades definition is found in the Metafacade
Descriptor a file in the cartridge .JAR file named /METAINF/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.
For more information on the Cartridge Descriptor, see The Cartridge Descriptor
at http://team.andromda.org/docs/andromda-cartridges/index.html.
For more information on the Metafacade Descriptor, see
http://www.andromda.org/andromda-metafacades/configuring.html

Generating code from templates


Once the AndroMDA engine has identified a class from the UML model and
matched it to a cartridge, the appropriate templates are called to generate code.
By default, AndroMDA uses the Apache Software Foundations Velocity
template engine to generate code. Mechanisms exist to allow other template
engines to be used, but in practice, Velocity does most of the work. If you are
unfamiliar with Velocity, see http://jakarta.apache.org/velocity/docs/userguide.html#What%20is%20Velocity? for a good overview.
To see all of the templates available from a particular cartridge, examine the
contents of the cartridges Cartridge Descriptor file (/METAINF/andromda/cartridge.xml). This file can be found in one of two places:
1. inside of the cartridge .JAR file itself
2. if it is part of the default AndroMDA source distribution, in the /src/METAINF/andromda sub-directory of the cartridges 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:
1. The path attribute specifies the complete path (inside of the cartridge
.JAR file) to the template file

2. 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
cartridges 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 subdirectory where all configuration files are to be written to.
3. The overwrite attribute specifies whether or not the template will
overwrite pre-existing source files on subsequent runs of the code
generator. In general, source code that requires hand modification will
have the overwrite attribute set to false and will have a different outlet
than code that does not require hand modification.
4. The <modelElements> tag defines the Metafacade used by the
template. 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
http://www.andromda.org/andromda-cartridges/index.html
The Velocity Template Language reference guide can be found here
http://jakarta.apache.org/velocity/docs/vtl-reference-guide.html
For more details on the Velocity template engine in general, see
http://jakarta.apache.org/velocity/index.html

Customizing code generation


There are several ways to customize the code generation process.
1. Override a template from a pre-existing cartridge with a custom version
2. Customize the entire cartridge, re-compiling the .JAR file
3. Write your own cartridge from scratch.

Overriding a cartridges default template(s)


The simplest way to customize code generation is to slightly modify or simply rewrite 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 cartridges .JAR file.
1. locate the original template file you wish to modify. These files can be
found in the /templates sub-directory of the cartridges .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 cartridges
source directory
(<androMDASourceDir>/cartridges/<nameOfCartridge>).
2. 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/andromdahibernate/templates/hibernate3.
3. In the cartridges <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:
<namespacename=hibernate>

<properties>

<propertyname="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 cartridges .JAR file.
See Overriding cartridge resources at http://www.andromda.org/andromdacartridges/index.html for more details.

Customizing existing cartridges


The standard cartridges that come with AndroMDA can be modified and
extended 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 cartridges 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.
For more details on developing cartridges, see
http://www.andromda.org/andromda-cartridges/developing.html

Writing cartridges from scratch


Entire cartridges can also be developed. The most difficult aspect of cartridge
development is the probable need for custom Metafacades. The good news is
that AndroMDA can be used to develop metafacades. You can model your
metafacade with MagicDraw, then have AndroMDA generate the metafacade
code.
For more details on developing metafacades, see
http://www.andromda.org/andromda-metafacades/developing.html

S-ar putea să vă placă și