Chapter 14. Generation

Table of Contents
Code Generation
Advanced Code Generation
Documentation Generation

UML wouldn't be worth all the sophisticated work if all it came down to was pretty vector graphics. When analyzing and designing a software system, your final goal will be to generate well-implemented code.

Poseidon for UML provides a very powerful and flexible code generation framework, based on a template mechanism. It is currently used to generate a variety of code types including Java and HTML, but it is flexible enough to generate any kind of programming language, or other output, such as XML.

Code Generation

Java code generation is usually based on the classes of a model and other information displayed in the respective Class Diagrams. Additionally, Poseidon can generate setter and getter methods for the fields of each class.

By default, associations between classes in UML are bi-directional; that is, associations allow navigation between classes in both directions. For the common object-oriented programming languages, these need to be transformed into separate uni-directional associations. If one of these is set, the other should be set accordingly. The code for managing bidirectional as well as unidirectional associations is also generated automatically.

Generation Settings

Code and documentation generation are both invoked from the Generation menu.

Figure 14-1. Generation menu

Select the type of generation you would like from the Generation menu and a dialog will appear. Here you can select or deselect model elements from the tree, specify an output and a template folder, and indicate if the destination folder should be cleared. Poseidon can remember your selection of model elements if you enable the checkbox titled, 'Remember current node selection'.

Note that the output and template folders are saved by project and language. This means that output of Java generation can be placed in one folder, and Perl generation from the same project can be placed in another folder. These folder preferences will be saved to the current project, but another project will not recognize these preferences and must have its own preferences set. This is to avoid accidentally overwriting the output from a previous project.

Figure 14-2. Code Generation dialog and settings - Java

You'll find the generated java files in the specified output folder, sorted by packages.

Reverse Engineering

Software engineers often run into the problem of having to re-engineer an existing project for which only code and no models are available. This is where reverse-engineering comes into play; a tool analyzes the existing code and auto-generates a model and a set of Class diagrams for it.

Poseidon for UML can do this for Java programs, where source code is available and is in a state where it can be compiled without errors. With the corresponding JAR Import function (available only in the Professional and Enterprise editions), it even works with JAR files of compiled Java classes.

To launch this process, go to the Import Files menu and direct the file chooser to the sources' root package. It will then analyze this as well as all sub-packages. The outcome is a model containing the corresponding packages, all the classes, their complete interface, their associations, as well as one Class Diagram for each package. Note that the path that you select here will be automatically adopted by the generation dialog. The next time you open the code generation dialog, this path will be displayed as output folder by default.

If the imported file uses classes that are part of the JDK, these classes will be created in the model as required, so you may see some apparently empty classes in the package java in your model. This is of no concern and is done solely to have a smaller model. But these classes are necessary to have a consistent project. All classes that the imported files use must be present in the model.

Additionally, you can give an import classpath. This is necessary to make the model complete if a file references classes that are not imported themselves. Here you can specify one or more jar files, each entry separated by a colon. If you want to import files that make use of foo.jar, anotherfoo.jar and stillanotherfoo.jar, then it should look similar to this:

folder/subfolder/foo.jar:anotherfolder/anotherfoo.jar:stillanotherfoo.jar

Figure 14-3. Import Files dialog.

Classes that are needed to make the model complete but are not present in the package structure are created on demand. If you give an import classpath but the imported file does not use any classes from it, then no additional classes will show up in your model.

Roundtrip Engineering

Generating code and reverse engineering that same code still does not make round-trip engineering. Reverse-engineering generates a new model from existing code, but it does not by itself reconnect the existing code to an existing model. This feature is only available in the Professional Edition, which contains the RoundTrip UML/Java Plug-in. It is one of the most recommended and highly sophisticated features provided by Poseidon for UML.

Generate a UML model from your existing code, change the model, re-generate the code, change the code and so on. All generated Java code files are watched, so that changes you have made with an external editor are imported into Poseidon's model of your project. Use your favorite source code editor to edit method bodies, add or remove methods and member variables. Poseidon keeps track of all changes, and all your project data is in one place - in Poseidon.

Please note that the round-trip plug-in is primarily an import tool; it imports changes in the source code for you and updates the model as necessary. Automatic code generation in the background is not yet implemented, but will be in one of the next minor releases.

To use this feature:

  1. Create or load a model in Poseidon

  2. Set the interval after which Poseidon checks for file modifications

    Figure 14-4. Select file check interval.

  3. Generate the code (the generation window will automatically pop up if you load a model)

  4. Use your preferred editor to modify the code (especially the method bodies), modify identifier names, add or remove methods and/or variables

  5. Save the file in your editor

And the changes will appear in Poseidon!

Some words on how to handle accessor methods:

You should unset the check box Generate accessor methods after you have generated accessors once. Otherwise, they would be generated again, and would clutter up your classes. The preferred way to create set/get methods is by adding them in an attribute's Properties tab, and by checking Create accessor methods for new attributes in the dialog Edit-Settings.

Figure 14-5. Java code generation - settings.

In the code generation settings dialog, you have the ability to specify an additional classpath for compilation.

You might temporarily have non-compiling source code that you do not want to import into Poseidon right away. For these instances, you can temporarily disable the automatic import with the button next to the Import sources button. It will turn to red, showing that automatic round-trip is disabled.

By clicking it again, it will turn back to green, designating that round-trip is enabled again.

When the round-trip plug-in is running and you have imported files, Poseidon asks if you would like to keep these source files and the model in sync.

When you load a new model, Poseidon asks you if you want to generate the source code now or if you want to import existing source code. Choose the first alternative if the you want to ensure that the source code you have reflects the current model. Using the latter choice (import), you can synchronize the code and model even if you have changed the source code while Poseidon was not running and therefore could not keep track online of the changes you did to the source.

Note that a folder for the source code is always set in Poseidon. This may not be the one that is suitable for your new project. To change it, select 'Update' and view the contents of another folder. This way, you can make sure that after opening a project, you can either update the project with the correct source code (and select option 2), or generate fresh code if the project is the latest version (select option 1).

Fine Tuning Code Generation

There are several possibilities to fine-tune the appearance of the generated Java source code. Among them are the creation of accessor methods for attributes, the types for collection attributes, and the list of import statements in the files.

  • Accessor Methods

    From Poseidon 1.4 on, you can create accessor methods for attributes automatically. This way, you can fine-tune the code so that some attributes have accessors, some not. In previous versions of Poseidon, you could only have setters/getters for all attributes, or for none.

    In Edit - Settings, there is a check box called 'Generate accessor methods for attributes'. Check this box to have accessor methods created for every attribute that is created. If the attribute has a multiplicity of 1..1 or 0..1, two simple getAttribute() and setAttribute() methods are created. For attributes with a finite multiplicity, an array is generated, and the accessor methods include addAttribute() and setAttribute(). For an unbounded multiplicity, a Collection is generated, and the appropriate access methods like addAttribute() and removeAttribute() are produced.

    You can fill the bodies of these access methods according to your business logic. Also, you can hide the display of accessors by setting the check box 'Hide accessor methods' in Edit-Settings-View.

    Additionally, you can generate the standard accessor methods for your attributes at code generation time. These will be visible only in the generated code, not in your Poseidon project.

  • Collection Types

    Poseidon up to version 1.3.1 used the type Vector whenever an association had a multiplicity of ..*.

    From version 1.4 on, the rules are:

    1. Create an attribute of the element's type if the multiplicity is 0..1 or 1..1.

    2. Create a Collection type attribute if the multiplicity has an upper bound of *.

    3. Create an array of the element's type if the multiplicity has an upper bound that is not 1 and not * (that is, it is a number).

    In Code Generation-Settings, you can define what type of collection should be used for Collection types. The default is ArrayList, but you can enter any type (e.g., Vector ) that implements Collection. Accessor methods are programmed against Collection.

    This version of Poseidon, you are now able to distinguish between ordered, unordered and sorted attributes, and you will be able to give different kinds of implementation types such as TreeSet for unordered, ArrayList for ordered and Vector for sorted attributes.

  • Import Statements

    Import statements can be added to classes in two ways: By drawing dependencies or by entering tagged values.

    The graphical way is to draw a dependency from the class to the class or package that you want to import. An appropriate import statement will be generated: Either import package.* or import package.Class.

    The second way (that does not clutter up your diagrams) is to add a Tagged Value called JavaImportStatement to the class. Then enter a number of imports, separated with colons. Qualified names can be given in Java syntax. For example, import java.lang.reflect.* and java.io.IOException by setting the tagged value JavaImportStatement to java.lang.reflect.*:java.io.IOException.

    Above, you can see the import statement in the Tagged Values tab, and below is the resulting Java code generated by Poseidon.

  • Modifying Templates (Not available in the Community Edition)

    More advanced customizaton of the generated code is possible if you are using one of the Premium Editions. Modification of the templates that are used for code generation is possible with these editions. We cover this topic briefly in a separate chapter and more deeply in a separate document that is distributed with these editions and online under http://www.gentleware.com?redirect=codegenapi.

  • Javadoc Tags

    You may not want certain operations to be reverse engineered. Any operations with the Javadoc tag '@poseidon-generated' will be excluded from the reverse engineering process.