One of the challenges of developing (J2EE) applications is information. It’s very hard to have an overview of the different components, objects, database tables etc. and how they interact. This can make refactoring a difficult task. With ADF BC applications it can be quite difficult to track where and how the ViewObjects are being used in the faces application, especially because they are used via their instance or usage as defined in the application module. The ADF binding framework can make it even more complicated, because it abstracts the underlying business components. So, changing a viewobject, or just adding an extra attribute, is always a tricky business. You’re therefore easily fooled in making a new viewobject instead of re-using an existing one. Which can lead to an abundance of similar viewobjects that nobody actually knows why they are there for and that nobody dares to touch anymore, especially when the original developers have been gone. By the way, this is quite similar to the ‘old EJB era’ when using value or data objects.
Off course, an important part of the solution is documentation. But this requires a good documentation system, discipline and continuous re-documentation. But if you are using JHeadstart for your application generation, you can consider yourself lucky (which you probably already did), because the application definition contains a wealth of information. JHeadstart uses it to generate the ADF Faces application, but we can also use it for documentation purposes.
JHeadstart stores all it’s information in the application definition file and provides an editor to define the application. But neither the editor nor the application definition file is directly suited for documentation purposes. However, since it is in XML format, it provides easy access to all the information and with the use of an XML stylesheet (xslt) we can extract the data and present it in a suitable way. The only drawback is that you have to run the transformation process to get the documentation. This could be a part of the continuous integration process, but other options are available as well. At AMIS we use the confluence WIKI for documentation purposes and that provides us with a very good solution since it contains a built-in xslt parser. It can use the application definition file and the xslt directly from subversion to generate the output right into the wiki 🙂 and we can define as many transformations as we like, thus producing different reports.
So if we’d like to have an overview of all the viewobjects and their usages in an HTML table you only need the following xslt :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:jhs="http://www.oracle.com/jheadstart/applicationStructure"
xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:output version="1.0" method="html" encoding="UTF-8"/>
<xsl:template match="/">
<html>
<head>
<title>Viewobjects that are used by the <xsl:value-of select="/jhs:Service/@name"/></title>
</head>
<body>
<h1>Viewobjects that are used by the <xsl:value-of select="/jhs:Service/@name"/></h1>
<table border="1">
<thead>
<tr>
<th>Group</th>
<th>DataCollection</th>
<th>DataCollectionImpl</th>
<th>TreeDataCollection</th>
<th>TreeDataCollectionImpl</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="//jhs:Group">
<xsl:apply-templates select="jhs:Group"/>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="jhs:Group">
<tr>
<td><xsl:value-of select="@name"/></td>
<td><xsl:value-of select="@dataCollection"/></td>
<td><xsl:value-of select="@dataCollectionImpl"/></td>
<td><xsl:value-of select="@treeDataCollection"/></td>
<td><xsl:value-of select="@treeDataCollectionImpl"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Beware of the fact that the application definition file has a namespace attached to it (at the Service element) and that you therefore have to include that namespace in your xslt file, as you can see by the definition and the use of the jhs prefix.
Another nice piece of information is for which groups the pagedef generation has been disabled :
<?xml version=”1.0″ encoding=”UTF-8″?>
<xsl:stylesheet version=”2.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”
xmlns:fn=”http://www.w3.org/2005/xpath-functions”
xmlns:jaxb=”http://java.sun.com/xml/ns/jaxb”
xmlns:jhs=”http://www.oracle.com/jheadstart/applicationStructure”
xmlns:xdt=”http://www.w3.org/2005/xpath-datatypes”
xmlns:xjc=”http://java.sun.com/xml/ns/jaxb/xjc”
xmlns:xs=”http://www.w3.org/2001/XMLSchema”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema“>
<xsl:output method=”html” version=”1.0″ encoding=”UTF-8″ />
<xsl:template match=”/”>
<html>
<head>
<title>About generation of the pagedefinitions</title>
</head>
<body>
<h1>NO generation of pagedefinition?</h1>
<xsl:for-each select=”//jhs:Group”>
<xsl:call-template name=”pagedefgeneration”/>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template name=”pagedefgeneration”>
<input type=”checkbox” >
<xsl:if test=”@generateBindings=’false'”>
<xsl:attribute name=”checked”>1</xsl:attribute>
</xsl:if>
<xsl:value-of select=”@name”/>
</input>
<br/>
</xsl:template>
</xsl:stylesheet>
Off course the options are endless: the list of the user-defined templates, insert/update/delete mode of a group, items that are updatable or disabled, all the labels or hints etc. etc, probably only limited by your xslt knowledgde. And you know what… all of the faces configuration files, the web.xml and all of the Business Components and the application modules are XML files too and even the jsf pages :-).
Take care, this is a bit trickier, because the generateBindings attribute can have the value ‘false’, ‘true’ or be totally absent, in which case the JHeadstart application generator (jag) uses its default value ‘true’.