org.apache.struts2.views.xslt
Class XSLTResult

java.lang.Object
  extended by org.apache.struts2.views.xslt.XSLTResult
All Implemented Interfaces:
com.opensymphony.xwork2.Result, java.io.Serializable

public class XSLTResult
extends java.lang.Object
implements com.opensymphony.xwork2.Result

XSLTResult uses XSLT to transform action object to XML. Recent version has been specifically modified to deal with Xalan flaws. When using Xalan you may notice that even though you have very minimal stylesheet like this one

 <xsl:template match="/result">
   <result />
 </xsl:template>

then Xalan would still iterate through every property of your action and it's all descendants.

If you had double-linked objects then Xalan would work forever analysing infinite object tree. Even if your stylesheet was not constructed to process them all. It's becouse current Xalan eagerly and extensively converts everything to it's internal DTM model before further processing.

Thet's why there's a loop eliminator added that works by indexing every object-property combination during processing. If it notices that some object's property were already walked through, it doesn't get any deeper. Say, you have two objects x and y with the following properties set (pseudocode):

 x.y = y;
 and
 y.x = x;
 action.x=x;

Due to that modification the resulting XML document based on x would be:

 <result>
   <x>
     <y/>
   </x>
 </result>

Without it there would be an endless x/y/x/y/x/y/... elements.

The XSLTResult code tries also to deal with the fact that DTM model is built in a manner that childs are processed before siblings. The result is that if there is object x that is both set in action's x property, and very deeply under action's a property then it would only appear under a, not under x. That's not what we expect, and that's why XSLTResult allows objects to repeat in various places to some extent.

Sometimes the object mesh is still very dense and you may notice that even though you have relatively simple stylesheet execution takes a tremendous amount of time. To help you to deal with that obstacle of Xalan you may attach regexp filters to elements paths (xpath).

Note: In your .xsl file the root match must be named result.
This example will output the username by using getUsername on your action class:

 <xsl:template match="result">
   <html>
   <body>
   Hello <xsl:value-of select="username"/> how are you?
   </body>
   <html>
 <xsl:template/>
 

In the following example the XSLT result would only walk through action's properties without their childs. It would also skip every property that has "hugeCollection" in their name. Element's path is first compared to excludingPattern - if it matches it's no longer processed. Then it is compared to matchingPattern and processed only if there's a match.


 <result name="success" type="xslt">
   <param name="location">foo.xslt</param>
   <param name="matchingPattern">^/result/[^/*]$</param>
   <param name="excludingPattern">.*(hugeCollection).*</param>
 </result>
 
This result type takes the following parameters:

struts.properties related configuration:

Example:

 <result name="success" type="xslt">foo.xslt</result>
 

See Also:
Serialized Form

Field Summary
static java.lang.String DEFAULT_PARAM
           
protected  boolean noCache
           
 
Constructor Summary
XSLTResult()
           
XSLTResult(java.lang.String stylesheetLocation)
           
 
Method Summary
 void execute(com.opensymphony.xwork2.ActionInvocation invocation)
           
protected  AdapterFactory getAdapterFactory()
           
protected  javax.xml.transform.Source getDOMSourceForStack(java.lang.Object action)
           
 java.lang.String getStylesheetLocation()
           
protected  javax.xml.transform.Templates getTemplates(java.lang.String path)
           
protected  javax.xml.transform.URIResolver getURIResolver()
          Get the URI Resolver to be called by the processor when it encounters an xsl:include, xsl:import, or document() function.
protected  void setAdapterFactory(AdapterFactory adapterFactory)
           
 void setLocation(java.lang.String location)
          Deprecated. Use #setStylesheetLocation(String)
 void setParse(boolean parse)
          If true, parse the stylesheet location for OGNL expressions.
 void setStylesheetLocation(java.lang.String location)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_PARAM

public static final java.lang.String DEFAULT_PARAM
See Also:
Constant Field Values

noCache

protected boolean noCache
Constructor Detail

XSLTResult

public XSLTResult()

XSLTResult

public XSLTResult(java.lang.String stylesheetLocation)
Method Detail

setLocation

public void setLocation(java.lang.String location)
Deprecated. Use #setStylesheetLocation(String)


setStylesheetLocation

public void setStylesheetLocation(java.lang.String location)

getStylesheetLocation

public java.lang.String getStylesheetLocation()

setParse

public void setParse(boolean parse)
If true, parse the stylesheet location for OGNL expressions.

Parameters:
parse -

execute

public void execute(com.opensymphony.xwork2.ActionInvocation invocation)
             throws java.lang.Exception
Specified by:
execute in interface com.opensymphony.xwork2.Result
Throws:
java.lang.Exception

getAdapterFactory

protected AdapterFactory getAdapterFactory()

setAdapterFactory

protected void setAdapterFactory(AdapterFactory adapterFactory)

getURIResolver

protected javax.xml.transform.URIResolver getURIResolver()
Get the URI Resolver to be called by the processor when it encounters an xsl:include, xsl:import, or document() function. The default is an instance of ServletURIResolver, which operates relative to the servlet context.


getTemplates

protected javax.xml.transform.Templates getTemplates(java.lang.String path)
                                              throws javax.xml.transform.TransformerException,
                                                     java.io.IOException
Throws:
javax.xml.transform.TransformerException
java.io.IOException

getDOMSourceForStack

protected javax.xml.transform.Source getDOMSourceForStack(java.lang.Object action)
                                                   throws java.lang.IllegalAccessException,
                                                          java.lang.InstantiationException
Throws:
java.lang.IllegalAccessException
java.lang.InstantiationException


Copyright © 2000-2006 Apache Software Foundation. All Rights Reserved.