19-Jul-04 (Created: 19-Jul-04) | More in 'OSCON-2004'

Pluggable transformations: Code Examples

Start out with a URL definition

Defines data and transformation for this page


<url name="page1URL">
	<transform requestName="page1TransformRequet"/>
	<data requestName="page1DataRequest"/>
</url>

Specifying a transform


<request name="page1TransformRequest" classname="com.ai.jsp.JSPTransform">
	<includeOrForward>include</includeOrForward>
</request>

for XSLT you would do


<request name="page1TransformRequest" classname="com.ai.xml.XSLTTransform">
</request>

So on and so forth ....

Define data


<request name="page1-data">
   <main>page1-main-data</main>
   <table1>page1-table1-data</table1>
   <list1>page1-list1-data</list1>
</request>

<request name="page1-main-data">
	<classname>com.ai.db.DBRequestExecutor2</classname>
	<db>my-database</db>
	<stmt>select *</stmt>
</request>

<request name="page1-table1-data">
	<classname>com.ai.db.DBRequestExecutor2</classname>
	<db>my-database</db>
	<stmt>select * from t1 where key1, key2</stmt>
</request>

<request name="page1-list1-data">
	<classname>com.ai.db.DBRequestExecutor2</classname>
	<db>my-database</db>
	<stmt>select * from t2 where key3, key4</stmt>
</request>

Implementing the JSPTransform


public class JSPTransform implements IAIHttpTransform, ICreator, IMultiInstance
{
   private bool bInclude = false;
   public void initialize(String requestName)
   {
   	 	String include = AppObjects.getValue(requestName + ".includeOrForward", "forward");
		if (include.toLowerCase() == "include")
		{
			bInclude = true;
		}
   }
   public void transform( String htmlFilename
                          , IFormHandler formHandler
                          , HttpServletRequest request
                          , HttpServletResponse response
                          , RequestDispatcher dispatcher
                         ) throws java.io.IOException, ServletException
   {
      request.setAttribute("Aspire.formHandler",formHandler);
	  if (bInclude == false)
      	dispatcher.forward(request,response);
	  else
	  	dispatcher.include(request,response);
   }                         
} 

Implementing an XSLT transform


public class ClassicXSLTransform implements IAITransform, ICreator
{
   public void transform(String htmlFilename, PrintWriter writer, Ihds ihds)
   throws java.io.IOException
   {
      boolean test = true;
	 // from the form handler get a DOM document
	 Document doc = transformToXML((ihdsd));   
	 String outputFormat = ihds.getValue("aspire_output_format");
	 if (outputFormat == null) outputFormat = "xsl";
		
	 if (outputFormat.equalsIgnoreCase("xml") == true)
	 {
		writeDOMToOutput(writer,doc);
	 }
	 else
	 {
		Transformer xslt = getTransformer(htmlFilename);
		xslt.transform(new DOMSource(doc), new StreamResult(writer));
	 }
	 //lot of try/catch blocks left out
   }//eof-function
}//eof-class

Data structure coming out of the definition


key1
key2
key3
key4
<loop name="table1">
   <row>col1, col2</row>
   <row>col1, col2</row>
</loop>   
<loop name="list1">
	<row>col1,col2</row>
	<row>col1, col2</row>
</loop>

Example JSP page


Ihds pageData = request.getAttribute("Aspire-dataset");
String key1=pageData.getValue("key1");
String key2=pageData.getValue("key2");

Ihds table1Data = pageData.getLoopData("table1");
for(table1Data.moveToFirst();table1Data.isNotAtTheEnd();table1Data.moveToNext())
{
	String col1 = table1Data.getValue("col1");
	String col2 = table1Data.getValue("col2");
}  

Ihds list1Data = pageData.getLoopData("list1");
for(list1Data.moveToFirst();list1Data.isNotAtTheEnd();list1Data.moveToNext())
{
	String col1 = table1Data.getValue("col1");
	String col2 = table1Data.getValue("col2");
}  
ihds.close();

Jsp page with typed binding

Define a class for this page


public class ThisPage
{
	String key1, key2, key3, key4;
	
	//List of typed ThisTableData
	List table1Data;
	
	//List of typed ThisList1Data 
	List list1Data;
}
public class ThisTable1Data
{
	String col1, col2;
}

public class ThisList1Data
{
	String col1, col2;
}

Use the class to bind to the data and paint


Ihds pageData = request.getAttribute("Aspire-dataset");
ThisPage tpd = Utils.bind(pageData, new ThisPage());

String key1=tpd.key1;
String key2=tpd.key2;

List table1Data = tpd.tableData;
Iterator itr = table1Data.getIterator();
while(itr.hasNoMoreRows())
{
	ThisTable1Data row = itr.nextElement();
	String col1 = row.col1;
	String col2 = row.col2;
}
  
List list1Data = tpd.list1Data;
Iterator itr = list1Data.getIterator();
while(itr.hasNoMoreRows())
{
	ThisList1Data row = itr.nextElement();
	String col1 = row.col1;
	String col2 = row.col2;
}  

XSLT page


some text
some more text

addtional text <xsl:value-of select="AspireDataSet/key1"/> 
dddd <xsl:value-of select="AspireDataSet/key2"/>
some more text


<table>
<tr>header row</tr>
<xsl:for-each select="AspireDataSet/tabl1data"/>
<tr><td>{{col1}}</td><td>{{col2}}</td>
</xsl:for-each>
</table>

<ul>
<xsl:for-each select="AspireDataSet/tabl1data"/>
<li>{{col1}}</li>
</xsl:for-each>
</ul>

<p><b>Another data island</b></p>
addtional text 
<xsl:value-of select="key3"/> 
dddd 
<xsl:value-of select="key4"/>
some more text

References

1. General Introduction to other Server side Patterns in this series

2. OSCON 2004 Summary page for Server side patterns session

3. Abstract Page Data Pattern: Code Examples