Generic Type

The generic type support touches three levels:

  1. Template type presentation
    1. Template definition
    2. Template binding
  2. Java Code generation
    1. JDT template
    2. Velocity template

1. Template type presentation

The template support deals with two issues: Template definition and Template binding.

1.1 Template definition

The first requirement of this integration is to capture the generic type data, convert it into UML and then display it in a UML diagram. Here is an example of java.util.Collection.

In the diagram above, we find the class template, operation template and operation parameter template. In the class template, “ E ” is a template variable type, which is used in the method add(E) .

We can also find an operation template using a local template variable:

<T> T[] toArray(T[] a); 

where the variable “ T ” is an operation template variable. It is used in the scope of this method.

1.2 Template binding

Besides the template definition, it is necessary to show the template utilization relationship, called template binding. In the above diagram, this relationship is shown as an arrow “ E -> ? ”. The first example is the following method:

boolean retainAll(Collection<?> c); 

The class template variable “ E ” of the collection binds to an unspecified type in the argument for this method.

2. Java Code generation

eUML2 uses a template engine to generate the Java code. In the Free edition, the template engine is JDT’s one, which provides only getter/setter. In Studio edition, it is possible to use the powerful Velocity template engine. Of course, it can be disabled in the Preferences.

2.1 JDT template

JDT template provides a getter/setter code generation pattern. This pattern is used by the eUML2 Free edition or when the Velocity template engine is disabled in the Studio edition.

Here is the standard JDT template pattern.

$(modifiers) ${field_type} ${field};

/**
 * @return Returns the ${bare_field_name}.
 */
$(modifiers) ${field_type} get${bare_field_name} () {
	return ${field};
}


/**
 * @param ${param} The ${bare_field_name} to set.
 */
$(modifiers) void set${bare_field_name} (${field_type} ${param}) {
	${field} = ${param};
}

In the case of the type boolean , the prefix of the getter is “ is ” instead of “ get ”.

The key-words in blue color and bold/italic enclosed in brackets followed by a $ character, are template variables. Here is the detailed description of each variable

Variable name

Description

$(modifiers)

Java member such as public, protected, private, final static etc…

${field_type}

Field member type

${field} Field member name
${bare_field_name} Normalized file name by removing the prefix/suffix defined in Preferences->Java->Code Style. In general, the first letter is capital.
${param} The parameter name based on the prefix/suffix defined in Preferences->Java->Code Style.

eUML2 inserts two new variables for UML model storage purposes:

Variable name

Description

$(uml_property_specification)

This variable contains all UML information about the property such as property name, cardinality, stereotype, dependencies etc…

${uml_property_member}

This variable is used to mark the property membership of an accessor. The syntax is @uml.property name=”${property_name}”

The template patterns are changed as following:

/**
 * ${uml_property_specification}
 */
$(modifiers) ${field_type} ${field};

/**
 * @return  Returns the ${bare_field_name}.
 * ${uml_property_member}
 */
$(modifiers) ${field_type} get${bare_field_name} () {
	return ${field};
}


/**
 * @param  ${param} The ${bare_field_name} to set.
 * ${uml_property_member}
 */
$(modifiers) void set${bare_field_name} (${field_type} ${param}) {
	${field} = ${param};
}

In the following model, the Company and Project have a qualified association. The field type of this association is designed as java.util.Map.

The generated codes based on the JDT templates are as follows:

/** 
 * @uml.property name="project"
 * @uml.associationEnd multiplicity="(0 -1)"
 *       inverse="person:model.Company"
 *       qualifier="key:java.lang.Object model.Project"
 */
private Map<Object, Collection<Project>> projectMap;

/** 
 * Getter of the property <tt>project</tt>
 * @return Returns the project.
 * @uml.property name="project"
 */
public Map<Object, Collection<Project>> getProject()
{
	return projectMap;
}

/** 
 * Setter of the property <tt>project</tt>
 * @param company The project to set.
 * @uml.property name="project"
 */
public void setCompany(Map<Object, Collection<Project>> project) {
	this.projectMap = project;
}

2.2 Velocity template

On top of the velocity template engine, eUML2 Studio provides more powerful template capabilities. Not only can users easily change the template definition, but also override the template definition or/and change the application scope at project, package, class and even property granularity.

Three template files are provided to handle three kinds of collection:

Variable name

Template file name

Description

java.util.Collection

uml2.Property-java.util.Collection.vm

General collection template

java.util.List

uml2.Property-java.util.List.vm

General ordered collection template.

Java.util.Map uml2.Property-java.util.Map.vm Qualified association template.

Here is the outline of the methods defined in these files. Please reference the Studio documentation for detailed information.

Collection template definition

{ElementType} get{PropertyName}; 
boolean is{PropertyName}Empty; 
boolean contains{PropertyName}({ElementType} o); 
Iterator<{ElementType}> {PropertyName}Iterator(); 
{ElementType} [] toArray(); 
<T extends {ElementType}> T[] toArray(T[] a) ; 
boolean add({ElementType} o); 
Object remove({ElementType} o); 
boolean containsAll{PropertyName}(Collection<? extends {ElementType}> c); 
boolean addAll{PropertyName}(Collection<? extends {ElementType}> c); 
void clear{PropertyName}(); 

List template definition

int {PropertyName}Size(); 
boolean is{PropertyName}Empty(); 
boolean contains{PropertyName}({ElementType} o); 
Iterator<{ElementType}> iterator(); 
{ElementType} [] toArray(); 
<T extends {ElementType}> T[] toArray(T[] a); 
boolean add{PropertyName}({ElementType} o); 
Object remove{PropertyName}(Object o); 
{ElementType} get{PropertyName}(int index); 
void add{PropertyName}(int index, {ElementType} element);  

Map template definition

int{PropertyName}Size();
boolean is{PropertyName}Empty();
boolean containsKey{PropertyName}({Qualifier.Key} o);
boolean containsValue{PropertyName}({Qualifier.Value} value);
{Qualifier.Value} get{PropertyName}({Qualifier.Key} key);
{Qualifier.Value} put{PropertyName}({Qualifier.Key} key, {Qualifier.Value} value);
{Qualifier.Value} remove{PropertyName}({Qualifier.Key} key);
Set<{Qualifier.Key}> keySet{PropertyName}();
Collection<{Qualifier.Value}> values{PropertyName}();

Back to the same example as for JDT template, the new version of the implementation is as follows:


/**
 * @uml.property name="project"
 * @uml.associationEnd multiplicity="(0 -1)" 
 *      inverse="company:model.Project" qualifier="key:java.lang.Object model.Project"
 */
private Map<Object, Collection<Project>> projectMap;

/**
 * Getter of the property <tt>project</tt>
 * @return  Returns the projectMap.
 * @uml.property name="project"
 */
public Map<Object, Collection<Project>> getProject() {
	return projectMap;
}

/**
 * Returns a set view of the keys contained in this map.
 * @return  a set view of the keys contained in this map.
 * @see java.util.Map#keySet()
 * @uml.property name="project"
 */
public Set<Object> projectKeySet() {
	return projectMap.keySet();
}

/**
 * Returns a collection view of the values contained in this map.
 * @return  a collection view of the values contained in this map.
 * @see java.util.Map#values()
 * @uml.property name="project"
 */
public Collection<Collection<Project>> projectValues() {
	return projectMap.values();
}

/**
 * Returns <tt>true</tt> if this map contains a mapping for the specified key.
 * @param key key whose presence in this map is to be tested.
 * @return  <tt>true</tt> if this map contains a mapping for the specified key.
 * @see java.util.Map#containsKey(Object)
 * @uml.property name="project"
 */
public boolean projectContainsKey(Object object) {
	return projectMap.containsKey(object);
}

/**
 * Returns <tt>true</tt> if this map maps one or more keys to the specified value.
 * @param value  value whose presence in this map is to be tested.
 * @return  <tt>true</tt> if this map maps one or more keys to the specified value.
 * @see java.util.Map#containsValue(Object)
 * @uml.property name="project"
 */
public boolean projectContainsValue(Collection<Project> project) {
	return projectMap.containsValue(project);
}

/**
 * Returns the value to which this map maps the specified key.
 * @param key key whose associated value is to be returned.
 * @return the value to which this map maps the specified key, or 
 *      <tt>null</tt> if the map contains no mapping for this key.
 * @see java.util.Map#get(Object)  
 * @uml.property name="project"
 */
public Collection<Project> getProject(Object object) {
	return (Collection<Project>) projectMap.get(object);
}

/**
 * Returns <tt>true</tt> if this map contains no key-value mappings.
 * @return <tt>true</tt> if this map contains no key-value mappings.
 * @see java.util.Map#isEmpty()  
 * @uml.property name="project"
 */
public boolean isProjectEmpty() {
	return projectMap.isEmpty();
}

/**
 * Returns the number of key-value mappings in this map.
 * @return the number of key-value mappings in this map.
 * @see java.util.Map#size()  
 * @uml.property name="project"
 */
public int projectSize() {
	return projectMap.size();
}

/**
 * Setter of the property <tt>project</tt>
 * @param value the projectMap to set.
 * @uml.property name="project"
 */
public void setProject(Map<Object, Collection<Project>> project) {
	projectMap = project;
}

/**
 * Associates the specified value with the specified key in this map 
 * (optional operation). 
 * @param key key with which the specified value is to be associated.
 * @param value value to be associated with the specified key.
 * @return  previous value associated with specified key, or <tt>null</tt>
 * @see java.util.Map#put(Object,Object)  
 * @uml.property name="project"
 */
public Collection<Project> putProject(Object object, Collection<Project> project) {
	return (Collection<Project>) projectMap.put(object, project);
}

/**
 * Removes the mapping for this key from this map if it is present 
 * (optional operation).
 * @param key key whose mapping is to be removed from the map.
 * @return  previous value associated with specified key, or <tt>null</tt> 
 *   if there was no mapping for key.
 * @see java.util.Map#remove(Object)  
 * @uml.property name="project"
 */
public Collection<Project> removeProject(Object object) {
	return (Collection<Project>) projectMap.remove(object);
}

/**
 * Removes all mappings from this map (optional operation).
 * @see java.util.Map#clear()  
 * @uml.property name="project"
 */
public void clearProject() {
	projectMap.clear();
}

 

© Soyatec 2002-2004. All Rights Reserved.