This article describes how to extend the EA’s code generation framework to support your required code generation approach.
A few basics first:
The code generation framework of EA is based on templates. Each template is derived from a specific type like Attribute, Class, Operation, etc. and provides access to the objects provided by the template type, the attributes of a class or all class properties like stereotype, etc.
With the templates you get access to parts of the model and with the substitution macros you get access to the actual values of the model which is currently processed.
In addition to the substitution macros you can also use control structures, like if then else and variables to store intermediate results and further process the values with function, which are the last part of the code generation framework.
EA provides a set of predefined functions. The complete list of functions and substitution macros can be found in the EA help.
Now we come to the more interesting part of this blog post; how to extend the code framework if you miss something in the list of macros and functions.
EA provides an additional function which is called EXEC_ADD_IN(…) which allows to call you own add in. With other words you can create your own functions/macros and call it from within the code templates.
One of our customers had the problem with the EASL_GET(…) function, which allows to query properties from the currently processed element. This function is mainly used behavior code generation. However, EASL_GET(…) is restricted to be able to query only the tree branch in which currently processed model element is contained!
If you would like to call an Activity1 which is contained in a ClassX in PackageA, it is not possible to the these information from an Activtiy2 which is contained in ClassY in PackageB with the EASL_GET(…) function.
However, you can use the EXEC_ADD_IN function to call your own MyEASL_GET() function.
Call this line from within a code generation template:
%EXEC_ADD_IN(“TestEAAddIn”, “MyEASL_GET”, “element”, $GUID, “Name”)%
This line will call the following function within an EA AddIn:
public string MyEASL_GET(Repository rep, object args)
{
string result = “”;
try
{
var p = (Array) args;
var what = p.GetValue(0) as string;
var owner = p.GetValue(1) as string;
var name = p.GetValue(2) as string;
switch (what)
{
case “element”:
Element ownerElement = rep.GetElementByGuid(owner);
result = ownerElement != null ? GetElementProperty(rep, ownerElement, name) : “”;
break;
case “attribute”:
EA.Attribute diagramByGuid = rep.GetAttributeByGuid(owner);
result = diagramByGuid != null ? GetAttributeProperty(rep, diagramByGuid, name) : “”;
break;
}
}
catch (Exception e)
{
rep.CreateOutputTab(Output);
rep.EnsureOutputVisible(Output);
rep.WriteOutput(Output, string.Format(“Error in Function MyEASL_GET: {0}“, e.Message), 0);
}
return result;
}
The actual work is done by the follwing operation:
public static string GetElementProperty(EA.Repository repo, EA.Element element, string name)
{
Type elementAsType = element.GetType();
PropertyInfo property = elementAsType.GetProperty(name);
if (property != null) //there is a property of name: name
{
object value = property.GetValue(element, null);
return value.ToString();
}
throw new Exception(string.Format(“EA Element of type: {0} do not has aproperty with name: {1}“, element.Type, name));
}
The provided function allows to query properties from an element or diagram in a generic way. The function MyEASL_GET is a kind of dispatcher, the actual work is done by the operation GetElementProperty(…).
You can query any property of the provided EA element. The property name is stored in the variable “name”. The operation uses reflection to check if a property “name” is available, if the property is found, its value is returned.
You can query any property with this generic approach, simply provide the name of the property as string when you call MyEASL_GET. The $GUID provides the guid of the currently processed model object. The string “element” indicates that the last parameter (“name”) should be interpreted as a property of an element.
When you call MyEASL_GET from within an attribute template, $GUID will contain the attribute guid and you can get any property of an EA attribute when you add “attribute” as the 3rd parameter.
If you need further support to adopt you code generator please send us a request at vendor@sparxsystems.eu.
Alternatively you can also use other code generation frameworks like the UML2Code framework from our partner company Lieber Lieber.