Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 5E58E200C04 for ; Mon, 9 Jan 2017 10:08:08 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 5D176160B3E; Mon, 9 Jan 2017 09:08:08 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 8A74D160B3B for ; Mon, 9 Jan 2017 10:08:07 +0100 (CET) Received: (qmail 24826 invoked by uid 500); 9 Jan 2017 09:08:06 -0000 Mailing-List: contact commits-help@struts.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@struts.apache.org Delivered-To: mailing list commits@struts.apache.org Received: (qmail 24805 invoked by uid 99); 9 Jan 2017 09:08:06 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 Jan 2017 09:08:06 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 7C0CADF9FD; Mon, 9 Jan 2017 09:08:06 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: lukaszlenart@apache.org To: commits@struts.apache.org Date: Mon, 09 Jan 2017 09:08:06 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/3] struts git commit: WW-4731 Moves detailed description to wiki archived-at: Mon, 09 Jan 2017 09:08:08 -0000 Repository: struts Updated Branches: refs/heads/master 97419283e -> 2b12f06b0 WW-4731 Moves detailed description to wiki Project: http://git-wip-us.apache.org/repos/asf/struts/repo Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/14d56fbb Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/14d56fbb Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/14d56fbb Branch: refs/heads/master Commit: 14d56fbb93866646eb0152c0c56b64430c8a5704 Parents: 9741928 Author: Lukasz Lenart Authored: Sun Jan 8 20:29:58 2017 +0100 Committer: Lukasz Lenart Committed: Sun Jan 8 20:29:58 2017 +0100 ---------------------------------------------------------------------- .../apache/struts2/views/xslt/XSLTResult.java | 177 ++----------------- 1 file changed, 13 insertions(+), 164 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts/blob/14d56fbb/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java b/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java index fb5068c..c264a59 100644 --- a/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java +++ b/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java @@ -43,162 +43,8 @@ import java.net.URL; import java.util.HashMap; import java.util.Map; - /** - * - * - * XSLTResult uses XSLT to transform an action object to XML. The recent version - * has been specifically modified to deal with Xalan flaws. When using Xalan you - * may notice that even though you have a very minimal stylesheet like this one - *
- * <xsl:template match="/result">
- *   <result/>
- * </xsl:template>
- * - *

- * Xalan would still iterate through every property of your action and all - * its descendants. - *

- * - *

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

- * - *

- * That'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 was already walked through, it doesn't go 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 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 children 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 a 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>
- * 
- * - *

- * In the following example the XSLT result would use the action's user property - * instead of the action as it's base document and walk through it's properties. - * The exposedValue uses an ognl expression to derive it's value. - *

- * - *
- * <result name="success" type="xslt">
- *   <param name="location">foo.xslt</param>
- *   <param name="exposedValue">user$</param>
- * </result>
- * 
- * * - * This result type takes the following parameters: - * - * - * - *
    - * - *
  • location (default) - the location to go to after execution.
  • - *
  • encoding - character encoding used in XML, default UTF-8.
  • - * - *
  • parse - true by default. If set to false, the location param will - * not be parsed for Ognl expressions.
  • - * - * - * - *
- * - *

- * struts.properties related configuration: - *

- *
    - * - *
  • struts.xslt.nocache - Defaults to false. If set to true, disables - * stylesheet caching. Good for development, bad for production.
  • - * - *
- * - * - *

- * Example: - *

- * - *
- * 
- * <result name="success" type="xslt">foo.xslt</result>
- * 
- * 
- * + * XSLTResult uses XSLT to transform an action object to XML. */ public class XSLTResult implements Result { @@ -233,7 +79,7 @@ public class XSLTResult implements Result { /** Indicates the property name patterns which should be excluded from the xml. */ private String excludingPattern; - /** Indicates the ognl expression respresenting the bean which is to be exposed as xml. */ + /** Indicates the ognl expression representing the bean which is to be exposed as xml. */ private String exposedValue; /** Indicates the status to return in the response */ @@ -258,8 +104,6 @@ public class XSLTResult implements Result { } public void setStylesheetLocation(String location) { - if (location == null) - throw new IllegalArgumentException("Null location"); this.stylesheetLocation = location; } @@ -306,12 +150,15 @@ public class XSLTResult implements Result { long startTime = System.currentTimeMillis(); String location = getStylesheetLocation(); + if (location == null) { + throw new IllegalArgumentException("Parameter 'stylesheetLocation' cannot be null!"); + } + if (parse) { ValueStack stack = ActionContext.getContext().getValueStack(); location = TextParseUtil.translateVariables(location, stack); } - try { HttpServletResponse response = ServletActionContext.getResponse(); response.setStatus(status); @@ -331,10 +178,12 @@ public class XSLTResult implements Result { transformer.setErrorListener(buildErrorListener()); String mimeType; - if (templates == null) + if (templates == null) { mimeType = "text/xml"; // no stylesheet, raw xml - else + } else { mimeType = templates.getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE); + } + if (mimeType == null) { // guess (this is a servlet, so text/html might be the best guess) mimeType = "text/html"; @@ -383,8 +232,9 @@ public class XSLTResult implements Result { } protected AdapterFactory getAdapterFactory() { - if (adapterFactory == null) + if (adapterFactory == null) { adapterFactory = new AdapterFactory(); + } return adapterFactory; } @@ -428,8 +278,7 @@ public class XSLTResult implements Result { return templates; } - protected Source getDOMSourceForStack(Object value) - throws IllegalAccessException, InstantiationException { + protected Source getDOMSourceForStack(Object value) throws IllegalAccessException, InstantiationException { return new DOMSource(getAdapterFactory().adaptDocument("result", value) ); } }