ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Using Hierarchical Data Sets with Aspire and Tomcat
Pages: 1, 2

Example Code for Exploring the ihds API



The following code will walk through the ihds tree, printing it out:

import com.ai.htmlgen.*;
import com.ai.common.TransformException;
import Java.io.*;
import com.ai.data.*;

	// above code removed for clarity 

    public static void staticTransform(ihds data, PrintWriter out) 
           throws TransformException
    {
        try
        {
            writeALoop("MainData",data,out,"");
        }
        catch(DataException x)
        {
            throw new TransformException(
				"Error: DebugTextTransform: Data Exception",x);
        }
    }
    
    /**********************************************************
     * A recursive function to write out a loop worth of ihds
     **********************************************************
     */
     
    private static void writeALoop(
		String loopname, ihds data, PrintWriter out, String is)
            throws DataException
    {
        println(out,is, ">> Writing data for loop:" + loopname);

        // write metadata
        IMetaData m = data.getMetaData();
        IIterator columns = m.getIterator();

        StringBuffer colBuffer = new StringBuffer();
        for(columns.moveToFirst();!columns.isAtTheEnd();columns.moveToNext())
        {
            String columnName = (String)columns.getCurrentElement();
            colBuffer.append(columnName).append("|");
        }
        println(out,is,colBuffer.toString());

        //write individual rows
        for(data.moveToFirst();!data.isAtTheEnd();data.moveToNext())
        {
            StringBuffer rowBuffer = new StringBuffer();
            for(columns.moveToFirst();!columns.isAtTheEnd();columns.moveToNext())
            {
                String columnName = (String)columns.getCurrentElement();
                rowBuffer.append(data.getValue(columnName));
                rowBuffer.append("|");
            }
            println(out,is,rowBuffer.toString());

            // recursive call to print children
            IIterator children = data.getChildNames();
            for(children.moveToFirst();!children.isAtTheEnd();children.moveToNext())
            {
                // for each child
                String childName = (String)children.getCurrentElement();
                ihds child = data.getChild(childName);
                writeALoop(childName,child,out,is + "\t");
            }
        }

        println(out,is,">> Writing data for loop:" + loopname + " is complete");
    }
    
    private static void println(PrintWriter out, String indentationString, 
	                            String line)
    {
        out.print(indentationString);
        out.print(line);
        out.print("\n");
    }

    // code removed for clarity

How to Use ihds Under Tomcat

The facilities presented so far demonstrate accessing Hierarchical Data Sets anywhere in Java code, including command-line applications. When Aspire is initalized under Tomcat, it goes a step further and allows you to include data sets directly in your web pages. Currently supported formats include classic XML, object XML, text, and Excel data. Formats planned for the near future include Java class definitions to match the object XML, XSD, and generic HTML pages.

Before being able to obtain your web pages in one of these formats, you need to know how to initialize Aspire under Tomcat. Besides the article referenced above, see "Improve Your Career with Tomcat and Aspire." Once this is accomplished, your remaining work is to:

  1. Link your Hierarchical Data Set definition to a URL in the configuration file.
  2. Invoke the URL with the desired type of data format.

Link Your Hierarchical Data Set Definition to a URL

Add this section to the existing data definition configuration file:

###################################
# ihdsTestURL: linking to a URL
###################################
ihdsTestURL=aspire:\\samples\\ihds-test\\ihds-default-html-template.html
ihdsTestURL.formHandlerName=ihdsTest
request.ihdsTest.form_handler.class_request.className=
         com.ai.htmlgen.DBHashTableFormHandler1

There are two parts to a URL defined in Aspire: the data source and the data transformation. Aspire can transform data using JSP, XSLT, or tags. The default transformation, tags, requires a template filename that includes the tags. The first line indicates a transformation file for the data. The second line points to a data definition called ihdsTest, which is defined down the line. Line 3 says essentially the same thing as line 1 of section 1. This discrepancy is due to some backward compatibility with Aspire.

Ensure that the Java Classes Responsible for Transformations Are Present in the Properties Files

Aspire allows a Hierarchical Data Set to be transformed in one of two ways, generic or page-specific. This example definition is page-specific, because the presented HTML template is specific to that page. A generic transformation will take any Hierarchical Data Set belonging to any page and transform it in a generic manner. Generic transformations are included in the configuration file as follows:

# Generic transform support
# XML output
GenericTransform.Classic-xml.classname=
           com.ai.xml.FormHandlerToXMLTransform
GenericTransform.Object-xml.classname=
           com.ai.generictransforms.ObjectXMLGenericTransform

# Excel output
GenericTransform.Excel.classname=
           com.ai.generictransforms.ExcelGenericTransform

# Text
GenericTransform.Text.classname=
           com.ai.generictransforms.DebugTextTransform

These definitions are usually included in the master aspire.properties file.

Invoke the URL with a Proper Output Format Parameter

Once the URL is defined, you can see the resulting HTML page by calling the defined URL as follows:

http://yourhost:yourport/your-webapp/servlet/DisplayServlet?url=ihdsTestURL

This will produce an HTML page. Say that we want to call the URL and obtain the data as classic XML; simply add the following additional argument to the above URL:

&aspire_output_format=classic-xml

For Excel data, do something similar:

&aspire_output_format=Excel

The key is to tie down an argument called aspire_output_format to a generic Java classname. It is very easy to write these generic transformations to suit your output needs. The following example shows Excel's generic transform implementation.

Establishing Your Own Output Formats Or Implementing Your Own Generic Data Transform

package com.ai.generictransforms;
import com.ai.htmlgen.*;
import com.ai.common.TransformException;
import Java.io.*;
import com.ai.data.*;
import Javax.servlet.http.*;

public class ExcelGenericTransform 
      extends AHttpGenericTransform 
      implements IFormHandlerTransform
{
    private static String s_separator = "\t";
    protected String getDerivedHeaders(HttpServletRequest request)
    {
        return "Content-Type=application/vnd.ms-excel|Content-Disposition=
                     filename=aspire-hierarchical-dataset.xls";
    }
    public void transform(ihds data, PrintWriter out) 
                    throws TransformException
    {
        staticTransform(data,out);
    }
    public void transform(IFormHandler data, PrintWriter out)
           throws TransformException
    {
        staticTransform((ihds)data,out);
    }
    public static void staticTransform(ihds data, PrintWriter out) 
           throws TransformException
    {
        try
        {
            writeALoop("MainData",data,out,"");
        }
        catch(DataException x)
        {
            throw new TransformException("Error: ExcelGenericTransform: 
			                              Data Exception",x);
        }
    }
    private static void writeALoop(String loopname, 
                                   ihds data, 
                                   PrintWriter out, 
                                   String is)
            throws DataException
    {
        println(out,is, ">> Writing data for loop:" + loopname);

        // write metadata
        IMetaData m = data.getMetaData();
        IIterator columns = m.getIterator();

        StringBuffer colBuffer = new StringBuffer();
        for(columns.moveToFirst();!columns.isAtTheEnd();columns.moveToNext())
        {
            String columnName = (String)columns.getCurrentElement();
            colBuffer.append(columnName).append(s_separator);
        }
        println(out,is,colBuffer.toString());

        //write individual rows
        for(data.moveToFirst();!data.isAtTheEnd();data.moveToNext())
        {
            StringBuffer rowBuffer = new StringBuffer();
            for(columns.moveToFirst();!columns.isAtTheEnd();columns.moveToNext())
            {
                String columnName = (String)columns.getCurrentElement();
                rowBuffer.append(data.getValue(columnName));
                rowBuffer.append(s_separator);
            }
            println(out,is,rowBuffer.toString());

            // recursive call to print children
            IIterator children = data.getChildNames();
            for(children.moveToFirst();!children.isAtTheEnd();children.moveToNext())
            {
                //for each child
                String childName = (String)children.getCurrentElement();
                ihds child = data.getChild(childName);
                writeALoop(childName,child,out,is + "\t");
            }
        }

        println(out,is,">> Writing data for loop:" + loopname + " is complete");
    }
    private static void println(PrintWriter out, String 
          indentationString, String line)
    {
        out.print(indentationString);
        out.print(line);
        out.print("\n");
    }
}

The Implications of Hierarchical Data Sets and Aspire to the Tomcat Development Community

The implications of these facilities are quite exciting to the Tomcat developer community. If page developers use this mechanism to retrieve data, they can put a series of data icons at the top of each page that allow end users to retrieve data in their preferred format. End users will benefit from Excel output as they can now work with data in their spreadsheets. B2B users can retrieve data as XML. Java and other programmers can retrieve the data binding as Java classes and can choose to work with objects, as opposed to XML.

All of the documented facilities are available for Tomcat developers free of cost and in a very small package. For a large number of students and entry-level programmers, this means that they can download a couple of megs of Tomcat and Aspire and sit with a tool like Dreamweaver and be immediately productive with any database of their choice.

As they progress in their learning experience, they can start writing plug-ins and other sophisticated Java programs that can do some specialized work while the basics are supplied by the framework. This ladder-like approach to learning Java, J2EE, XML, and the Enterprise is good.

A Demo URL that Demonstrates the Workings of Hierarchical Data Sets

Access Aspire's sample pages at Indent, Inc., should have a set of pages demonstrating the Hierarchical Data Sets by the time this article is published. You may have to scroll down to see the section that talks about Hierarchical Data Sets, as this URL demonstrates a few other features, as well.

Give Me Your Valuable Feedback

I would be delighted to hear from you if you see any architectural anomalies with Hierarchical Data Sets as well as the potential of Hierarchical Data Sets in programming. You can email me any time at satya@activeintellect.com.

Additional References

  • " For Tomcat Developers, Aspire Comes in a JAR." This article will show how to use Aspire for accessing data declaratively under Tomcat. It also introduces Aspire's configuration service and Factory Service.
  • " Improve Your Career with Tomcat and Aspire." This article shows how to use Aspire for web development by Java and Non-Java programmers.
  • "Is it not time to invite the cathedral to the bazaar." This article tries to propose bolstering J2EE with a declarative set of tools for bringing non-Java programmers and Java beginners to J2EE.
  • "Transparent data pipelines." This article is about the architectural underpinnings of generating Hierarchical Data Sets, and is appropriate for Java programmers and architects.
  • "A JSP architecture for Oracle stored procedures," July 2001 Java Report
  • "Generating/consuming XML documents from relational databases," Vol 2, Issue 4, XML Journal
  • The Aspire home page. You can download Aspire distributions from here.

Satya Komatineni is the CTO at Indent, Inc. and the author of Aspire, an open source web development RAD tool for J2EE/XML.


Return to ONJava.com.