Friday, February 12, 2010

I don't see my words in your design

It has always been a long and tough session to make the business people understand the thought process behind attaining a particular design model. In my career as a software designer I faced several categories of stakeholders for my design such as the IT-managers from the client's side, technical IT people, business people, end-users etc.
Usually we go and meet these users to grab the requirement of the system/application they are looking for and then try to draw a mapping between the requirement and the software logical constructs such as classes, objects, services, components etc. During the process some new terms pop up based on the abstraction of the designer which might not surface the exact word specified in the requirement. Designers try to map the features/requirement of the application with the logical software constructs which is sometimes beyond the understanding of some of the stakeholders.
Based on the technical knowledge on software design of the stakeholder it becomes harder or easier to bridge the gap and make them happy. I am sure all the designers have experienced these kinds of sessions where the audience is shouting at you syaing "I don't see my words in your design, make me understand how are you arriving at this model of yours..". It will be followed by a long discussion of why I did it.
For example, a person who drives a car might not be very familier with the internal structure or mechanism of a chasis or gear box, but you have to make him/her understand how is it related to the process of driving else S/he will not buy the car... I just had this kind of session today :)

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.

The Rarest Skill in Software Engineering · Enterprise Architecture · 30 Years in the Trenches The Rarest Skill in Softwar...