Model Driven Mural/MDM - NetBeans UML & Code Generation

Read this for background.

UML Class Diagram

Here's the UML example I will use for illustration purposes in the upcoming posts: it shows a composition of three classes representing a Patient. We'll revisit this diagram later once we know more about the MDM configuration.

There are a couple of noticeable things on this diagram:

  • The Patient class's stereotype is MDM_Root
  • One of the patient class's attribute is tagged as a primary key
  • Some of the attributes have tagged values like size or matchType
  • The classes Address and Phone are associated with the Patient class and this association is navigable.
I will explain the reasons for these additions to the model later on - for now the important thing to note is that the model contains this additional information to the basic class information.

Understanding NetBeans UML Code Generation

The first step on achieving Model Driven Development (MDD) bliss with Mural is to actually understand how the NetBeans template library and the UML module work.

Luckily somebody else already wrote an excellent article on the basics -NetBeans UML Custom Code Generation.

Let me just paraphrase the article before I'll add some additional points:

  • Templates used for code generation are Freemaker templates - so it's handy to have the link to the reference close by. There is also a Freemaker NetBeans Plug In referenced in the code generation tutorial.
  • There are a couple of NetBeans tools involved in the process the Template Manager, UML Options Panel (Templates tab) and UML Project Properties (Templates section). The article talks you through all these tools in detail.
    • Template Manager: add/manage template files used by different NetBeans Plug Ins. Here we will add our MDM templates.
    • UML Options Panel: here we will map our templates to a type of model component and UML stereotype
    • UML Project Properties: we will have to enable the templates we have created on a per project basis.
The article guides you through all the necessary steps to add a set of templates (EJB SLSB) to NetBeans. The interesting part here is that the way the templates are set up they are applied to classes with a certain stereotype. It looks like we will have to add our own steretype for MDM type elements. The sample templates are a bit more straightforward to understand than the templates shipped with the UML Plug In so this is a good starting point to gain an understanding how the code generation works.

Understanding the Source Data Model & Developing Templates

While the article makes a good job at describing the nuts and bolts of the tooling it doesn't actually explain how the EJB templates were developed in the first place. There are two areas one needs to know about in oder to understand and create templates:

  • Framemaker Scripting - hence the link above
  • Source Data Model - this is briefly described in the tutorial and the description mentions classInfo and modelElement

Knowing more about the latter will help tremendously in developing templates. Both classInfo and modelElement refer to the same UML object. They will contain the information from the model of the UML object (class, interface etc.) that code generation is run for. classInfo is an instance of class org.netbeans.modules.uml.integration.ide.events.ClassInfo. This class is actually an abstraction of the underlying UML model - it exposes a sub set of the available information that is deemed to be relevant for generating Java Code. It actually acts as a wrapper around another class that provides fine grained access to the underlying UML model.
Therefore every time one needs to access UML attributes like "tagged values" or "stereotype" or "primary key" one needs to get hold of an instance of the underlying fine grained class.
modelElement is just this - an instance of the underlying fine-grained class.

The same model applies to other elements like class attributes or methods. Here's a table of the most important classes. I have included links to the source code of these classes as this proved to be the best reference I could find (there is definitely no Javadoc for the simplified API and I couldn't locate a Javadoc for the fine-grained interfaces yet)

UML Type

 Fine Grained Representation

 Simplified Representation

Element

org.netbeans.modules.uml.core.metamodel.core.foundation.IElement

org.netbeans.modules.uml.integration.ide.events.ElementInfo

Class

org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IClassifier

 org.netbeans.modules.uml.integration.ide.events.ClassInfo

 Attribute

 org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAttribute

org.netbeans.modules.uml.integration.ide.events.MemberInfo

 Method

org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IOperation

org.netbeans.modules.uml.integration.ide.events.MethodInfo

Each of the Simplfied interfaces provides access to the underlying Fine Grained interface, e.g. ClassInfo offers a "getClassElement()" method just as MemberInfo provides a "getAttribute()" method.

Template Examples

Let's look at some template examples to see how these classes are used:

The example below renders some XML for the class that code generation is run on. I've highlighted how the classInfo itself is used, how the member variables/attributes of the class are accessed and how to get hold of the underlying object implementing IAttribute  to obtain Tagged Values that were added in the UML diagram.

   <nodes>
        <tag>${classInfo.getShortClassName()}</tag>
<#list classInfo.getFieldsCodeGenSorted() as fieldInfo > 
        <fields>
            <field-name>${fieldInfo.getName()!}</field-name>
            <field-type>${fieldInfo.getCodeGenType()?lower_case!}</field-type>
    <#if fieldInfo.getAttribute().getTaggedValueByName("size")?? >
            <size>${fieldInfo.getAttribute().getTaggedValueByName("size").getDataValue()!}</size>
    <#else>
            <size>20</size>
    </#if>
        </fields>
</#list>
    </nodes>

There are navigable relationships in our class diagram so here's an example how to follow these relationships (this is going to be important since all of the domain object model needs to be represented in MDM). All of the code below actually uses the fine-grained access to the UML model.

In the example we first obtain all relationships of the element then use the other end of the relationship to obtain information about the element/class that is associated with current element/class.

<#list modelElement.getAssociationEnds() as thisEnd > 
<#list thisEnd.getOtherEnd() as otherEnd > 
    <nodes>
        <tag>${otherEnd.getParticipant().toString()}</tag>
<#list otherEnd.getParticipant().getAttributes() as elem > 
        <fields>
            <field-name>${elem.toString()!}</field-name>
            <field-type>${elem.getTypeName()?lower_case!}</field-type>
        </fields>
</#list>
</#list>
</#list>


Comments:

Post a Comment:
Comments are closed for this entry.
About

Swen, resident alien in the UK based part of a team at SUN called FAST

Search

Top Tags
Categories
Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today