You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by he...@apache.org on 2006/07/20 19:23:13 UTC

svn commit: r423995 [2/2] - /struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java?rev=423995&r1=423994&r2=423995&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java Thu Jul 20 10:23:12 2006
@@ -18,7 +18,6 @@
 package org.apache.struts2.views.xslt;
 
 import org.apache.struts2.ServletActionContext;
-import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.config.Configuration;
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
@@ -39,7 +38,6 @@
 import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.regex.Pattern;
 
 
 /**
@@ -181,131 +179,146 @@
  */
 public class XSLTResult implements Result {
 
-	private static final long serialVersionUID = 8024698928688847685L;
-	
-	private static final Log log = LogFactory.getLog(XSLTResult.class);
-    public static final String DEFAULT_PARAM = "location";
-
-    private static final Object LOCK = new Object(); // lock in synchronized code
-
-    protected boolean noCache = false;
-    protected Map templatesCache;
-    protected String location;
-    protected boolean parse;
-    protected Pattern matchingPattern = null;
-    protected Pattern excludingPattern = null;
+    private static final Log log = LogFactory.getLog(XSLTResult.class);
+    public static final String DEFAULT_PARAM = "stylesheetLocation";
+
+    protected boolean noCache;
+    private final Map<String, Templates> templatesCache;
+    private String stylesheetLocation;
+    private boolean parse;
+    private AdapterFactory adapterFactory;
 
     public XSLTResult() {
-        templatesCache = new HashMap();
-        noCache = Configuration.getString(StrutsConstants.STRUTS_XSLT_NOCACHE).trim().equalsIgnoreCase("true");
+        templatesCache = new HashMap<String, Templates>();
+        noCache = Configuration.getString("struts.xslt.nocache").trim().equalsIgnoreCase("true");
     }
 
+    /**
+     * @deprecated Use #setStylesheetLocation(String)
+     */
     public void setLocation(String location) {
-        this.location = location;
+        setStylesheetLocation(location);
     }
 
-    public void setMatchingPattern(String matchingPattern) {
-        this.matchingPattern = Pattern.compile(matchingPattern);
+    public void setStylesheetLocation(String location) {
+        if (location == null)
+            throw new IllegalArgumentException("Null location");
+        System.out.println("location = " + location);
+        this.stylesheetLocation = location;
     }
 
-    public void setExcludingPattern(String excludingPattern) {
-        this.excludingPattern = Pattern.compile(excludingPattern);
+    public String getStylesheetLocation() {
+        return stylesheetLocation;
     }
 
+    /**
+     * If true, parse the stylesheet location for OGNL expressions.
+     *
+     * @param parse
+     */
     public void setParse(boolean parse) {
         this.parse = parse;
     }
 
     public void execute(ActionInvocation invocation) throws Exception {
-        long startTime = -1;
-
-        if (log.isDebugEnabled()) {
-            startTime = System.currentTimeMillis();
-        }
+        long startTime = System.currentTimeMillis();
+        String location = getStylesheetLocation();
 
         if (parse) {
             OgnlValueStack stack = ActionContext.getContext().getValueStack();
             location = TextParseUtil.translateVariables(location, stack);
         }
 
-        if (location == null || location.trim().length() == 0) {
-            String msg = "Location paramter is empty. " +
-                "Check the <param name=\"location\"> tag specified for this action.";
-            log.error(msg);
-            throw new IllegalArgumentException(msg);
-        }
-
         try {
             HttpServletResponse response = ServletActionContext.getResponse();
 
             Writer writer = response.getWriter();
 
             // Create a transformer for the stylesheet.
-            Templates templates = getTemplates(location);
-            Transformer transformer = templates.newTransformer();
-
-            String mimeType = templates.getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE);
-
+            Templates templates = null;
+            Transformer transformer;
+            if (location != null) {
+                templates = getTemplates(location);
+                transformer = templates.newTransformer();
+            } else
+                transformer = TransformerFactory.newInstance().newTransformer();
+
+            transformer.setURIResolver(getURIResolver());
+
+            String mimeType;
+            if (templates == null)
+                mimeType = "text/xml"; // no stylesheet, raw xml
+            else
+                mimeType = templates.getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE);
             if (mimeType == null) {
                 // guess (this is a servlet, so text/html might be the best guess)
-                log.debug("Not possible to determine MineType from media-type, using text/html then");
                 mimeType = "text/html";
             }
 
             response.setContentType(mimeType);
 
-            Source xmlSource = getTraxSourceForStack(invocation.getAction());
+            Source xmlSource = getDOMSourceForStack(invocation.getAction());
 
             // Transform the source XML to System.out.
             PrintWriter out = response.getWriter();
-            try {
-                transformer.transform(xmlSource, new StreamResult(out));
-            } finally {
-                out.close(); // ...and flush...
-            }
+
+            log.debug("xmlSource = " + xmlSource);
+            transformer.transform(xmlSource, new StreamResult(out));
+
+            out.close(); // ...and flush...
 
             if (log.isDebugEnabled()) {
-                log.debug("Time: " + (System.currentTimeMillis() - startTime) + "ms");
+                log.debug("Time:" + (System.currentTimeMillis() - startTime) + "ms");
             }
 
             writer.flush();
         } catch (Exception e) {
-            log.error("Unable to render XSLT Template with location=[" + location + "]", e);
+            log.error("Unable to render XSLT Template, '" + location + "'", e);
             throw e;
         }
     }
 
-    private Templates getTemplates(String path) throws TransformerException, IOException {
+    protected AdapterFactory getAdapterFactory() {
+        if (adapterFactory == null)
+            adapterFactory = new AdapterFactory();
+        return adapterFactory;
+    }
+
+    protected void setAdapterFactory(AdapterFactory adapterFactory) {
+        this.adapterFactory = adapterFactory;
+    }
+
+    /**
+     * 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.
+     */
+    protected URIResolver getURIResolver() {
+        return new ServletURIResolver(
+                ServletActionContext.getServletContext());
+    }
+
+    protected Templates getTemplates(String path) throws TransformerException, IOException {
         String pathFromRequest = ServletActionContext.getRequest().getParameter("xslt.location");
 
-        if (pathFromRequest != null) {
+        if (pathFromRequest != null)
             path = pathFromRequest;
-        }
 
-        if (path == null) {
+        if (path == null)
             throw new TransformerException("Stylesheet path is null");
-        }
 
-        Templates templates = (Templates) templatesCache.get(path);
+        Templates templates = templatesCache.get(path);
 
         if (noCache || (templates == null)) {
-            synchronized (LOCK) {
+            synchronized (templatesCache) {
                 URL resource = ServletActionContext.getServletContext().getResource(path);
 
                 if (resource == null) {
                     throw new TransformerException("Stylesheet " + path + " not found in resources.");
                 }
 
-                if (log.isDebugEnabled()) {
-                    // This may result in the template being put into the cache multiple times
-                    // if concurrent requests are made, but that's ok.
-                    log.debug("Preparing new XSLT stylesheet: " + path);
-                }
+                log.debug("Preparing XSLT stylesheet templates: " + path);
 
                 TransformerFactory factory = TransformerFactory.newInstance();
-                log.trace("Uri-Resolver is: " + factory.getURIResolver());
-                factory.setURIResolver(new ServletURIResolver(ServletActionContext.getServletContext()));
-                log.trace("Uri-Resolver is: " + factory.getURIResolver());
                 templates = factory.newTemplates(new StreamSource(resource.openStream()));
                 templatesCache.put(path, templates);
             }
@@ -314,9 +327,8 @@
         return templates;
     }
 
-    protected Source getTraxSourceForStack(Object action) throws IllegalAccessException, InstantiationException {
-        DOMAdapter adapter = new DOMAdapter();
-        adapter.setPattern(matchingPattern, excludingPattern);
-        return new DOMSource(adapter.adapt(action));
-    }
+    protected Source getDOMSourceForStack(Object action)
+            throws IllegalAccessException, InstantiationException {
+        return new DOMSource(getAdapterFactory().adaptDocument("result", action) );
+	}
 }

Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/package.html
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/package.html?rev=423995&r1=423994&r2=423995&view=diff
==============================================================================
--- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/package.html (original)
+++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/xslt/package.html Thu Jul 20 10:23:12 2006
@@ -1 +1,24 @@
-<body>Classes for views using XSLT.</body>
+<body>
+<p>
+The new xslt view supports an extensible Java XML adapter framework that makes
+it easy to customize the XML rendering of objects and to incorporate structured
+XML text and arbitarary DOM fragments into the output.
+</p>
+<p>
+The XSLTResult class now uses an extensible adapter factory for rendering the
+Struts action Java object tree to an XML DOM for consumption by the
+stylesheet.  Users can easily register their own adapters to produce custom XML
+views of Java types or simply extend a default "String" adapter and return
+plain or XML text to be incorporated into the DOM.  The new adapter mechanism
+is capable of proxying existing DOM trees and incorporating them into the
+results, so you can freely mix DOMs produced from other sources into your
+result tree.
+</p>
+<p>
+A default java.util.Map adapter is also now provided to render Maps to XML.
+</p>
+<p>
+Please see the javadoc on the AdapterFactory for more details.
+</p>
+
+</body>