Monday, August 25, 2008

Websphere Datapower


IBM came up with a hardware to work as an Enterprise Service Bus (ESB). Well not entirely. It's called Datapower, a part of Websphere SOA solution stack. In our project there's a need to convert data from a mainframe fixed field format to XML and vice versa. So we were looking for a solution that can support a huge volume of transactions in a fraction of second. Using an ESB could be a possible approach but this one is easy to setup and since the conversion is done through hardware, it's really fast. They have three models for the appliance - XS35, XA40 and XI50. We were interested about the XI50 which includes the features of XS35 and XA40. It's a big (approx. 2.5ft / 2ft) blue box weighing nearly 20lbs. (I was about to break my back while trying to carry it). The cooling fans make loud noises. It has got an USB interface to the computer. You can set up the initial configurations using that and then it will let you access a web-interface (embedded as a firmware - like a wireless router) to handle configuration. Among the other main features
  • Transforms disparate message formats - binary, legacy, and XML. It can load XSL templates, so XML to XML translations can be carried out using XSLT.

  • Provides message routing (basic routing using round-robin) and security supporting standards such as WS-Security and WS-SecurityPolicy.

  • Able to connect with MQ, HTTP or FTP.

  • Helps heterogeneous applications to connect to registries and repositories, as well as directly to database.

  • Able to translation modules generated by WTX (Websphere Transformation Extender). We tried this while converting XML from/to fixed field format. So it supports non-XML such as COBOL Copybooks.
  • A piece of routing logic can be injected using the routing policies.

Here is a link for more information http://www-01.ibm.com/software/integration/datapower/

It doesn't support adapters like ESBs. It's a hardware so it can give you a power of processing equivalent to 10 servers running ESBs. Looking at the current prices of servers and the limitations on the customization making a selection will be a little tough. Unless it's not an XML to XML conversion WTX should be kept handy.

Monday, July 14, 2008

Pluggable knowledge base for human brain

I bought my first 1GB USB flash drive in 3300 Indian Rupees ($80 approx.) in 2004. Nowadays I see 4GB flash drives are available in $14.99. It's so cheap these days and I hope someday we are going to have 1TB USB drive in $50 or less. USB has become universal and you can find it in computers, cameras, media players bluetooth devices, external drives; all most any device that's pluggable with a computer.
I remember the movie Terminator to be good instance of man-machine fusion. Imagine someday we all will have an USB port attached to our heads. All our knowledge base will be made available in market in USB drives so that we can plug that into our brain and use them. An idea called Brain-Computer Interface close to this is already out in the market (http://en.wikipedia.org/wiki/Brain-computer_interface).


The OS vendors can see a nice business case in developing a firmware to install in the brain so that it understand and interact with the USB port.
An interpretation layer to translate the data from the external media in a format that the brain can understand (may be an electric pulse language :))
A lucrative business opportunity for Google to come up with a search utility to look up the knowledge base and find out the required material and supply it to the brain :)
We will have knowledge bases available for a doctor, an engineer, a lawyer, software engineer and whatever else you can think of under this sky.
If I need to be a doctor in the morning a pilot in the evening and a cook in the night, I can do every thing very skillfully with all these equipments :)
Well you will still need to practice if you are going for a swimming competition.

Yes you are correct I have some free time to relax my brain and talk rubbish :)

Tuesday, June 17, 2008

Code Generator Part VIII: The generated code

As the concluding part of the Code Generator series here is an example of how the generator works to generate the code. In this post I am going to present a sample object definition as the input (order.xml) to generate couple of Java source files using the home made code generator.

A piece of code generated using your home made Code Generator

Here is an example of an XML object specification for Customer, Order, OrderItem and Item objects to be supplied as the input for the code generation.


Order.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- order.xml -->
<OOSpec name="Order">
<Package name="">
<Class name="Customer" stereotype="class" visibility="public" baseInterfaces="Transformer">
<Import reference="java.util.Vector"/>
<Attribute name="code"/>
<Attribute name="names" multiplicity="3" defaultValue="Partha,Sarathi,Sengupta"/>
<Attribute name="age" type="integer"/>
<Attribute name="contacts" multiplicity="*"/>
<Operation constructor="yes" documentation="This is default constructor"></Operation>
<Operation directive="" documentation="This is transform operation" name="transform" returnType="string" bodyClassName="com. codegenerator.ToXMLStringBody">
</Operation>
</Class>
<Class name="Order" baseInterfaces="Transformer">
<Attribute name="number"/>
<Attribute name="date" type="date"/>
<Operation constructor="yes"></Operation>
<Operation name="transform" returnType="string" bodyClassName="com. codegenerator.ToXMLStringBody" synchronized="yes">
</Operation>
</Class>
<Class name="OrderItem" baseInterfaces="Transformer">
<Attribute name="number" type="integer"/>
<Attribute name="quantity" type="integer"/>
<Operation constructor="yes"></Operation>
<Operation name="transform" returnType="string" bodyClassName="com. codegenerator.ToXMLStringBody">
</Operation>
</Class>
<Class name="Item" documentation="This is a sample documentation">
<Attribute name="number"/>
<Attribute name="description" defaultValue="This is a description of the item"/>
<Attribute name="price" type="double" defaultValue="2.12"/>
<Operation constructor="yes"></Operation>
<Operation name="transform" returnType="string" visibility="public" bodyClassName="com.codegenerator.ToXMLStringBody">
</Operation>
</Class>
<Class name="Transformer" stereotype="interface" baseInterfaces="java.io.Serializable">
<Operation name="transform" returnType="string"></Operation>
</Class>
</Package>
<Association name="">
<Role class="Customer" multiplicity="1" name="" start="yes" navigable="no"/>
<Role class="Order" multiplicity="2" name="myOrders" navigable="yes"/>
</Association>
<Association name="">
<Role class="Order" multiplicity="1" name="order" start="yes" navigable="no"/>
<Role class="OrderItem" multiplicity="4" name="orderItems" navigable="yes"/>
</Association>
<Association name="">
<Role class="OrderItem" multiplicity="1" name="" start="yes" navigable="no"/>
<Role class="Item" multiplicity="1" name="item" navigable="yes"/>
</Association>
</OOSpec>


The Java source codes generated from the above specification are presented below. Notice how the transform method has been generated differently in each class.
Customer.java

/* This file has been generated by the CodeGenerator */
package com.order;
import java.util.Vector;

public class Customer implements Transformer {
private String code;
private String[] names;
private int age;
private java.util.ArrayList contacts;
private Order[] myOrders;

public String getCode() { return this.code; }
public void setCode(String code) { this.code = code; }
public String[] getNames() { return this.names; }
public void setNames(String[] names) { this.names = names; }
public int getAge() { return this.age; }
public void setAge(int age) {this.age = age;}
public java.util.ArrayList getContacts() {return this.contacts;}
public String getContacts(int index) {return (String)this.contacts.get(index);}
public void setContacts(java.util.ArrayList contacts) {this.contacts = contacts;}
public void addContacts(String contacts) {this.contacts.add(contacts);}
public Order[] getMyOrders() {return this.myOrders;}
public void setMyOrders(Order[] myOrders) { this.myOrders = myOrders;}
public Customer() {
code = new String();
names = new String[3];
names[0] = new String("Partha");
names[1] = new String("Sarathi");
names[2] = new String("Sengupta");
age = 0;
contacts = new java.util.ArrayList();
myOrders = new Order[2];
for(int i=0; i<myOrders.length; i++) { myOrders[i] = new Order(); }
}

/*This is transform operation*/
public String transform() {
StringBuffer sb = new StringBuffer();
if(code != null && !code.toString().equals("")) {
sb.append("<code>"+code+"</code>");
}
else {
sb.append("<code/>");
}
for(int i=0; i<names.length; i++) {
if(names[i] != null && !names[i].toString().equals("")) {
sb.append("<names>"+names[i]+"</names>");
}
Else {
sb.append("<names/>");
}
}
sb.append("<age>"+age+"</age>");

for(int i=0; i<contacts.size(); i++) {
if(contacts.get(i) != null && !contacts.get(i).toString().equals("")) {
sb.append("<contacts>"+((String)contacts.get(i)).toString()+"</contacts>");
}
Else {
sb.append("<contacts/>");
}
}
for(int i=0; i<myOrders.length; i++) {
if(myOrders[i] != null){
sb.append("<myOrders>");
sb.append(myOrders[i].transform());
sb.append("</myOrders>");
}
Else {
sb.append("<myOrders/>");
}
}
return sb.toString();
}
}
Order.java

/* This file has been generated by the CodeGenerator */

package com.order;
import java.util.*;

public class Order implements Transformer{
private String number;
private java.util.Date date;
private OrderItem[] orderItems;
public String getNumber() {return this.number;}
public void setNumber(String number) { this.number = number; }
public java.util.Date getDate() { return this.date; }
public void setDate(java.util.Date date) { this.date = date; }
public OrderItem[] getOrderItems() { return this.orderItems; }
public void setOrderItems(OrderItem[] orderItems) { this.orderItems = orderItems; }
public Order(){
number = new String();
date = new java.util.Date();
orderItems = new OrderItem[4];
for(int i=0; i<orderItems.length; i++) {
orderItems[i] = new OrderItem();
}
}
public synchronized String transform() {
StringBuffer sb = new StringBuffer();
if(number != null && !number.toString().equals("")){
sb.append("<number>"+number+"</number>");
}
else {
sb.append("<number/>");
}
if(date != null && !date.toString().equals("")) {
sb.append("<date>"+date+"</date>");
}
else {
sb.append("<date/>");
}
for(int i=0; i<orderItems.length; i++) {
if(orderItems[i] != null){
sb.append("<orderItems>");
sb.append(orderItems[i].transform());
sb.append("</orderItems>");
}
else {
sb.append("<orderItems/>");
}
}
return sb.toString();
}
}
Item.java

/* This file has been generated by the CodeGenerator */

package com.order;
import java.util.*;

/*This is a sample documentation*/
public class Item implements java.io.Serializable{
private String number;
private String description;
private double price;
public String getNumber() { return this.number; }
public void setNumber(String number) { this.number = number; }
public String getDescription() { return this.description; }
public void setDescription(String description) { this.description = description; }
public double getPrice() { return this.price; }
public void setPrice(double price) { this.price = price; }
public Item() {
number = new String();
description = new String("This is a description of the item");
price = 2.12;
}
public String transform(){
StringBuffer sb = new StringBuffer();
if(number != null && !number.toString().equals("")){
sb.append("<number>"+number+"</number>");
}
else{
sb.append("<number/>");
}
if(description != null && !description.toString().equals("")) {
sb.append("<description>"+description+"</description>");
}
else{
sb.append("<description/>");
}
sb.append("<price>"+price+"</price>");
return sb.toString();
}
}
OrderItem.java

/* This file has been generated by the CodeGenerator */

package com.order;
import java.util.*;

public class OrderItem implements Transformer{
private int number;
private int quantity;
private Item item;
public int getNumber(){ return this.number; }
public void setNumber(int number) { this.number = number; }
public int getQuantity(){ return this.quantity; }
public void setQuantity(int quantity){ this.quantity = quantity; }
public Item getItem(){ return this.item; }
public void setItem(Item item){ this.item = item; }
public OrderItem(){
number = 0;
quantity = 0;
item = new Item();
}
public String transform(){
StringBuffer sb = new StringBuffer();
sb.append("<number>"+number+"</number>");
sb.append("<quantity>"+quantity+"</quantity>");
if(item != null && !item.toString().equals("")) {
sb.append("<item>");
sb.append(item.transform());
sb.append("</item>");
}
else{
sb.append("<item/>");
}
return sb.toString();
}
}
Hope this article will help those who are looking for preliminary information on the concepts and technologies used in code generation. Please feel free to leave your comments.

Wednesday, June 4, 2008

Code Generator Part VII: Controller Layer

Finally here comes the control room for the code generation process. This is the place where the Importer, Exporter and the IOM get together to generate the code for me. This layer controls the orchestration of the entire process and is designed to be unaffected by any change in the Importer, Exporter or IOM layers. In my next post I will try to provide an example to explain how the code generator actually works in reality and generates code.

The Control Layer
It’s layer from where the Code Generator gets executed by the user. It has mainly two classes Generator and GeneratorUtility as shown in Fig 1.


Fig 1

This shows that the Generator class instantiates the Importer and Exporter type of classes. In case of Java source code generation, the Generator instantiates the XMLOOImporter (Fig 6) which implements the Importer interface for importing the XML input model. Once the XML model is imported and stored in the memory in the form of IOM model, the Generator instantiates the JavaExporter (Fig 7) which implements the Exporter interface for generating the Java source files as per the IOM model (Fig 3).

Generator is the common entry point for both code generation and template generation processes. This class has mainly two methods called “generate” and “main”.
The “generate” method takes 4 parameters as input – input model type (i.e. XML), output source code language (i.e. Java), name of the input model file (i.e. XML model file name) and the output destination directory. To generate the source codes, this class invokes the importer and the exporter simultaneously to read the class specifications from the XML input model file and to generate Java source code according to the class specifications.
Since this class also has a “main” method, it can be invoked from the command-line by using the 4 parameters described above. The Generator class is shown in figure 1.

GeneratorUtility is a common utility class that gets used by most of the classes involved in the code generator system. It contains some static values and utility methods used for intermediate processing or formatting. The GeneratorUtility class is shown in figure 1.
Below is a high-level sequence diagram of the Code Generator.



Fig 2

Actor invokes the Code Generator by calling the generate() method of the main class “Generator”. The actor specifies the input type (i.e. XML), output type (i.e. Java), input model file (XML file) name and the output destination (directory or path) while calling this method (Fig 2).
In case of Java source code generation, the generate() method instantiates XMLOOImporter class (which implements Importer) and invokes its start() method to read the class specifications from the XML model file provided as input (Fig 2). Once the classes are identified from the input model (XML), Generator instantiates the JavaExporter class (which implements Exporter interface) to generate java source files from those classes as specified in the XML model (Fig 2). At the end of generating the source files the Code Generator system will display a list of source files that have been generated and a message with the number of source files. Incase an invalid (not an XML) input document is provided to the system it will throw an exception and display the stack-trace for the exception.
Figure 3 shows detailed sequence diagram of the code generation process.


Fig 3
This section provides the relationship or mapping between the XML-tags used in the XML model supplied as the input to the Code Generator and the corresponding IOM class that represents the tag in the memory object model (IOM).
Figure 4 shows the relationship between different components defined in XML and realized in IOM for the source code generation process. Blue boxes marked with "XML Tag" in the diagram represents the tags used in the input XML model and other boxes are representing the IOM classes already shown in Part IV of this series. The attributes shown in the XML-tags (blue boxes) are the XML-attributes. The names of the XML-attributes are quite identical to those of the corresponding IOM class e.g. the attributes – name, stereotype, visibility, documentation, isStatic, isFinal, isAbstract etc. of IOMClass are having identical names with the respective XML-attributes (i.e. name, stereotype, visibility, documentation, static, final, abstract) in the Class tag. The attributes that are not in the XML-tags but present in corresponding IOM class are used for internal processing of Code Generator.
Since XML does not allow data types other than character strings, the data type of XML-attributes is given as string. After the XML input model file is parsed, individual XML tags are parsed and translated to the respective IOM objects and stored as the internal object model in the memory. During the translation of input XML the string data types are also converted to appropriate Java data types e.g. value of isStatic is given as “yes/no” in the XML, it’s converted to Java boolean (true/false) type. While generating the output the exporter reads the internal object model from the memory and generates appropriate documents accordingly.

Fig 4

Wednesday, May 21, 2008

Code Generator Part VI: Exporter Layer

It's been a long time I managed to keep myself busy :) , back again to stretch a little bit on the blog. It's the turn of the Exporter part of my code generator. I would try to put together a rough idea about the design model of the Exporter. This layer is responsible for exporting the object model (IOM) that has been created in the memory by the Importer to a desired code (e.g. Java, C++ etc.). The input for the exporter should be the IOM (stored in the memory) and the output should be the generated code in a desired programming language or any other format (e.g. CSV, RTF), provided the exporter has to be made knowledgeable enogh to transform the IOM into the desired format. I will try put the pieces (Importer, Exporter, IOM) together in a a controlling framework in my next post.


The Exporter Layer

The exporter has the responsibility of translating the IOM created by the importer and generating the desired output document (i.e. Source Codes or Documents in a specific format).
Incase of code generation the exporter translates the IOM created by the importer and generates the desired output source codes from the IOM. The code generator can have different exporters depending on different output types (i.e. output languages like Java, C++ etc.). Currently we are generating the Java source codes by the exporter. The exporter has been designed using a generic interface (Exporter) as the parent. Any class that generates source codes in a specific object-oriented language from the IOM should have the Exporter interface as its parent. In our case we have an exporter class (JavaExporter) that exports Java source codes according to the object-oriented class specification as defined in the input XML model. This class, called JavaExporter implements another interface called OOCodeExporter which already implements the Exporter interface (Fig 7). The reason behind introducing the OOSpecExporter interface is to encapsulate the activities involved in generating source code in all object-oriented languages in a single interface. This way the Exporter interface can be further implemented by other exporters for generating source codes in different object-oriented languages other than Java (e.g. C++, C# etc.). Below are the descriptions for the classes that belong to the exporter layer.
Please refer to Fig 1 for the classes involved in the Exporter layer.



Fig 1

Exporter is designed as a generic interface. The interface contains the start(), initialize() and finalize() methods. The main entry point of the code generator i.e. the Generator class invokes the exporter using the start() method of this interface. To use the code generator for generating source code in a specific object-oriented language (e.g. Java, C++, C# etc.), new exporter classes can be introduced implementing the same Exporter interface.

OOCodeExporter is an interface implementing the Exporter interface. The purpose of this interface is to encapsulate the operations required to generate source codes in object-oriented languages. Currently the JavaExporter implements this interface to generate Java source codes according to class specifications defined in the input XML model. In future new exporters can be introduced as children to this interface for generating source codes in different OO languages other than Java, e.g. C++, C#, VB etc. The implementation of the Exporter interface depends on the type of OO languages (Java in our case) in which the source code will be generated, so different languages can have very different implementations.

JavaExporter implements the OOCodeExporter interface. The architecture of this class is closely bound to the SAX parser philosophy. This class works on the IOM objects (i.e. IOMClass, IOMAttribute, IOMOperation etc.) stored in the IOMOOController by XMLOOImplorter. The start() method begins to navigate through each object in the internal object model (IOM) and calls the startClass() method each time a IOMClass object is processed, and in general the startXxx() method each time an instance of IOMXxx is processed. The exporter then invokes the endXxx() methods when an instance of IOMXxx is finished to be processed. It creates an output file using the name of the class and adding the JAVA extension. Then it writes, by using the information coming from the IOMClass object, Java code for declaring a class. By implementing all the methods, the JavaExporter class generates the Java classes corresponding to XML model in terms of attributes, operations, and associations. The JavaExporter works based on certain assumptions as described below.
The generated Java source files involved in the DTOs will by default
- Do not need to implement a base class.
- Implement the "Serializable" interface.
- Import "java.util.*" and “java.io.Serializable”.
- Have the stereotype as "class".
- Have visibility "private" for attributes.
- Uses public getter/setter operations.
- Has non-final and non-static attributes or operations.
- Use attributes with type "String".
- Use attributes with multiplicity as "1".

Tuesday, April 15, 2008

Code Generator Part V: Importer Layer

As was mentioned in the previous post that a typical code generator includes an IOM, Importer and an Exporter, this post will try to draw a picture of the design model of the Importer part of a code generator. This layer is responsible for importing the object model that has to be generated in code to the memory and draw a IOM model in the memory. The input can be XML, database schema or any other customized format provided the importer has to be designed in order to understand and interpret the input format and convert it to the IOM. There is one more layer included in the anatomy of the code generator - the Exporter. I will try explain it in my next post.

The Importer Layer

The importer has the responsibility of reading the model as input and creating the IOM. The code generator can have different importers for different input data sources (XML, CSV, Database schema etc.).In accordance with MDA paradigm, the importer for code generation process reads an input model — representing UML and created by UML tools, such as Rational Rose. Currently we are creating the XML model manually. Presently the importer has been designed using a generic interface (Importer) as the parent. Any class that imports a model should have the Importer interface as its parent. In our case we have an importer class (XMLOOImporter) that imports XML model containing the specification for the classes whose source files has to be generated. The class named XMLOOImporter implements another interface called OOSpecImporter which already implements the Importer interface (Fig 6). The reason behind introducing the OOSpecImporter interface is to encapsulate the activities involved in importing an object-oriented model in a single interface.This way the Importer interface can be further implemented by other importers for importing models defined in different formats other than XML (e.g. XMI, CSV, XML schema, Database schema etc.). Below are the descriptions for the classes that belong to the importer layer. Please refer to Fig 6 for the classes involved in the Importer layer.




Fig 6


An Importer (as shown in fig 6) is designed as a generic interface. The interface contains the start() method that starts the importing process. The main entry point of the code generator i.e. the Generator class invokes the importer using the start() method of this interface. To use the code generator for generating source codes in a specific object-oriented language (e.g. Java, C++, C# etc.) new importer classes can be introduced as the children to the same Importer interface. New importer classes can be written for different formats (e.g. XML, Database schema, DTD, XML schema, XMI etc.) of the input model to the code generator as well.



OOSpecImporter is a child interface of Importer interface. The purpose of this interface is to encapsulate the operations required to import object-oriented class specifications. Currently the XMLOOImporter class implements this interface to import object-oriented class specifications defined in the XML format. In future new importers can be introduced as children to this interface for importing different input models other than XML, e.g. database schema, XML schema, CSV format etc. Each of the createXxx() (i.e. createClass(), createAttribute() etc.) methods in this interface takes “data” of type java.lang.Object as the input. By implementing the createXxx() methods the IOM structure can be created starting with the “data” as input. The createXxx() methods returns the corresponding types i.e. createClass() returns IOMClass, createAttribute() returns IOMAttribute and so on. The implementation of the Importer interface depends on the model as input, so different models can have very different implementations. Nevertheless, the common target is creating the IOM structure.



XMLOOImporter class is inherited from the OOSpecImporter interface and org.sax.helpers.DefaultHandler class (to handle SAX parser events). This class works on a XML representation of UML. The XML structure is straightforward—it recalls UML concepts such as classes, attributes, operations, parameters, associations, and roles. The XMLOOImporter class uses a SAX parser. For each relevant element found in the XML as input, it calls the proper method of the OOSpecImporter interface. For example the element causes the invocation of the createClass() method. The method creates a new IOMClass object, populates the name, stereotype, visibility, documentation, packageName etc. attributes with the value coming from the XML, and pushes the object into a stack for future uses. The other createXxx() methods (createAttribute(), createOperation(), createParameter() etc.) are implemented in a similar way.

Thursday, March 20, 2008

Code Generator Part IV: IOM

Following the previous post the current post will try to draw a picture of the design model of a code generator. All the objects included in the context of a code generation process (e.g. for a code generator that generates object-oriented source code, the building blocks of the IOM are class, attribute, operation, parameter etc.) has been designed as the Internal Object Model (IOM). There are two more layers included in the anatomy of the code generator - Importer and Exporter.

The IOM Layer

For the object-oriented code generation process the IOM has been designed borrowing UML concepts. Basically, the internal model can be a representation of the object-oriented concepts following the structure of UML model and notation. Therefore, a set of classes and associations has been designed representing UML classes, attributes, operations, parameters, and associations. Basically in this case the UML features and rules have been designed by using UML itself. As a convention, IOM classes start with the IOM prefix. Fig 3 shows a class diagram of the IOM classes. The IOMClass class models a UML class. It has an aggregation with the IOMAttribute and IOMOperation classes because classes have attributes and operations. Since operations have parameters, an aggregation is modeled between the IOMOperation and the IOMParameter classes. The IOMAssociation class represents a UML association. It has two roles (start and end) that are modeled by the IOMRole class. Then, that last class has an association with the IOMClass class (involved), which represents the start or the end class of the UML association. IOMOOController class acts a controller and stores the entire IOM (collection of all classes and associations included in the IOM) as a static aggregation. IOMOperationBody is an interface that represents the body of any operation to be defined at a later time. Any class that represents the body of an operation will have to implement the IOMOperationBody interface. For instance, ToXMLStringBody class contains the implementation of the “transform” method (a method to print out the values of all the attributes of a DTO) for all the generated DTOs. The descriptions of the classes involved in the IOM layer are given below. Fig 3 shows the classes involved in the IOM layer for the source code generation process.


Figure 3

IOMClass class represents a class in object-oriented scenario according to UML. It has ten attributes: name (the name of the class), stereotype (the UML associated stereotype), documentation (documentation for the class), packageName (the package in which the class belongs to), visibility (the visibility of the class, the values of this attribute can be private, public, protected.), isFinal (indicates whether the class is a final one), isAbstract (indicates whether the class is an abstract class), baseClasses (list of base classes of this class), baseInterfaces (list of base interfaces of this class) and imports (list of links to other libraries or APIs, e.g. “import” clause in Java). The aggregations with the IOMAttribute and IOMOperation classes are implemented by two ArrayList (attributes and operations) and related get/set/add methods. The class also contains the getAssociations() method that returns all the IOMAssociations in which the class is involved as a start or end role.

IOMAttribute class represents an attribute/member of a class in object-oriented scenario. It has twelve attributes: name (the name of the attribute), type (the type of the attribute, currently the code generator supports boolean, char, byte, integer, float, double, long, string, date, short or any custom type like “MyClass”), multiplicity (multiplicity of the attribute, if it’s a collection or array), documentation (documentation for the attribute), visibility (the visibility of the attribute/member, permitted values are private, public, protected.), defaultValue (the default value with which this attribute will be initialized, if not specified, the attribute will be initialized by it’s default value according to Java standards e.g. string type will initialized by “new String()”), isStatic (indicates whether the attribute is a static one), isFinal (indicates whether the attribute is a final one), isTransient (indicates whether the attribute is a transient, i.e. uses the transient keyword of Java), classParent (this is a reference to the IOMClass instance to which the attribute belongs), elementTag (XML tag in which the value of this attribute will be encapsulated during XML transformation) and groupTag (If the member is a collection of values i.e. multiplicity is more than one, the value of groupTag will be used as an XML tag encapsulating the group of values during XML transformation).

IOMOperation class represents an operation / method of a class in object-oriented scenario. It has sixteen attributes: name (the name of the operation), returnType (the return type of the operation, currently the supported types by the code generator are boolean, char, byte, integer, float, double, long, string, date, short or any custom type like “MyClass”), documentation (documentation for the operation), visibility (the visibility of the operation / method, the permitted values are private, public, protected.), isStatic (indicates whether the operation is a static one), isFinal (indicates whether the operation is a final one), isAbstract (indicates whether the operation is an abstract one), isConstructor (indicates whether the operation is a constructor. The constructor name will always be same as the class name for Java code generation), isDestructor (indicates whether the operation is a destructor. Currently this attribute is not used it’s kept for future uses for generation in other languages like C++.), exceptions (list of exceptions that this operation might throw while executed), isSynchronized (indicates whether the operation is synchronized), isNative (indicates whether the operation is native), classParent (this is a reference to the IOMClass instance to which the operation belongs), directive (this indicates any other options that might be required in future, not used currently), bodyClassName (the name of the class that returns the body content of this operation) and body (the body content of the operation as returned by the class whose name is mentioned in bodyClassName. The class with the given name will be loaded at the runtime by the code generator and invoked using reflection to get the body content of the operation), body (the body content of the operation that has been returned by the class mentioned in the bodyClassName) and classParent (the parent class to which the operation belongs). The usage of bodyClassName attribute makes the code generator independent of the business logic of an operation. This way the logic of an operation is externalized from the code generator.

IOMParameter class represents a parameter of an operation in object-oriented scenario. It has three attributes: name (the name of the parameter), type (the type of the parameter, currently the supported types by the code generator are boolean, char, byte, integer, float, double, long, string, date, short or any custom type like “MyClass”) and operationParent (the operation name that takes this parameter as the input).

IOMAssociation class represents an association with another Class in object-oriented scenario. It has two roles (start and end) that are modeled by the IOMRole class i.e. two IOMRole instances indicating start and end of the association. It has one attribute: name, which is the name of the Association. This class contains the get/set methods for the above-mentioned attributes.To explain the way in which the associations will be implemented we can consider an example. In this example, four different cases of relations between two classes have been considered. Fig 4 shows those cases.


Figure 4

As it has been depicted in the above figure, when the class A has a bi-directional (navigation is true on both sides) association with just one class, B, the generator creates the setXxx/getXxx methods for both A and B. If the association is unidirectional (navigation is true on one side and false on the other side), B won't have the setA and getA methods, because that navigation is not allowed. When the A class can be associated to more B classes, A contains addB and getAllB, while B contains setA and getA, if the association is bi-directional, and no method otherwise.

Since a role in an association is interpreted as an attribute of a class, the IOMRole class has been designed as a child class of IOMAttribute. The IOMRole class represents the role of a class in an UML association. It has three attributes in addtion to the attributes of IOMAttribute class: isNavigable (unidirectional or bi-directional), classInvolved (name of the IOMClass having this Role), isStart (indicates whether the role is indicating the start or end of an association). This class contains the get/set methods for all the above-mentioned attributes.
IOMOperationBody is an interface representing the body of an operation. This interface has only one method - getOperationBody(). The method takes an IOMClass object as the input and returns a string containing the content of body of an operation. The IOMClass object is considered as the parent to the operation whose body is returned. Once there is a need to describe an operation body, a new class has to be developed implementing this interface and the actual body content of the operation has to be returned from the getOperationBody() method of the child class. ToXMLStringBody is such a child of IOMOperationBody interface.

The root class of the model is IOMOOController, which is shown in Fig 3. It contains and provides the possibility of access to the instances of IOMClass and IOMAssociation involved in the model. This class is designed as a static class. Since the Code Generator System is not a part of any client-server system or product and it is to be used by a project team member/developer in stand-alone mode, this class has not been designed to run in a multi-threaded environment. In addition, the IOMOOController class implements the queryClass() method that may be useful to search a class by name. Importers and exporters start from that class respectively to create the IOM and to read metadata from it to write the output.

Thursday, February 14, 2008

Code Generator Part III: Code Generation using MDA

Code Generation using MDA mainly involves three phases.
  • Parsing the code that is supplied as the input. This is known as import.

  • Collecting the theme or model of a language from the input, known as internal modeling.

  • Generating the theme in a form of code that can be understood by the target, known as export. The target might be hardware or another software interpreter.

Based on the functionality the architecture of a typical Code Generator can be perceived as below. A code generator can be imagined of being consisted of three different modules / layers as shown in (Fig 2):

Fig2

Importer – This module reads the model as input and translates it into a platform-independent internal format based on an object model. An importer could be seen as a sort of XML parser. But, by generalizing the design of an Importer any kind of input can be read.

Internal Object Model (IOM) – This is the platform-independent internal format of the input model and could be considered as the core of the code-generator architecture. IOM contains a set of classes that make it easy to manipulate the information coming from the model to generate outputs. The structure of the IOM is a very important issue— if designed carefully it can be a powerful target-technology (Java, C++, etc.), independent representation that can be converted easily in source code.

Exporter – This module accesses the IOM and takes the relevant information to generate code. It could use templates, which drives the generation process and makes the exporter more generic and independent of the output language syntax. For the current version code generator, the exporter has been designed without using the Template-Based approach.

The architecture described above has following benefits for code generation:

  • The input is completely independent of the output in terms of technologies. For instance, an importer can be created that reads a UML diagram and then an exporter writing C#-ADO code and another one writing Java-JDBC code, but both work with the same UML model as input.

  • If the IOM is implemented following the UML, everything that can be represented with UML can be done with IOM as well, which means that every kind of input can be represented and converted into a real object-oriented design. It is a big advantage in writing importers and exporters manipulating the model. The IOM layer adds flexibility to the code generator and introduces loose coupling between the importer and the exporter.

  • By implementing multiple exporters and applying a simple pattern, different layers of code can be created—source code, descriptors, documentation, scripts, and so on—with a single pass that assures consistency and synchronization among the different outputs.

Tuesday, February 12, 2008

Code Generator Part II: Architecture of a typical Code Generator

A code generator is a program that takes a model as an input and produces an output source code, by implementing that model. The model consists of a set of metadata containing information about the code that will be generated. Based on the requirement a model can be a Unified Modeling Language (UML) design, a proprietary descriptor file, a database schema or even another source code. The model format can be XML, plain text, CSV, or other kinds of sources such as directories, databases, or repositories. Starting from the information contained in the model, a code generator creates source code, which belongs to a programming language (C, C++, Java, C#, VB, and so on) or to another type of output: documentation, descriptors, configuration files, SQL code, and so on (Fig 1).




Fig 1

Depending on the type of input, code generators can be classified in two types – code driven and model driven. A code-driven generator takes as input a file containing source code and special tags, which drive the code generation process e.g. JavaDoc. Model-driven generators can also be sub-classified into two types – custom and MDA. A custom generator takes as input a proprietary model representing the information that must be converted in source code e.g. Apache Velocity. When the model as input is a representation of UML, then the code generator follows the Model-Driven Architecture (MDA). An MDA code generator takes a platform-independent model (usually XMI, an XML representation of UML) as input and turns it into a platform-specific model, which can be converted easily in source code by means of templates.

In this article and the following articles I will try to explain a code generator that converts a set of object definitions (expressed in an
object-oriented paradigm i.e. UML) of simple Data Transfer Objects (DTO) from a XML text to a Java program. The same code generator can be enhanced to generate C++ programs, SQL scripts, PHP scripts from the same XML input. In the real world scenario, a programmer might not possess the skills in all the languages but he/she can be well conversant with the concepts of the object-oriented (OO) paradigm and is able to design an OO system. The concepts or design of a system can be stored in a widely popular common format e.g. XML. The utility of this tool is to facilitate the transformation of the concepts and design from the XML to a desired language. Most of Computer-aided Software Engineering (CASE) tools like Rational Rose etc. support this sort of code generation.

Thursday, February 7, 2008

Code Generator Part I: Compiler, Interpreter and Code Generator

The evolution of computer programming languages started from assembly languages and traversed a long way through first, second, third and fourth generation. The clue of this advancement was mostly based on abstraction, meaning we always tried using a programming language to make the hardware understand human instructions. At the same there is a continuous effort to make our programming languages look good and similar to a human language (e.g. English). So every time a new language evolved it came along with an interpretation tool like a compiler or an interpreter. The role of an interpretation tool is basically to interpret the human like language to something that the machine can understand. For example if I write a computer program to make the computer print something on the screen – “Hello World”. The program might look like - Print(“Hello World”); The interpretation tool transforms the program above in a binary code like “!#$233#4@36644!~~2%4^ Hello$@@$63World#&&^##%” (believe me it’s a pure example, not an abusive language and has got no link to an actual machine/binary code). Finally the hardware understands this binary code and generates signals to print out the “Hello World” on the monitor.

This is a very basic instance of code generation – from a human like programming language to machine code. Nowadays there nice and beautiful graphic interfacing tools are available that lets you create a document (e.g. Word Processors), draw a picture (Drawing tools), send a mail (mailing software), browse the internet (browsers) and even designing a user interface graphically using mouse can be done by tools. They all use code generation to save and read documents or pictures, interpreting the mail or web pages and showing them in nice graphical interfaces, generating codes for user interfaces that can be executed by the machine later after designing.

In the internet age, the most popular way of expressions and communications are being done using the markup languages like HTML, XML, WML, SGML, SVG etc. The reason behind the popularity of these languages is that they are English text based and easily explicable to the common people and other software systems. The languages are very helpful in communicating in the global community of heterogeneous software systems.
Think of a scenario where my program which is built using a latest technology (e.g. C++/Java, J2EE .Net etc.) is trying to talk with another program which is built using COBOL running on the other part of the world, we need a language or protocol of communication that can be understood by both of them. This is where the markup languages could help a lot. My program can interpret its data to a XML text and send it to the other program while it can translate the data back from XML to a format that it can understand. The other program can reply to my program in a similar fashion.

I will try to explain the Architecture of a typical Code Generator in the following posts.