Start with a hierarchical data set


<AspireDataSet>
    <!-- A set of key value pairs at the root level -->
    <key1>val1</key1>   
    <key2>val2</key2>

    <!-- A set of named loops -->
    <loop name="loop">
    </loop>
    <loop name="loop2">
    </loop>
</AspireDataSet>

Inner loop further expanded


<loop name="loopname">
    <row>
        <!-- a set of key value pairs -->
        <key1>val1</key1>
        <key2>val2</key2>

        <!-- a set of named loops -->
        <loop name="loopname1">
        </loop>

        <!-- a set of named loops -->
        <loop name="loopname2">
        </loop>
    </row>
    <row>
    </row>
</loop>

Well that smells like a structure or a class


public class MyData
{
	String key1;
	String key2;
	List loop1;
	List loop2;
}

public class Loop1Class
{
	String key1;
	String key2;
	List loop11;
	List loop12
}

public class Loop2Class
{
	String key1;
	String key2;
	List loop21;
	List loop22
}

Let us first see how to get the data as an HDS declaratively


###################################
# ihdsTest data definition: section1
###################################
request.ihdsTest.className=com.ai.htmlgen.DBHashTableFormHandler1
request.ihdsTest.loopNames=loop1,loop2

#section1 - main key value pairs
request.ihdsTest.mainDataRequest.classname=com.ai.db.DBRequestExecutor2
request.ihdsTest.mainDataRequest.db=my-database
request.ihdsTest.mainDataRequest.stmt=some-select

#section2 - loop1
request.ihdsTest.loop1.class_request.className=com.ai.htmlgen.GenericTableHandler6
request.ihdsTest.loop1.loopNames=loop11
request.ihdsTest.loop1.query_request.className=com.ai.data.RowFileReader
request.ihdsTest.loop1.query_request.filename=aspire:\\samples
            \\pop-table-tags\\properties\\pop-table.data

         
#section3 - loop2
request.ihdsTest.loop2.class_request.className=com.ai.htmlgen.GenericTableHandler6
request.ihdsTest.loop2.loopNames=loop11
request.ihdsTest.loop2.query_request.className=com.ai.data.RowFileReader
request.ihdsTest.loop2.query_request.filename=aspire:\\samples
            \\pop-table-tags\\properties\\pop-table.data

#section3 - subloop to loop1
request.loop11.class_request.classname=com.ai.htmlgen.GenericTableHandler6
request.loop11.query_request.classname=com.ai.data.RowFileReader
request.loop11.query_request.filename=aspire:\\samples\\pop-table-tags
           \\properties\\pop-table.data

How is this data structure navigated using the above data type


    Ihds myDataAsHds = Utils.executeDataTransaction("ihdsTest",new Hashmap());
	MyData myTypedHDSData = Utils.bind(myDataAsHDS, getTypeOf(MyData)); 

Language bindings


public class Utils
{
	String getJavaClassDefinition(Ihds hdsData);
	String getVBClassDefinition(Ihds hdsData);
	String getActionScriptClassDefinition(Ihds hdsData);
}

What can I do with language bindings?


    Ihds myDataAsHds = Utils.executeDataTransaction("ihdsTest",new Hashmap());

	//A java client	
	//Produce MyData definition dynamically
	String javaClass = Utils.getJavaClass(myDataAsHDS);
	
	//Compile MyData with your source code
	MyData myTypedHDSData = Utils.bind(myDataAsHDS, getTypeOf(MyData)); 

	
	//A C# client	
	//Produce MyData definition dynamically
	String cSharpClass = Utils.getCSharpClass(myDataAsHDS);
	
	//Compile MyData with your c# source code
	MyData myTypedHDSData = Utils.bind(myDataAsHDS, getTypeOf(MyData)); 

References

1. Qualities of a Good Middle-Tier Architecture This article at OnJava.com discusses typed data sets in the context of a larger middleware architecture.

2. Using Hierarchical Data Sets with Aspire and Tomcat, at OnJava.com

3. Use Aspire and Tomcat to retrieve XML declaratively from any relational database

4. Code Examples for relational data sets

5. OnJava article on relational data sets

6. Overview of data access using Aspire

7. OSCON 2004 Summary page for Server side patterns session