The following example is very simplistic but will take you through the important stages. We will model two entities with a relationship between them and will generate and examine Java classes. We assume the user's knowledge of UML and basic tools like ant.
Let's model two entities, Customer and PurchaseOrder, with one-to-many relationship:
Modelling in MagicDraw 11.5
Save the resulting XMI file into the chosen project directory. While exporting in XMI format is easy in Poseidon and MagicDraw, Rational Rose will require a plug-in.
Saving as XMI 2.1 in MagicDraw 11.5
Saving as XMI 1.1 in Rational Rose with Unisys UML Export plugin
You'll need to choose a name for your project, project's base packages and a directory where it will reside. You can either set them up as parameters in build.properties file or provide later as external parameters during transformation.
Edit build.properties file in Medea's resources directory: res.
projectName=quickstart modelFile=c:/projects/medea/model/quickstart.xml # directory where the generated project will reside projectDir=/projects/quickstart # package name that will be prepended to all packages in the model, like 'com.mycompany'; set it to void not to add anything basePackage=void # name of the subpackage where all pure classes (not having any stereotype) will reside purePackage=data
We'll apply a Java template that generates Java classes from all classes found in the model.
Stay in in the res directory. We'll execute an ant target from the build file there: build.xml.
C:\projects\medea\res>ant trans -Dtemplate=Java Buildfile: build.xml trans: [echo] Java [java] /projects/quickstart/gen/data/Customer.java [java] /projects/quickstart/gen/data/PurchaseOrder.java [java] Creates Java classes and interfaces for all classes not marked by a stereotype. BUILD SUCCESSFUL Total time: 2 seconds
Alternatively you can use the XSLT processor from the command line. In this case the template parameters must be passed as name-value pairs.
C:\projects\medea>java -jar %SAXON_HOME%\saxon8.jar model\quickstart.xml style\Java.xsl projectDir=/projects/quickstart basePackage=void purePackage=data projectName=quickstart /projects/quickstart/gen/data/Customer.java /projects/quickstart/gen/data/PurchaseOrder.java Creates Java classes and interfaces for all classes not marked by a stereotype.
Note that the template prints out names of the files it generates as well as its short documentation.
You will see two new files, in the project directory /projects/quickstart, directory for generated source files gen and package data.
Let's take a closer look at how Java.xls template transforms our entities into source files.
<xsl:for-each select="cr:classes('void', root(.))"> <xsl:variable name="className" select="cr:nameUpper(current())"/> <xsl:variable name="ends" select="cr:ends(current(), root(.))"/> <xsl:variable name="attrs" select="cr:attributes(current())"/> <xsl:variable name="visibility" select="cr:visibility(current())"/> <xsl:variable name="abstract" select="cr:abstract(current())"/> <xsl:variable name="package" select="cr:classPackage($purePackage, current(), root(.))"/> <xsl:variable name="fileName" select="cr:fileNameJava($purePackage, $className, current(), root(.))"/> <xsl:variable name="extends"> <xsl:if test="cr:extends(current(), root(.)) != ''"> extends <xsl:value-of select="cr:extends(current(), root(.))"/></xsl:if> </xsl:variable> <xsl:variable name="implements"> <xsl:choose> <xsl:when test="cr:implements(current(), root(.)) != ''"> implements <xsl:value-of select="cr:implements(current(), root(.))"/></xsl:when> </xsl:choose> </xsl:variable>
<xsl:result-document href="{$fileName}"><xsl:value-of select="$package"/>; java.util.*; <xsl:value-of select="cr:classImports($purePackage, 'void', root(.))"/> <xsl:value-of select="cr:classImports($purePackage, 'entity', root(.))"/> /** fileName=<xsl:value-of select="$fileName"/> xmi.id=<xsl:value-of select="@xmi.id"/> * <![CDATA[<!-- begin-user-doc --> * <!-- end-user-doc --> * @generated]]> */ <xsl:value-of select="concat($visibility, ' ', $abstract)"/> class <xsl:value-of select="$className"/><xsl:value-of select="$extends"/><xsl:value-of select="$implements"/> { /** * <![CDATA[<!-- begin-user-doc --> * no argument constructor * <!-- end-user-doc --> * @generated]]> */ <xsl:value-of select="$className"/>() { <xsl:for-each select="$ends"> <xsl:if test="cr:multiUpper(current()) = -1"> <xsl:value-of select="cr:endFieldName(current(), root(.))"/>Set = new HashSet(); </xsl:if> </xsl:for-each> // begin-user-code // end-user-code }
<xsl:for-each select="$attrs"> <xsl:variable name="name" select="cr:name(current())"/> <xsl:variable name="nameUpper" select="cr:nameUpper(current())"/> <xsl:variable name="dataType" select="cr:dataType(current(), root(.))"/> <xsl:variable name="initialValue" select="cr:initialValue(current())"/> /** xmi.id=<xsl:value-of select="@xmi.id"/> * @unmodifiable */ <xsl:value-of select="concat($dataType, ' ', $name)"/><xsl:if test="$initialValue != ''"> = <xsl:value-of select="$initialValue"/></xsl:if>; /** * @unmodifiable */ <xsl:value-of select="$dataType"/> get<xsl:value-of select="$nameUpper"/>() { <xsl:value-of select="$name"/>; } /** * @unmodifiable */ void set<xsl:value-of select="$nameUpper"/>(<xsl:value-of select="concat($dataType, ' ', $name)"/>) { .<xsl:value-of select="$name"/> = <xsl:value-of select="$name"/>; } </xsl:for-each>
We've covered basic steps of Medea transformations and you can now start using other templates to generate source code for application layers. You can also move on to more complex examples that use ant build targets to transform and build components and applications.