About the Java 5 transformation feature in Rational Software Architect
IBM Rational Software Architect includes several predefined transformations, some of which transform a UML model into source code. Version 7 introduced a transformation that includes Java 5 features. Like its predecessor, this transformation can be extended. This article walks you through the steps necessary to create a simple example that demonstrates the core capabilities of this functionality.
As with most features in Rational Software Architect, to extend it you use the normal Eclipse extension mechanisms, creating a plug-in and implementing specific extension points. This article does not address general plug-in development (see Resources for recommended articles and examples). Instead, it focuses on just enough plug-in development skills as necessary to create and test a transformation extension.
Figure 1. Overall transformation structure
When a transformation is invoked, it begins with the UML model, package, class, interface, or enumeration element, depending on what was selected when the transformation was invoked. The transformation will operate on the selected element (or the entire model if no element is selected) and all of the elements that it contains. This provides many opportunities for a transformation extension author to tap into and contribute to the overall transformation. An extension targets just one part of the overall transformation. You will find a complete list of targets in the appendix (see Downloads).
For this simple example, you will define a simple class-level extension that gets invoked each time that a transformation is ready to transform a UML class element into a Java source file. This extension will do nothing more than look for any keywords defined for this class and use them to add a new Javadoc tag associated with the class in the source code.
You will follow these steps:
- Create a new plug-in project for your transformation extension. This project may be combined with other extensions; however, to make this example simple, you will create a new project from scratch.
- Add a set of required plug-in dependencies. These plug-ins define the extension point that you are implementing and provide the APIs that you will need to invoke your extension.
- Define the extension point in the plug-in descriptor, which identifies the transformation that you are extending and the point within it that you want to make a contribution.
- Provide a Java implementation of the class rule that will be invoked each time that the transformation encounters the element type that you indicate.
- Test the transformation by invoking a runtime workbench and running a UML-to-Java 5 transformation.
Step 1. Create and configure a new plug-in project
The transformation extension begins with a new plug-in project:
- Select the menu File > New > Project, and select Plug-in Project from the list of project types, and click Next.
- On the first page of the New Plug-In Project wizard, enter a valid project name. The Eclipse convention for plug-ins is to use a URI domain like the one shown in Figure 2.
Figure 2. New Plug-in Project wizard
- On the second page (Figure 3), update the default Plug-in Name field; the remaining defaults are acceptable.
Figure 3. New Plug-in Project wizard Properties page
On the final page, it is not necessary to select a plug-in template, because there are no templates for transformation extensions, just for new complete transformations.
Figure 4. New Plug-in Project wizard final page
- Uncheck the template option and click the Finish button (Figure 4.)
Figure 4. New Plug-in Project wizard final page When the wizard finishes, it creates a new plug-in project and opens the Overview page of the project descriptor (Figure 5).
Figure 5. New project structure
Step 2. Add required plug-in dependencies
The next step is to add a few plug-ins as dependencies. These plug-ins contain the extension point definitions for the implementation plus APIs that will be used in the implementation of the extension.
- Switch to the Dependencies tab (at the bottom of this editor), and add the following plug-ins as dependencies:
- com.ibm.xtools.modeler
- com.ibm.xtools.transform.core
- com.ibm.xtools.transform.uml2.java5
- org.eclipse.jdt.core
- Verify that the plug-ins were added. The resulting list should look similar to Figure 6.
Figure 6. Dependent plug-ins
Step 3. Define and implement the extension
The next step is to declare that you are going to provide an implementation to one or more extension points.
Switch to the Extensions tab, and click the Add button to add a new extension. You will then see the dialog box that Figure 7 shows. Enter this extension point: com.ibm.xtools.transform.core.transformationExtensions. When you find it, select it and click Finish.
Figure 7. New Extension dialog
- There is more information that needs to be supplied in the extension point definition. These values can be entered through the user interface on the Extension tab page. However, most people find it easier to just edit the raw XML of the plugin.xml file. This file is created the first time that an extension is defined (before that, it was not necessary, so it was not created by the New Project wizard)
- Switch to the plugin.xml tab, and you will see the XML source file, which you can edit.
- For this example, add the detail shown in Listing 1 to the extension point.
Listing 1. Extension declaration
<extension point="com.ibm.xtools.transform.core.transformationExtensions" >
<TransformationExtension version="1.0.0"
name="My UML to Java5 Transformation Extensions"
enabled="true"
targetTransformation=
"com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform"
id="com.ibm.rsa.java5.extension.sample.transformationExtensions.id">
<RuleDefinition
name="Javadoc Keyword Rule"
class="com.ibm.rsa.java5.extension.sample.ClassKeywordJavadocRule"
id="com.ibm.rsa.java5.extension.sample.ClassKeywordJavadocRule.id"/>
<ExtendTransform
targetTransform=
"com.ibm.xtools.transform.uml2.java5.internal.ClassTransform">
<AddRule id="com.ibm.rsa.java5.extension.sample.ClassKeywordJavadocRule.id"/>
</ExtendTransform>
</TransformationExtension>
</extension>
|
The body of an extension element is defined by the extension point provider. In this case, that is the Rational Software Architect Core Transformation component. This extension expects TransformationExtension child elements (one for each type of transformation to extend). Each one of these elements defines which transformation is being extended.
- For this simple example, specify a targetTransformation with the ID of
com.ibm.xtools.transform.uml2.java5.internal.UML2JavaTransform. - Supply appropriate values for the ID: version number, name, and the Boolean value for enabled.
Each transformation extension defines, as child elements. a rule definition that specifies a class that implements a rule interface. This class does most of the work of contributing to the transformation. It is defined as a separate element, because it is possible for a single class to contribute to multiple parts of a transformation (for example, class, property, and operation).
After all of the rules have been defined, they are matched with the part of the
transformation that they will contribute to with ExtendTransform elements. This
element defines the part of the transformation that a rule will contribute to. For
this, you want to contribute to the extension each time a new class is being
transformed, and the value of the targetTransform should be
com.ibm.xtools.transform.uml2.java5.internal.ClassTransform.
The appendix that you can download from this article page contains a complete
listing of target transformation ID (see Resources).
Given that more than one rule can contribute to any particular part of a transformation, they are collected here as child elements of the ExtendTransform element. You have only one rule defined in your project as you are using it here.
Note:
The ID of the rule in the RuleDefinition element must match
that of the AddRule element.
Step 4. Provide a Java implementation of the class rule
When you are finished editing this file, save it. You should notice a small error icon in the left margin, next to the line in the plugin.xml file, that specifies the implementation class. This indicates that the class could not be found in the project.
- You can double-click the icon and select the prompt to Create a new class. This invokes the New Class wizard, which you can use it to create the class file. You can also manually create the class with the File > New menu. Whichever way you prefer to create Java classes in Eclipse, create one in the designated package and with the correct name.
- To make the implementation as easy as possible, extend the Rational Software
Architect transformation framework class
com.ibm.xtools.transform.uml2.imple.internal.java5.ClassRule. With this class as a super class, there are only three methods that should be overridden. -
canAccept -
createTarget -
isSourceConsumed
Each of these methods accepts a transformation context object that can be queried
to gain access to the source and target objects. With this information, you can
decide whether you want to process this particular class
(canAccept) or whether further processing of this class
should stop (isSourceConsumed). If this extension
accepts the context, then the createTarget() method is
used to make the actual contribution to the transformation.
- For this simple transformation extension, return False in the isSourceConsumed method to indicate that further processing should continue, and that the extension does not mean that all of the work of the transformation of this particular element was completed.
- Indicate that you can accept a particular class when there is at least one
keyword defined. If there are no keywords, there is nothing for you to do, so
indicate that you are not interested. You can access the source UML class
through the transformation context that is passed in as an argument. The
getSource()method on the context should return a reference to a UML class, since we specified in the extension point that we were interested only in Class transforms. - Type the source object to a UML class, and then get the keyword list from it.
If the list is empty, then return
False.
If there are keywords, then you can expect the
createTarget() method to be called. This is where you
are expected to make your contribution to the transformation.
Listing 2. Java rule class implementation
package com.ibm.rsa.java5.extension.sample;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.uml2.uml.Class;
import com.ibm.xtools.transform.core.ITransformContext;
import com.ibm.xtools.transform.uml2.impl.internal.java5.ClassRule;
public class ClassKeywordJavadocRule extends ClassRule {
protected Object createTarget(ITransformContext context) {
TypeDeclaration target = (TypeDeclaration) context.getTarget();
Javadoc javadoc = target.getJavadoc();
List tags = javadoc.tags();
AST ast = target.getAST();
Class umlCls = (Class) context.getSource();
EList keywords = umlCls.getKeywords();
for (Iterator iter = keywords.iterator(); iter.hasNext();) {
String keyword = (String) iter.next();
TagElement tag = ast.newTagElement();
tag.setTagName("@" + keyword);
tags.add(tag);
}
return target;
}
public boolean isSourceConsumed(ITransformContext context) {
return false;
}
public boolean canAccept(ITransformContext context) {
Class umlCls = (Class) context.getSource();
return umlCls.getKeywords().size()>0;
}
} |
The first contribution that developers usually make when implementing the createTarget() method is to access the source and target objects for this part of the transformation. Because you have defined this extension to be invoked when the transformation is processing a UML class, you can safely type the target object to an Abstract Syntax Tree (AST) TypeDeclaration object. The Eclipse Java Developer Tools (JDT) project provides all of the APIs for manipulating Java source code. The AST is the object model that parses source code for Eclipse. When this method is invoked, a new TypeDeclaration object is created by the transformation framework. It should be noted that if there is any existing Java source code, this is not made available in the target object. Merging of the newly generated code with any existing code happens after all of the model elements have been transformed.
Discussing the AST in detail is beyond the scope of this article, other than to say that when the extension needs to add new elements to the generated source code, that is done by calling methods on the AST objects. For this simple example, you will just add a new Javadoc tag to the class definition's Javadoc comments. Javadoc is an object type in the AST, and is obtained from the TypeDeclaration object.
- From the Javadoc object, get the list of tags that make up this Javadoc. You can add (or remove) tags from the generated source code.
- To determine which tag to add, access the source object from the transformation context and cast it to a UML class. From this object, you get the list of keywords (similar to how you did that when implementing the canAccept() method).
- With this list, iterate over the keywords and create a new TagElement for each keyword.
- Set the name of the tag to the value of the keyword (prefaced with the @ symbol).
- Finally, add the new tag to the list of tags for the class Javadocs.
The method must return a target object. Usually, it is the same object that was passed in as a target. This completes the creation and implementation of your transformation extension.
Now that you have defined and implemented the extension, it's time to test it. You do this by creating a new debug configuration that opens a new runtime workbench.
- To create this configuration, select Run > Debug from the main menu.
- In the dialog, create a new Eclipse application configuration and name it appropriately.
Tip:
You can change the location of the workspace, and it is usually
a good idea to choose a new location to avoid inadvertently affecting an existing
workspace.
- Leave the remaining default settings as they are (Figure 8).
Figure 8. New debug configuration
- When you have finished editing the configuration, click Debug to start a new instance of Eclipse. This new instance will have the transformation extension that you just created installed as a plug-in.
- To test the extension, you need to create a new Java project and a UML model in that project within the new instance of the Eclipse shell.
- Within the UML model, create a test package and class, and include a few attributes or operations. The resulting workspace should look something like that of Figure 9.
Figure 9. Test project in runtime workbench
Next, you need to add a keyword to the class, because your extension will work only on a class that has a keyword defined.
- Select the class and then the Stereotypes sub-tab in the Properties view.
- Enter text in the Keywords field (Figure 10).
Figure 10. Setting the keywords property
With the test project and model set, you now need to create a new transformation configuration that defines the main parameters of the UML-to-Java 5 transformation.
- Select File > New from the main menu.
- Under the Transformations category, select Transformation Configuration, and then click Next (Figure 11.).
Figure 11. Creating a new transformation configuration
- There are many transformation types that are included with Rational Software Architect. Choose the UML-to-Java 5 transformation (Figure 12), because that is the one for the extension that you created.
- Give it an appropriate name. This will be used as the file name of the configuration in the Java project.
Figure 12. Selecting the transformation
- The first things that you need to specify in a transformation configuration are the source model and the target project.
- Be sure to select the UML model, because it appears under the Models virtual folder, and not the actual .emx file.
- Select the target by choosing the Java project itself (Figure 13).
Figure 13. Setting the source and targets for the transformation
- Optionally, you can turn off the automatic generation of get and set methods on the next configuration setup page (Figure 14), and experiment with the other options on the remaining pages. However, for this simple test, accepting the defaults clicking Finish should work.
Figure 14. Transformation configuration options
Now that the configuration has been created, it can be invoked. For the life of this project, it does not have to be created again.
- To invoke the transformation and your extension to it, select the class in the diagram, invoke the popup menu, and select Transform > My UML to Java5 Transform Test.tc > UML to Java V5.0 (Figure 15).
Figure 15. Invoking the transformation
Figure 16 shows the results of the transformation. You can see that a Javadoc tag that matches the value of the keyword that you added is included in the Javadocs of the class.
Figure 16. Results of generated code
This simple example of a UML-to-Java 5 extension was meant just to demonstrate the basic mechanism for creating extensions. Real-life extensions would most likely be more intelligent, using information in the model and making more interesting changes to the generated code or even adding companion artifacts to the source code. The important point to take away from this article is that creating extensions to existing transforms makes a lot of sense when you want to leverage all of the existing work and just need to make small changes or contributions to the output. Having one common transformation that generates the code, as well as other artifacts (deployment descriptors or companion files, for example) also simplifies the development process, because you need to run only one transformation rather than many.
| Description | Name | Size | Download method |
|---|---|---|---|
| List of transformation targets | UML_to_Java5_transformation_targets.pdf | 32KB | HTTP |
Information about download methods
Learn
-
An introduction to the AST, the base framework for many powerful tools of the Eclipse IDE, including refactoring, Quick Fix and Quick Assist.
-
Exploring Eclipse's ASTParser, an article that teaches how to use the parser to generate code.
-
"Developing Eclipse plug-ins,"
an article by David Gallardo about how to create, debug, and install your plug-in
(developerWorks, December 2002).
-
Eclipse Corner Articles by Eclipse
developers on the Eclipse.org Web site.
-
"Eclipse Plugins Exposed, Part 1: A First Glimpse"
(onJava.com, February 2005).
-
"Building
templates with the Eclipse Plug-in Development Environment"
by Chris Aniszczyk (developerWorks, February 2007).
-
"Notes on the Eclipse Plug-in Architecture"
(Eclipse.org, July 2003).
-
"How to Internationalize your Eclipse Plug-In,"
a roadmap for writing Eclipse plug-ins destined for the international market
(Eclipse.org, August 2002).
- Read Contributing to Eclipse: Principles,
Patterns, and Plugins, a book by by Erich Gamma and Kent Beck
(Addison-Wesley Professional, October 31, 2003).
- Visit the
Rational software area on developerWorks
for technical resources and best practices for Rational Software Delivery Platform
products.
- Subscribe to the
developerWorks Rational zone newsletter.
Keep up with developerWorks Rational content. Every other week, you'll
receive updates on the latest technical resources and best practices for the
Rational Software Delivery Platform.
- Browse the
technology bookstore
for books on these and other technical topics.
Get products and technologies
- Download
a trial
version of IBM Rational Software Architect Version 7.
- Evaluate
IBM Rational Software Architect V7.0
online by taking this three-hour test drive without installing or configuring it
on your own system. This advanced model-driven development and static analysis
tool is ideal for software architects and developers who are creating
service-oriented architecture (SOA), Java™ Platform, Enterprise Edition
(J2EE), and portal applications.
- Download
IBM product evaluation versions
and get your hands on application development tools and middleware products from
DB2®, Lotus®, Rational®, Tivoli®, and
WebSphere®.
Discuss
- Participate in the
Rational
Development Tools forum.
- Join the
Rational
Unified Modeling Language (UML) forum.
- Check out
developerWorks
blogs and
get involved in the
developerWorks community.

Jim Conallen is a software engineer in IBM Software Group's Rational Model-Driven Development Strategy team, where he is actively involved in applying the Object Management Group's (OMG) Model-Driven Architecture (MDA) initiative to IBM's Rational model tooling. Jim is a frequent conference speaker and article writer. His areas of expertise include Web application development, where he developed the Web Application Extension for UML (WAE), an extension to the UML that lets developers model web-centric architectures with UML at appropriate levels of abstraction and detail. This work served as the basis for IBM Rational Rose and IBM Rational XDE Web Modeling functionality.
Comments (Undergoing maintenance)





