Introducing the XX Framework

David Moskowitz, President, Infoblazer LLC.

September 2006

© David Moskowitz, 2006. All Rights Reserved.

Introduction

The XX framework is a configurable, XML-centric implementation of the MVC development paradigm that incorporates simple and commonly used patterns of development.

The framework promotes a use case oriented development approach. In this approach, use cases are defined for each task the user will perform. In general, each use case will be implemented by a single logical servlet, as defined in the J2EE Specification. The logical servlet may be implemented by one or more implementation classes each implemented a distinct portion of that use case and providing a portion of the resultant display. The developer simply needs to write implementation of for these classes. Configuration files determine which implementation classes are called based on user click events. The most common implementation approach has each class return an XML result, yielding a set of XML documents for each use case. XSL transformation is then applied to the XML results, each transform providing a portion of the desired display. A single JSP page is then used to display the final product. We call this approach XX Foundation.

The framework then builds upon this foundational approach to provide automation of typical application tasks, such as add, update, delete, select of records from a database. By specifying a simple mapping from the HTML page on one end, through the middle layers, and to the database on the other end, a large subset of application functionality can be achieved without the need to write any Java code. Instead, a combination of XML configuration files, XSL transformation templates, as well as open source tools, namely Hibernate and Castor, are used. We call this approach XX Automation.

The XX Framework incorporates common programming tasks, in an open, configurable, and generic manner

The primary goal of the XX Framework is to handle typical application CRUD (create, retrieve, update, delete) with little or no Java programming. Instead of telling the application how to retrieve and how to display the data, we configure what to retrieve (through XML) and what to display (through XSLT). This generally leads to a simpler and more elegant solution that a purely procedural approach. Where the applications needs more than simple CRUD, additional business logic can be easily incorporated into the process. . Furthermore, since much of the framework if based on XML and XSL, automatic generation of complete applications is achievable. This capability will be referred to as XX generation.

The framework differs itself from other frameworks, such as Struts, in its simplicity and XML/XSL focus.

Other benefits of the XX framework are:

  • Extremely simple to use.
  • Built around open web standards, including J2EE, XHTML, XML, XSL, and CSS.
  • Built-in, configurable data caching for optimal performance
  • Many common application tasks can be handled with little or no Uses a “Portal-based” approach to page design, allowing easy compartmentalization of functionality.
  • Web service integration
  • Reuse common classes and operations for pre-built functionality.
  • Thread pooling for greatly increased performance.

The XX Framework comprised two components technologies XX Foundation and XX Automation. The XX Foundation is synonymous with the XX framework itself and the two will be used interchangeably.

The XX Automation layer builds upon the XX Foundation described above to handle a large portion of application CRUD (create, retrieve, update, delete operation). Seen this way, XX automation is actual an XX Foundation application.

Using XX Automation, complex operations can be built without writing a single line of java code. The application is configured using XML and XSL files. An advantage of this approach is that automated routines can be used to read and generate XML and XSL (which is just XML).

XML centric development has other advantages as well. These advantages are described in the following white paper, as well as on numerous web sites and articles, such as http://www.xml.com

An application will generally be comprised of XX Foundation and XX Automation components, the distinction being whether a custom Java implementation class is created or not. In fact, many custom Java classes can extend existing automation classes, thereby adding the necessary custom functionality while using the existing functionality of the automation layer. Since the XX framework conforms to the J2EE standard and uses a standard web.xml file, it is possible to selectively use the framework on a servlet by servlet basis.

XX Foundation

The XX Foundation only addresses the interaction between the presentation layer and the business layer. Additional architecture concerns, such as database access and object-oriented class design, are discussed elsewhere in this and other XX documents, as part of XX Automation or in discussion of application design in general.

XX uses a base servlet approach, freeing the developer of the need to create actual servlet classes (that implement the abstract class javax.servlet.http.HttpServlet or equivalent). To develop XX applications, the developer simply creates one or more classes which implement the required use case functionality, as represented by a desired back-end action or XML response. These implementation classes must implement (in Java terms) a specific interface. This allows for standardization of calls to the implementation methods and therefore easier development. Configuration files are then created which map a Java servlet to one of these interfaces your class. The servlet needs only be defined in the standard web.xml
file. No new servlets (i.e. extending HttpServlet )actually needs to be written.

The task of developing an XX application involves

  1. Determine application use cases
  2. Configure a java servlet (the XX Base servlet) to implement each use case
  3. Create an XX configuration file for each servlet. The XX configuration file specifies the following
    1. Implementation Class(es) and method(s) that will be called
    2. XSL file(s) which transforms the data the implementation class(es) returns
    3. JSP file where the transformed data is displayed
  4. Implement these three components, or choose existing XX framework automation classes

In practice most implementation classes in an XX application will take advantage of the XX Automation component, either specifying operations using the automation’s CRUD handler directly, or implementing classes that extend the functionality of CRUD handler operations. By extending existing automation classes, the developer does not need to rewrite an entire portion of functionality, but may simple add additional functionality to what is provided by the CRUD handler.

XX development starts with identification of application use cases. Each use case is generally handled by a single Servlet. The servlet is built using a custom framework which builds off a single Base Servlet (Base.java, part of the org.xxframework package). While the use case servlets are defined individually in the web. XML file, all use the Base.java Servlet as their actual servlet class. Base.java then calls the developer’s implementation classes that perform the specific functionality required of each use case. No actual servlet needs to be written. The developer simply builds a java class which implements BaseFlow. .

In the XX approach, each use case generally maps to a single servlet. While the use case will map to a single servlet, as implemented by Base.java, the actual implementation, as provided by the developer, can be divided into multiple implementation portions. The best way to think about this is to think of the use case providing a single response page (the view). The page can be divided into several independent portions, such as a menu, data entry area, etc. Each of these components is implemented as a separate class/method call, and subsequent XSL (view) transformation.

This approach is similar to a portal based framework, where multiple independent components are pieced together to make up a complete page view.

For each implementation class, XX defines certain common functions routinely performed in an application as commonly identified in Use Case analysis. These functions are

  • List- return rows of data for display
  • Get- returns a single row of data.
  • Delete- a row of data
  • Set- add or update a row of data
  • Custom – any operation. It is recommended to use one of the above four methods wherever possible.

These functions all return a single XML string and must conform to the BaseFlow interface.

The above methods correspond to the most common application tasks. By designing this type of interface, related tasks revolving around a single entity can be grouped together. Additional, private functions can be added to the implementation class as needed. Class design will typically involve building an implementation class that implements each of these XX methods. The methods will be called from the appropriate location in the application, as specified in the XX configuration files.

Request/Response Paradigm

The XX framework uses a request/response approach, similar to most HTTP or Servlet-based approaches. Each web request will be automatically translated into a XM document. Based on the processing of this request, one or more XML “reply” documents must be produced by the developer as part of the implementation class. The framework then passes applies the configured XSL transformation to the XML reply and passes the result (usually HTML) to the configured JSP page for display.

Many current web frameworks use a component, also called event-based, approach. Such a framework attempts to hide the actual workings of HTTP, such as servlets, hyperlinks, forms, etc. By contrast, XX exposes these HTTP standards. By doing such, functionality can be built in a HTTP standard manner, without the need to learn a custom template based language that these frameworks attempt to hide HTTP beneath.

To use a simple example, here is the result of a typical request

http://myserver/myapplication/ShowContact?id=1

Request Format

<?xml version=”1.0″ encoding=”UTF-8″?>

<root sid=”6B8BD9761980E910E049364274B06A73“>

<request>

<id>1</id>

</request>

<Initialization>

<Init-params>

<configFile>ShowContact.xml</configFile>

</Init-params>

<Env-params>

<Devel>true</Devel>

<hibernate_config_file>/com/mycompany/myapplication/entity/hibernate.cfg.xml</hibernate_config_file>

<xml_path>C:projectsmyapplicationWebRootWEB-INFxml</xml_path>

</Env-params>

</Initialization>

</root>

The request XML will be passed into the implementing class, as specified in the XX Config file.

The XML is wrapped in a “root” element. The “sid” attribute of the root element is the server generated session id.

The URL parameters for form variables are wrapped in a “request” element. All parameters or variables are represented as XML elements. Hierarchical structure can be implemented in the request.

For example, modifying the URL to the following:

http://myserver/myapplication/ShowContact?contact/id=1

Will yield the following request element:

<?xml version=”1.0″ encoding=”UTF-8″?>

<root sid=”6B8BD9761980E910E049364274B06A73“>

<request>

<contact>

<id>1</id>

</contact>

</request>

<Initialization>

<Init-params>

<configFile>ShowContact.xml</configFile>

</Init-params>

<Env-params>

<Devel>true</Devel>

<hibernate_config_file>/>/com/mycompany/myapplication/entity/hibernate.cfg.xml </hibernate_config_file>

<xml_path>C:projectsmyapplicationWebRootWEB-INFxml</xml_path>

</Env-params>

</Initialization>

</root>

In addition to main request information, some additional information is included as well.

Init-params contains the extra parameters specified in the web.xml file. This can be seen from the ShowContact servlet definition from the application’s web.xml file.

<servlet>

<servlet-name>ShowContact</servlet-name>

<display-name>ShowContact</display-name>

<servlet-class>org.xxframework.Base</servlet-class>

<init-param>

<param-name>configFile</param-name>

<param-value>ShowContact.xml</param-value>

</init-param>

</servlet>

Finally, certain environment parameters from the web.xml file are also passed in. using the Env-params element. Here is the corresponding section from the application’s web.xml file.

<env-entry>

<env-entry-name>xmlpath</env-entry-name>

<env-entry-value>C:projectsmyapplicationWebRootWEB-INFxml</env-entry-value>

<env-entry-type>java.lang.String</env-entry-type>

</env-entry>

<env-entry>

<env-entry-name>devel</env-entry-name>

<env-entry-value>true</env-entry-value>

<env-entry-type>java.lang.String</env-entry-type>

</env-entry>

<env-entry>

<env-entry-name>hibernate_config_file</env-entry-name>

<env-entry-value>/org/empowerNewHaven/contractApplication/entity/hibernate.cfg.xml</env-entry-value>

<env-entry-type>java.lang.String</env-entry-type>

</env-entry>

These three parameters are passed in, as they are often used in XX applications. Any other parameters are accessible in the implementation class via the Servlet Context object

Reply Format

In XX Foundation, the design of the Reply document, as well as the XSL transformation applied to that document, are up to the developer. It is, however, recommended that the developer conform to certain standards used by the XX Automation layer, as that will make development more standardized and allow easier incorporation of XX Java and XSL libraries. This, however, is not a requirement to use XX.

In implementing the above request, the XX automation layer would provide a Reply document similar to the following. Note that this is an abbreviated document. Several additional elements are removed for brevity at this point in the discussion. See the reference section for additional information.

<?xml version=”1.0″ encoding=”UTF-8″?>

<root edit=”” mode=”edit xx_user_role=”Administrator xx_user_access=”edit xx_user_restrict=”” class=”org.mycompany.myapplication.entity.Contact child_id=”” short_class=”Contact“>

<contact>

<id>1</id>

<firstname>David</firstname>

<lastname>Moskowitz</lastname>

<city>Sarasota</city>

<state>

<stateabbrev>FL</stateabbrev>

<statename>Florida</statename>

<id>2</id>

</state>

<userrole xx_access_mode=”edit“>

<id>1</id>

<typename>Administrator</typename>

</userrole>

<organization xx_access_mode=”edit“>

<id>1</id>

<organizationname>Infoblazer, LLC.</organizationname>

</organization>

</contact>

<request>

<id>1</id>

</request>

</root>

The reply is wrapped in a root element. The root element contains several attributes, related to the particular request (see reference section for more detail). Note that the original request is included automatically as a child of the root element. This is a convenient way to package the original request, which would be difficult to make available to an XSL transform.

Error Handling

In XX Foundation, the developer is responsible for creating the appropriate error messages, which should be returned in the XML reply document. By configuring error handling, control can be passed to alternate stylesheets and JSP page for error reporting. The design and generation of the error XML document is left to the developer. Configuration of error handling is done in the XX Config file.

In XX Automation, as standard error document is returned. The document will have a formula similar to the following

<Reply>

<Result value=”-10 returnMessage=”An error has occurred attempting to save data.“>

<xx_error>Security Error: You do not have permission to perform that operation</xx_error>

</Result>

</Reply>

An error condition will generally be indicated by a Reply element, instead of the Root element. An overall “Result” will be returned, containing one or more “xx_error” elements.

The value attribute can be used to determine which error occurred. A default message can be included in the XML itself. Otherwise, the value attribute can be queries and a custom error message displayed.

Errors are returned as negative numbers. The values from 10000-99999 are reserved for the application itself. Other values are reserved for the XX framework

Servlet-based approach

In any java servlet-based approach, the main entry point into the application is a single servlet, which handles a specific web requests. Server configuration files will determine which servlet handles a specific request. To build a servlet based application, the developer must write classes that implement each servlet, as well as related business logic and database access classes.

Most application development frameworks will provide the servlet class(es), so the developer is not responsible for it’s actual implementation. Struts for example, uses a single servlet to handle all application requests, then map the request to the appropriate handler based on a configuration file.

XX takes a similar, but slightly different, approach, to provide the servlet implementation, Instead of a single servlet as the application entry point, each use case or web request will be handled by a separate servlet. This approach is more in line with the original Java Servlet specification.For example, requests such as showsystemusers or listappointments will generally be handled by a different servlet. This does not preclude using url parameters, such as “listappointments?day=today” or as “listappointments?status=completed”, which will still be handled by whatever servlet listappointments* is mapped to.

XX still provides the base servlet to use, so the developer is not required to create an actual servlet implementation. So for multiple servlets, the XX Base servlet will be defined multiple times in the application’s web.xml configuration file.

In most cases, you should not need to update the base servlet. All initialization and request parameters are passed from the base Servlet to the XX implementation class as an XML document. Additional servlet information is also available from within the implementation class via the Servlet’s Context object.

Request Parsing

In order for meaningful application functionality, the form values of an HTTP request (a data entry form with a submit button, for example) must be available to the implementation function. XX converts the request to an XML representation and passes the XML as a parameter of the implementation function. XX also provides access to the servlet context as well, but in most cases, the necessary request information is prepackages neatly as XML. HTML form variables, such as input boxes are translated into the XML structure as well.

For example, a portion of the HTML for a contact entry screen might be the following:

With the corresponding HTML:

<form action=”update_contact”>

<h1>Contact</h1>

<input type=”hidden” name=”id” value=”1″/>

First Name:<input type=”text” name=”first_name”/>

<br/>

Last Name:<input type=”text” name=”last_name”/>

<br/>

<input type=”submit”/>

</form>

Upon submission, the XX framework would translate the values in the HTML form into the following XML request and pass the XML to the XX implementation function.

<request>

<last_name>User</last_name>

<first_name>Joe</first_name>

<id>1</id>

</request>

So in this case, the implementation function can simply grab the value of id, do a lookup to find the contact record with id equal to 1, and if found, update the first and last name values to that specified.

We can improve the request XML by adding a little more structure to the XML. By renaming the form fields in the html page

<form action=”HelloWorld”>

<h1>Contact</h1>

<input type=”hidden” name=”contact/id” value=”1″/>

First Name:<input type=”text” name=”contact/first_name”/>

<br/>

Last Name:<input type=”text” name=”contact/last_name”/>

<br/>

<input type=”submit”/>

</form>

We can generate a better XML representation in the request object.

<request>

<contact>

<id>1</id>

<last_name>User</last_name>

<first_name>Joe</first_name>

</contact>

</request>

This capability will be put to greater use in XX Automation, where a more hierarchical XML representation is necessary. The bolded HTML is now a reasonable representation of a Contact object.

We can implement the naming in whatever manner is desired. In many cases, a flat representation, such as in the first representation is simpler, especially if these values will be accessed directly. In other cases, the developer might wish to perform a transform on the XML or pass the XML to another method or service, in which case a more hierarchical approach is preferred. XX Automation, discussed later in this document, makes great use of this hierarchical naming approach, translating the hierarchical XML document to its related Java objects.

Framework Configuration

The following files define the framework configuration.

Web.xml

This standard J2EE configuration file defines the servlets that make up the application. The various XX configuration files used are also specified here, as well as any system level parameters.

Any Servlet initialization parameters will be passed on to the implementation class. In addition, several of these parameters are needed in the configuration of the Servlet.

Here is an example

<servlet>

<servlet-name>default</servlet-name>

<display-name>default</display-name>

<servlet-class>com.infoblazer.base.Base</servlet-class>

<init-param>

<param-name>configFile</param-name>

<param-value>default.xml</param-value>

</init-param>

</servlet>

Only one parameter is added to the standard web.xml file. That is an init-parameter with param-name “configFile”. The value of this init parameter will point to the location of the actual XX configuration file. Additional init parameters may be added on a servlet by servlet basis and will not affect the

XX configuration file

The “configFile” parameter mentioned as the init param in the web.xml file described above is the main XX specific configuration file used in the framework. We will refer to this as the XX Config File.

The XX Config File specifies the actual implementation class, the method responsible for returning the results, the XSL file that will be applied to the result, and the JSP file used to display the results.

There exists one XML configuration file for every application Servlet.

There is no naming standard on these files. The name is simply specified in the web.xml file. However, it is recommended that they be given the same name as the Servlet.

Example XML configuration file

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE xx_config SYSTEM “http://www.xxframework.org/dtd/xx_config.dtd”&gt;

<xx_config>

<classes>

<class id=”1 use=”xsl scope=”page applyxsl=”true“>

<classname>org.xxframework.tutorial.HelloWorld</classname>

<method>SayHelloXML</method>

<xsl_file>HelloWorld.xsl</xsl_file>

</class>

</classes>

<jsp>simple.jsp</jsp>

</xx_config>

In this example, the base servlet will call the HelloWorld class, which is expected to return an XML string. The resulting string will be transformed by the XSL file HelloWorld.xsl. The results of the XSL transformation, generally HTML, will be passed to simple.jsp using a reference id of 1.

XML Configuration File Parameters

The above sample files defines the most common and necessary parameters. See the XX reference document for a complete description of the configuration file/

id Each id must be unique within that config file. Used as an identifier for the Servlet. The results of the class operation can be referenced from the JSP page using that id.
use Determines formats of results returned by class. All results are stored in the request object

Values include:

  1. xsl – class returns XML doc string or simple string. It is possible to return a preformatted html string if the “applyxsl” parameter is set to false. This will cause the implementation class’ results to be displayed without further transformation.
  2. bean – class returns a java bean (not fully supported in current release)
  3. web – pass XML input parameters to an XX compatible web service. No java implementation class is needed
  4. file – read the result of the operation from a server file.

Note: The web and file options will not require an implementation class.

classname Fully qualified implementation class name
applyxsl Use the specified XSL stylesheet to transform the implementation class results
xsl_file XSL file to apply. Transforms the results of the implementation method.

Valid if “applyxsl” parameter = “true”

jsp The JSP file use to display the resultant page.
method Method in the implementation class to call. Values include:

  1. List
  2. Set
  3. Get
  4. Delete
  5. (Custom function name)
scope Controls caching of the implementation class results

  • page– no caching will be applied
  • session– results are cached for each user for the entire user session
  • application – results are cached for all users of the application.

Passing HTML results the JSP

XX uses JSP to ultimately display dynamic information to the user. However, since most of the view creation logic is handled in XSL and CSS, the JSP is generally a very light page wrapper, with little functional logic.

Results of the implementation class are stored in the request object, as either a string value. Typically, any XML will already be transformed at this point.

The naming convention used is

“html”_[config_file_name]_[ID]

where id is the id of the class as specified in the XML config file and config_file_name is the full path to the specific config file used for that servlet.

The config_file_name is passed into the JSP, so the page author will not need to specify it explicitly.

Instead, the html string can be retrieved from the request object with the following code in the JSP page.

public String xxOutput(Object s){

String result = “”;

if (s!=null) result=(String)s;

return (result);

}

xxOutput(request.getAttribute(“html_”+(String)request.getAttribute(“configfile”)+”_1″))

Result Caching

One of the advantages of using XML in general, and XX in particular, is that data can easily be saved to storage in it’s native XML format, since XML is represented as a String object. XX implements result caching by actually caching the HTML (also a string) result of application requests. This bypasses possibility lengthy XSL transformations that tend to be a bottle next in XML/XSL applications. Building on its Request/Response approach, responses can be selectively cached at three levels, Application, Session, and Page. When a page is requested, if not available in the appropriate cache, it will be generated. The results will then be saved to the appropriate cache. Application level caching uses the same result for the entire application. Session caching uses the results for the same user session. Page caching instructs XX not to cache at all.

Since XX uses a portal based approach, individual components of page requests, represented in the XX Config file by classes with ID’s, will each be cacheable and configurable separately.

Cache Context

Since page request parameters may affect the results of any request. For example, a call to listcontacts?state=ny will return a different result than listcontacts?state=ct. Therefore, XX caching is done with respect to any parameters included in the request.

Caching is specified in the XX config file. The scope attribute of the class determines if a class if cached. Setting the scope to “application” or “session’ will cause caching to occur. An additional optional element within the class, the “cache_context” can further determine how a page is cached.

Below is an example XX Config file.

<class id=”2 scope=”application applyxsl=”true use=”xsl“>

<classname>org.xxframework.control.RecordControl</classname>

<method>list</method>

<hb_classname etail=”true“>org.xxframework.guestbook.entity.Contact</hb_classname>

<xsl_file>ListUsers.xsl</xsl_file>

<security secure=”false“/>

</class>

In this example, the XML result is cached at the application level, based on the URL context, in this case, a call to display a particular organization. XX will cache based on the URL context by default. An additional cache_context element can be included to further control how caching occurs. See the reference document for more information on this element.

Cache Clearing

Cache can be cleared using a timeout approach, or based on certain events. Most typically, a cache will be cleared when an update operation is performed.

Cache clearing is accomplished by adding a cache_control element to the XX Config file.

In the example below, upon successful completion of the specified Set operation, the cache associated it the XX Config file editaccount.xml is cleared. In the case were editaccount.xml included multiple classes, all caches for those classes will be cleared. It is also possible to specify particular class caches to clear. See the reference document for additional information.

<xx_config>

<classes>

<class id=”1 scope=”page applyxsl=”true use=”xsl“>

<classname>org.xxframework.control.RecordControl</classname>

<method>set</method>

<hb_classname>org.xxframework.petstore.entity.Useraccount

</hb_classname>

<error_pattern>&lt;xx_error</error_pattern>

<error_jsp>main.jsp</error_jsp>

<error_xsl>reply.xsl</error_xsl>

<cache_control>

<cached_page name=”editaccount.xml“/>

</cache_control>

</class>

</classes>

<jsp>EditAccount</jsp>

<title>Account Detail</title>

</xx_config>

Debugging

An XML-centric approach to development has some distinct advantages in regards to debugging. An XML request/response paradigm makes it easier to include concrete specification for input and output parameters from any functional unit an application. This also makes service oriented programming easier to implement.

The XML Layer may be designed and debugged independently from the application, using XML development tools such as XML Spy.

In assisting with debugging, XX will save the request and response XML documents to disk if the debug parameter is set in the Web.xml config file. The request and response files are written to the application’s XML directory, with the names

response_N.xml

request_N.xml

where N is the class id in the XX Configuration file.

XX Automation

XX Automation builds upon the XX foundation layer to provide code free implementation of a large subset of application tasks. In this release of XX, CRUD (Create, Read, Update, Delete) operations are the main focus. Additional common application functionality will be added in future releases, with the goal of having a larger part of application development be code free and configuration based.

As was shown earlier, XX will automatically parse submitted form variables into an XML representation. The XML representation is then passed to the Java implementation. XX Automation add functionality to translate the XML representation into a Java object model. The Object-Relational mapping tool Hibernate is used to persist the Java objects model to a database. The reverse process, reading from a database into a Java model and XML representation is also handled. As we will see, this entire procedure can be automated based on configurable parameters.

To explain how XX Automation is implemented, let’s look at an example of each of the CRUD operations and see how XX Automation logically builds on the XX Foundation to handle this functionality.

In XX foundation, we divide the read operation in two related operations, List and Get. Let’s look at each of these in turn.

List

A list operation will generally return a representation of a set of objects. In our case, Java objects or table row objects are the two most likely.

Since we will use XML as the result of the list operation, a likely XML representation of a set of objects will generally be a collection of XML elements, each element corresponding to the attributes of that object or record.

So looking at a simple example of performing a list operation on a set of contact records, With a URL requests such as

http://myserver/myapp/listusers

we might get an XML result as follows

<contacts>

<contact>

<id>1</id>

<first_name>Joe</first_name>

<last_name>User</last_name>

</contact>

<contact>

<id>2</id>

<first_name>Jim</first_name>

<last_name>Bean</last_name>

</contact>

<contact>

<id>3</id>

<first_name>Sally</first_name>

<last_name>Fieldman</last_name>

</contact>

</contacts>

Using XX foundation, a request would be passed into the implementation function in a format such as

<root sid=”727F7163BAE2B922F1F9386ED7495BAF”>

<request
/>

</root>

The custom functioning implementing the servlet mapped to the url request “listusers” would need to examine this request XML and determine the necessary operations needed to return the correct XML. In this case, the implementation function would perform a database select against (most likely) a Contact table, and then return each row as a “contact” element.

What business specific knowledge is needed by the implementation class.? The implementation needs to know what database entity must be queries as well as what filter should be applied to the query. Using XX foundation, the implementing function might

  1. Create a DB Select statement on the DB Contact table
  2. Cycle through the result set and convert the results to XML.

After the custom implementation does its job, the XML results are passed back to the XX framework, where it is transformed using XSL and displayed as HTML to the user.

So with the goal of automatic these operations, we look back to our friend XML and represent the additional needed information in the XX configuration file.

To accomplish this, we will add one additional element to the XX config file

hb_classname The Hibernate (entity) class the will be the target of the CRUD operation.

Forgetting about Hibernate for now, this class would simply be the application class “Contact”. Now, using the foundation layer, a Contact object is not even required. Using a more service oriented approach; a single implementation class could open the database connection, read the database result, and convert the result to XML. However, XX recommends a more object oriented data model be used. In many cases, even using XX foundation, that Contact class would likely exist if the developer chose to implement an OO model. However, for XX Automation, an OO model is required.

So now we now know which class is being requested. We also know, from the XX Config file, that the desired operation is a “list”, which in XX translates into a list of objects.

So knowing nothing else, we can imagine an operation that reads through all the Contact objects and converts these to XML

But all we’ve accomplished to far is telling the implementing class which entity class contains the data desired. We still don’t tell it how to find the data, which is likely stored in a database. This is where Hibernate comes in.

Hibernate is an Object to Relational mapping layer. Hibernate stores the needed information, in XML configuration files, to map the attributes of the Contact object to the field of the Contact table.

So, given a list operation on the Contact class, hibernate can be used to automatically return a collection of Java Contact objects, representing the Contact table.

At this point in the operation we still need to convert the Java object collection to XML representation. This is where Castor is uses. Castor is another Java mapping library that is used by XX to convert Java Objects to XML representation. Castor mapping files can also be used to fine tune the conversion, thought in most case, the default conversion will a sufficient. In example process, the Java objects returned by Hibernate will be passed to Castor and an XML representation will be produced. This XML representation is then passed back to the XX framework and the XSL transformation is applied. If all works as expected, an HTML list of contacts will be displayed.

XX automation also provides the capabilities to filter and sort the list, as well as enabling record navigation through the result set.

Get

The get operation is similar, except that only a single primary element is returned. However, we need to specify which object or row to retrieve. This is done by incorporating an id parameter as part of the request.

<request
>

<id>1</id>

</request>

Instead of a select on all Contact objects, now only those where the id attribute equals 1 is returned. This criterion can most easily be passed into the request in the URL as followed

http://myserver/myapp/getuser?id=1

The get can be seen as a subset of a list, which it is. However, it is implemented as a separate XX operation since a get of a single record sometimes requires a more detailed data representation; either returning all object attributes and possibly a large subset of related attributes in other objects are tables. This follows general application design, where if a large number of rows are returned in a list, only a small portion of data from each row is displayed. The user will then select an object from the list to view in more detail, where additional information is displayed. This approach is done for the sake of performance (it would take too long to return all object data for a large list) and page design (it would be too unwieldy to display all information about all objects on a single page)

Configuration files are used to instruct XX as to which objects and attributes to return, so a get operation can be configured to return more attributes than a list operation.

In object and relational modeling, data is stored in multiple classes or tables. In many cases, a list or get operation will need data from related classed or tables, as is typically done in an SQL join operation. Luckily, Hibernate also can also represent the relationship between classes. So a list or get operation is not limited to the data contained in a singe class or table, which would rarely be sufficient. We can request data in related classes or tables, and hibernate will automatically get this related data as well. The returned set of Java objects will now contain related objects as well, essentially a graph of objects. Luckily, Castor has no problem converting a graph of objects as well, and again, the default XML representation of a Java object graph is usually sufficient.

Since the returned object model can be elaborate, which would greatly impact performance and memory use, a combination of Hibernate lazy loading and castor mapping files is used to fine tune the result set.

Automation Example XML configuration file

For the previous example, the configuration might be the following

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE xx_config SYSTEM “http://www.xxframework.org/dtd/xx_config.dtd”&gt;

<xx_config>

<classes>

<class id=”1 use=”xsl scope=”page applyxsl=”true“>

<classname>org.xxframework.control.RecordControl</classname>

<method>get</method>

<hb_classname>org.myapp.entity.Contact</hb_classname>

<xsl_file>ShowContact.xsl</xsl_file>

</class>

</classes>

<jsp>main.jsp</jsp>

</xx_config>

In this simple example, the framework will issue a get (single record lookup) on the Contact class, generally using an “id” parameter passed in with the request. The resulting XML document will be transformed using the ShowMessage.xsl XSL file. The results, generally HTML, will be passed to main.jsp using a reference id of 1. Note that unlike earlier examples of the XX foundation, where the developer is responsible for implementing the XML generation; here the classname element points to an XX framework class. XX now provides the actual implementation class that generates the response XML. The additional element, hb_classname, tells XX where to locate the needed data.

Delete

The delete operation is conceptually similar to the above case. By simply telling the framework which class and id within that class to delete, the operation can be automated. An example configuration might be the following

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE xx_config SYSTEM “http://www.xxframework.org/dtd/xx_config.dtd”&gt;

<xx_config>

<classes>

<class id=”1 use=”xsl scope=”page applyxsl=”true“>

<classname>org.xxframework.control.RecordControl</classname>

<method>delete</method>

<hb_classname>org.myapp.entity.Contact</hb_classname>

<xsl_file>DeleteContact.xsl</xsl_file>

</class>

</classes>

<jsp>main.jsp</jsp>

</xx_config>

Here only the method is different than in the get operation configuration. As in the get, this operation will expect input of the form

<request
>

<id>1</id>

</request>

But now, instead of generating XML for the Contact class with id equal to 1, that class will now be deleted from the object graph as well as the database. Hibernate is again used to accomplish this.

Future versions of XX will allow deletion based on an arbitrary filter condition

Set

The update, or in XX parlance, set operation is more complex than the previous three, but logically follows. To save a single record of the Contact class for example, the values must be passed into the implementation function. Building off the above example, a save operation would need a request similar to the following:

<request>

<id>1</id>

<first_name>Joe</first_name>

<last_name>User</last_name>

</request>

In response to the above request, XX will set the firstName and lastName attributes in the instance of the Contact class where the id attribute equals 1 to the values specified. If no id attribute is specified, the class instance will be added, resulting in a new database row.

Additional automation components

XSL Data validation framework

One common component of an application development framework is a data validation methodology. XX provides a data validation framework using XSL. Validation is applied to all “set” operation, since that is the only operation where data validation is relevant. Validations are performed on the server side, as opposed to client-side JavaScript validation, and can be as complex as allowed by the XSL processing language.

The data validation is defined in the file xx_validate.xsl, which should be placed in the XML directory. This stylesheet contains a series of templates matching the related XML data elements. The template can perform tests against the submitted data, and return error conditions if necessary.

For example:

<xsl:template match=”user“>

<xsl:call-template name=”notemptytest“>

<xsl:with-param name=”val“>

<xsl:value-of select=”firstname“/>

</xsl:with-param>

<xsl:with-param name=”nodename“>

<xsl:value-of select=”name(firstname)“/>

</xsl:with-param>

<xsl:with-param name=”message“>First Name cannot be blank</xsl:with-param>

</xsl:call-template>

<xsl:call-template name=”notemptytest“>

<xsl:with-param name=”val“>

<xsl:value-of select=”lastname“/>

</xsl:with-param>

<xsl:with-param name=”nodename“>

<xsl:value-of select=”name(lastname)“/>

</xsl:with-param>

<xsl:with-param name=”message“>Last Name cannot be blank</xsl:with-param>

</xsl:call-template>

</xsl:template>

* the template “notemptytest” exists in the XX XSL library, includes.xsl

In this example, a user object, represented as XML, is passed into the validation routine. The routine checks for the existence of a “firstname” and “lastname” element. If either doesn’t exist, an error condition will be returned, using the message parameter specified. Custom functions also exist to manually return error messages as well.

Castor mapping files

XX Automation uses Castor for reading Java objects into XML Format. XX uses Castor mapping files to limit which Java attributes get included in the XML output. With an object oriented java mode, as required by Hibernate, very large XML files can be produced if no mapping file is used.

An advantage of using mapping files is that the required fields can be changes as needed. This is preferable to modifying the code base (and recompiling) every time a new field is needed in the output. This approach is also preferable to including all fields or coming up with an “inspection” function to return all database fields as XML, as these approaches may affect performance adversely.

Future Development

Application Generation

While XX automation provides some of the most common application tasks, it does not actually generate fully functional, stand alone operations. The most glaring omission is the lack of a front end. XX Applications generally use XSL as a large component of the front end. As one develops more applications, one reuses XSL code from other applications, sometimes just substituting class related work. So where I might have an XSL template to display a list of messages, to display a list of contacts I would only need to replace the word message with the word contact in the template.

This observation as well as the fact that XSL, being a text based language, is easily generated, can lead to great possibilities for more fully feature application generation.

Leave a comment