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!