Copyright © 2001-2007 innoQ GmbH, Cham, Switzerland
This documentation is part of innoQ's iQgen product suite and licensed under the terms of the accompanying license agreement.
iQgen is accompanied by, or makes use of third party software. The corresponding license agreements can be found here.
Januar 2007
| Revision History | ||
|---|---|---|
| Revision 3.0.2 | Januar 2007 | innoQ |
| Revision 2.1 | March 2006 | innoQ |
| Revision 2.0 | April 2004 | innoQ |
Abstract
This is the product documentation for iQgen, innoQ's model driven software generator.
Table of Contents
List of Figures
List of Tables
First of all: Thank you for using iQgen, innoQ's model driven software generator.
We have tried to make this manual as comprehensive, understandable and useful as possible. Unfortunately errors aren't completely avoidable. Should you find one - please let us know.
After you have installed iQgen, the user guide will help you with your first steps. To provide you with some hands-on experience, many sections of this guide will refer to samples you installed as part of the iQgen distribution. The most important of these samples is Tutorial_1, which will be referred to throughout the documentation. Once you have mastered Tutorial_1 the reference at the end of this document will be a helpful companion while working with iQgen.
Enjoy.
We are very interested in your experiences with iQgen. Therefore we invite you to let us know about your suggestions, problems or praise via email. Just write to <support@innoq.com>
Please remember to include the following information in your email:
Operating System
JDK manufacturer and version
iQgen version
CASE tool manufacturer and version, XMI exporter
XMI version
The following features are new in iQgen 3.0:
MacOS 10.4+ support
iQgen Plugin for Eclipse 3.1+
JDK 1.4+ compatible
The Plugins for iQgen introduce a new infrastructure to support more and different types of models. Previous versions officially only supported UML 1.X compliant models which were stored in XMI files. As the core of iQgen now handles any type of models, other model sources can be easily processed. With the right plugin iQgen can generate from any source of information, whether this is an UML model or not. The following list contains some examples of already implemented extensions based on iQgen 3.0:
Ecore (www.eclipse.org/emf)
Mapping between Ecore and UML 1.X
Instances of Ecore models (with Dynamic EMF)
UML2 (www.eclipse.org/uml2)
Mapping between UML2 and UML 1.X
JAXB (Java XML Data Binding)
WSDL (Web-Service Description Language)
XML-DOM (XML Document Object Model)
Databases (both schema and content)
To give you the opportunity to evaluate these capabilities please download the free "plugin pack" (iQgen-plugins-1.0.zip) with some plugins for our webpage. It contains these plugins:
ecore
ecore library sample (the library sample from Ecore)
uml2
xml (for XML-DOM)
For installation instructions please read the included readme.txt.
The following features are new in iQgen 2.1:
The iQgen Eclipse integration has been updated to work with Eclipse 3, the latest version of the leading Open integrated development environment.
Previous versions of iQgen generated files whenever the source model changed. With Smart Generation, iQgen checks whether the file's contents would change when generating, and only updates the file when necessary. While generation is seldomly, if ever, a performance problem, some configuration management systems and almost all build tools mistakenly check only for the timestamp of input files, and performed unnecessary work. With Smart Generation, build and check-in/check-out times are thus significantly reduced in larger projects.
To ease support for CASE tools and other software emitting XMI, the XMI reader associated with a particular XMI generator is configurable in an external XML file.
iQgen 2.1 has been bundled as a Mac OS X application, supporting simple drag & drop installation and the native Mac OS X look & feel (i.e. the menu bar where a Mac user would expect it to be, quit, preferences and about menus in the right places, storage of user preferences in the appropriate location etc.).
The following features are new in iQgen 2.0:
Plugin for the Eclipse platform
Enhanced user interface
Hooks for model validation
Properties to control transformation settings
Improved logging for command line and Ant integration
Updated and enhanced documentation
In addition to the stand-alone user interface, iQgen is now fully integrated with the Eclipse platform. The iQgen Eclipse plugin enables you to edit templates, start the generation process, and edit the resulting artifacts - all without leaving the IDE. Combined with an Eclipse-integrated modeling tool such as TogetherEC, all of your MDA toolset can be combined in a single environment.
We have made numerous improvements to the user interface, including the ability to view stereotypes and tagged values.
Based on customer feedback, we have created hooks that allow iQgen users to validate their UML models, e.g. to check compliance to the UML profile being used. As this is a programmatic interface, there is virtually no limit to what can be checked. Validation errors can be defined to emit warnings, errors or fatal errors (the last of which will terminate the code generation process).
Not all information should be stored in the UML model; with advanced template sets, there is often a need for an easy way to provide parameters. Transformation settings are an easy-to-use solution to this problem.
Log filters that have been available in the UI only in previous versions of iQgen are now usable from both the command line and from Ant scripts that use the iQgen Ant task.
Table of Contents
Before you install iQgen please take some time and verify that your system meets the system requirements laid out in the next section. Then you should decide which distribution format best fits your needs. iQgen comes in three different flavors:
as a ZIP archive, extractable with WinZip™ and other, similar tools
as a GZIP-compressed tar archive (for Unix™ or Cygwin™ users)
as a self-extracting installation program for Windows operating systems
As a Mac OS X 10.x application compressed in .tar.gz format.
The Windows installer is the easiest way to get iQgen up and running if you are on a Windows platform. If you plan to use iQgen on both Windows and Unix boxes, you may want to use the same .zip or .tar.gz archive for both installations. The Mac OS X distribution is the easiest way to get up and running on this fine platform.
Like any other tool iQgen requires a certain execution environment. The following sections list these requirements.
You can install iQgen on any machine capable of running a Java Development Kit (JDK) version 1.3 or higher. iQgen has been successfully tested on the following platforms:
Microsoft Windows NT 4.0 with Service Pack 5
Microsoft Windows 2000 Professional
Microsoft Windows XP
SuSE Linux 7.1, 8.0, 9.0
Apple Mac OS X 10.3, 10.4
Eclipse 3.2
Before you install iQgen, you should have a working Java Development Kit (JDK) installation on your system.
Note that the Java Runtime Environment (JRE) is not sufficient, because iQgen needs to compile Java source code it generates, even if you do not use Java as your programming language.
You can get the JDK from Sun's web site at http://www.java.com/.
Start the installation process by double-clicking on the .exe file in Explorer and follow the instructions.
Extract all files from the .zip file to a directory of your choice, e.g. c:\Program Files\iQgen. You can use any location you like, just make sure that you remember to replace your installation root directory wherever we refer to it throughout the documentation. In the root directory, you will find scripts called iqgen.bat (for Windows platforms) and iqgen.sh (for Unix or Cygwin installations). The file iqgen.bat assumes, that Java was correctly installed and java.exe is part of the %PATH% variable. For iqgen.sh, modify it and set JAVA_HOME to the appropriate value, e.g. c:\jdk1.3.1.
First decide where you want to install iQgen. We assume that you choose /usr/local, but you can use anything you like - just make sure that you remember to replace your installation root directory wherever we refer to it throughout the documentation. Change to the directory you just created and extract the archive's contents using the following command:
gzip -d -c iQgen-x.x.tar.gz | tar xvf
This will create a directory called iQgen under the current directory. In the root directory, you will find a script called iqgen.sh. Edit this file and set JAVA_HOME to the appropriate value, e.g. /usr/local/jdk1.3.1
To install iQgen for Ant, just execute the local_ant_install.xml file that is located in your iQgen home directory. It will copy all necessary files to your Ant directory. Please note that for this to work, the environment variable ANT_HOME must be set.
The Eclipse plug-in is not yet a standard component of iQgen. Before installing, please download it from our website.
Then simply unpack the .zip archive into your Eclipse/plugins directory. The unpacked directory structure is shown in the figure below.
Table of Contents
This guide is designed to help you getting started with iQgen, innoQ's model driven software generator. If you have no idea what Model Driven Architecture is, we suggest you spend some time to read up on the topic on the Object Management Group's (OMG) website: http://www.omg.org/mda/ For the impatient developer, here is a short summary taken from the OMG's site:
The MDA is a new way of writing specifications and developing applications, based on a platform-independent model (PIM). A complete MDA specification consists of a definitive platform-independent base UML model, plus one or more platform-specific models (PSM) and interface definition sets, each describing how the base model is implemented on a different middleware platform. A complete MDA application consists of a definitive PIM, plus one or more PSMs and complete implementations, one on each platform that the application developer decides to support.
MDA development focuses first on the functionality and behavior of a distributed application or system, undistorted by idiosyncrasies of the technology or technologies in which it will be implemented. MDA divorces implementation details from business functions. Thus, it is not necessary to repeat the process of modeling an application or system's functionality and behavior each time a new technology (e.g., XML/SOAP) comes along. Other architectures are generally tied to a particular technology. With MDA, functionality and behavior are modeled once and only once. Mapping from a PIM through a PSM to the supported MDA platforms will be implemented by tools, easing the task of supporting new or different technologies.
To put this into context: Actually MDA is a successor to the model driven generative approach which has been around since the early nineties. In the mid-nineties, this generative approach failed partly due to the fact that code generators often had problems re-generating and merging artifacts. But that was only one reason for the artifacts of the development process to become inconsistent. The divergence of artifacts was a big problem, and still is. It has to be addressed carefully with an appropriate process.
The novelty of MDA, which makes it so powerful and promising, is the fact that there are well defined middleware standards like J2EE and CORBA. They and MDA together enable us to separate modeling concerns on the conceptual level rather than on a project or enterprise level. This means that there is a new chance for all of us to achieve long term technology independence and protection of investments. As mentioned by the OMG, tools are needed to support this process.
iQgen is one of these tools. With iQgen you can map your platform-independent model (PIM) to a platform-specific model, i.e. a model specific to a platform like .NET or J2EE.
Not surprisingly, you need to create the PIM somehow. The easiest way to do this is to use a CASE tool. Just create a model with one of the supported case tools and export it as an XMI file.
Your platform independent model is transformed to a platform specific model by means of a transformation, which is defined as a set of code generation templates.
In iQgen, there is no explicit PSM other than the code of your generated system. Conceptually, you can think of iQgen creating the PSM in a transient form. We have found this approach to work extremely well, although we consider adding model-to-model transformation to a future version of iQgen.
Once you have a PIM and at least one set of templates, you can simply hit iQgen's generate button and your application will be generated for a given platform. How well this works depends on the quality of both the PIM and the templates.
In order to successfully work with iQgen you need to understand how to specify your transformation, i.e. how to write templates. But before we delve into template creation, you should first get a better understanding of how code generation with iQgen works. This will be covered in the next section of this tutorial.
To get some hands-on experience with iQgen we recommend to run the tutorial that comes with the iQgen distribution. You will find the templates in the directory samples/getting_started/tutorial_1/templates and the XML models in XMI format in directory samples/getting_started/tutorial_1/model.
The UML profile for Tutorial 1 is extremely simple - essentially, it doesn't use any stereotypes or tagged values at all.
Tutorial 1 uses the model depicted in the figure below. It will not result in a complete application, but in the end you will have source code which can be compiled and you will have obtained a deeper knowledge of how to develop templates.
To give you an overview of the templates in Tutorial 1, here's an overview table with some short comments.
Table 2.1. Files in Tutorial 1
| Directory | File | Comment |
|---|---|---|
| ./ | build.xml | Ant script for generation |
| model | Tutorial_1.xml | XMI v1.0 model file |
| model | Tutorial_1.mdl | Rational Rose model file |
| templates | main.jsp | Model element to template mapping |
| templates | interface.jsp | Simple example that demonstrates how to generate a Java interface |
| templates | class.jsp | More complex example that generates Java class files. Uses other templates like associations, attributes, and operations |
| templates | attributes.jsp | Used by class.jsp. Generates attribute declarations, getter and setter methods. |
| templates | operations.jsp | Used by class.jsp. Generates methods. |
| templates | associations.jsp | Used by class.jsp |
| templates | build.jsp | PostProcessTemplates example |
| templates | copyright.jsp | Copyright text |
| templates | drop_and_create.jsp | Simple SQL script |
| templates | params.jsp | Utility JSP that is included by other templates. |
| templates | utilities.jsp | Utility JSP that is included by other templates. |
In order to generate the files for the Tutorial 1 model, simply start iQgen and select the tutorial's model file. Then set both the target and template directory and start the generation. You will find the generated file in the output directory you chose. The next paragraph will guide you through the process step-by-step.
When you start iQgen you should see the screen below. This is the main screen. All settings necessary for generation can be found right there. The numbers (1-10) in the figure correspond to the 10 simple steps necessary for code generation.
Just follow these steps and you will generate some sample code (for this example we suggest that you have installed iQgen under c:\iQgen):
Project Root Path. Enter your project root path here: C:\iQgen\samples\getting_started\tutorial_1
Source Model File. Here you need to set the location of the model file: C:\iQgen\samples\getting_started\tutorial_1\model\tutorial_1.xml
Target Generation Path. This is where the generated files can be found after successful generation: C:\iQgen\samples\getting_started\tutorial_1\out
Template Path. Directory containing the templates: C:\iQgen\samples\getting_started\tutorial_1\templates
Master Template. Select your master template: main.jsp
Load Model. Now that all paths and files are set, you have to load model by clicking the toolbar button.
Generate. Start the generation by clicking the toolbar button.
Output. The output window should now contain the lines shown in the screen shot.
Technically the generation is now complete. The following two steps are entirely optional.
Open Generated File. Click on the tab Generated Files and double-click on one of the files. It will be opened in the editor.
New Transformation. Finally you can create a new transformation via . Just specify a location and a file name (e.g. tutorial_1).
Done. You have successfully created your first set of artifacts from the provided model file.
The GUI is not the only way you can use iQgen. You may also generate artifacts from the command line or from an Ant build file.
XMI, like many other standards, is unfortunately not a guarantee for interoperability. Different CASE tools export to XMI differently, and this can lead to interoperability problems. iQgen tries to minimize these by streamlining the differences by means of the MetaModelFacade API. Nevertheless, iQgen allows you to access everything that your CASE tool has exported. If you need to make sure that you can change CASE tools in the future, we strongly encourage you to use the MetaModelFacade as much as possible.
iQgen uses an embedded Java Server Pages (JSP) 1.1 engine to execute your templates. If you are familiar with JSP syntax, developing templates with iQgen should be a piece of cake. However, as not everybody can be fluent in JSP, we will give a short introduction.
A JSP's content is a mixture of literals, directives, declarations, scriptlets, and actions. Sun's JSP syntax card gives an excellent overview of which syntactic elements are legal in a JSP. The following paragraphs cover the most important of these elements. If you are familiar with JSP, you may skip this section and continue with how JSP are used in iQgen.
To understand the concept of JSP a little bit better it often helps to know that each JSP is compiled into a Java class. Like any other class this class has methods and fields. Not surprisingly you can also declare methods and fields in a JSP. This is done like this:
<%! declaration; [ declaration; ]+ ... %>
I.e. if you wanted to declare a method getDate() which returns the current date, you could write:
<%! public java.util.Date getDate() { return new java.util.Date(); } %>You might have noticed that instead of simply writing Date, we used the fully qualified classname java.util.Date. Of course this is very tedious, if you have to use classnames like com.great.company.with.a.very.long.name.util.MasterUtility. No one likes to write classnames like this. Therefore, each JSP can import packages. The mechanism is exactly the same as in Java - just the syntax is different:
<%@ page import="{package.class|package.*}, ... " %>Example:
<%@ page import="java.util.*,java.net.URL" %>
Ideally you place such a page directive at the top of your page. In addition to the packages you want to import, the page directive lets you specify a class you want to extend. As mentioned before, a JSP will be compiled into a special Java class. This class may inherit some of its behavior from a superclass. To specify this superclass, you may place a page directive with an extends attribute in your page:
<%@ page extends="package.class" %>
Example:
<%@ page extends="com.innoq.generator.jsp.JspBase" %>
You probably have guessed that you cannot simply subclass any class. Contrary to ordinary JSP engines, iQgen restricts you to extend com.innoq.generator.jsp.JspBase or any of its subclasses. This ensures that certain functionalities expected from iQgen are always available in your templates. If you do not specify a class you want to extend, iQgen will automatically use com.innoq.generator.jsp.JspBase as default class.
Of course declaring methods and inheriting functionality does not get us very far. At least it does not generate any output. Therefore we want to explore means of generating...
Everything you write in a JSP that isn't marked with special tags (usually starting with <% and ending with %>) will be copied to the output of your template literally. And everything means everything - in particular this rule applies also to whitespace such as tabs, spaces, and newlines.
Expressions provide you with a way of inserting the value of objects or primitives ( int, float, boolean, ...) into the output. In the case of primitives the value is printed, in the case of an object either null is printed or the result of the toString() method. The syntax is as follows:
<%= any kind of Java expression %>
Example:
<%= new java.util.Date() %>
This prints the current date. Of course you can also use other Java expression such as the conditional ? : operator, a method invocation, or any combination of valid expressions.
<%= i>100 ? "i is greater than 100" : "i is not greater than 100" %> <%=someObject.someMethod() %>
With the means we introduced so far, we cannot use control structures like loops or embed a great deal of logic in our templates - or at least not in a reasonable way. Scriptlets offer you a way to easily embed any valid Java code, you could otherwise write in a method, in your template. Note that you cannot declare methods here.
<% code fragment of one or more lines %>
And this is how you can write a loop with a scriptlet:
<%
// this is a comment in Java code
// first scriptlet
for (int i=0; i<100; i++) { %>
Number: <%=i%>
<%
// second scriptlet
} %> In the first scriptlet the block that shall be executed 100 times is opened with a curly brace; in the second scriptlet it is closed again. In between we placed a literal ( Number:) and an expression ( <%=i>). They will both be evaluated, i.e. printed, 100 times.
Please note that this might look very practical and simple, but is actually a maintenance nightmare. Often taglibs (we will talk about them later) do a much better job at encapsulating control structures like conditional execution ( if) or repeated execution ( for, while).
JSP are capable of including other files, which are statically compiled into your template and executed as if they have always been part of your template. Syntax:
<%@ include file="relativeURL" %>
This is often very useful, if you have a lengthy import section in all your JSP or a copyright notice that always stays the same. Simply include it, where you need it. Example:
<%@ include file="copyright.txt" %> <%@ include file="imports.jsp" %>
Please note that you can include files containing literals as well as scriptlets or any other element of a valid JSP.
Of course JSP aren't executed in a vacuum. To access your environment you can use a number of implicitly declared variables. Some of them are listed in the table below.
Table 2.2. Some of the implicit objects available in a JSP template
| Name | Type | Comment |
|---|---|---|
| request | javax.servlet.ServletRequest | The request from the generator. |
| response | javax.servlet.ServletResponse | The response to the generator. Not typically used by iQgen authors. |
| pageContext | javax.servlet.jsp.PageContext | You can store objects in this context. |
| out | javax.servlet.jsp.JspWriter | The Writer the output is written with. |
As mentioned above, taglibs provide a much cleaner way of encapsulating certain tasks or logic. In order to use a taglib, you first have to register it with the page you want to use it in. This can be done with the taglib directive. Syntax:
<%@ taglib uri="taglibURI" prefix="prefix" %>
iQgen comes with a default taglib with the URI iqgen. To use a custom taglib you need to place it in the taglibs directory. The uri refers to the name of the taglib Jar file without the .jar suffix. Once you have registered the taglib, you can use it with the prefix you chose in the taglib directive:
<tagPrefix:tagName attribute="value"+... /> <tagPrefix:tagName attribute="value"+... > ... </tagPrefix:tagName>
iQgen comes with a pre-built taglib, which we will be mentioned again later.
Since JSP aren't brand new anymore there are plenty of books and online tutorials around.
iQgen uses JSP for two purposes:
the mapping of model elements to templates
the templates themselves.
As you know, a model consists of different model elements such as classes, interfaces, associations, diagrams and so forth. Usually a single model element cannot be mapped one to one to a generated file. Instead often a single model element leads to the generation of multiple files, e.g. a SQL script, a configuration file, a deployment descriptor and a couple of classes. Therefore you need to specify which files should be generated for a given model element. To allow you to specify this in a very flexible and powerful way, this is done with a special JSP - the file main.jsp - a.k.a. the master template.
There are three things you need to do, to write your own main.jsp:
Extend the class com.innoq.generator.jsp.JspMain
Implement the method public String[] getTemplates(MBase)
Implement the method public String getName()
So the most basic main.jsp looks like this:
<%@ page extends="com.innoq.generator.jsp.JspMain"
import="ru.novosoft.uml.MBase" %>
<%!
/**
* For performance reasons this array is declared as static
* final and can be reused for every invocation of getTemplates.
*/
private static final String[] TEMPLATE = {"template.jsp"};
/**
* Returns the names of the templates to execute for a specific
* model element.
*
* @param element The model element to return the template names for
* @return Array of template names for a element
*/
public String[] getTemplates(MBase element) {
return TEMPLATE;
}
/**
* Name of this modelelement-template mapping.
*/
public String getName() {
return "My first main.jsp";
}
%> This main.jsp would return the name of the template template.jsp for every model element. Of course this only makes sense in the most simple case. You cannot to generate a SQL script and a Java class file for a persistent object with a single template. Our next example shows a slightly more complex, but a lot more realistic mapping:
<%@ page extends="com.innoq.generator.jsp.JspMain"
import="ru.novosoft.uml.MBase" %>
<%!
private static final String[] PERSISTENT = {"class.jsp", "drop_and_create.jsp"};
private static final String[] INTERFACE = {"interface.jsp"};
private static final String[] DEFAULT = {"class.jsp"};
public String[] getTemplates(MBase element) {
String s = getMetaModel().getStereotype(element);
String name = getMetaModel().getName(element);
if ("Persistent".equals(s)) {
return PERSISTENT;
} else if (getMetaModel().isInterface(element)) {
return INTERFACE;
} else {
return DEFAULT;
}
}
public String getName() {
return "My second main.jsp";
}
%> Instead of always returning the same template name for every model element, we return PERSISTENT for all model elements marked with the stereotype Persistent, INTERFACE for all interfaces and DEFAULT for all other madel elements. This allows us to generate SQL scripts with the template drop_and_create.jsp and class files with class.jsp for all persistent madel elements. All other elements lead to the generation to either an interface or a class file.
Let's look how this is done in detail. In every iQgen JSP you can obtain access to the model by invoking the method getMetaModel(). This will return an object of the type com.innoq.generator.metamodel.IMetaModelFacade, which can help you inspecting the current modelelement. The three methods we use in this example are getStereotype(MBase), getName(MBase), and isInterface(MBase). Additionally the metamodel offers many more methods to obtain detailed information about the current element. All methods are covered in the API reference section.
So far we can invoke templates for and with specific model elements. Often some templates need only be invoked once per model and even without a specific model element. Such cases can be covered with the method public String[] getPostprocessTemplates(). Just overwrite this method in your main.jsp to provide the names of all templates that should be executed after all model element-specific templates have been executed:
<%@ page extends="com.innoq.generator.jsp.JspMain"
import="ru.novosoft.uml.MBase" %>
<%! [...]
private static final String[] POST = {"build.jsp"};
public String[] getPostprocessTemplates() {
return POST;
}
%> Our example always returns the name of the template build.jsp which generates an XML file that can be used as an Ant build script. Another useful application of this feature is a template for deployment descriptors.
There are several hook methods you can overwrite to control your generation process. The following sequence diagram should help you to get an overview about the calling order. MyJspMain means your JspMain specialization. The writeToFile method should be used very carefully and at the end of this method you must call super.writeToFile(filename, inoutstream).

Figure 1: JspMain Sequence
For a complete description of JspMain 's API, take a look at the API reference section page.
The second use for JSP in iQgen is to write the actual templates.
Probably the most important methods already defined in iQgen templates are getElement() and getMetaModel(). getElement() allows you to access the model element this template was invoked for. getMetaModel() grants you access to the model - just like in main.jsp. Additionally there are some other methods already defined, mainly dealing with how to compute the name for the file to generate and other path related tasks.
As an example we will take a look at a template for generating Java interfaces.
<%@ page import="ru.novosoft.uml.MBase,java.util.Collection,java.util.Iterator"
extends="com.innoq.generator.jsp.JspBase" %>
<%@ taglib uri="iqgen" prefix="iqgen" %>
<%! private String getClassname() {
return getMetaModel().getName(getElement());
}
private String getExtendsString() {
Collection superclasses = getMetaModel().getAllSuperclasses(getElement());
if (superclasses.isEmpty())
return "";
StringBuffer sb = new StringBuffer(" extends ");
for (Iterator i=superclasses.iterator(); i.hasNext();) {
sb.append(getMetaModel().getName((MBase)i.next()));
if (i.hasNext())
sb.append(", ");
}
return sb.toString();
}
public String getPrefix(char pSeparator, MBase m) {
return "com"+pSeparator+"innoq"+pSeparator+"tutorial_1"+pSeparator;
}
%>
package <%=getPath()%>;
<iqgen:import prefix="<%=getPrefix()%>" collectiontype="java.util.List"/>
/**
* Interface <%=getClassname()%>
*/
public interface <%=getClassname()%><%=getExtendsString()%> {
[...]
} This excerpt from the complete template generates the package statement, import statements, and the interface declaration complete with extend clause. In the first part we register the taglib iqgen and declare three methods. Let's look at the first of these three methods.
getClassname() is a simple helper method that returns the name of the interface. To obtain the model element this template is executed for we simply call the getElement() method. This method is automatically declared in every template. Using the metamodel, we find out the name of the particular element. In the case of an interface this is also the classname.
getExtendsString() works similar to getClassname(). Through the metamodel we obtain a collection of the interface's the superclasses. If this collection is empty, the method simply returns an empty string. Otherwise the names of all superclasses are appended to a StringBuffer which starts with extends.
getPrefix() is already declared in the superclass JspBase. In its default implementation it simply returns an empty string. In our example it is overwritten to return the package name. Note that the package separator is provided as a parameter. This is necessary, because this method is called for computing the filename, too. By overwriting getPrefix() in the given way we achieve that the method getPath() automatically returns the right package name and the generated file is written into the right directory, i.e. [OUTPUT_PATH]/com/innoq/tutorial_1/.
Which file the output is written to, is determined by the JspBase method getFilename(). By default this method is implemented like this:
public String getFilename() {
return getDirectory() + File.separator
+ getPath(File.separatorChar,
getElement())
+ File.separator + getName()
+ "." + getFileExtension();
}
getPath() in turn is implemented like this:
public String getPath(char pSeparator, MBase m) {
return getPrefix(pSeparator, m)
+ getMetaModel.getNamespaceName(m, pSeparator)
+ getPostfix(pSeparator, m);
}
You can also find a complete description of JspBase's API, here in the API reference section.
So far we provided methods to easily access the classname, write the extends clause, and compute the package name. Before we write the whole interface with all its methods, it makes sense to import the classes we use in the method's signatures. Alternatively we could simply always use fully qualified classnames - but who would do this in real code? And shouldn't the quality of generated code be at least the same as the quality of handwritten code?
To gather all the import-classes we need to look at every method parameter, every superclass, every interface, every association and so forth. This is rather tedious, repetitive, and error prone work and therefore a perfect candidate for a custom tag. Custom tags allow you to encapsulate tasks like computing import tags and easily re-use their functionality. The import tag provided in the standard iQgen tag library provides the functionality to automatically generate all necessary import statements for the current class or interface. In order to keep the imports in sync with other generated files you can specify a prefix for all imports. Also, if your model contains associations with undefined multiplicity, you may specify a collectiontype that will always be included in your import statements:
<iqgen:import prefix="<%=getPrefix()%>" collectiontype="java.util.List"/>
Let's finish our interface-example. We still need to generate the method section. Here's how it works:
<%@ page import="ru.novosoft.uml.MBase,java.util.Collection,java.util.Iterator"
extends="com.innoq.generator.jsp.JspBase" %>
<%@ taglib uri="iqgen" prefix="iqgen" %>
[...]
/**
* Interface <%=getClassname()%>
*/
public interface <%=getClassname()%><%=getExtendsString()%> {
<iqgen:foreach group="<%=getMetaModel().getOperations(getElement())%>" item="method">
<%
String methodName = getMetaModel().getName(method);
Object retType = getMetaModel().getReturnType(method);
String retTypeName = getMetaModel().getReturnTypeName(method);
String parList = getMetaModel().getParameterListAsString(method);
%>
/**
* Method <%=methodName%>
* <iqgen:foreach group="<%=getMetaModel().getParameterList(method)%>" item="parameter">
* @param <%=getMetaModel().getName(parameter)%> <%=getMetaModel().getDocumentation(parameter)%></iqgen:foreach>
<iqgen:if expr="<%=retType!=null%>">
* @return <%=retTypeName%>
</iqgen:if>
*/
public <%=retTypeName%> <%=methodName%>(<%=parList%>) <%=getMetaModel().getExceptionListAsString(method)%>;
</iqgen:foreach>
} Basically we just have to iterate over all the declared methods and print out their documentation and signature. In our example this is done using the built-in foreach tag. As attribute we define a group of elements to iterate over. This is done with the JSP expression <%=getMetaModel().getOperations(getElement())%>. Additionally we need to specify a variable in which the items of the group are to be placed during the iteration. In our case this is method. So the whole iteration looks like this:
<iqgen:foreach group="<%=getMetaModel().getOperations(getElement())%>" item="method"> [...] </iqgen:foreach>
The rest is pretty much straight forward. First we declare a number of variables like methodName and retTypeName for easier access to the method model element. Then we print the documentation, which includes another foreach iteration over the method's parameters. Finally we print the method's signature. That's it.
Of course generating interfaces is pretty simple, because usually you don't need to add custom code.
Generated code usually isn't perfect. Not all information is contained in model and templates, some needs to be added manually. With simple code generators the manual changes are lost during re-generation. iQgen solves this problem with usercode blocks.
During each generation the output directory is checked for files from earlier runs. If these files exist, the contents of protected sections of these files are inserted into the newly generated files. These special sections are marked as usercode blocks. Here is an example for adding custom imports to a Java file:
[...] <%@ taglib uri="iqgen" prefix="iqgen" %> <iqgen:usercode id="imports"> // your own imports </iqgen:usercode> <iqgen:import prefix="<%=getPrefix()%>" collectiontype="java.util.Collection"/> [...]
To use the usercode tag you have to register the iqgen taglib. Once this is done, you may mark a section of the template with the tag. Make sure that you specify a unique id attribute in the opening tag. This ensures that the right piece of code is merged into this section.
In the generated code the section will look like this:
[...] //==> Begin Protected Area imports // your own imports //==> End Protected Area imports [...]
Never modify the //==> [...] Protected Area [...] lines!
Alternatively to the id attribute you can also set a model element as attribute element:
[...] <%@ taglib uri="iqgen" prefix="iqgen" %> <iqgen:usercode element="<%=getElement()%>"> // your own code for the current modelelement </iqgen:usercode> [...]
id and element are mutually exclusive.
This chapter will show you how to use your own Tag Libraries (taglibs) with iQgen. We will use a Tag Library to format date and time data as an example. iQGen supports JSP 1.1 Tag Libraries. If you want to know how to program tag libraries, please consult the JSP 1.1 specification or any JSP tutorial.
Tag Libraries enable you to write simpler templates. Basically they allow you to move complicated logic from your templates into custom tags. Templates often are much easier to read, understand, and maintain, when Tag Libraries are used. They can be structured more clearly. As a consequence, you should use Tag Libraries whenever you feel that your templates are getting too complicated and unreadable.
Basically you can deploy every JSP 1.1 Tag Library into iQgen. The library has to meet certain criteria, though: First of all, the Tag Library has to be packed into a jar file and this jar file must contain a Tag Library Descriptor (TLD). The TLD is a file that describes the tags contained in the Tag Library. It is best - but not required - to be placed in the META-INF directory for compatibility with some IDEs e.g. IntelliJ IDEA™. The JSP engine uses this file to get all the necessary information to process the Tag Library.
Now the Tag Library can be deployed. You have to copy it into a subdirectory taglibs in the home directory of your iQgen installation (e.g. C:\Programme\iQgen). If the directory does not exist, you have to create it. Now this Tag Library can be used in all iQgen templates.
If the deployed Tag Library uses any libraries (jar files), they have to be put into a subdirectory of the taglibs directory called lib.
In case you want to use the Ant interface of iQgen a special issue arises. The jar file of the Tag Library then has to be placed in a taglibs directory in the lib directory of your Ant installation. The reason for this is that iQgen searches the jars of Tag Libraries relatively to the iQgen jar file. This jar file - in the Ant mode - resides in the lib directory of Ant.
If you have completed all the steps explained in the previous paragraph, you can use your Tag Libraries in your templates. Here is some example code which shows you how to access a Tag Library:
[...] <%@taglib uri="your_taglib" prefix="your_prefix" %> [...] <your_prefix:your_tag your_attr1="a" your_attr2="b"> In case of a body tag there can be something in here </your_prefix:your_tag> [...]The taglib directive ( <%@taglib ... %>) makes a Tag Library available within a template. To do this the URI of the Tag Library and the prefix must be specified as attributes of the directive. The URI of a Tag Library in the taglibs directory is the filename of the jar file of the Tag Library without .jar It is used to locate the Tag Library. Now you can use the Tag Library identifying it using the prefix, you have specified (i.e. <your_prefix:your_tag ... >).
The iQgen Sample Tag Library is included in the iQgen distribution, you can find it in the directory samples/getting_started/taglib_tutorial in your iQgen directory.
The Java class com.innoq.generator.samples.taglibs.SampleTag implements the date and time formating feature. The following TLD is used:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>iqgen-taglib-sample</shortname>
<info>Sample which shows you how to use the taglibs</info>
<tag>
<name>date</name>
<tagclass>com.innoq.generator.samples.taglibs.SampleTag</tagclass>
<info>Formats Dates</info>
<attribute>
<name>time</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>date</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>format</name>
<required>false</required>
</attribute>
</tag>
</taglib>The Tag Library contains only one tag, which
is called date. The attributes are
time, date and
format. The allowed values for the attribute
format are date,
time and datetime,
which is the default. If none of these values is given, the default
will be used.The tutorial includes an Ant build file ( build.xml), which can be used to compile, assemble and install the Tag Library. Just have to call the target install, respectively install-for-ant in order to make this Tag Library available for the GUI or the Ant interface of iQgen.
The important parts of the build file to illustrate what is done to deploy the Tag Library are:
[...]
<target name="dist" depends="compile">
<copy file="${basedir}/taglib.tld" todir="${classes.dir}/META-INF"/>
<jar jarfile="${jar.file}" basedir="${classes.dir}"/>
</target>
<target name="install" depends="dist">
<mkdir dir="${generator.dir}/taglibs"/>
<copy file="${jar.file}" todir="${generator.dir}/taglibs"/>
</target>
<target name="install-for-ant" depends="dist">
<mkdir dir="${ant.home}/lib/taglibs"/>
<copy file="${jar.file}" todir="${ant.home}/lib/taglibs"/>
</target>
[...]As you can see the taglib.tld is
copied into the META-INF directory of the jar file
in order to build the jar. This ensures the correct structure of the
jar file. The install and
install-for-ant targets then copy the jar
file into the correct directory.After having successfully installed the Tag Library there will be a taglibsample.jar in the taglibs directory of your iQgen installation. Now you can use the taglibsample Tag Library in your templates:
[...] <%@taglib uri="taglibsample" prefix="datelib" %> [...] <datelib:date format="date"/> <datelib:date time="<%=System.currentTimeMillis() + 3600000%>" format="datetime"/> [...]
This will result in the following output:
09.08.2002 09.08.2002 11:06:43
Transformation Properties represent a set of properties which can be accessed from within your templates. This enables you to add some flexibility to your templates, as you can change the result of the generation without changing the templates themselves.
This text refers to a sample which is included in the iQgen installation. The templates are in the directory samples/getting_started/properties_sample/templates. It will generate a HTML report on any model. You can use for instance the model of Tutorial 1.
To use Transformation Properties from the GUI just create a properties file and place it into the project directory of the transformation you want to use. When the transformation is opened this file will appear in the Transformation Properties combo box in the GUI. Just select it and the properties are available in the templates.
In order to use Transformation Properties on the command line set the -transformationProperties option.
Example:
iqgen.bat "-transform=tutorial_1 -nobackup -transformationProperties=transformation.properties"
In Ant use the transformationProperties attribute of the Generate Task.
If Transformation Properties are set they will be loaded when generation has started. They can be accessed in the templates via methods of the iQgen JSP base class, i.e. any iQgen JSP.
Table 2.3. Methods for accessing Transformation Properties
| Method | Description |
|---|---|
| public final String getProperty(String pKey) | Returns a property with the given key pKey |
| public final String getProperty(String pKey, String pDefault) | Returns a property with the given key pKey if defined, default pDefault otherwise |
| public final Properties getProperties() | Returns the whole set of Transformation Properties |
It is also possible to add new properties to the Transformation Properties or to change the value of an existing property. The following methods can be used:
Table 2.4. Methods for manipulating Transformation Properties
| Method | Description |
|---|---|
| public final void setProperty(String pKey, String pValue) | Sets a property with given key and value |
| public final void setProperties(Properties pProps) | Replaces Transformation Properties with pProps |
| public final void addProperties(Properties pProps) | Adds the given properties to the Transformation Properties |
The following example is a set of templates which generate an HTML report for a model. A Transformation Property (sort) is used to decide whether the lists of classes, attributes or methods will be sorted:
[...]
<TABLE cellpadding="3" cellspacing="3" border="1">
<TR bgcolor="#98AEB7" align="center">
<TD>Class Name</TD>
</TR>
<% List list = new ArrayList(getAttributeList("CLASS_KEY")); %>
<iqgen:if expr="<%=\"true\".equals(getProperty(\"sort\"))%>">
<% Collections.sort(list, myComparatorInstance); %>
</iqgen:if>
<iqgen:foreach group="<%=list%>" item="item" type="ru.novosoft.uml.MBase">
<TR bgcolor="#FFFFFF" align="right">
<TD>
<a href="<%=getMetaModel().getPath(item)%>/<%=getMetaModel().getName(item)%>.html">
<%=getMetaModel().getName(item)%>
</a>
</TD>
</TR>
</iqgen:foreach>
</TABLE>
[...] To sort the lists all you need is the following
property file: sort=true
The following example demonstrates how to validate a model exported by your CASE tool. You can find the templates and the model for this example at: ../samples/getting_started/validation. The templates use the Model Validation feature and will generate an HTML report for the underlying UML model.
Here is a complete list of files of this example:
Table 2.5. Files for the Model Validation example
| Directory | File | Comment |
|---|---|---|
| ./ | validation.iqp | Project file for this example |
| ./ | build.xml | Ant Script for generation |
| model | valid_model.xmi | Valid model XMI file |
| model | invalid_model.xmi | Invalid model XMI file |
| model | model.zargo | ArgoUML model file |
| templates | main.jsp | Model element to template mapping, Validation |
| templates | report.jsp | Creates the HTML output |
The UML profile in this case is very simple. What we want to show is how to use model validation. Model validation answers the question: Does the UML model satisfy the UML profile?
The UML profile looks like this:
only Entity, Process and Enum are allowed stereotypes
every navigable association must be named with a rolename
a usage dependency of processes to classes shows implicitly a get method of the used class
First let us start with the invalid model. It looks as follows:
You can find the invalid model as XMI file in the folder validation/model. Please open the transformation samples/getting_started/validation/validation.iqp. When you start generation and change to the validation page you should see that the model has three validation errors:
| Unknown stereotype: | Class: User |
| Association [Document -> Version] is navigable but missing rolename. | Association: |
| Association [Version -> Label] is navigable but missing rolename. | Association: |
The Unknown stereotype error is a warning, the missing rolename exceptions are errors (different images in table!). If we used a fatal error the execution would have stopped. In our example the validation violation status are arbitrarily.
The next step is that we fix the model, remove the validation violations and re-generate. The correct model looks as follows:
You can load the model from the XMI file valid_model.xmi. Now re-generating will not produce errors anymore!
You can find both templates main.jsp and report.jsp in the templates directory of this example. Most of the used methods are explained in further examples so we can concentrate on the validation method (see main.jsp):
[...]
private static final List STEREOTYPES = Arrays.asList(
new String[] {"Entity", "Process", "Enum"}
);
[...]
public boolean canBeGenerated(MBase pElement) {
return super.canBeGenerated(pElement)
|| getMetaModel().isAssociation(pElement);
}
public ValidationMessage isValid(MBase pElement) {
String s = getMetaModel().getStereotype(pElement);
// valid stereotypes
if (getMetaModel().isClass(pElement) && !STEREOTYPES.contains(s)) {
return new ValidationMessage(ValidationMessage.WARN, "Unknown stereotype: " + s);
}
// navigable associations do have a rolename?
if (getMetaModel().isAssociation(pElement)) {
for (Iterator it = ((MAssociation)pElement).getConnections().iterator(); it.hasNext(); ) {
MAssociationEnd lAssocEnd = (MAssociationEnd)getMetaModel().getOppositeEnd((MBase)it.next());
if (getMetaModel().isNavigable(lAssocEnd)
&& getMetaModel().getName(lAssocEnd).length() == 0) {
StringBuffer sb = new StringBuffer();
sb.append("Association [");
sb.append(getMetaModel().getTypeName(lAssocEnd.getOppositeEnd()));
sb.append(" -> ");
sb.append(getMetaModel().getTypeName(lAssocEnd));
sb.append("] is navigable but lacks a rolename.");
return new ValidationMessage(ValidationMessage.ERROR, sb.toString());
}
}
}
return new ValidationMessage(ValidationMessage.OK, "No error found!");
}
[...] The model validation happens programmatically. For validation purpose you can use the hook method isValid. This method is called for every model element that is to be processed during generation. You can control which model element leads to the generation of an artifact by overwriting the method canBeGenerated. By default only classes and interfaces are generated. In our example we have added associations, because the UML profile demands a validation of associations, too. Our intention is to check navigable associations and their rolenames.
In our custom isValid method we check whether all classes have a valid stereotype - if not we return a ValidationMessage of type ValidationMessage.WARN. Then we check whether all navigable associations have rolenames.
To do this we check, if the element is an association, then we take a look at the association's ends. Every association consists of two association ends which you can get by calling the method getConnections. Finally we check the UML profile constraint ("Association is navigable and has a rolename?!?"). If this constraint is violated we return a ValidationMessage of type ValidationMessage.ERROR.
If the element is no association in the first place, there is nothing to test form, so we simply return a ValidationMessage of type ValidationMessage.OK.
In a real world application the model validation would be more complex. Therefore we recommend to handle it in a separate class. Our experience is that it is also an incremental process to make your model validation more and more detailed. In a way, this is comparable with unit testing your model.
Dynamic classloading allows you to change certain classes while the iQgen GUI is running. Maybe you like Java helper classes do some work for your generation progress. Typically these classes are not bug free, so you have to fix them and test again. Dynamic classloading relieves you from having to restart iQgen every time you make a tiny change to a class. The only thing you have to do is to recompile your helper classes and start generation again.
Of course iQgen has to know where to find these classes. The properties enables you to define a directory from which iQgen will reload the classes for every generation process! (see Properties/Dirs)
The example itself generates one IDL file for the model.
Here is a complete list of files of this example:
| Directory | File | Comment |
|---|---|---|
| ./ | classloading.iqp | Project file for this example |
| ./ | build.xml | Ant Script for Generation |
| model | model.xmi | Model XMI file |
| model | model.zargo | ArgoUML model file |
| templates | main.jsp | Model element to template mapping |
| templates | idl.jsp | Creates the IDL output |
| classes/com/innoq/iqgen/classloadingtemplates | AttributeList.java | Container for attributes and associations |
| classes/com/innoq/iqgen/classloadingtemplates | Attribute.java | Attribute Wrapper |
| classes/com/innoq/iqgen/classloadingtemplates | Sequence.java | Association Wrapper |
The UML profile looks like this:
only Struct and Interface are allowed as stereotypes
the stereotype Struct maps to IDL struct
the stereotype Interface maps to IDL interface
every navigable association must be named with a rolename
The model describes a simple message board. The interface to the message board is the board itself. You are able to login, logout, add a message (addMessage) and add a reply to a message (addReply). Entities are User and Message. Every Message can have multiple replies which are also messages. In addition it is possible to add an Attachment to every Message.
This example does not produce a complete runnable application it only generates the compilable IDL for the model.
First of all: If you try to verify the generated IDL file you have to download an IDL compiler. The JDK IDL compiler idlj.exe does not support forward declarations, which are required for this example.
In structs we have to list all attributes and navigable associations. For this purpose we write a helper class AttributeList. Its init method iterates over all attributes and associations. For an attribute and an association with multiplicity one an Attribute will be created and for an association with multiplicity many a Sequence will be created. In order to take advantage of the dynamic reloading feature for the helper class, we place it in the classes directory.
Finally we are able to iterate over the resulting collection in idl.jsp:
[...]
struct <%=getMetaModel().getName(_struct)%> {
<iqgen:foreach group="<%=new AttributeList(getMetaModel(),_struct).getElements()%>" item="_attribute"
type="com.innoq.iqgen.classloading.Attribute">
<%=getProperty(_attribute.getTypeName(),_attribute.getTypeName())%> <%=_attribute.getName()%>;
</iqgen:foreach>
}; // <%=getMetaModel().getName(_struct)%>
[...] Open the project file /samples/getting_started/classloading/classloading.iqp and load the model. Set the Properties/Dirs/User Classes to C:\iqgen\samples\getting_started\classloading\classes (or where else your sample is located!). Press the button.
A single file should have been generated. Try to make an IDL compilation of this file (maybe use JacORB ). It will lead to the following exception:
$ ./idl.bat Classloading.idl Error in Classloading.idl, line:42(13): Declarator attachment already defined in scope. Attachment Can't recover from previous error(s), giving up. : parse error: null
The problem is that the type Attachment is equal to the attribute name attachment!
How do we solve this problem?
We can change the getName method in com.innoq.iqgen.classloading.Attribute to:
public class Attribute {
[...]
public String getName() {
//old : return metamodel.getName(clazz);
return "m" + StringHelper.fu(metamodel.getName(clazz));
}
[...]
} Just recompile the Attribute class and regenerate the model - now the IDL compilation should work just fine!
In this example we will show how to use activity diagrams to connect some HTML pages and simulate a simple screenflow. The content of the HTML pages is added as HTML to the modelelement documentation which we use to generate some visual content.
Here is a complete list of files of this example:
| Directory | File | Comment |
|---|---|---|
| ./ | activity.iqp | Project file for this example |
| ./ | build.xml | Ant Script for Generation |
| model | activity.xmi | Model XMI file |
| model | activity.zargo | ArgoUML model file |
| templates | main.jsp | Model element to template mapping |
| templates | form.jsp | Creates a HTML form |
| templates | index.jsp | Creates a HTML index site |
Table of Contents
As with any tool, code generation and MDA is not a silver bullet. The key to successfully applying it to your project is to decide when this makes sense, and when it doesn't.
The following list includes the main indicators that your project might benefit from using a generative approach:
You have few business model elements, such as entities and processes, but a complicated infrastructure
You are using a technology that requires you to specify information in multiple places, yet maintain consistency (such as J2EE)
There is a need to isolate technical changes from changes in business requirements
There are also some indicators that a generative approach might not be the best tool for the job:
The project's focus is largely on algorithms, not largely static structure
You are building a low-level component, such as an I/O library
Your project is trivial and small
As with any recommendation, these guidelines are not intended to be applied without careful consideration. In general, most developers start building a prototype, and while doing so, recognize repetitive elements. This is generally the best way to find out whether you should use a generative approach in your project.
Once you have decided to use a generative approach in your development effort, it is a good idea to apply some architectural guidelines as to how to use it:
In general, you should try to meet the goal that all of the generated code must be at least as good as if it had been written manually. While not always possible, the idea of this goal is to avoid using code generation to circumvent problems with the underlying architecture and frameworks.
While code generation can sometimes improve performance, you need to be careful to avoid the dreaded “code bloat” symptom. Since generating code is so easy, you might find yourself with a million lines of code, where a lot of them are basically just identical, with only minor changes. Your underlying platform will often allow you to solve these problems by building libraries or frameworks. Use this approach, and augment it with code generation where your platform does not provide the needed means.
A well-known, and in our opinion, false assertion about code generation is, that it is a sign of a bad design to need something like this at all. There are, of course, cases where this is true. Most of the time, though, you need to be concerned about the division of your solutions into “generic” and “generative”, and there is most definitely no single best strategy here.
Consider, for example, mapping objects, their relations, and their associations, to code. One way to address this is to statically type your classes according to your model - have a get and set method for your attributes, a Java class for each model class, use e.g. java.util.Vector to contain associated objects. If you want to do this, and have a model that exceeds trivial complexity, a generative approach - i.e., using iQgen - is a perfect match.
On the other hand, you could also define a class called ApplicationObject with a java.util.HashMap to hold the attributes, keyed by their name. You could then change your business model (to a certain degree) without touching your code, too.
Which of these solutions is better? Clearly, there is no simple answer to this question, since it depends very much on your specific requirements. Quite often, a generative approach will improve performance and make code easier to read, since it is a lot more explicit than the generic solution. Generic solutions work at compile time, though, so sometimes they might be too inflexible for a given problem. Generating code can also significantly enhance your code base, which might hurt both performance at run time and turn-around cycles at development time. Quite often, a thin veneer that is generated at compile time and wraps the generic object structure is a possible solution.
In summary, there can be no clear, universal preference to either solution. Each project requires careful consideration of the requirements at hand, and to find the right balance requires a skilled software architect.
Designing a UML profile is a technically simple task, but should be done with great care nonetheless. Essentially, the UML profile for your project is just a set of possible stereotypes and tagged values that model elements can be annotated with. Their role, though, is very important, since they define the language you can work with as you model your domain.
You should strive to enable the creation of models that are simple enough to be understood, yet formal enough to enable code generation. In your iQgen templates, you can use this information to map model constructs to system artifacts. Because of this, having a large set of stereotypes and tagged values to finely control what kind of output to generate makes building templates easy, but burdens you (or whoever creates the model) with having to decide which element to chose for a given purpose.
From applying an MDA approach in a significant number of projects, our experience is that it's best to err on the side of too few stereotypes and tagged values and accept having to write more complicated templates. While this will increase the effort in setting up the infrastructure, templates can almost always be changed easier than a complex model.
It's also a good idea not to clutter your UML profile with low-level, technical details. This cannot be avoided completely. Still, it makes sense to e.g. not introduce a stereotype such as “EntityBean”, but rather opt for “Entity” - although you might consider a J2EE Entity Bean to be the best match in a given scenario, it should be possible to change this to some other mechanism (such as a non-J2EE persistence framework) without having to modify the model. Of course the name does not have any inherent meaning for iQgen, so it would be possible to generate, say, a C# class from a model element stereotyped with “MessageDrivenBean”, but this clearly does not make things any clearer.
iQgen follows a strict forward engineering approach, as opposed to other well known strategies such as reverse engineering or round-trip engineering. What this means for you is that you need to be careful to make any changes in the appropriate place - either in the model or inside the protected areas in your generated artifacts. A failure to do so will result in your code being overwritten unintentionally, resulting in code loss. To address this, your development process should be adjusted to match the generative approach to software development.
It's tempting to view this as a disadvantage, and require that every artifact in the system should be modifiable with whatever tool is best suited to the purpose. But the generation of multiple artifacts from a simpler, central source element raises productivity so much that you will soon get used to it and appreciate the benefits. An obvious analogy to the classical compile step can be made, and after all, you would not expect to be able to modify the machine (or VM) code emitted by a language compiler.
The first step to take when introducing a generative approach is to embed the code generation process into your processing chain. In general, this means that you should generate code from within your build scripts. The iQgen Ant integration allows you to call iQgen from within your Ant scripts. If you prefer make or some other build management tool, you can use the command line tools.
As with other software artifacts, you should take care to put your source model under configuration management control. Depending on your CASE tool of choice, you can either version the model file itself or only the XMI export. While the first choice is preferable, some tools don't offer this possibility - most notably those that are based on some centralized repository. They do, however, usually offer some built-in versioning mechanism instead.
As a result, your build cycle will roughly resemble the following process:
Generate code from the XMI model file
Compile the source code
Link and build your deployment units
Deploy to your test environment
Test and repeat
It is a recommended best practice to set up a periodic, automated build process that runs centrally to minimize integration problems. When using a generative development process, you should make sure that your centralized build includes the code generation step. This is the best way to make sure that no code that has been manually added outside the protected areas becomes part of the system.
Table of Contents
This part of the documentation in intended to serve you as reference while you work with iQgen. It is not meant for reading from beginning to end.
On Windows systems you can start iQgen by selecting the corresponding entry in the start menu or by double clicking on {install-dir}/iqgen.bat. On Unix you need to run {installdir}/iqgen.sh. If you start one of these programs without passing any arguments, iQgen will start using the GUI mode.
In the figure below you can see the screen of the sample transformation Tutorial_1. A transformation is defined as a set of configuration items as displayed in the initial screen above. The main items of a transformation (the so called configuration set) are:
Source model file (any XMI file that has been exported by a CASE tool)
Target generation path (the root directory of the generated code)
Template directory (the directory that contains all the templates to be used by the generator)
Master template (a special template that controls the generation process; the default is main.jsp)
Transformation Properties (a property file to customize your generation at runtime)
As soon as the source model is selected, the generator loads the XMI file. The model contents are displayed in the pane Model Elements.
You do not need to generate the whole model every time. Instead you can select single or multiple model elements which you want to generate.
The button will be enabled, if all settings are made and a model is loaded. You can load the model by selecting or by clicking the corresponding toolbar button. This button will be enabled, if the source model file is an existing and valid XMI file. The GUI will mark invalid entries with a red border:
The text fields have a quick edit mode. By pressing Tab the entry will be expanded to a valid, existing one or if there are more than one possible file a list will be presented for selection (like UNIX shells).
The root path helps you to move projects to another location. You can physically save your project under a different directory. When changing the root path, iQgen offers to translate the other transformation settings (e.g. source model file) to this new location.
The following tables provide a reference for GUI menu options.
Table 4.1. menu
| Item | Shortcut | Comment |
|---|---|---|
| Ctrl-N | Creates a new transformation definition file (*.iqp) | |
| Ctrl-O | Opens a transformation | |
| Ctrl-S | Saves the current transformation, if modified | |
| Enables you to save the current transformation with another name | ||
| Ctrl-Q | Saves the properties and quits the program |
Table 4.2. menu
| Item | Shortcut | Comment |
|---|---|---|
| F7 | Expands or collapses the view with detail information about the current selected model element | |
| F8 | Expands or collapses the view with the selected elements for generation |
Table 4.3. menu
| Item | Shortcut | Comment |
|---|---|---|
| Ctrl-G | Starts generation | |
| F5 | Loads the model which is set as source model file | |
| Ctrl-W | Opens the work directory in the filemanager view. The work directory is the place where iQgen saves the compiled JSP templates | |
| Removes all files from work directory. This causes iQgen to create and compile all JSP templates when generating |
To set iQgen properties, open the properties dialog with the menu item or simply with the accelerator Ctrl-P. There are various kinds of settings. Most settings are self-explanatory.

| Item | Comment |
|---|---|
| Show attributes | Show attributes as elements in modeltree |
| Show operations | Show operations as elements in modeltree |
| Show stereotypes | Show stereotypes as informational text in modeltree |

| Item | Comment |
|---|---|
| Use model validation | It is possible to validate your model. With this setting you can turn validation on or off. |
| Clear message field before generating | |
| Clear System.out before generating | |
| Confirmation if no elements are selected | Suppress the confirmation dialog |
| Create backups for generated files | Every generated file is copied to a file with .old-extension before overwriting |
| Force regeneration of all files | All files will be generated although the template and the model have been unchanged |
| Smart Generation - Avoid regeneration of equal files | iQgen makes a checksum comparison of the existing file and the new generated file. If they are equal by checksum the new file will not be written. |
| Reload model automatically if newer | If your model has changed it will be reloaded from disk |
| Auto-Load model on opening a transformation | |
| Serialize model after generation | After generation the XMI file will be serialized to file to be faster when reloading model. |

If you like to use more than one instance of iQgen at the same time you will have to define different a ports for each instance. You can set the port to a static number (e.g. 16222), a range (e.g. 16222-16333) or a list of free port numbers (e.g. 16222;16333;16444)
On Windows systems:
iqgen.bat "-xmi=(File) -out=(Dir) -jsp=(Dir) -main=(filename) [-nobackup] [Options] [Filter]"
or
iqgen.bat "-transform=(name of transformation)"
On Unix/Linux systems:
iqgen.sh -xmi=(File) -out=(Dir) -jsp=(Dir) -main=(filename) [-nobackup] [Options] [Filter]
or
iqgen.sh "-transform=(name of transformation)"
Basic settings:
| Option | Comment |
|---|---|
| -transform=[name] | Name of defined transformation |
| -xmi=[file] | XMI input file |
| -out=[dir] | Output directory |
| -jsp=[dir] | Jsp directory |
| -main=[filename] | Name of the master jsp file (transformation) |
Advanced settings:
| Option | Comment | Default |
|---|---|---|
| -classes=[dir] | Path to classes for dynamic classloading | IQGEN_HOME/taglibs/classes |
| -taglibsDir=[dir] | User defined taglibs dir | IQGEN_HOME/taglibs |
| -externalDir=[dir] | User defined path to external libraries (JARs) | IQGEN_HOME/taglibs/lib |
Options:
| Option | Comment | Default |
|---|---|---|
| -nobackup | If set, no backup files will be created during merge | not set |
| -noSerialze | If set, avoids serialisation of model after generation | not set |
| -useChecksum | If set, equal files will not be written (checksum comparison) | not set |
| -force | If set, forces regenerating of all files | not set |
| -loglevel | Defines the LogLevel ';' separated (FILEINFO;VALIDATION; WARN;INFO;DEBUG;TRACE) | WARN;FILEINFO; VALIDATION |
| -verbose | Use -loglevel | |
| -quiet | Quiet mode; no output | off |
Filter:
| Option | Comment |
|---|---|
| -name=[pattern] | Generates only model elements with name pattern[a] |
| -stereotype=[pattern] | Generates only model elements with stereotype pattern |
| -filename=[pattern] | Generates only files with name pattern |
| -package=[packagepattern] | Generates only model elements which match the packagepattern[b] |
[a] A pattern can include * and ? [b] A packagepattern is an antstyle pattern. It can include ** representing 1-n packages and * representing one package (Example **.basic.*) | |
Example:
iqgen.bat "-xmi=./samples/getting_started/tutorial_1/model/crm.xml -out=./samples/getting_started/tutorial_1/src -jsp=./samples/getting_started/tutorial_1/templates -main=main.jsp -nobackup"
or
iqgen.bat "-transform=tutorial_1 -nobackup"
For information about installing Ant please refer to the Ant installation documentation.
For information about installing iQgen for Ant, please take a look at the section called “Installing iQgen for Ant”.
For an example on how to use iQgen from Ant, please take a look at the build file in the directory ../samples/getting_started/tutorial_1. The most interesting task is generate-code:
<target name="generate-code" depends="prepare" if="generator_is_present">
<generate jspDir="${basedir}/templates"
xmiFile="${basedir}/model/crm.xml"
outputDir="${gen.dir}"
mainJsp="main.jsp"/>
</target> or <target name="generate-code" depends="prepare" if="generator_is_present"> <generate transform="tutorial_1"/> </target>
The generated code will be written to ./src. The tutorial also generates its own build.xml file, which compiles the generated classes and creates a Jar file.
We have finished to revise our plug-in for Eclipse. It supports Eclipse 3.0 now. With the plug-in you will be able to edit an iQgen project file (*.iqp) and select model elements for generation. The status of generation will be logged to the iQgen console in Eclipse. You are also able to start generation by clicking the right mouse button and select in the popup menu under > . Only .iqp files enable the popup menu item for generation.
Double-click a file with the .iqp extension to open the iQgen project editor. The editor shows several pages to edit the project file.
On the Transformation page you can set the model file, the project root path, the output directory, the template directory, the main jsp and properties to be used
On the Model page you can select the model elements for which you want to start the generation
On the Source page you can see the source of the project file
Do not edit the source of the project file!
You can start generation by clicking the button in the toolbar or by opening the popup menu on a .iqp file and selecting .
The iQgen console is released as a view, and you can open it via > > > . The following figure shows a list of generated files and some other information of the generation status.
You can set the logging filter and open a detail view by double-clicking an element of the list. If the element is a generated file, the file will be opened in the corresponding editor (e.g. Java files). If an error occurred while generating, you can double-click the error entry in the iQgen console (red triangle) and the JSP editor is opened with the right JSP file at the line which produced the error.
A short list of features we are thinking about:
Support of WSAD
Wizard for project structure creation (subdirectories, main.jsp-dummy, ...)
Eclipse modeling Framework (EMF) connection
Usage of the Graphical Editing Framework (GEF) for model presentation
Editor, which allows editing only in protected areas
Although the IMetaModelFacade (documented in the iQgen API) offers many simple methods to access the actual model, sometimes you will find that you need more information than the facade has to offer. Then you will need to use the model directly. In order to do this successfully, you will have to learn about the relationships between different model elements.
The figure below depicts the core package of the UML.
The centerpiece of this diagram is the class Classifier. A classifier is an element that describes behavioral and structural features; it comes in several specific forms, including Class, DataType, Interface, Component, and others that are defined in the classifier package. In the metamodel, a Classifier declares a collection of Features, such as Attributes, Methods, and Operations. It has a name, which is unique in the Namespace enclosing the Classifier.
Classifier is an abstract metaclass that is subclassed by concrete classes like Class and Interface as shown in the figure below.
In iQgen you can access elements of the metamodel through the method ru.novosoft.uml.MBase getElement(). The implementation of the model is based on a library by Novosoft. The figure below shows the interface hierarchy of Novosoft's core UML package ru.novosoft.uml.foundation.core.You can cast the element you obtain with MBase getElement() to the appropriate interface type in order to access its methods. These are defined in the Novosoft API reference.Let's say you want to access all parameters of a method or operation. The appropriate code looks like this:
<%@ page extends="com.innoq.generator.jsp.JspBase"
import="java.util.*,ru.novosoft.uml.*,ru.novosoft.uml.foundation.core.*,
ru.novosoft.uml.foundation.data_types.MParameterDirectionKind" %>
<%!
public Collection getParameters(MBase m) {
Collection parameters = Collections.EMPTY_LIST;
MBase m = getElement();
// a MBehavioralFeature includes both methods and operations
// see class diagram above
if (m instanceof MBehavioralFeature) {
MBehavioralFeature bf = (MBehavioralFeature) m;
parameters = new ArrayList();
Iterator it = bf.getParameters().iterator();
while (it.hasNext()) {
MParameter par = (MParameter) it.next();
// exclude the return parameter
if (par.getKind().getValue() != MParameterDirectionKind._RETURN) {
parameters.add(par);
}
}
}
return parameters;
}
%>Taglibs are very useful to separate logical structures (e.g. iterations, conditions) and code. A custom taglib with the following tags is included in the iQgen release.
The IfTag enables you to generate code depending on conditions. The body of the tag will only be executed if the condition (stored in the tag attribute expr) is true. Syntax:
<iqgen:if expr="[true|false]"> ...body </iqgen:if>
Examples:
<iqgen:if expr="true"> ...something to write </iqgen:if>or
<iqgen:if expr="<%=!attrName.equals(\"name\")%>"> ...something to write </iqgen:if>or
<iqgen:if expr="<%=isProcessable(element)%%>"> ...something to write </iqgen:if>
The ForEachTag is used to iterate over a Collection, a List or with an Iterator.
<iqgen:foreach group="<%=attr.iterator()%>" item="element" type="ru.novosoft.uml.MBase">The parameter item allows you to access the current element of the loop.
String attrName = getMetaModel().getName(element);type is optional (default type="ru.novosoft.uml.MBase") and defines the type of the item. An incorrect type raises a ClassCastException.
The ImportTag is deprecated
The ImportTag is only useful if you are generating Java source code. This tag creates the necessary import statements, which usually is a pretty hard job. This encapsulation dramatically simplifies the development of templates that generate Java code.
<iqgen:import prefix="<%=getPrefix()%>" collectiontype="java.util.Collection"/> <iqgen:usercode id="imports"> // ... own imports </iqgen:usercode>See samples/getting_started/tutorial_1/templates/import.jsp
The parameter prefix is set to the path of the class. This is helpful for evaluating import statements because none of the classes in this path needs to be imported. The collectiontype parameter defines which collectiontype should be used for *-associations.
The PropertyTag is only useful in the context of Java, too. It encapsulates a list of attributes by generating getter and setter methods (see samples/getting_started/tutorial_1/templates/attribute.jsp):
<iqgen:properties>
Developers need to be able to extend generated code. To ensure this, iQgen recognizes protected areas which remain unchanged during re-generation. In the generated source code a protected area may look like this:
//==> Begin Protected Area global // ... //==> End Protected Area global
Developers have to write their code in these areas. During a re-generation iQgen merges generated and implemented areas.
In a template the protected area is marked with the usercode tag like this:
<iqgen:usercode id="global"> // ... </iqgen:usercode>
The id (here global) is used to identify a protected area within the generated code. The name for the id has to be unique.
As mentioned before, XMI does not necessarily equal XMI. Meaning: Different tools support XMI in different ways. Therefore we test interoperability with every release of iQgen.
We start with a simple UML model and redraw it in every modeling tool we test. You can find the model for the test at the beginning of each section. After exporting the model to XMI format, we try to access all of the model information we have specified. In some cases we are able to retrieve all information, in some cases we are not.
Since version 2.0 we support both:
static UML
dynamic UML
The mentioned categories in the following tables can be found in the model of each chapter.
Table 4.6. XMI versions exported by different CASE tools
| Rational Rose 2000/ 2003 | MID Innovator 7.0.4 | MID Innovator 8.0.02; 8.0.03 | TogetherJ 4.2 + 6.0 | objectIF 4.6 | ObjectDomain R3 | Poseidon 1.2 + 1.4 | Poseidon 2.2 | ArgoUML 0.9.8 |
|---|---|---|---|---|---|---|---|---|
| 1.1 and 1.0[a] | 1.1 | 1.1 | 1.1 and 1.0[b] | 1.0 | 1.0 | 1.1 | 1.2 | 1.1 |
[a] We test both exporter versions. You can find the Rose plug-in on the rational website, in the “Download Center” at “Plug-Ins for Rational Rose”. [b] We use XMI 1.0 export. | ||||||||
With this test we test the associations, multiplicity and role names between two classes.

Table 4.7. Tool specific support of associations
| Category | Rational Rose 2000 | MID Innovator 7.0.4 | MID Innovator 8.0.02; 8.0.03 | TogetherJ 4.2 + 6.0 | objectIF 4.6[a] | ObjectDomain R3 | Poseidon 1.2 + 1.4 | Poseidon 2.2 | ArgoUML 0.9.8 |
|---|---|---|---|---|---|---|---|---|---|
| simpleAssoc | X | X | X | X | X | X | X | X | X |
| singleNavOneToMany | X | X | X | X | X | X | X | X | X |
| bidirectedManyToMany | X | X | X | X | X | X | X | X | X |
| backdirected | X | X | X | X | X | X | X | X | X |
[a] rolenames must be set | |||||||||
Let's have a look at the interfaces and classes themselves. Do we get all information about generalizations and specializations we need?

Table 4.8. Supported interface and class inheritance
| Category | Rational Rose 2000 | MID Innovator 7.0.4 | MID Innovator 8.0.02; 8.0.03 | TogetherJ 4.2 + 6.0 | objectIF 4.6 | ObjectDomain R3 | Poseidon 1.2 + 1.4 | Poseidon 2.2 | ArgoUML 0.9.8 |
|---|---|---|---|---|---|---|---|---|---|
| AbstractMother is superclass of Mother | X | X | X | X | X | X | X | X | X |
| Mother is subclass of AbstractMother | X | X | X | X | X | X | X | X | X |
| AbstractMother implements IParent and IChild | X | X | X | X | X | X | X | X | X |
| IParent is implemented by AbstractMother | X | X | X | X | X | X | X | X | X |
| IChild is implemented by AbstractMother | X | X | X | X | X | X | X | X | X |
| IFather extends IParent and IChild | X | X | X | X | X | X | X | X | X |
| IParent is generalization of IFather | X | X | X | X | X | X | X | X | X |
| IChild is generalization of IFather | X | X | X | X | X | X | X | X | X |
In most cases we need to specify some architectural information in the model. Stereotypes and tagged values are often used for this task. With this test we want to find out which stereotypes and tagged values are supported.

Table 4.9. Supported stereotypes and tagged values
| Category | Rational Rose 2000 | MID Innovator 7.0.4 | MID Innovator 8.0.02; 8.0.03 | TogetherJ 4.2 + 6.0 | objectIF 4.6 | ObjectDomain R3 | Poseidon 1.2 + 1.4 | Poseidon 2.2 | ArgoUML 0.9.8 |
|---|---|---|---|---|---|---|---|---|---|
| PlugException has stereotype PlugException | X | X | X | X | X | X | X | X | X |
| *XMIImporter[a] has stereotype plugin | X | X | X | X | X | X | X | X | X |
| IPluggable#plug throws PlugException | -- | -- | -- | -- | -- | -- | -- | -- | -- |
| All parameters are correct | X | X | X | X | X | X | X | X | X |
[a] RoseXMIImporter, InnovatorXMIImporter and TogetherXMIImporter | |||||||||
This test shows what information about attributes and operations can be used.

Table 4.10. Supported attributes and operations properties
| Category | Rational Rose 2000 | MID Innovator 7.0.4 | MID Innovator 8.0.02; 8.0.03 | TogetherJ 4.2 + 6.0 | objectIF 4.6 | ObjectDomain R3 | Poseidon 1.2 + 1.4 | Poseidon 2.2 | ArgoUML 0.9.8 |
|---|---|---|---|---|---|---|---|---|---|
| Scope is correct | default scope is wrong (private) | default scope is wrong (private) | X | default scope is wrong (public) | default scope is wrong (protected) | default scope is wrong (protected) | default scope is wrong (protected) | X | default scope is wrong (protected) |
| static is recognized | -- | X | X | -- | -- | X | X | X | X |
| final is recognized | -- | -- | -- | -- | X | -- | -- | -- | -- |
| Stereotypes are recognized | X | X | X | X | X | X | X | X | X |
| Tagged values are recognized | -- (differs) | -- (differs) | -- (differs) | -- (differs) | -- (differs) | X | X | X | X |
Dependencies between different kinds of model elements.

Table 4.11. Supported package/class/interface dependencies
| Category | Rational Rose 2000 | MID Innovator 7.0.4 | MID Innovator 8.0.02; 8.0.03 | TogetherJ 4.2 + 6.0 | objectIF 4.6 | ObjectDomain R3 | Poseidon 1.2 + 1.4 | Poseidon 2.2 | ArgoUML 0.9.8 |
|---|---|---|---|---|---|---|---|---|---|
| TEClass1 is client dependency of TEClass2 | X | X | X | X | -- | X | X | X | X |
| TEClass2 is supplier dependency of TEClass1 | X | X | X | X | -- | X | X | X | X |
| TEInterface1 is client dependency of TEInterface2 | X | X | X | X | -- | X | -- | X | -- |
| TEInterface2 is supplier dependency of TEInterface1 | X | X | X | X | -- | X | -- | X | -- |
| TEClass1 is client dependency of TEInterface1 | X | X | X | X | -- | X | -- | X | -- |
| TEInterface1 is supplier dependency of TEClass1 | X | X | X | X | -- | X | -- | X | -- |
| TEClass2 is supplier dependency of TEInterface2 | X | X | X | -- | -- | X | -- | X | -- |
| TEInterface2 is client dependency of TEClass2 | X | X | X | -- | -- | X | -- | X | -- |
With this test we test states and transitions.

Table 4.12. Tool specific support of associations
| Category | Rational Rose 2003 | TogetherJ 6.0 | ArgoUML 0.14 |
|---|---|---|---|
| find all states | X | X | X |
| find all transitions | X | X | X |
| Name of state | X | X | X |
| Name of transition | -- | X | X |
| All incomings/outgoins (states) | X | X | X |
| All sources/tragets (transitions) | X | X | X |
| Stereotypes on states | X | X | -- |
| Stereotypes on transitions | X | X | -- |
| TaggedValues on states | -- | -- | X |
| TaggedValues on transitions | -- | -- | X |
Some helpful links to external resources:
CASE (computer-aided software engineering) is the use of a computer-assisted method to organize and control the development of software, especially on large, complex projects involving many software components and people. Using CASE allows designers, code writers, testers, planners, and managers to share a common view of where a project stands at each stage of development. CASE helps ensure a disciplined, check-pointed process. A CASE tool may portray progress (or lack of it) graphically. It may also serve as a repository for or be linked to document and program libraries containing the project's business plans, design requirements, design specifications, detailed code specifications, the code units, test cases and results, and marketing and service plans. (Source: whatis.com)
Common Object Request Broker Architecture (CORBA) is an architecture and specification for creating, distributing, and managing distributed program objects in a network. It allows programs at different locations and developed by different vendors to communicate in a network through an “interface broker”. CORBA was developed by a consortium of vendors through the Object Management Group (OMG), which currently includes over 500 member companies. Both International Organization for Standardization (ISO) and X/Open have sanctioned CORBA as the standard architecture for distributed objects (which are also known as components). CORBA 3 is the latest level. (Source: whatis.com)
See IDL.
Interface Definition Language (IDL) is a generic term for a language that lets a program or object written in one language communicate with another program written in an unknown language. In distributed object technology, it's important that new objects be able to be sent to any platform environment and discover how to run in that environment. An Object Request Broker (ORB) is an example of a program that would use an interface definition language to “broker” communication between one object program and another one. (Source: whatis.com)
See CORBA.
Java Server Page (JSP) is a technology for controlling the content or appearance of Web pages through the use of servlets, small programs that are specified in the Web page and run on the Web server to modify the Web page before it is sent to the user who requested it. JSP is comparable to Microsoft's Active Server Page (ASP) technology. Whereas a Java Server Page calls a Java program that is executed by the Web server, an Active Server Page contains a script that is interpreted by a script interpreter (such as VBScript or JScript) before the page is sent to the user. (Source: whatis.com)
JSP are defined in the JSP specification by Sun Microsystems. There are numerous tutorials published on the web. Very helpful - as a quick reference - is the JSP Syntax Card.
In iQgen JSP are not used for Web pages, but rather as templates for generating artifacts like classes, SQL scripts or configuration files that can be used for a software application. More information about how JSP are used in iQgen can be found here.
A model of a system is a description or specification of that system and its environment for some certain purpose. A model is often presented as a combination of drawings and text. The text may be in a modeling language such as UML or in a natural language. (Source: OMG MDA Guide)
This is probably the least known of the OMG standards, but maybe the most important one. The Meta-Object Facility (MOF) is a conceptual framework for describing meta-data. Meta-data is, as the names suggests, data about data. To explain this, consider the following layers:
A customer, ACME Corp., has placed an order for 32 boxes of candy on the 23rd of April.
A customer has a name and can place zero to n orders, each order having a date and referencing a specfic item that is being sold.
Classes have attributes which have a type, and classes can be related to each other.
There are things that describe something, and there are connections between those things.
MOF is mainly concerned with level 4, for which it contains a hard-coded set of “things”. (in fact this layer is a subset of UML).
So what is MOF? MOF is a way to describe meta-models, which in turn describe a specific way to model something. One example of a well-known meta-model is UML. But the separation allows MOF to be independent of UML and support other meta-models as well. MOF is thus a very generic and very powerful framework for expressing model and meta data information.
Apart from being a conceptual framework, MOF also defines a CORBA IDL mapping that specifies how MOF data can be accessed from CORBA applications. With JMI, the Java Metadata Interface, the Java Community Process (JCP) has just finalized a mapping of these interfaces for the Java language.
A platform is a set of subsystems and technologies that provide a coherent set of functionality through interfaces and specified usage patterns, which any application supported by that platform can use without concern for the details of how the functionality provided by the platform is implemented. (Source: OMG MDA Guide)
A platform independent model (PIM) is a view of a system from the platform independent viewpoint. A PIM exhibits a specified degree of platform independence so as to be suitable for use with a number of different platforms of similar type.
A very common technique for achieving platform independence is to target a system model for a technology-neutral virtual machine. A virtual machine is defined as a set of parts and services (communications, scheduling, naming, etc.), which are defined independently of any specific platform and which are realized in platform specific ways on different platforms. A virtual machine is a platform, and such a model is specific to that platform. But that model is platform independent with respect to the class of different platforms on which that virtual machine has been implemented. This is because such models are unaffected by the underlying platform. (Source: OMG MDA Guide)
A platform specific model (PSM) is a view of a system from the platform specific viewpoint. A PSM combines the specifications in the PIM with the details that specify how that system uses a particular type of platform.
Stereotypes are the core extension mechanism of the UML. They let you create modeling constructs that aren't included in the UML, but are very similiar to something that is. An example are interfaces. Interfaces are very similiar to classes, but really aren't the same. Parts of the UML extended with a defined set of stereotypes can together form a UML profile.
The Unified Modeling Language (UML) has become the one and only wide-spread standard modeling language, so that if anybody uses a modeling tool or simply draws something on a whiteboard, it will most likely follow UML conventions. UML defines a lot of different diagram types, the best-known of which are the class and the interaction diagram. Most CASE tools can export UML models as XMI files.
A UML profile is a specification that does one or more of the following:
Identifies a subset of the UML metamodel (which may be the entire UML metamodel).
Specifies “well-formedness” rules beyond those specified by the identified subset of the UML metamodel. “Well-formedness rule” is a term used in the normative UML metamodel specification to describe a set of constraints written in natural language and UML's Object Constraint Language (OCL) that contributes to the definition of a metamodel element.
Specifies “standard elements” beyond those specified by the identified subset of the UML metamodel. “Standard element” is a term used in the UML metamodel specification to describe a standard instance of a UML stereotype, tagged value or constraint.
Specifies semantics, expressed in natural language, beyond those specified by the identified subset of the UML metamodel.
Specifies common model elements (i.e., instances of UML constructs), expressed in terms of the profile.
(Source: UML Profile for CORBA)
XML Metadata Interchange (XMI) is a standard, XML-based language to exchange model information between tools. All of the leading CASE tools, such as Rose, Together, Innovator, ArgoUML, Enterprise Architect and so on support XMI as their standard import and export format. XMI is not as standard as one could hope, but it's getting there.