Generate JavaBean classes dynamically with XSLT

Use the XSLT processor as a powerful source code generator

In some commercial software projects, you cannot afford to cast in stone the structure of business objects. For example, different companies may have different and even mutually exclusive requirements for Product bean properties. Without a proper framework in place, you may end up spending long hours customizing all your data structures, including classes, database tables, DTDs (document type definitions), and so on, for every new customer. Needless to say, you may soon find yourself with a pocketful of parallel software versions and a maintenance headache. How do you ensure that your design is flexible enough to satisfy varying business requirements without a need to do extra coding each time those requirements change?

In this article, I lay a foundation for a simple framework I successfully employed to build truly adaptive systems. It is based upon dynamic source code generation from a class's metadata maintained in a data dictionary. In the process, you'll get a refresher on JDBC (Java Database Connectivity) and JSPs (JavaServer Pages), and you'll also learn to generate source code with one of today's most fascinating XML-related technologies, XSLT (Extensible Stylesheet Language for Transformations).

Short design session

First, let's set up a simple hypothetical project to which we can apply all the wonderful techniques discussed here. The project will be an application geared towards a vertical market that has a

Product

concept in its business vocabulary. You can pick your own favorite business domain -- financial services, online retailing, or maybe even technical training; anything that uses a product. The system architecture is not a constraint either; it may range from a standalone application to a distributed

n

-tier system. In this article, we will concentrate on the business object design issues equally applicable in the wide array of different projects.

Since we won't design this application for a particular customer, we must make sure we know the business well enough to cover the most complex cases. To achieve that, we hire the best domain experts, run a few CRC (class-responsibility-collaboration) sessions, chart several use cases, and eventually assemble a clear understanding of a Product concept, among many others. With that information on hand, we can build a conceptual business domain model that includes our perfect Product bean depicted below:

Product

code: int

name: String

testedOnAnimals: boolean

availableSince: java.util.Date

This is roughly what we do in real projects before the actual coding, especially if we adhere to a good software development process.

Traditional implementation

Now we can implement the construction phase, where we craft the Product bean's Java code. In Java terms, a bean is a reusable component from either the JavaBean or the Enterprise JavaBean (EJB) frameworks. Despite many significant differences between the two kinds of beans, there are also similarities. For example, they share the notion of a bean property. The bean property is based on the standard Java naming convention for the pair of accessor methods. Thus, if the bean has a nonindexed property code, it is assumed that it provides the writer and reader methods setCode() and getCode(), respectively. The reader method for the boolean type property would be isCode(). For an indexed property, the bean is assumed to possess two sets of setCode() and getCode() methods, one of which would be indexed while the other would deal with the whole array. The java.beans.Introspector uses the same rule set applied in reverse to dynamically analyze the bean class and discover the set of exposed bean properties on the fly.

The properties concept becomes particularly handy when you need to map a business object to a data repository, like a database table or an XML document. Similarly, it helps at the presentation tier too. For example, the JSP API provides a mechanism for mapping HTTP request parameters to the bean's properties. The following action saves a tremendous amount of routine coding by magically initializing bean properties from the matching fields in an HTML form:

<jsp:setProperty name="myBean" property="*"/>

Ultimately, a bean is just a Java class that adheres to a set of well-defined rules. Let's use the simpler bean type, JavaBean, for our project, which will adequately demonstrate the points made here. Later you may apply these techniques to EJB components as well.

Now we can say that our Product bean has the integer property code, the String property name, the boolean property testedOnAnimals, and the date property availableSince. As we might expect, the bean translates to Java as Listing 1 shows:

Listing 1. Product.java

public class Product {
  private int code;
  private String name;
  private boolean testedOnAnimals;
  private java.util.Date availableSince;
  public Product() {}
  public int getCode() {
    return code;
  }
  public void setCode(int newCode) {
    code = newCode;
  }
  public void setName(String newName) {
    name = newName;
  }
  public String getName() {
    return name;
  }
  public void setTestedOnAnimals(boolean newTestedOnAnimals) {
    testedOnAnimals = newTestedOnAnimals;
  }
  public boolean isTestedOnAnimals() {
    return testedOnAnimals;
  }
  public void setAvailableSince(java.util.Date newAvailableSince) {
    availableSince = newAvailableSince;
  }
  public java.util.Date getAvailableSince() {
    return availableSince;
  }
}

The pros and cons of traditional implementation

For this project, we've chosen a straightforward, fast, and inexpensive approach to building the Product bean. Certainly, we may extend it to EJBs as well. As a result, we will have a system that hopefully suits all possible scenarios within the business domain.

In most cases, we can get away with this approach. However, what happens if a new customer unexpectedly comes up with a different perspective on our carefully designed beans? What if we must add a new Boolean property y3KCompliant to the Product bean? Remember, we'd need to modify not only this particular bean's source code, but also all the relevant data structures, including BeanInfo classes, SQL statements, and perhaps some classes that belong to our application's view and controller parts. Worse yet, what if the customer wants permission to do all that without our help? Don't forget that when you deal with a real commercial business application, you likely have at least 100 different business objects. So, what if you must tune each object for every new customer? On the flip side, what once looked like a quick and easy solution appears to be a bottleneck.

One common solution adds extra properties to each business object, reserved specifically for the client's proprietary purposes. Let's try this tactic and add three extra properties for a few primitive types, as well as for the String and the Date types to our Product class:

Product

code: int

name: String

testedOnAnimals: boolean

availableSince: java.util.Date

num01: double

num02: double

num03: double

bool01: boolean

bool02: boolean

bool03: boolean

str01: String

str02: String

str03: String

date01: Date

date02: Date

date03: Date

Sometimes this solves the problem, but frankly it looks ugly and feels uncomfortable. From my years in software development, I've learned that a lack of inner comfort is a reliable sign of bad design. And really, how can we be certain that each type's three extra properties are sufficient? Moreover, those customers who never needed those extra properties will pay high price in the form of wasted table space. Can't we design a system that easily adapts itself to the different business requirements?

Code generation to the rescue

The problem we face resembles the situation in which a Website's static HTML content can no longer satisfy business demand. In that case, Web application developers use various technologies to deliver dynamic data-driven content. We need something similar that, instead of HTML, generates Java source code for our beans. This becomes our main objective now. Once we have an adequate solution, you can extend it to all other data structures involved in application customization. Assuming you have a proper application framework in place, you should be able to simply plug in the new code without any additional coding. If you can do that, then your clients will be able to perform such customization themselves -- if provided with a slick GUI interface, of course.

To benefit from the automatic code generation process, we need to feed it detailed bean descriptions. In other words, we need a repository that we can query for the class's metadata. This is similar to the idea of the database metadata we can obtain using the getMetaData() method of the java.sql.Connection interface from the JDBC API. In the RDBMS (relational database management system) world, such information is usually maintained through the data dictionary -- a set of system tables that completely describe the database structure.

In the OOAD (object-oriented analysis and design) world, UML (Unified Modeling Language) often expresses the class metadata. An increasing number of UML modeling tools provide forward-engineering facilities from UML to source code and vice versa. Even though I prefer to keep the UML model and the source code in synch, I am not satisfied with the level of control we have over the code-generation process with these kind of tools.

Another language used to describe metadata is, of course, XML. It has several features that make it particularly attractive for this task:

  • XML is platform and application independent
  • You can easily validate XML documents against a DTD or schema
  • XSLT stylesheet processors easily transform XML documents into any other format, including source code in Java, Smalltalk, or even C#

In fact, the XML Metadata Interchange (XMI) format developed by IBM, Unisys, Oracle, and other industry leaders is a common language for metadata interchange between modeling tools, as well as between the tools and metadata repositories. Though we could use it here, it probably would require another article as an introduction. Also, XMI is to some extent overkill for what we want to do. However, you should keep XMI in mind when you work on more sophisticated projects. Certainly all the techniques we discuss in this article will still be valid if you decide to employ XMI.

Before we continue, I would like to mention one interesting solution addressed in Mark Pollack's "Code Generation Using Javadoc" (JavaWorld, August 2000). Pollack and his team used simple Java classes to describe the metadata for complex classes. They took advantage of the Java compiler to check their model's integrity. Then they created a doclet for the javadoc utility included in the Java SDK. The doclet generated source code based on the information the javadoc dynamically obtained from analyzing these metadata classes. Although I give much credit to this team for its innovation and reuse of existing tools, we cannot use this approach in our hypothetical project. Someone still has to know how to code the metadata classes manually. This would be a hard sell to an average customer. Our objective is to build a framework that provides hands-free business object customization.

The game plan

In our solution, we will combine the best of existing techniques. We'll maintain the class metadata in the simple data dictionary that we design from scratch. A relational database is probably the most suitable tool for this purpose, for the following reasons:

  • It provides secure and reliable data storage
  • It is easy to build a user interface for data management
  • It puts no technological constraints on the tools that extract the data
  • It is part of most software projects anyway

Once we have the metadata in the data dictionary, we can use the XML metadata server to dynamically extract the information and present it as an XML document by HTTP request. By using HTTP, we remove any technological constraints on the XML metadata server implementation, although I do prefer using JSPs or the Servlet API to build a metadata server.

As soon as we receive the XML document's class metadata, we will employ a generic XSLT processor to transform the document into Java source code. In addition to the metadata, we also need an XSLT stylesheet, which includes the processing instructions that the XSLT processor needs to perform its transformation magic.

Once we have all the pieces in place, we just need to customize a bean class by tweaking a few records in the data dictionary, sending an HTTP request, and receiving freshly minted Java classes. Any customer could probably do this, since no programming is involved.

The following figure is a high-level sequence diagram that helps to visualize this game plan.

The game plan

Create a data dictionary

There is no standard data dictionary schema that we can borrow for our project. Every team designs one that suits its requirements best. Let's design a simple proof-of-concept data dictionary. Later, I'll elaborate on how to make it more sophisticated and suitable for a commercial project.

We need just two tables. The Beans table contains information about the bean classes, while the Properties table describes their properties. Below are the SQL statements that you can use to build these tables in the relational database of your choice:

DROP TABLE Beans;
CREATE TABLE Beans (id INT,name VARCHAR(30) NOT NULL,comments
VARCHAR(100));  DROP TABLE Properties;
CREATE TABLE Properties (beanId INT,name VARCHAR(30) NOT NULL,type
VARCHAR(30) NOT NULL,comments VARCHAR(100));

Even though I'd rather you use JDBC to create these tables, feel free to use whatever tools and interfaces you prefer to enter data. This might be a good time to think about what kind of tool you'll provide to future customers for these purposes as well. Let's describe the metadata for our Product bean in this data dictionary:

INSERT INTO Beans (id,name,comments) VALUES (1,"Product","This
bean represents a product that the company offers to its customers");
INSERT INTO Properties (beanId,name,type,comments) VALUES
(1,"code","int","the product inventory code");
INSERT INTO Properties (beanId,name,type,comments) VALUES
(1,"name","String","the product name");
INSERT INTO Properties (beanId,name,type,comments) VALUES
(1,"testedOnAnimals","boolean","the flag that indicates if the product
was tested on animals");
INSERT INTO Properties (beanId,name,type,comments) VALUES
(1,"availableSince","java.util.Date","the date when the company started
offering this product to its customers");

As I mentioned earlier, this is probably the absolute minimum information we need to maintain in order to make our metadata useful. (Well, we could probably live without the comments, but uncommented code is considered unprofessional in the programming world.) Therefore, Tables 1 and 2 show what we finally need.

Table 1. Beans

IdName Comments
1ProductThis bean represents a product that the company offers to its customers

Table 2. Properties

BeanIdNameTypeComments
1Codeintthe product inventory code
1NameStringthe product name
1testedOnAnimalsboolean

the flag that indicates if the product

was tested on animals

1availableSincejava.util.Date

the date when the company started

offering this product to its customers

In real life, you would probably need to stretch these tables a bit. You may want to consider including more useful information in your metadata. Actually, the Java API provides some good suggestions in the form of java.lang.Class and several classes from the java.lang.reflect package. There are also two useful classes in the java.beans package. In fact, the java.beans.BeanDescriptor class essentially encapsulates the metadata about the bean itself, whereas the java.beans.PropertyDescriptor class does the same for a bean property. If you are not satisfied with the offered metadata model, these descriptor classes let you expand it by associating a set of named attributes with the entity. I have found this feature particularly handy for setting constraints on the acceptable data values for the bean's properties. I've described it in the context of a data validation framework presented in "Validation with Pure Java" (JavaWorld, December 2000).

With all this in mind, here are additional fields with self-describing names that may be worth adding to your commercial-grade metadata structure.

Beans table:

  • package
  • imports
  • modifiers
  • isAbstract
  • isInterface
  • superClass
  • implements
  • displayName
  • description

Properties table:

  • modifiers
  • isAbstract
  • isIndexed
  • isHidden
  • isLookup
  • lookupTableName
  • isLowercaseAllowed
  • isPassword
  • isRequired
  • isReadonly
  • defaultValue
  • maxValue
  • minValue
  • maxLength
  • displayName
  • description
  • displayFormat

You probably also need to make provisions for the metadata version control by adding a project and version field or similar extra fields to each table.

Describe metadata in XML

Before we extract metadata into the XML document, we must agree on its structure. For that purpose, we can use one of the two existing metalanguages: DTDs or XML Schemas.

DTDs are somewhat old fashioned, mostly due to their limited typing capabilities; however, they are simple, compact, and readable by the human eye. Perhaps that is why they remain quite popular. On the other hand, XML Schemas offer more advanced features, like inheritance and strong typing, at the expense of simplicity. For our purposes, a DTD works fine. Here is how we structure the metadata document:

<!ELEMENT bean (name,property*,comments?)>
<!ELEMENT property (name,type,comments?)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT type (#PCDATA)>
<!ELEMENT comments EMPTY>

This really means that a <bean> element must have exactly one <name> child and optionally any number of <property> elements. A <property> element in turn must have exactly one <name> and one <type> element. Both <bean> and <property> elements may have an optional <comments> element.

Now we need to build an XML metadata server that does the following:

  • Extracts the metadata from the data dictionary
  • Generates an XML document according to the above DTD
  • Communicates with clients via HTTP protocol

We use JSPs to create this simple XML metadata server. The server accesses the database directly from the JSP with the JDBC 2.0 core API, which comes with the Java 2 Platform, Standard Edition (J2SE). Please note that this is not the recommended approach. I've chosen it solely to stay focused on the functionality without distracting your attention with complex Web application design issues. According to Sun Microsystems' Java BluePrints, you should create JSPs with as little Java code exposed as possible. Normally you would implement something like this with a servlet or at least with a custom JSP tag from something like the Jakarta Taglibs project for the database access. My goal today, however, is to provide you with an easy-to-understand algorithm that you can try on your home computer with minimum effort.

To open a database connection, the java.sql.DriverManager class needs the following information:

  • Fully qualified JDBC driver class name
  • Database URL
  • Database user name (optional)
  • User's password (optional)

We provide this information as the HTTP request's parameters. Another important request parameter is the name of the bean whose metadata we are extracting. Listing 2 is the resulting JSP:

Listing 2. GenXml.jsp

<?xml version="1.0" encoding="ISO-8859-1"?>
<%@ page import="java.sql.*" %>
<%
try {
  
  String driver = request.getParameter("driver");
  String url = request.getParameter("url");
  String username = request.getParameter("username");
  String password = request.getParameter("password");
  String bean = request.getParameter("bean");
  
  Class.forName(driver);
  Connection con = DriverManager.getConnection(url, username,
password);
  Statement st = con.createStatement();
  ResultSet rs = st.executeQuery("SELECT * FROM Beans WHERE name='" +
bean + "'");
  
  // we expect exactly one record here
  if( !rs.next() ) {
      throw new IllegalArgumentException("No metadata found for the
bean " + bean);
  }
%>  
  <bean>
  <name><%= rs.getString("name") %></name>
  <comments><%= rs.getString("comments")
%></comments>
<%  
  rs.close();
  rs = st.executeQuery("SELECT b.* from Beans a, Properties b WHERE
b.beanId=a.id AND a.name='" + bean + "'");
  
  while(rs.next()) {
%>
      <property>
      <name><%= rs.getString("name") %></name>
      <type><%= rs.getString("type") %></type>
      <comments><%= rs.getString("comments")
%></comments>
      </property>
<%
  }
  st.close();
  con.close();
%>
  </bean>
<%
} catch( Exception ex ) { 
%>
  <exception><%= ex.getMessage() %></exception>
<%
}
%> 

For the JSP to function, it must be deployed on a Web server that provides a JSP/Java servlet engine. These days it is increasingly difficult to find a Web server that doesn't support Java technology. If you don't have one yet, maybe now is the time. Check out these free products that offer full JSP and servlet support:

  • Tomcat servlet container, developed by the Apache Software Foundation, is the official reference implementation for the Java Servlet and JavaServer Pages technologies. Tomcat is a subproject of the larger Jakarta Project.
  • iPlanet Web Server, FastTrack Edition is a joint venture between Netscape and Sun Microsystems. When Sun announced the End of Life (EOL) of the Java Web Server 2.0 on February 7, 2001, it began referring users to the iPlanet server. I particularly like the server's intuitive Web interface for remote administration.

Once you deploy GenXml.jsp on a Web server, you should be able to process a request in the following format:

http://<myserver>/<mypath>/GenXml.jsp?driver=<jdbcd
river>&url=<dburl>&username=<dbuser>&password=<dbpwd>
&bean=Product

You must substitute the variables with angle brackets for real values. Don't forget to use &amp; instead of &, when specifying the url parameter. If you do everything correctly, you should receive a response, which is essentially the Product bean's metadata expressed in XML:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<bean>
    <name>Product</name> 
    <comments>This bean represents a product that the company
offers to its customers</comments> 
    <property>
        <name>code</name> 
        <type>int</type> 
        <comments>the product inventory code</comments> 
    </property>
    <property>
        <name>name</name> 
        <type>String</type> 
        <comments>the product name</comments> 
    </property>
    <property>
        <name>testedOnAnimals</name> 
        <type>boolean</type> 
        <comments>the flag that indicates if the product was
tested on animals</comments> 
    </property>
    <property>
        <name>availableSince</name> 
        <type>java.util.Date</type> 
        <comments>the date when the company started offering this
product to its customers</comments> 
    </property>
</bean> 

If your request causes an exception, most likely due to invalid parameter values, the page generates a different type of XML document with the <exception> element:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<exception>No metadata found for the bean Produkt</exception>

If you're itching to see how this XML metadata server works, you may query mine, available here.

Transform XML into Java code

Before XSLT became a wonderful reality, you had to transform XML into Java like this: handcraft a class that utilizes a DOM or a SAX parser to extract the data from the source XML document, apply some hardcoded rules to it, and eventually spit out the Java code. Every time you had to change some rules, you would have to modify and recompile the handcrafted class. If you decided to transform into another language -- Smalltalk, say -- you would have had to build another class that does just that. This is doable, of course, but it's no fun, especially if you know about XSLT. XSLT is an official World Wide Web Consortium (W3C) Recommendation. It lets you transform an XML document into almost anything else. Traditionally, though, you use it to transform the document into HTML, text, or other XML document types. The XSLT processor performs the transformation according to the rules defined in the XSLT stylesheet, which is an XML document itself. If you need to change the transformation logic, you simply modify the stylesheet with a text editor.

Many different implementations of the XSLT processors are available today; check the W3C Website for references. We will use the Xalan XSLT processor developed under the Apache XML project. Because it's a Java-based implementation, Xalan comes with some features particularly attractive for a Java developer. One such feature is support for TRaX (Transformation API for XML), which is part of the Java API for XML Processing (JAXP). TRaX helps you build applications that utilize the XSLT transformation service through a standard, implementation-neutral interface.

Another goodie is the XSLT Compiler, a tool that compiles the transformation logic from a stylesheet into a lightweight Java class called a translet. You may then use Sun's XSLT runtime processor to apply the translet to an XML document and significantly increase the transformation performance.

Listing 3 defines a stylesheet to transform our simple metadata into Java source code. If you later decide to expand your metadata structure, you will have to reflect the changes in the stylesheet as well:

Listing 3. JavaBean.xsl

<?xml version="1.0"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"   
    xmlns:java="http://xml.apache.org/xslt/java"
    exclude-result-prefixes="java">
<xsl:output method = "text"/>
<xsl:template match="bean">
/**
 * <xsl:value-of select="comments"/>
 * This class has been generated by the XSLT processor from the
metadata 
 */
public class <xsl:value-of select="name"/> {
    /**
     * Creates a new instance of the <xsl:value-of
select="name"/> bean
     */
    public <xsl:value-of select="name"/>() {}
         
    <xsl:apply-templates select="property"/>
}
</xsl:template>
<xsl:template match="property">
    private <xsl:value-of select="type"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="name"/>;
    <xsl:variable name="name" select="name"/>
    <xsl:variable name="cname" select="java:Capitalizer.capitalize($name)"/>
    /**
     * Sets <xsl:value-of select="comments"/>
     * @param <xsl:value-of select="name"/> is <xsl:value-of
select="comments"/>
     */
    public void set<xsl:value-of select="$cname"/>(<xsl:value-
of select="type"/> <xsl:text> </xsl:text><xsl:value-
of select="name"/>) {
      this.<xsl:value-of select="name"/> = <xsl:value-of
select="name"/>;          
    }
    /**
     * Returns <xsl:value-of select="comments"/>
     * @return <xsl:value-of select="comments"/>
     */
    public <xsl:value-of select="type"/><xsl:text></xsl:text>
    <xsl:apply-templates select="type"/><xsl:value-of
    select="$cname"/>() {
      return <xsl:value-of select="name"/>;
    }
</xsl:template>
<xsl:template match="type">
    <xsl:variable name="type" select="."/>
    <xsl:choose>
    <xsl:when test="$type='boolean'">is</xsl:when>
    <xsl:otherwise>get</xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet> 

The XSLT language, XSL, requires time and effort to learn. The above stylesheet may not tell you much yet. If you are already versed in XSL, let me briefly explain how this works.

There are three templates in this stylesheet. One processes the <bean> element. This is where we provide the bean's class definition and the default constructor. The other template processes the <property> element. Please note that I used the Xalan-Java extensions mechanism to initialize the XSL variable arbitrarily called cname. This variable contains the name of the property with the first character capitalized. Here I use it to generate the names of the accessor methods. Since XSLT does not provide an extension function, I had to create a small Java utility class, Capitalizer (shown in Listing 4), that capitalizes the first character in the string. This class must be compiled and made available to the XSLT processor via the CLASSPATH at transformation time:

Listing 4. Capitalizer.java

/**
 * This class provides an XSLT extension function that
 * may be utilized by Xalan-Java extension mechanism.
 */
public class Capitalizer {
    /**
     * This method capitalizes the first character
     * in the provided string.
     * @return modified string
     */
    public static String capitalize(String str) {
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }
}

Please note that the idea of the XSLT extensions is not proprietary to Xalan. In fact, it is part of the XSLT Recommendation.

Finally, a third template decides on the getter method's name. Remember, it should have the prefix is for boolean properties and get for all the others. Before we continue, please note that XSLT is rich enough to let you accomplish the same transformation in different ways. For example, instead of a separate template, we could use the <xsl:for-each select="property"> element to process the <property> element.

Now we have all the ingredients to cook up our Product bean. Once you have Xalan installed and configured, you may perform the transformation from the command line like this:

java org.apache.xalan.xslt.Process -in xmlSource  -xsl stylesheet -out outputfile

The mandatory -in parameter must be the source XML document's URL. You may point it to a local file or to the URL I suggested earlier.

The optional -xsl parameter is the URL pointing to an XSLT stylesheet. Again, you are welcome to try the one I have prepared for you: http://www.climbstairs.org/examples/JavaBean.xsl. Please note that this parameter is optional because you may specify the XSLT URL directly inside the source XML document via processing instruction (PI). I would not recommend doing that simply because by decoupling these two documents you gain more flexibility. For example, you may decide in the future to create another XSLT stylesheet to generate an IDL (Interface Definition Language) for your CORBA application.

The optional -out parameter specifies the name of the file to host the source code for the Java class we are about to receive. You may omit it to output the transformation results on the screen.

If you've configured your CLASSPATH properly, Listing 5 shows what you get as a result of the transformation:

Listing 5. Product.java

/**
 * This bean represents a product that the company offers to its
customers
 * This class has been generated by the XSLT processor from the
metadata
 */
public class Product {
    /**
     * Creates a new instance of the Product bean
     */
    public Product() {}
         
         
    private int code;
         
    /**
     * Sets the product inventory code
     * @param code is the product inventory code
     */
    public void setCode(int code) {
        this.code = code;          
    }
    /**
     * Returns the product inventory code
     * @return the product inventory code
     */
    public int getCode() {
        return code;
    }
    private String name;
         
    /**
     * Sets the product name
     * @param name is the product name
     */
    public void setName(String name) {
        this.name = name;          
    }
    /**
     * Returns the product name
     * @return the product name
     */
    public String getName() {
        return name;
    }
    private boolean testedOnAnimals;
         
    /**
    * Sets the flag that indicates if the product was tested on animals
    * @param testedOnAnimals is the flag that indicates if the product
was tested on animals
    */
    public void setTestedOnAnimals(boolean testedOnAnimals) {
        this.testedOnAnimals = testedOnAnimals;          
    }
    /**
     * Returns the flag that indicates if the product was tested on
animals
     * @return the flag that indicates if the product was tested on
animals
     */
    public boolean isTestedOnAnimals() {
        return testedOnAnimals;
    }
    private java.util.Date availableSince;
         
    /**
     * Sets the date when the company started offering this product to
its customers
     * @param availableSince is the date when the company started
offering this product to its customers
     */
    public void setAvailableSince(java.util.Date availableSince) {
        this.availableSince = availableSince;          
    }
    /**
     * Returns the date when the company started offering this product
to its customers
     * @return the date when the company started offering this product
to its customers
     */
    public java.util.Date getAvailableSince() {
        return availableSince;
    }
} 

This result is exactly what we expected. This source code compiles very well; I'm sure the compiler has no appreciation for what it took to put it together.

What's next

Once you are happy with the transformation, you are welcome to build a JSP or a servlet that performs it via the TRaX API or by utilizing the XSL Tag Library, which is part of the Apache Jakarta Taglibs collection. You may then request the transformation via an HTTP request, receive the Java code, and compile it dynamically using the java.lang.Compiler class. You may apply the same technique to produce the BeanInfo class, different support classes, relevant SQL statements, DTDs, and anything else to accompany every bean class you generate. To plug the freshly minted classes into your application, you may consider using the Reflection API, which dynamically discovers their structure.

A framework that works

Everything I've described in this article serves as a foundation of the framework I am successfully applying in commercial projects. The business domain of financial services where I currently work operates with large quantities of relatively bulky business objects. Every new customer requires a substantial customization of these objects. Without this framework, our team would not be able to meet the tight development schedules. I'm sharing it with you because it really works, it saves you a lot of time and money, and it utilizes some of the most fascinating technologies available today.

Sun Certified Java Programmer and Microsoft Systems Engineer Victor Okunev is a design architect of the research and development team for Vancouver-based Marlborough Stirling Plexus. With an M.S. in computer science from the Moscow State Institute of Radio Engineering, Electronics, and Automation, Victor has more than 11 years' experience in software development, primarily on enterprise-scale applications. Victor also works as a Java instructor with Learning Tree International, writes for JavaWorld, snowboards, and enjoys sea and whitewater kayaking.

Learn more about this topic