You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2022/12/04 17:24:36 UTC

[struts] branch WW-5264-xslt updated (ebd0d4827 -> 9b11842bf)

This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a change to branch WW-5264-xslt
in repository https://gitbox.apache.org/repos/asf/struts.git


 discard ebd0d4827 WW-5264 Moves XSLT result into a dedicated plugin
     new 9b11842bf WW-5264 Moves XSLT result into a dedicated plugin

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (ebd0d4827)
            \
             N -- N -- N   refs/heads/WW-5264-xslt (9b11842bf)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../result/xslt/AbstractAdapterElement.java        |  5 +-
 .../struts2/result/xslt/AbstractAdapterNode.java   | 72 ++++++++++------------
 .../apache/struts2/result/xslt/AdapterFactory.java |  1 -
 .../apache/struts2/result/xslt/ArrayAdapter.java   |  1 +
 .../apache/struts2/result/xslt/BeanAdapter.java    | 10 ++-
 .../struts2/result/xslt/CollectionAdapter.java     |  1 +
 .../org/apache/struts2/result/xslt/MapAdapter.java |  1 +
 .../struts2/result/xslt/ProxyAttrAdapter.java      |  1 +
 .../struts2/result/xslt/ProxyElementAdapter.java   |  4 ++
 .../struts2/result/xslt/ProxyNodeAdapter.java      | 23 ++++---
 .../struts2/result/xslt/ProxyTextNodeAdapter.java  |  1 +
 .../struts2/result/xslt/ServletURIResolver.java    |  1 -
 .../struts2/result/xslt/SimpleAdapterDocument.java | 11 ++++
 .../apache/struts2/result/xslt/SimpleNodeList.java |  4 +-
 .../apache/struts2/result/xslt/SimpleTextNode.java |  3 +
 .../apache/struts2/result/xslt/StringAdapter.java  |  1 +
 16 files changed, 81 insertions(+), 59 deletions(-)


[struts] 01/01: WW-5264 Moves XSLT result into a dedicated plugin

Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5264-xslt
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 9b11842bf2e2a12b6194a54642641a23714bcac1
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Sun Dec 4 12:49:44 2022 +0100

    WW-5264 Moves XSLT result into a dedicated plugin
---
 apps/showcase/pom.xml                              |   5 +
 bom/pom.xml                                        |   5 +
 .../java/org/apache/struts2/StrutsConstants.java   |   3 -
 .../struts2/config/entities/ConstantConfig.java    |   1 -
 core/src/main/resources/struts-default.xml         |   2 +-
 plugins/pom.xml                                    |   1 +
 plugins/xslt/README.md                             |   3 +
 plugins/{ => xslt}/pom.xml                         |  62 +++--------
 .../result}/xslt/AbstractAdapterElement.java       |  31 +++---
 .../struts2/result}/xslt/AbstractAdapterNode.java  | 117 +++++++++----------
 .../struts2/result}/xslt/AdapterFactory.java       |  26 ++---
 .../apache/struts2/result}/xslt/AdapterNode.java   |   2 +-
 .../apache/struts2/result}/xslt/ArrayAdapter.java  |   7 +-
 .../apache/struts2/result}/xslt/BeanAdapter.java   |  57 +++++-----
 .../struts2/result}/xslt/CollectionAdapter.java    |  13 ++-
 .../apache/struts2/result}/xslt/MapAdapter.java    |  26 ++---
 .../struts2/result}/xslt/ProxyAttrAdapter.java     |  13 +--
 .../struts2/result}/xslt/ProxyElementAdapter.java  |  21 ++--
 .../struts2/result}/xslt/ProxyNamedNodeMap.java    |  10 +-
 .../struts2/result}/xslt/ProxyNodeAdapter.java     |  58 +++++-----
 .../struts2/result}/xslt/ProxyTextNodeAdapter.java |   3 +-
 .../struts2/result}/xslt/ServletURIResolver.java   |  26 ++---
 .../result}/xslt/SimpleAdapterDocument.java        |  40 ++++---
 .../struts2/result}/xslt/SimpleNodeList.java       |  16 +--
 .../struts2/result}/xslt/SimpleTextNode.java       |   5 +-
 .../apache/struts2/result}/xslt/StringAdapter.java |  10 +-
 .../apache/struts2/result}/xslt/XSLTResult.java    |   6 +-
 .../apache/struts2/result/xslt/XsltConstants.java  |  22 ++--
 .../org/apache/struts2/result}/xslt/package.html   |   0
 .../xslt/src/main/resources/struts-plugin.xml      |  21 ++--
 .../struts2/result}/xslt/XSLTResultTest.java       | 124 ++++++++++-----------
 .../src/test/resources/XSLTResultTest-val.xml      |   0
 .../resources/XSLTResultTest.bad.character.xsl     |   0
 .../xslt}/src/test/resources/XSLTResultTest.xsl    |   0
 .../xslt}/src/test/resources/XSLTResultTest2.xsl   |   0
 .../xslt}/src/test/resources/XSLTResultTest3.xsl   |   0
 .../test/resources/XSLTResultTest4.badinclude.xsl  |   0
 .../xslt}/src/test/resources/XSLTResultTest4.xsl   |   0
 .../xslt}/src/test/resources/XSLTResultTest5.xsl   |   0
 .../xslt}/src/test/resources/XSLTResultTest6.xsl   |   0
 pom.xml                                            |  45 +++++---
 41 files changed, 389 insertions(+), 392 deletions(-)

diff --git a/apps/showcase/pom.xml b/apps/showcase/pom.xml
index add8be9a5..cc6d51d5e 100644
--- a/apps/showcase/pom.xml
+++ b/apps/showcase/pom.xml
@@ -99,6 +99,11 @@
             <artifactId>struts2-velocity-plugin</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.struts</groupId>
+            <artifactId>struts2-xslt-plugin</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
diff --git a/bom/pom.xml b/bom/pom.xml
index f1db01489..289e83b02 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -181,6 +181,11 @@
                 <artifactId>struts2-velocity-plugin</artifactId>
                 <version>${struts-version.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.struts</groupId>
+                <artifactId>struts2-xslt-plugin</artifactId>
+                <version>${struts-version.version}</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java
index c75ff3d54..9a1920f02 100644
--- a/core/src/main/java/org/apache/struts2/StrutsConstants.java
+++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java
@@ -177,9 +177,6 @@ public final class StrutsConstants {
     @Deprecated
     public static final String STRUTS_OBJECTFACTORY_SPRING_ENABLE_AOP_SUPPORT = "struts.objectFactory.spring.enableAopSupport";
 
-    /** Whether or not XSLT templates should not be cached */
-    public static final String STRUTS_XSLT_NOCACHE = "struts.xslt.nocache";
-
     /** Location of additional configuration properties files to load */
     public static final String STRUTS_CUSTOM_PROPERTIES = "struts.custom.properties";
 
diff --git a/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java b/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
index 63c30ce2f..0fe1e300c 100644
--- a/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
+++ b/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
@@ -204,7 +204,6 @@ public class ConstantConfig {
         map.put(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE_ALWAYS_RESPECT, Objects.toString(objectFactorySpringAutoWireAlwaysRespect, null));
         map.put(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_USE_CLASS_CACHE, Objects.toString(objectFactorySpringUseClassCache, null));
         map.put(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_ENABLE_AOP_SUPPORT, Objects.toString(objectFactorySpringEnableAopSupport, null));
-        map.put(StrutsConstants.STRUTS_XSLT_NOCACHE, Objects.toString(xsltNocache, null));
         map.put(StrutsConstants.STRUTS_CUSTOM_PROPERTIES, StringUtils.join(customProperties, ','));
         map.put(StrutsConstants.STRUTS_CUSTOM_I18N_RESOURCES, StringUtils.join(customI18nResources, ','));
         map.put(StrutsConstants.STRUTS_MAPPER_CLASS, beanConfToString(mapperClass));
diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml
index 0bb197b56..7b81e9013 100644
--- a/core/src/main/resources/struts-default.xml
+++ b/core/src/main/resources/struts-default.xml
@@ -331,7 +331,7 @@
             <result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/>
             <result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/>
             <result-type name="stream" class="org.apache.struts2.result.StreamResult"/>
-            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
+            <result-type name="xslt" class="org.apache.struts2.result.xslt.XSLTResult"/>
             <result-type name="plainText" class="org.apache.struts2.result.PlainTextResult"/>
             <result-type name="postback" class="org.apache.struts2.result.PostbackResult"/>
         </result-types>
diff --git a/plugins/pom.xml b/plugins/pom.xml
index e22f4040f..5c6749590 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -58,6 +58,7 @@
         <module>testng</module>
         <module>tiles</module>
         <module>velocity</module>
+        <module>xslt</module>
     </modules>
 
     <dependencies>
diff --git a/plugins/xslt/README.md b/plugins/xslt/README.md
new file mode 100644
index 000000000..f0130e163
--- /dev/null
+++ b/plugins/xslt/README.md
@@ -0,0 +1,3 @@
+# Struts 2 XSLT plugin
+
+The XSLT plugin provides XSLT result.
diff --git a/plugins/pom.xml b/plugins/xslt/pom.xml
similarity index 52%
copy from plugins/pom.xml
copy to plugins/xslt/pom.xml
index e22f4040f..2b3d3bbb6 100644
--- a/plugins/pom.xml
+++ b/plugins/xslt/pom.xml
@@ -23,66 +23,38 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.struts</groupId>
-        <artifactId>struts2-parent</artifactId>
+        <artifactId>struts2-plugins</artifactId>
         <version>6.2.0-SNAPSHOT</version>
     </parent>
 
-    <artifactId>struts2-plugins</artifactId>
-    <packaging>pom</packaging>
-    <name>Struts 2 Plugins</name>
-
-    <modules>
-        <module>async</module>
-        <module>bean-validation</module>
-        <module>cdi</module>
-        <module>config-browser</module>
-        <module>convention</module>
-        <module>dwr</module>
-        <module>embeddedjsp</module>
-        <module>gxp</module>
-        <module>jasperreports</module>
-        <module>javatemplates</module>
-        <module>jfreechart</module>
-        <module>json</module>
-        <module>junit</module>
-        <module>osgi</module>
-        <module>oval</module>
-        <module>pell-multipart</module>
-        <module>plexus</module>
-        <module>portlet</module>
-        <module>portlet-mocks</module>
-        <module>portlet-tiles</module>
-        <module>rest</module>
-        <module>sitemesh</module>
-        <module>spring</module>
-        <module>testng</module>
-        <module>tiles</module>
-        <module>velocity</module>
-    </modules>
+    <artifactId>struts2-xslt-plugin</artifactId>
+    <packaging>jar</packaging>
+    <name>Struts 2 XSLT Plugin</name>
 
     <dependencies>
-
         <dependency>
             <groupId>org.apache.struts</groupId>
-            <artifactId>struts2-core</artifactId>
+            <artifactId>struts2-junit-plugin</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet.jsp</groupId>
+            <artifactId>jsp-api</artifactId>
+            <scope>provided</scope>
         </dependency>
-
-        <!-- Test dependencies -->
         <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
             <scope>test</scope>
         </dependency>
-
         <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
-            <scope>provided</scope>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>test</scope>
         </dependency>
-
     </dependencies>
 
     <properties>
-    	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
+
 </project>
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AbstractAdapterElement.java
similarity index 86%
rename from core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AbstractAdapterElement.java
index e2f136271..11783dffe 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AbstractAdapterElement.java
@@ -16,10 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
-
-import java.util.HashMap;
-import java.util.Map;
+package org.apache.struts2.result.xslt;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.DOMException;
@@ -27,28 +24,33 @@ import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.TypeInfo;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * AbstractAdapterElement extends the abstract Node type and implements
  * the DOM Element interface.
  */
 public abstract class AbstractAdapterElement extends AbstractAdapterNode implements Element {
 
-    private Map attributeAdapters;
+    private Map<String, Object> attributeAdapters;
 
-    public AbstractAdapterElement() { }
+    protected AbstractAdapterElement() {
+    }
 
     public void setAttribute(String string, String string1) throws DOMException {
         throw operationNotSupported();
     }
 
-    protected Map getAttributeAdapters() {
-        if ( attributeAdapters == null )
+    protected Map<String, Object> getAttributeAdapters() {
+        if (attributeAdapters == null) {
             attributeAdapters = buildAttributeAdapters();
+        }
         return attributeAdapters;
     }
 
-    protected Map buildAttributeAdapters() {
-        return new HashMap();
+    protected Map<String, Object> buildAttributeAdapters() {
+        return new HashMap<>();
     }
 
     /**
@@ -63,15 +65,15 @@ public abstract class AbstractAdapterElement extends AbstractAdapterNode impleme
     }
 
     public String getAttributeNS(String string, String string1) {
-        return null;
+        throw operationNotSupported();
     }
 
     public Attr setAttributeNode(Attr attr) throws DOMException {
         throw operationNotSupported();
     }
 
-    public Attr getAttributeNode( String name ) {
-        return (Attr)getAttributes().getNamedItem( name );
+    public Attr getAttributeNode(String name) {
+        return (Attr) getAttributes().getNamedItem(name);
     }
 
     public Attr setAttributeNodeNS(Attr attr) throws DOMException {
@@ -82,10 +84,12 @@ public abstract class AbstractAdapterElement extends AbstractAdapterNode impleme
         throw operationNotSupported();
     }
 
+    @Override
     public String getNodeName() {
         return getTagName();
     }
 
+    @Override
     public short getNodeType() {
         return Node.ELEMENT_NODE;
     }
@@ -102,6 +106,7 @@ public abstract class AbstractAdapterElement extends AbstractAdapterNode impleme
         return false;
     }
 
+    @Override
     public boolean hasChildNodes() {
         return getElementsByTagName("*").getLength() > 0;
     }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AbstractAdapterNode.java
similarity index 76%
rename from core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AbstractAdapterNode.java
index a9713fa92..1a7262542 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AbstractAdapterNode.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -29,7 +29,7 @@ import java.util.List;
 
 /**
  * AbstractAdapterNode is the base for childAdapters that expose a read-only view
- * of a Java object as a DOM Node.  This class implements the core parent-child
+ * of a Java object as a DOM Node. This class implements the core parent-child
  * and sibling node traversal functionality shared by all adapter type nodes
  * and used in proxy node support.
  *
@@ -37,43 +37,44 @@ import java.util.List;
  */
 public abstract class AbstractAdapterNode implements AdapterNode {
 
-    private static final NamedNodeMap EMPTY_NAMEDNODEMAP =
-            new NamedNodeMap() {
-                public int getLength() {
-                    return 0;
-                }
+    private static final Logger LOG = LogManager.getLogger(AbstractAdapterNode.class);
 
-                public Node item(int index) {
-                    return null;
-                }
+    private static final NamedNodeMap EMPTY_NAMED_NODE_MAP =
+        new NamedNodeMap() {
+            public int getLength() {
+                return 0;
+            }
 
-                public Node getNamedItem(String name) {
-                    return null;
-                }
+            public Node item(int index) {
+                return null;
+            }
 
-                public Node removeNamedItem(String name) throws DOMException {
-                    return null;
-                }
+            public Node getNamedItem(String name) {
+                return null;
+            }
 
-                public Node setNamedItem(Node arg) throws DOMException {
-                    return null;
-                }
+            public Node removeNamedItem(String name) throws DOMException {
+                return null;
+            }
 
-                public Node setNamedItemNS(Node arg) throws DOMException {
-                    return null;
-                }
+            public Node setNamedItem(Node arg) throws DOMException {
+                return null;
+            }
 
-                public Node getNamedItemNS(String namespaceURI, String localName) {
-                    return null;
-                }
+            public Node setNamedItemNS(Node arg) throws DOMException {
+                return null;
+            }
 
-                public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
-                    return null;
-                }
-            };
+            public Node getNamedItemNS(String namespaceURI, String localName) {
+                return null;
+            }
+
+            public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
+                return null;
+            }
+        };
 
     private List<Node> childAdapters;
-    private Logger log = LogManager.getLogger(this.getClass());
 
     // The domain object that we are adapting
     private Object propertyValue;
@@ -81,19 +82,15 @@ public abstract class AbstractAdapterNode implements AdapterNode {
     private AdapterNode parent;
     private AdapterFactory adapterFactory;
 
-
-    public AbstractAdapterNode() {
-        if (LogManager.getLogger(getClass()).isDebugEnabled()) {
-            LogManager.getLogger(getClass()).debug("Creating " + this);
-        }
+    protected AbstractAdapterNode() {
+        LOG.debug("Creating: {}", this);
     }
 
     /**
-     *
      * @param adapterFactory the adapter factory
-     * @param parent the parent adapter node
-     * @param propertyName the property name
-     * @param value value
+     * @param parent         the parent adapter node
+     * @param propertyName   the property name
+     * @param value          value
      */
     protected void setContext(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
         setAdapterFactory(adapterFactory);
@@ -108,11 +105,11 @@ public abstract class AbstractAdapterNode implements AdapterNode {
      * @return List of child adapters.
      */
     protected List<Node> buildChildAdapters() {
-        return new ArrayList<Node>();
+        return new ArrayList<>();
     }
 
     /**
-     * Lazily initialize child childAdapters
+     * Lazily initialize child adapters
      *
      * @return node list
      */
@@ -124,27 +121,26 @@ public abstract class AbstractAdapterNode implements AdapterNode {
     }
 
     public Node getChildBeforeOrAfter(Node child, boolean before) {
-        log.debug("getChildBeforeOrAfter: ");
-        List adapters = getChildAdapters();
-        if (log.isDebugEnabled()) {
-            log.debug("childAdapters = {}", adapters);
-            log.debug("child = {}", child);
+        LOG.debug("getChildBeforeOrAfter: ");
+        List<Node> adapters = getChildAdapters();
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("childAdapters = {}", adapters);
+            LOG.debug("child = {}", child);
         }
         int index = adapters.indexOf(child);
         if (index < 0)
             throw new StrutsException(child + " is no child of " + this);
         int siblingIndex = before ? index - 1 : index + 1;
-        return ((0 < siblingIndex) && (siblingIndex < adapters.size())) ?
-                ((Node) adapters.get(siblingIndex)) : null;
+        return ((0 < siblingIndex) && (siblingIndex < adapters.size())) ? adapters.get(siblingIndex) : null;
     }
 
     public Node getChildAfter(Node child) {
-        log.trace("getChildAfter");
+        LOG.trace("getChildAfter");
         return getChildBeforeOrAfter(child, false/*after*/);
     }
 
     public Node getChildBefore(Node child) {
-        log.trace("getChildBefore");
+        LOG.trace("getChildBefore");
         return getChildBeforeOrAfter(child, true/*after*/);
     }
 
@@ -165,19 +161,16 @@ public abstract class AbstractAdapterNode implements AdapterNode {
     }
 
     public NodeList getElementsByTagNameNS(String string, String string1) {
-        // TODO:
-        return null;
+        throw operationNotSupported();
     }
 
-    // Begin Node methods
-
     public NamedNodeMap getAttributes() {
-        return EMPTY_NAMEDNODEMAP;
+        return EMPTY_NAMED_NODE_MAP;
     }
 
     public NodeList getChildNodes() {
         NodeList nl = new SimpleNodeList(getChildAdapters());
-        log.debug("getChildNodes for tag: {} num children: {}", getNodeName(), nl.getLength());
+        LOG.debug("getChildNodes for tag: {} num children: {}", getNodeName(), nl.getLength());
         return nl;
     }
 
@@ -211,7 +204,7 @@ public abstract class AbstractAdapterNode implements AdapterNode {
     }
 
     public Node getParentNode() {
-        log.trace("getParentNode");
+        LOG.trace("getParentNode");
         return getParent();
     }
 
@@ -241,9 +234,9 @@ public abstract class AbstractAdapterNode implements AdapterNode {
 
     public Node getNextSibling() {
         Node next = getParent().getChildAfter(this);
-        if (log.isTraceEnabled()) {
-            log.trace("getNextSibling on " + getNodeName() + ": "
-                    + ((next == null) ? "null" : next.getNodeName()));
+
+        if (next != null) {
+            LOG.trace("getNextSibling on {}: {} ", getNodeName(), next.getNodeName());
         }
 
         return next;
@@ -278,7 +271,7 @@ public abstract class AbstractAdapterNode implements AdapterNode {
     }
 
     public Node cloneNode(boolean b) {
-        log.trace("cloneNode");
+        LOG.trace("cloneNode");
         throw operationNotSupported();
     }
 
@@ -295,7 +288,7 @@ public abstract class AbstractAdapterNode implements AdapterNode {
     }
 
     public void normalize() {
-        log.trace("normalize");
+        LOG.trace("normalize");
         throw operationNotSupported();
     }
 
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AdapterFactory.java
similarity index 91%
rename from core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AdapterFactory.java
index c08d3925c..00d01bbea 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AdapterFactory.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.struts2.StrutsException;
 import org.w3c.dom.*;
@@ -100,7 +100,7 @@ import java.util.Map;
  */
 public class AdapterFactory {
 
-    private Map<Class, Class> adapterTypes = new HashMap<>();
+    private final Map<Class<?>, Class<?>> adapterTypes = new HashMap<>();
 
     /**
      * Register an adapter type for a Java class type.
@@ -108,7 +108,7 @@ public class AdapterFactory {
      * @param type        the Java class type which is to be handled by the adapter.
      * @param adapterType The adapter class, which implements AdapterNode.
      */
-    public void registerAdapterType(Class type, Class adapterType) {
+    public void registerAdapterType(Class<?> type, Class<?> adapterType) {
         adapterTypes.put(type, adapterType);
     }
 
@@ -121,16 +121,11 @@ public class AdapterFactory {
      * @param propertyValue the property value
      *
      * @return the document object
-     *
-     * @throws IllegalAccessException in case of illegal access
-     * @throws InstantiationException in case of instantiation errors
      */
-    public Document adaptDocument(String propertyName, Object propertyValue)
-            throws IllegalAccessException, InstantiationException {
+    public Document adaptDocument(String propertyName, Object propertyValue) {
         return new SimpleAdapterDocument(this, null, propertyName, propertyValue);
     }
 
-
     /**
      * Create an Node adapter for a child element.
      * Note that the parent of the created node must be an AdapterNode, however
@@ -145,7 +140,7 @@ public class AdapterFactory {
      * @return a node
      */
     public Node adaptNode(AdapterNode parent, String propertyName, Object value) {
-        Class adapterClass = getAdapterForValue(value);
+        Class<?> adapterClass = getAdapterForValue(value);
         if (adapterClass != null) {
             return constructAdapterInstance(adapterClass, parent, propertyName, value);
         }
@@ -161,7 +156,7 @@ public class AdapterFactory {
         }
 
         // Check other supported types or default to generic JavaBean introspecting adapter
-        Class valueType = value.getClass();
+        Class<?> valueType = value.getClass();
 
         if (valueType.isArray()) {
             adapterClass = ArrayAdapter.class;
@@ -188,7 +183,6 @@ public class AdapterFactory {
      * </p>
      *
      * <p>
-     * // TODO:
      * NameSpaces are not yet supported.
      * </p>
      *
@@ -238,10 +232,10 @@ public class AdapterFactory {
      *
      * @return the new node
      */
-    private Node constructAdapterInstance(Class adapterClass, AdapterNode parent, String propertyName, Object propertyValue) {
+    private Node constructAdapterInstance(Class<?> adapterClass, AdapterNode parent, String propertyName, Object propertyValue) {
         // Check to see if the class has a no-args constructor
         try {
-            adapterClass.getConstructor(new Class []{});
+            adapterClass.getConstructor();
         } catch (NoSuchMethodException e1) {
             throw new StrutsException("Adapter class: " + adapterClass + " does not have a no-args constructor.");
         }
@@ -272,8 +266,8 @@ public class AdapterFactory {
         return new StringAdapter(this, parent, propertyName, "null");
     }
 
-    //TODO: implement Configuration option to provide additional adapter classes
-    public Class getAdapterForValue(Object value) {
+    public Class<?> getAdapterForValue(Object value) {
         return adapterTypes.get(value.getClass());
     }
+
 }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AdapterNode.java
similarity index 98%
rename from core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AdapterNode.java
index 81b0cd76f..13243e848 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/AdapterNode.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.w3c.dom.Node;
 
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ArrayAdapter.java
similarity index 89%
rename from core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ArrayAdapter.java
index bd000189a..b6eb7242e 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ArrayAdapter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -27,7 +27,7 @@ import java.util.List;
 
 public class ArrayAdapter extends AbstractAdapterElement {
 
-    private Logger log = LogManager.getLogger(this.getClass());
+    private static final Logger LOG = LogManager.getLogger(ArrayAdapter.class);
 
     public ArrayAdapter() {
     }
@@ -36,6 +36,7 @@ public class ArrayAdapter extends AbstractAdapterElement {
         setContext(adapterFactory, parent, propertyName, value);
     }
 
+    @Override
     protected List<Node> buildChildAdapters() {
         List<Node> children = new ArrayList<>();
         Object[] values = (Object[]) getPropertyValue();
@@ -45,7 +46,7 @@ public class ArrayAdapter extends AbstractAdapterElement {
             if (childAdapter != null)
                 children.add(childAdapter);
 
-            log.debug("{} adding adapter: {}", this, childAdapter);
+            LOG.debug("{} adding adapter: {}", this, childAdapter);
         }
 
         return children;
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/BeanAdapter.java
similarity index 77%
rename from core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/BeanAdapter.java
index c62582312..ce5b9abf9 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/BeanAdapter.java
@@ -16,10 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.message.ParameterizedMessage;
 import org.apache.struts2.StrutsException;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -46,53 +47,48 @@ import java.util.Map;
  *      public String getLastName();
  * }
  * </pre>
- *
+ * <p>
  * would be rendered as: &lt;myPerson&gt; &lt;firstName&gt;...&lt;/firstName&gt; &lt;lastName&gt;...&lt;/lastName&gt; &lt;/myPerson&gt;
  */
 public class BeanAdapter extends AbstractAdapterElement {
-    //Static fields/initializer
 
-    private static final Object[] NULLPARAMS = new Object[0];
+    private static final Logger LOG = LogManager.getLogger(BeanAdapter.class);
+
+    private static final Object[] NULL_PARAMS = new Object[0];
 
     /**
      * Cache can savely be static because the cached information is the same for all instances of this class.
      */
-    private static Map<Class, PropertyDescriptor[]> propertyDescriptorCache;
-
-    //Instance fields
-
-    private Logger log = LogManager.getLogger(this.getClass());
-
-    //Constructors
+    private static Map<Class<?>, PropertyDescriptor[]> propertyDescriptorCache;
 
     public BeanAdapter() {
     }
 
-    public BeanAdapter(
-            AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
+    public BeanAdapter(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
         setContext(adapterFactory, parent, propertyName, value);
     }
 
-    //Methods
-
+    @Override
     public String getTagName() {
         return getPropertyName();
     }
 
+    @Override
     public NodeList getChildNodes() {
         NodeList nl = super.getChildNodes();
         // Log child nodes for debug:
-        if (log.isDebugEnabled() && nl != null) {
-            log.debug("BeanAdapter getChildNodes for: {}", getTagName());
-            log.debug(nl.toString());
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("BeanAdapter getChildNodes for: {}", getTagName());
+            LOG.debug(nl.toString());
         }
         return nl;
     }
 
+    @Override
     protected List<Node> buildChildAdapters() {
-        log.debug("BeanAdapter building children. Property name: {}", getPropertyName());
+        LOG.debug("BeanAdapter building children. Property name: {}", getPropertyName());
         List<Node> newAdapters = new ArrayList<>();
-        Class type = getPropertyValue().getClass();
+        Class<?> type = getPropertyValue().getClass();
         PropertyDescriptor[] props = getPropertyDescriptors(getPropertyValue());
 
         if (props.length > 0) {
@@ -100,10 +96,9 @@ public class BeanAdapter extends AbstractAdapterElement {
                 Method m = prop.getReadMethod();
 
                 if (m == null) {
-                    //FIXME: write only property or indexed access
                     continue;
                 }
-                log.debug("Bean reading property method: {}", m.getName());
+                LOG.debug("Bean reading property method: {}", m.getName());
 
                 String propertyName = prop.getName();
                 Object propertyValue;
@@ -114,12 +109,13 @@ public class BeanAdapter extends AbstractAdapterElement {
                     Perhaps with annotations in Java5?
                 */
                 try {
-                    propertyValue = m.invoke(getPropertyValue(), NULLPARAMS);
+                    propertyValue = m.invoke(getPropertyValue(), NULL_PARAMS);
                 } catch (Exception e) {
+                    Exception report = e;
                     if (e instanceof InvocationTargetException) {
-                        e = (Exception) ((InvocationTargetException) e).getTargetException();
+                        report = (Exception) ((InvocationTargetException) e).getTargetException();
                     }
-                    log.error("Cannot access bean property: {}", propertyName, e);
+                    LOG.error(new ParameterizedMessage("Cannot access bean property: {}", propertyName), report);
                     continue;
                 }
 
@@ -131,14 +127,15 @@ public class BeanAdapter extends AbstractAdapterElement {
                     childAdapter = getAdapterFactory().adaptNode(this, propertyName, propertyValue);
                 }
 
-                if (childAdapter != null)
+                if (childAdapter != null) {
                     newAdapters.add(childAdapter);
+                }
 
-                log.debug("{} adding adapter: {}", this, childAdapter);
+                LOG.debug("{} adding adapter: {}", this, childAdapter);
             }
         } else {
             // No properties found
-            log.info("Class {} has no readable properties, trying to adapt {} with StringAdapter...", type.getName(), getPropertyName());
+            LOG.info("Class {} has no readable properties, trying to adapt {} with StringAdapter...", type.getName(), getPropertyName());
         }
 
         return newAdapters;
@@ -150,13 +147,13 @@ public class BeanAdapter extends AbstractAdapterElement {
     private synchronized PropertyDescriptor[] getPropertyDescriptors(Object bean) {
         try {
             if (propertyDescriptorCache == null) {
-                propertyDescriptorCache = new HashMap<Class, PropertyDescriptor[]>();
+                propertyDescriptorCache = new HashMap<>();
             }
 
             PropertyDescriptor[] props = propertyDescriptorCache.get(bean.getClass());
 
             if (props == null) {
-                log.debug("Caching property descriptor for {}", bean.getClass().getName());
+                LOG.debug("Caching property descriptor for {}", bean.getClass().getName());
                 props = Introspector.getBeanInfo(bean.getClass(), Object.class).getPropertyDescriptors();
                 propertyDescriptorCache.put(bean.getClass(), props);
             }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/CollectionAdapter.java
similarity index 84%
rename from core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/CollectionAdapter.java
index b53118f71..3fff01140 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/CollectionAdapter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -28,7 +28,7 @@ import java.util.List;
 
 public class CollectionAdapter extends AbstractAdapterElement {
 
-    private Logger log = LogManager.getLogger(this.getClass());
+    private static final Logger LOG = LogManager.getLogger(CollectionAdapter.class);
 
     public CollectionAdapter() { }
 
@@ -36,8 +36,9 @@ public class CollectionAdapter extends AbstractAdapterElement {
         setContext(rootAdapterFactory, parent, propertyName, value);
     }
 
+    @Override
     protected List<Node> buildChildAdapters() {
-        Collection values = (Collection) getPropertyValue();
+        Collection<?> values = (Collection<?>) getPropertyValue();
         List<Node> children = new ArrayList<>(values.size());
 
         for (Object value : values) {
@@ -47,10 +48,12 @@ public class CollectionAdapter extends AbstractAdapterElement {
             } else {
                 childAdapter = getAdapterFactory().adaptNode(this, "item", value);
             }
-            if (childAdapter != null)
+
+            if (childAdapter != null) {
                 children.add(childAdapter);
+            }
 
-            log.debug("{} adding adapter: {}", this, childAdapter);
+            LOG.debug("{} adding adapter: {}", this, childAdapter);
         }
 
         return children;
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/MapAdapter.java
similarity index 73%
rename from core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/MapAdapter.java
index 9595f6568..4536be73f 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/MapAdapter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.w3c.dom.Node;
 
@@ -39,21 +39,22 @@ import java.util.Map;
  */
 public class MapAdapter extends AbstractAdapterElement {
 
-    public MapAdapter() { }
+    public MapAdapter() {
+    }
 
-    public MapAdapter(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Map value) {
-        setContext( adapterFactory, parent, propertyName, value );
+    public MapAdapter(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Map<?, ?> value) {
+        setContext(adapterFactory, parent, propertyName, value);
     }
 
-    public Map map() {
-        return (Map)getPropertyValue();
+    public Map<?, ?> map() {
+        return (Map<?, ?>) getPropertyValue();
     }
 
+    @Override
     protected List<Node> buildChildAdapters() {
         List<Node> children = new ArrayList<>(map().entrySet().size());
 
-        for (Object o : map().entrySet()) {
-            Map.Entry entry = (Map.Entry) o;
+        for (Map.Entry<?, ?> entry : map().entrySet()) {
             Object key = entry.getKey();
             Object value = entry.getValue();
             EntryElement child = new EntryElement(getAdapterFactory(), this, "entry", key, value);
@@ -66,17 +67,16 @@ public class MapAdapter extends AbstractAdapterElement {
     static class EntryElement extends AbstractAdapterElement {
         Object key, value;
 
-        public EntryElement(  AdapterFactory adapterFactory,
-                              AdapterNode parent, String propertyName, Object key, Object value ) {
-            setContext( adapterFactory, parent, propertyName, null/*we have two values*/ );
+        public EntryElement(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object key, Object value) {
+            setContext(adapterFactory, parent, propertyName, null/*we have two values*/);
             this.key = key;
             this.value = value;
         }
 
         protected List<Node> buildChildAdapters() {
             List<Node> children = new ArrayList<>();
-            children.add( getAdapterFactory().adaptNode( this, "key", key ) );
-            children.add( getAdapterFactory().adaptNode( this, "value", value ) );
+            children.add(getAdapterFactory().adaptNode(this, "key", key));
+            children.add(getAdapterFactory().adaptNode(this, "value", value));
             return children;
         }
     }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyAttrAdapter.java
similarity index 93%
rename from core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyAttrAdapter.java
index 53ecf049e..2bed551ab 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyAttrAdapter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.DOMException;
@@ -35,13 +35,10 @@ public class ProxyAttrAdapter extends ProxyNodeAdapter implements Attr {
         super(factory, parent, value);
     }
 
-    // convenience
     protected Attr attr() {
         return (Attr) getPropertyValue();
     }
 
-    // Proxied Attr methods
-
     public String getName() {
         return attr().getName();
     }
@@ -62,8 +59,6 @@ public class ProxyAttrAdapter extends ProxyNodeAdapter implements Attr {
         return (Element) getParent();
     }
 
-    // DOM level 3
-
     public TypeInfo getSchemaTypeInfo() {
         throw operationNotSupported();
     }
@@ -72,12 +67,10 @@ public class ProxyAttrAdapter extends ProxyNodeAdapter implements Attr {
         throw operationNotSupported();
     }
 
-    // end DOM level 3
-
-    // End Proxied Attr methods
-
+    @Override
     public String toString() {
         return "ProxyAttribute for: " + attr();
     }
+
 }
 
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyElementAdapter.java
similarity index 91%
rename from core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyElementAdapter.java
index 8fbc6d45e..fe8dced9a 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyElementAdapter.java
@@ -16,11 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.w3c.dom.*;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.TypeInfo;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -40,7 +45,7 @@ import java.util.List;
  */
 public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
 
-    private Logger log = LogManager.getLogger(this.getClass());
+    private static final Logger LOG = LogManager.getLogger(ProxyElementAdapter.class);
 
     public ProxyElementAdapter(AdapterFactory factory, AdapterNode parent, Element value) {
         super(factory, parent, value);
@@ -53,6 +58,7 @@ public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
         return (Element) getPropertyValue();
     }
 
+    @Override
     protected List<Node> buildChildAdapters() {
         List<Node> adapters = new ArrayList<>();
         NodeList children = node().getChildNodes();
@@ -60,7 +66,7 @@ public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
             Node child = children.item(i);
             Node adapter = wrap(child);
             if (adapter != null) {
-                log.debug("Wrapped child node: {}", child.getNodeName());
+                LOG.debug("Wrapped child node: {}", child.getNodeName());
                 adapters.add(adapter);
             }
         }
@@ -86,11 +92,11 @@ public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
     }
 
     public Attr getAttributeNode(String name) {
-        log.debug("Wrapping attribute: {}", name);
+        LOG.debug("Wrapping attribute: {}", name);
         return (Attr) wrap(element().getAttributeNode(name));
     }
 
-    // I'm overriding this just for clarity.  The base impl is correct.
+    @Override
     public NodeList getElementsByTagName(String name) {
         return super.getElementsByTagName(name);
     }
@@ -103,12 +109,12 @@ public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
         return (Attr) wrap(element().getAttributeNodeNS(namespaceURI, localName));
     }
 
+    @Override
     public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
         return super.getElementsByTagNameNS(namespaceURI, localName);
     }
 
     // Unsupported mutators of Element
-
     public void removeAttribute(String name) throws DOMException {
         throw new UnsupportedOperationException();
     }
@@ -159,6 +165,7 @@ public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
 
     // end DOM level 3 methods
 
+    @Override
     public String toString() {
         return "ProxyElement for: " + element();
     }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyNamedNodeMap.java
similarity index 93%
rename from core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyNamedNodeMap.java
index f0a218195..b707c0da8 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyNamedNodeMap.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.w3c.dom.DOMException;
 import org.w3c.dom.NamedNodeMap;
@@ -24,16 +24,16 @@ import org.w3c.dom.Node;
 
 /**
  * A NamedNodeMap that wraps the Nodes returned in their proxies.
- *
+ * <p>
  * Note: Since maps have no guaranteed order we don't need to worry about identity
  * here as we do with "child" adapters.  In that case we need to preserve identity
  * in order to support finding the next/previous siblings.
  */
 public class ProxyNamedNodeMap implements NamedNodeMap {
 
-    private NamedNodeMap nodes;
-    private AdapterFactory adapterFactory;
-    private AdapterNode parent;
+    private final NamedNodeMap nodes;
+    private final AdapterFactory adapterFactory;
+    private final AdapterNode parent;
 
     public ProxyNamedNodeMap(AdapterFactory factory, AdapterNode parent, NamedNodeMap nodes) {
         this.nodes = nodes;
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyNodeAdapter.java
similarity index 71%
rename from core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyNodeAdapter.java
index 52f76d33d..831c30777 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyNodeAdapter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -32,14 +32,14 @@ import org.w3c.dom.Node;
  */
 public abstract class ProxyNodeAdapter extends AbstractAdapterNode {
 
-    private Logger log = LogManager.getLogger(this.getClass());
+    private static final Logger LOG = LogManager.getLogger(ProxyNodeAdapter.class);
 
     public ProxyNodeAdapter(AdapterFactory factory, AdapterNode parent, Node value) {
-        setContext(factory, parent, "document"/*propname unused*/, value);
-        log.debug("Proxied node is: {}" + value);
-        log.debug("Node class is: {}", value.getClass());
-        log.debug("Node type is: {}", value.getNodeType());
-        log.debug("Node name is: {}", value.getNodeName());
+        setContext(factory, parent, "document", value);
+        LOG.debug("Proxied node is: {}", value);
+        LOG.debug("Node class is: {}", value.getClass());
+        LOG.debug("Node type is: {}", value.getNodeType());
+        LOG.debug("Node name is: {}", value.getNodeName());
     }
 
     /**
@@ -60,72 +60,70 @@ public abstract class ProxyNodeAdapter extends AbstractAdapterNode {
     protected NamedNodeMap wrap(NamedNodeMap nnm) {
         return getAdapterFactory().proxyNamedNodeMap(this, nnm);
     }
-    //protected NodeList wrap( NodeList nl ) { }
-
-    //protected Node unwrap( Node child ) {
-    //  return ((ProxyNodeAdapter)child).node();
-    //}
-
-    // Proxied Node methods
 
+    @Override
     public String getNodeName() {
-        log.trace("getNodeName");
+        LOG.trace("getNodeName");
         return node().getNodeName();
     }
 
+    @Override
     public String getNodeValue() throws DOMException {
-        log.trace("getNodeValue");
+        LOG.trace("getNodeValue");
         return node().getNodeValue();
     }
 
     public short getNodeType() {
-        if (log.isTraceEnabled()) {
-            log.trace("getNodeType: " + getNodeName() + ": " + node().getNodeType());
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("getNodeType: " + getNodeName() + ": " + node().getNodeType());
         }
         return node().getNodeType();
     }
 
+    @Override
     public NamedNodeMap getAttributes() {
         NamedNodeMap nnm = wrap(node().getAttributes());
-        if (log.isTraceEnabled()) {
-            log.trace("getAttributes: " + nnm);
-        }
+        LOG.trace("getAttributes: {}", nnm);
         return nnm;
     }
 
+    @Override
     public boolean hasChildNodes() {
-        log.trace("hasChildNodes");
+        LOG.trace("hasChildNodes");
         return node().hasChildNodes();
     }
 
+    @Override
     public boolean isSupported(String s, String s1) {
-        log.trace("isSupported");
-        // Is this ok?  What kind of features are they asking about?
+        LOG.trace("isSupported");
         return node().isSupported(s, s1);
     }
 
+    @Override
     public String getNamespaceURI() {
-        log.trace("getNamespaceURI");
+        LOG.trace("getNamespaceURI");
         return node().getNamespaceURI();
     }
 
+    @Override
     public String getPrefix() {
-        log.trace("getPrefix");
+        LOG.trace("getPrefix");
         return node().getPrefix();
     }
 
+    @Override
     public String getLocalName() {
-        log.trace("getLocalName");
+        LOG.trace("getLocalName");
         return node().getLocalName();
     }
 
+    @Override
     public boolean hasAttributes() {
-        log.trace("hasAttributes");
+        LOG.trace("hasAttributes");
         return node().hasAttributes();
     }
 
-    // End proxied Node methods
-
+    @Override
     public String toString() {
         return "ProxyNode for: " + node();
     }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyTextNodeAdapter.java
similarity index 98%
rename from core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyTextNodeAdapter.java
index 1f5b45b22..8a586b81a 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ProxyTextNodeAdapter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Text;
@@ -38,6 +38,7 @@ public class ProxyTextNodeAdapter extends ProxyNodeAdapter implements Text {
         return (Text) getPropertyValue();
     }
 
+    @Override
     public String toString() {
         return "ProxyTextNode for: " + text();
     }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ServletURIResolver.java
similarity index 73%
rename from core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ServletURIResolver.java
index 23a1c86a8..8521b334d 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/ServletURIResolver.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -31,39 +31,39 @@ import java.io.InputStream;
 /**
  * ServletURIResolver is a URIResolver that can retrieve resources from the servlet context using the scheme "response".
  * e.g.
- *
+ * <p>
  * A URI resolver is called when a stylesheet uses an xsl:include, xsl:import, or document() function to find the
  * resource (file).
  */
 public class ServletURIResolver implements URIResolver {
 
-    private Logger log = LogManager.getLogger(getClass());
-    static final String PROTOCOL = "response:";
+    private static final Logger LOG = LogManager.getLogger(ServletURIResolver.class);
+
+    private static final String PROTOCOL = "response:";
 
-    private ServletContext sc;
+    private final ServletContext servletContext;
 
-    public ServletURIResolver(ServletContext sc) {
-        log.trace("ServletURIResolver: {}", sc);
-        this.sc = sc;
+    public ServletURIResolver(ServletContext servletContext) {
+        this.servletContext = servletContext;
     }
 
     public Source resolve(String href, String base) throws TransformerException {
-        log.debug("ServletURIResolver resolve(): href={}, base={}", href, base);
+        LOG.debug("ServletURIResolver resolve(): href={}, base={}", href, base);
         if (href.startsWith(PROTOCOL)) {
             String res = href.substring(PROTOCOL.length());
-            log.debug("Resolving resource <{}>", res);
+            LOG.debug("Resolving resource <{}>", res);
 
-            InputStream is = sc.getResourceAsStream(res);
+            InputStream is = servletContext.getResourceAsStream(res);
 
             if (is == null) {
                 throw new TransformerException(
-                        "Resource " + res + " not found in resources.");
+                    "Resource " + res + " not found in resources.");
             }
 
             return new StreamSource(is);
         }
 
         throw new TransformerException(
-                "Cannot handle protocol of resource " + href);
+            "Cannot handle protocol of resource " + href);
     }
 }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleAdapterDocument.java
similarity index 90%
rename from core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleAdapterDocument.java
index 23c315070..0747acf75 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleAdapterDocument.java
@@ -16,10 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
-
-import java.util.Arrays;
-import java.util.List;
+package org.apache.struts2.result.xslt;
 
 import org.apache.struts2.StrutsException;
 import org.w3c.dom.Attr;
@@ -38,12 +35,15 @@ import org.w3c.dom.NodeList;
 import org.w3c.dom.ProcessingInstruction;
 import org.w3c.dom.Text;
 
+import java.util.Arrays;
+import java.util.List;
+
 /**
  * SimpleAdapterDocument adapted a Java object and presents it as
  * a Document.  This class represents the Document container and uses
  * the AdapterFactory to produce a child adapter for the wrapped object.
  * The adapter produced must be of an Element type or an exception is thrown.
- *
+ * <p>
  * Note: in theory we could base this on AbstractAdapterElement and then allow
  * the wrapped object to be a more general Node type.  We would just use
  * ourselves as the root element.  However I don't think this is an issue as
@@ -53,12 +53,11 @@ public class SimpleAdapterDocument extends AbstractAdapterNode implements Docume
 
     private Element rootElement;
 
-    public SimpleAdapterDocument(
-            AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
+    public SimpleAdapterDocument(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Object value) {
         setContext(adapterFactory, parent, propertyName, value);
-
     }
 
+    @Override
     public void setPropertyValue(Object prop) {
         super.setPropertyValue(prop);
         rootElement = null; // recreate the root element
@@ -68,24 +67,25 @@ public class SimpleAdapterDocument extends AbstractAdapterNode implements Docume
      * Lazily construct the root element adapter from the value object.
      */
     private Element getRootElement() {
-        if (rootElement != null)
+        if (rootElement != null) {
             return rootElement;
+        }
 
-        Node node = getAdapterFactory().adaptNode(
-                this, getPropertyName(), getPropertyValue());
-        if (node instanceof Element)
+        Node node = getAdapterFactory().adaptNode(this, getPropertyName(), getPropertyValue());
+        if (node instanceof Element) {
             rootElement = (Element) node;
-        else
-            throw new StrutsException(
-                    "Document adapter expected to wrap an Element type.  Node is not an element:" + node);
-
+        } else {
+            throw new StrutsException("Document adapter expected to wrap an Element type.  Node is not an element: " + node);
+        }
         return rootElement;
     }
 
+    @Override
     protected List<Node> getChildAdapters() {
         return Arrays.asList(new Node[]{getRootElement()});
     }
 
+    @Override
     public NodeList getChildNodes() {
         return new NodeList() {
             public Node item(int i) {
@@ -114,10 +114,12 @@ public class SimpleAdapterDocument extends AbstractAdapterNode implements Docume
         return null;
     }
 
+    @Override
     public NodeList getElementsByTagNameNS(String string, String string1) {
         return null;
     }
 
+    @Override
     public Node getFirstChild() {
         return getRootElement();
     }
@@ -126,14 +128,17 @@ public class SimpleAdapterDocument extends AbstractAdapterNode implements Docume
         return null;
     }
 
+    @Override
     public Node getLastChild() {
         return getRootElement();
     }
 
+    @Override
     public String getNodeName() {
         return "#document";
     }
 
+    @Override
     public short getNodeType() {
         return Node.DOCUMENT_NODE;
     }
@@ -178,6 +183,7 @@ public class SimpleAdapterDocument extends AbstractAdapterNode implements Docume
         return null;
     }
 
+    @Override
     public boolean hasChildNodes() {
         return true;
     }
@@ -186,10 +192,12 @@ public class SimpleAdapterDocument extends AbstractAdapterNode implements Docume
         return null;
     }
 
+    @Override
     public Node getChildAfter(Node child) {
         return null;
     }
 
+    @Override
     public Node getChildBefore(Node child) {
         return null;
     }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleNodeList.java
similarity index 82%
rename from core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleNodeList.java
index 7affaa919..cb5f96c76 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleNodeList.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -26,30 +26,30 @@ import org.w3c.dom.NodeList;
 import java.util.List;
 
 public class SimpleNodeList implements NodeList {
-    private Logger log = LogManager.getLogger(SimpleNodeList.class);
 
-    private List<Node> nodes;
+    private static final Logger LOG = LogManager.getLogger(SimpleNodeList.class);
+
+    private final List<Node> nodes;
 
     public SimpleNodeList(List<Node> nodes) {
         this.nodes = nodes;
     }
 
     public int getLength() {
-        if (log.isTraceEnabled()) {
-            log.trace("getLength: {}", nodes.size());
-        }
+        LOG.trace("getLength: {}", nodes.size());
         return nodes.size();
     }
 
     public Node item(int i) {
-        log.trace("getItem: {}", i);
+        LOG.trace("getItem: {}", i);
         return nodes.get(i);
     }
 
     public String toString() {
         StringBuilder sb = new StringBuilder("SimpleNodeList: [");
-        for (int i = 0; i < getLength(); i++)
+        for (int i = 0; i < getLength(); i++) {
             sb.append(item(i).getNodeName()).append(',');
+        }
         sb.append("]");
         return sb.toString();
     }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleTextNode.java
similarity index 97%
rename from core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleTextNode.java
index b09b58f99..4fd0665cf 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/SimpleTextNode.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import org.apache.struts2.StrutsException;
 import org.w3c.dom.DOMException;
@@ -45,14 +45,17 @@ public class SimpleTextNode extends AbstractAdapterNode implements Node, Text {
         return getStringValue().length();
     }
 
+    @Override
     public String getNodeName() {
         return "#text";
     }
 
+    @Override
     public short getNodeType() {
         return Node.TEXT_NODE;
     }
 
+    @Override
     public String getNodeValue() throws DOMException {
         return getStringValue();
     }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/StringAdapter.java
similarity index 93%
rename from core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/StringAdapter.java
index 3948d2e49..927019a5a 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/StringAdapter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import com.opensymphony.xwork2.util.DomHelper;
 import org.apache.logging.log4j.LogManager;
@@ -46,7 +46,8 @@ import java.util.List;
  */
 public class StringAdapter extends AbstractAdapterElement {
 
-    private Logger log = LogManager.getLogger(this.getClass());
+    private static final Logger LOG = LogManager.getLogger(StringAdapter.class);
+
     boolean parseStringAsXML;
 
     public StringAdapter() {
@@ -75,15 +76,16 @@ public class StringAdapter extends AbstractAdapterElement {
         return getPropertyValue().toString();
     }
 
+    @Override
     protected List<Node> buildChildAdapters() {
         Node node;
         if (getParseStringAsXML()) {
-            log.debug("parsing string as xml: {}", getStringValue());
+            LOG.debug("parsing string as xml: {}", getStringValue());
             // Parse the String to a DOM, then proxy that as our child
             node = DomHelper.parse(new InputSource(new StringReader(getStringValue())));
             node = getAdapterFactory().proxyNode(this, node);
         } else {
-            log.debug("using string as is: {}", getStringValue());
+            LOG.debug("using string as is: {}", getStringValue());
             // Create a Text node as our child
             node = new SimpleTextNode(getAdapterFactory(), this, "text", getStringValue());
         }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/XSLTResult.java
similarity index 98%
rename from core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/XSLTResult.java
index 1361c628a..6bc7541b1 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/XSLTResult.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.Result;
@@ -62,7 +62,7 @@ public class XSLTResult implements Result {
     private static final Logger LOG = LogManager.getLogger(XSLTResult.class);
 
     /**
-     * 'stylesheetLocation' parameter.  Points to the xsl.
+     * 'stylesheetLocation' parameter. Points to the xsl.
      */
     public static final String DEFAULT_PARAM = "stylesheetLocation";
 
@@ -120,7 +120,7 @@ public class XSLTResult implements Result {
         setStylesheetLocation(stylesheetLocation);
     }
 
-    @Inject(StrutsConstants.STRUTS_XSLT_NOCACHE)
+    @Inject(XsltConstants.STRUTS_XSLT_NOCACHE)
     public void setNoCache(String xsltNoCache) {
         this.noCache = BooleanUtils.toBoolean(xsltNoCache);
     }
diff --git a/core/src/test/resources/XSLTResultTest.xsl b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/XsltConstants.java
similarity index 73%
copy from core/src/test/resources/XSLTResultTest.xsl
copy to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/XsltConstants.java
index 0d97e1525..a1749a579 100644
--- a/core/src/test/resources/XSLTResultTest.xsl
+++ b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/XsltConstants.java
@@ -1,7 +1,4 @@
-<!--
 /*
- * $Id$
- *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -19,13 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
--->
-<xsl:stylesheet version="1.0"
-                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-                xmlns="http://www.w3.org/TR/xhtml1/strict">
+package org.apache.struts2.result.xslt;
+
+public final class XsltConstants {
+
+    /**
+     * Avoids creating instance
+     */
+    private XsltConstants() {}
 
-    <xsl:template match="/">
-        <result/>
-    </xsl:template>
+    /** Whether XSLT templates should not be cached */
+    public static final String STRUTS_XSLT_NOCACHE = "struts.xslt.nocache";
 
-</xsl:stylesheet>
\ No newline at end of file
+}
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/package.html b/plugins/xslt/src/main/java/org/apache/struts2/result/xslt/package.html
similarity index 100%
rename from core/src/main/java/org/apache/struts2/views/xslt/package.html
rename to plugins/xslt/src/main/java/org/apache/struts2/result/xslt/package.html
diff --git a/core/src/test/resources/XSLTResultTest.xsl b/plugins/xslt/src/main/resources/struts-plugin.xml
similarity index 65%
copy from core/src/test/resources/XSLTResultTest.xsl
copy to plugins/xslt/src/main/resources/struts-plugin.xml
index 0d97e1525..9bda180f4 100644
--- a/core/src/test/resources/XSLTResultTest.xsl
+++ b/plugins/xslt/src/main/resources/struts-plugin.xml
@@ -1,7 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" ?>
 <!--
 /*
- * $Id$
- *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -20,12 +19,16 @@
  * under the License.
  */
 -->
-<xsl:stylesheet version="1.0"
-                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-                xmlns="http://www.w3.org/TR/xhtml1/strict">
+<!DOCTYPE struts PUBLIC
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
+
+<struts>
 
-    <xsl:template match="/">
-        <result/>
-    </xsl:template>
+    <package name="xslt-default" extends="struts-default">
+        <result-types>
+            <result-type name="xslt" class="org.apache.struts2.result.xslt.XSLTResult"/>
+        </result-types>
+    </package>
 
-</xsl:stylesheet>
\ No newline at end of file
+</struts>
diff --git a/core/src/test/java/org/apache/struts2/views/xslt/XSLTResultTest.java b/plugins/xslt/src/test/java/org/apache/struts2/result/xslt/XSLTResultTest.java
similarity index 68%
rename from core/src/test/java/org/apache/struts2/views/xslt/XSLTResultTest.java
rename to plugins/xslt/src/test/java/org/apache/struts2/result/xslt/XSLTResultTest.java
index ecc2b8469..861b02551 100644
--- a/core/src/test/java/org/apache/struts2/views/xslt/XSLTResultTest.java
+++ b/plugins/xslt/src/test/java/org/apache/struts2/result/xslt/XSLTResultTest.java
@@ -16,17 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.views.xslt;
+package org.apache.struts2.result.xslt;
 
 import com.opensymphony.xwork2.Action;
-import com.opensymphony.xwork2.ActionChainResult;
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.Result;
 import com.opensymphony.xwork2.mock.MockActionInvocation;
 import com.opensymphony.xwork2.util.ClassLoaderUtil;
 import com.opensymphony.xwork2.util.ValueStack;
+import junit.framework.TestCase;
 import org.apache.struts2.ServletActionContext;
-import org.apache.struts2.StrutsInternalTestCase;
+import org.apache.struts2.junit.StrutsTestCase;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockServletContext;
@@ -43,7 +43,7 @@ import java.util.List;
  * Unit test for {@link XSLTResult}.
  *
  */
-public class XSLTResultTest extends StrutsInternalTestCase {
+public class XSLTResultTest extends StrutsTestCase {
 
     private XSLTResult result;
     private MockHttpServletResponse response;
@@ -57,7 +57,7 @@ public class XSLTResultTest extends StrutsInternalTestCase {
             result.setParse(false);
             result.setStylesheetLocation(null);
             result.execute(mai);
-            fail("Should have thrown an IllegalArgumentException");
+            TestCase.fail("Should have thrown an IllegalArgumentException");
         } catch (IllegalArgumentException e) {
             // success
         }
@@ -68,7 +68,7 @@ public class XSLTResultTest extends StrutsInternalTestCase {
             result.setParse(false);
             result.setStylesheetLocation("nofile.xsl");
             result.execute(mai);
-            fail("Should have thrown a TransformerException");
+            TestCase.fail("Should have thrown a TransformerException");
         } catch (TransformerException e) {
             // success
         }
@@ -80,8 +80,8 @@ public class XSLTResultTest extends StrutsInternalTestCase {
         result.execute(mai);
 
         String out = response.getContentAsString();
-        assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-        assertTrue(out.indexOf("<result xmlns=\"http://www.w3.org/TR/xhtml1/strict\"") > -1);
+        TestCase.assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+        TestCase.assertTrue(out.contains("<result xmlns=\"http://www.w3.org/TR/xhtml1/strict\""));
     }
 
     public void testSimpleTransform5() throws Exception {
@@ -90,14 +90,14 @@ public class XSLTResultTest extends StrutsInternalTestCase {
         result.execute(mai);
 
         String out = response.getContentAsString();
-        assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-        assertTrue(out.contains("<title>WebWork in Action</title>"));
-        assertTrue(out.contains("<author>Patrick and Jason</author>"));
-        assertTrue(out.contains("<editions><edition value=\"I\">I</edition><edition value=\"IV\">IV</edition></editions>"));
-        assertTrue(out.contains("<book><title/><author/><editions/></book>"));
-        assertTrue(out.contains("<title>XWork not in Action</title>"));
-        assertTrue(out.contains("<author>Superman</author>"));
-        assertTrue(out.contains("<editions><edition value=\"1234\">1234</edition><edition value=\"345\">345</edition><edition value=\"6667\">6667</edition></editions>"));
+        TestCase.assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+        TestCase.assertTrue(out.contains("<title>WebWork in Action</title>"));
+        TestCase.assertTrue(out.contains("<author>Patrick and Jason</author>"));
+        TestCase.assertTrue(out.contains("<editions><edition value=\"I\">I</edition><edition value=\"IV\">IV</edition></editions>"));
+        TestCase.assertTrue(out.contains("<book><title/><author/><editions/></book>"));
+        TestCase.assertTrue(out.contains("<title>XWork not in Action</title>"));
+        TestCase.assertTrue(out.contains("<author>Superman</author>"));
+        TestCase.assertTrue(out.contains("<editions><edition value=\"1234\">1234</edition><edition value=\"345\">345</edition><edition value=\"6667\">6667</edition></editions>"));
     }
 
     public void testSimpleTransformParse() throws Exception {
@@ -106,8 +106,8 @@ public class XSLTResultTest extends StrutsInternalTestCase {
         result.execute(mai);
 
         String out = response.getContentAsString();
-        assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-        assertTrue(out.indexOf("<result xmlns=\"http://www.w3.org/TR/xhtml1/strict\"") > -1);
+        TestCase.assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+        TestCase.assertTrue(out.contains("<result xmlns=\"http://www.w3.org/TR/xhtml1/strict\""));
     }
 
     public void testTransform2() throws Exception {
@@ -116,36 +116,36 @@ public class XSLTResultTest extends StrutsInternalTestCase {
         result.execute(mai);
 
         String out = response.getContentAsString();
-        assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-        assertTrue(out.indexOf("<html xmlns=\"http://www.w3.org/TR/xhtml1/strict\"") > -1);
-        assertTrue(out.indexOf("Hello Santa Claus how are you?") > -1);
+        TestCase.assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+        TestCase.assertTrue(out.contains("<html xmlns=\"http://www.w3.org/TR/xhtml1/strict\""));
+        TestCase.assertTrue(out.contains("Hello Santa Claus how are you?"));
     }
-    
+
     public void testTransform3() throws Exception {
         result.setParse(false);
         result.setStylesheetLocation("XSLTResultTest3.xsl");
         result.execute(mai);
 
         String out = response.getContentAsString();
-        assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-        assertTrue(out.indexOf("<html xmlns=\"http://www.w3.org/TR/xhtml1/strict\"") > -1);
-        assertTrue(out.indexOf("Hello Santa Claus how are you?") > -1);
-        assertTrue(out.indexOf("WebWork in Action by Patrick and Jason") > -1);
-        assertTrue(out.indexOf("XWork not in Action by Superman") > -1);
+        TestCase.assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+        TestCase.assertTrue(out.contains("<html xmlns=\"http://www.w3.org/TR/xhtml1/strict\""));
+        TestCase.assertTrue(out.contains("Hello Santa Claus how are you?"));
+        TestCase.assertTrue(out.contains("WebWork in Action by Patrick and Jason"));
+        TestCase.assertTrue(out.contains("XWork not in Action by Superman"));
     }
-    
+
     public void testTransformWithBoolean() throws Exception {
         result.setParse(false);
         result.setStylesheetLocation("XSLTResultTest5.xsl");
         result.execute(mai);
 
         String out = response.getContentAsString();
-        assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-        assertTrue(out.indexOf("<html xmlns=\"http://www.w3.org/TR/xhtml1/strict\"") > -1);
-        assertTrue(out.indexOf("Hello Santa Claus how are you?") > -1);
-        assertTrue(out.indexOf("You are active: true") > -1);
+        TestCase.assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+        TestCase.assertTrue(out.contains("<html xmlns=\"http://www.w3.org/TR/xhtml1/strict\""));
+        TestCase.assertTrue(out.contains("Hello Santa Claus how are you?"));
+        TestCase.assertTrue(out.contains("You are active: true"));
     }
-    
+
     public void testTransform4WithDocumentInclude() throws Exception {
         result = new XSLTResult(){
             protected URIResolver getURIResolver() {
@@ -153,21 +153,21 @@ public class XSLTResultTest extends StrutsInternalTestCase {
                     public Source resolve(String href, String base) throws TransformerException {
                         return new StreamSource(ClassLoaderUtil.getResourceAsStream(href, this.getClass()));
                     }
-                    
+
                 };
             }
-            
+
         };
         result.setParse(false);
         result.setStylesheetLocation("XSLTResultTest4.xsl");
         result.execute(mai);
 
         String out = response.getContentAsString();
-        assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-        assertTrue(out.indexOf("<validators>") > -1);
+        TestCase.assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+        TestCase.assertTrue(out.contains("<validators>"));
     }
 
-    public void testTransform4WithBadDocumentInclude() throws Exception {
+    public void testTransform4WithBadDocumentInclude() {
         result = new XSLTResult(){
             protected URIResolver getURIResolver() {
                 return new URIResolver() {
@@ -183,28 +183,26 @@ public class XSLTResultTest extends StrutsInternalTestCase {
         result.setStylesheetLocation("XSLTResultTest4.badinclude.xsl");
         try {
             result.execute(mai);
-            fail("Should have thrown an exception");
+            TestCase.fail("Should have thrown an exception");
         } catch (Exception ex) {
-            assertEquals("Error transforming result", ex.getMessage());
+            TestCase.assertEquals("Error transforming result", ex.getMessage());
         }
     }
-    
-    public void testTransformWithError() throws Exception {
+
+    public void testTransformWithError() {
         result = new XSLTResult(){
             protected URIResolver getURIResolver() {
-                return new URIResolver() {
-                    public Source resolve(String href, String base) throws TransformerException {
-                        throw new TransformerException("Some random error");
-                    }
+                return (href, base) -> {
+                    throw new TransformerException("Some random error");
                 };
             }
         };
         result.setStylesheetLocation("XSLTResultTest4.xsl");
         try {
             result.execute(mai);
-            fail("Should have thrown an exception");
+            TestCase.fail("Should have thrown an exception");
         } catch (Exception ex) {
-            assertEquals("Error transforming result", ex.getMessage());
+            TestCase.assertEquals("Error transforming result", ex.getMessage());
         }
     }
 
@@ -213,9 +211,9 @@ public class XSLTResultTest extends StrutsInternalTestCase {
         result.setStylesheetLocation("XSLTResultTest.bad.character.xsl");
         try {
             result.execute(mai);
-            fail("Should have thrown an exception");
+            TestCase.fail("Should have thrown an exception");
         } catch (Exception ex) {
-            assertEquals("Error transforming result", ex.getMessage());
+            TestCase.assertEquals("Error transforming result", ex.getMessage());
         }
     }
 
@@ -227,9 +225,9 @@ public class XSLTResultTest extends StrutsInternalTestCase {
 
         String out = response.getContentAsString();
 
-        assertEquals(302, response.getStatus());
-        assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
-        assertTrue(out.indexOf("<result xmlns=\"http://www.w3.org/TR/xhtml1/strict\"") > -1);
+        TestCase.assertEquals(302, response.getStatus());
+        TestCase.assertTrue(out.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
+        TestCase.assertTrue(out.contains("<result xmlns=\"http://www.w3.org/TR/xhtml1/strict\""));
     }
 
     public void testEncoding() throws Exception {
@@ -240,16 +238,16 @@ public class XSLTResultTest extends StrutsInternalTestCase {
 
         String actual = response.getCharacterEncoding();
 
-        assertEquals(actual, "ISO-8859-1");
+        TestCase.assertEquals(actual, "ISO-8859-1");
     }
 
     public void testPassingNullInvocation() throws Exception{
         Result result = new XSLTResult();
         try {
             result.execute(null);
-            fail("Exception should be thrown!");
+            TestCase.fail("Exception should be thrown!");
         } catch (IllegalArgumentException e) {
-            assertEquals("Invocation cannot be null!", e.getMessage());
+            TestCase.assertEquals("Invocation cannot be null!", e.getMessage());
         }
     }
 
@@ -298,13 +296,13 @@ public class XSLTResultTest extends StrutsInternalTestCase {
         public String getUsername() {
             return "Santa Claus";
         }
-        
+
         public boolean isActive() {
             return true;
         }
 
-        public List getBooks() {
-            List list = new ArrayList();
+        public List<Book> getBooks() {
+            List<Book> list = new ArrayList<>();
             list.add(new Book("WebWork in Action", "Patrick and Jason", Arrays.asList("I", "IV")));
             list.add(null);
             list.add(new Book("XWork not in Action", "Superman", Arrays.asList("1234", "345", "6667")));
@@ -313,11 +311,11 @@ public class XSLTResultTest extends StrutsInternalTestCase {
 
     }
 
-    public class Book {
+    public static class Book {
 
-        private String title;
-        private String author;
-        private List<String> editions;
+        private final String title;
+        private final String author;
+        private final List<String> editions;
 
         public Book(String title, String author, List<String> editions) {
             this.title = title;
diff --git a/core/src/test/resources/XSLTResultTest-val.xml b/plugins/xslt/src/test/resources/XSLTResultTest-val.xml
similarity index 100%
rename from core/src/test/resources/XSLTResultTest-val.xml
rename to plugins/xslt/src/test/resources/XSLTResultTest-val.xml
diff --git a/core/src/test/resources/XSLTResultTest.bad.character.xsl b/plugins/xslt/src/test/resources/XSLTResultTest.bad.character.xsl
similarity index 100%
rename from core/src/test/resources/XSLTResultTest.bad.character.xsl
rename to plugins/xslt/src/test/resources/XSLTResultTest.bad.character.xsl
diff --git a/core/src/test/resources/XSLTResultTest.xsl b/plugins/xslt/src/test/resources/XSLTResultTest.xsl
similarity index 100%
rename from core/src/test/resources/XSLTResultTest.xsl
rename to plugins/xslt/src/test/resources/XSLTResultTest.xsl
diff --git a/core/src/test/resources/XSLTResultTest2.xsl b/plugins/xslt/src/test/resources/XSLTResultTest2.xsl
similarity index 100%
rename from core/src/test/resources/XSLTResultTest2.xsl
rename to plugins/xslt/src/test/resources/XSLTResultTest2.xsl
diff --git a/core/src/test/resources/XSLTResultTest3.xsl b/plugins/xslt/src/test/resources/XSLTResultTest3.xsl
similarity index 100%
rename from core/src/test/resources/XSLTResultTest3.xsl
rename to plugins/xslt/src/test/resources/XSLTResultTest3.xsl
diff --git a/core/src/test/resources/XSLTResultTest4.badinclude.xsl b/plugins/xslt/src/test/resources/XSLTResultTest4.badinclude.xsl
similarity index 100%
rename from core/src/test/resources/XSLTResultTest4.badinclude.xsl
rename to plugins/xslt/src/test/resources/XSLTResultTest4.badinclude.xsl
diff --git a/core/src/test/resources/XSLTResultTest4.xsl b/plugins/xslt/src/test/resources/XSLTResultTest4.xsl
similarity index 100%
rename from core/src/test/resources/XSLTResultTest4.xsl
rename to plugins/xslt/src/test/resources/XSLTResultTest4.xsl
diff --git a/core/src/test/resources/XSLTResultTest5.xsl b/plugins/xslt/src/test/resources/XSLTResultTest5.xsl
similarity index 100%
rename from core/src/test/resources/XSLTResultTest5.xsl
rename to plugins/xslt/src/test/resources/XSLTResultTest5.xsl
diff --git a/core/src/test/resources/XSLTResultTest6.xsl b/plugins/xslt/src/test/resources/XSLTResultTest6.xsl
similarity index 100%
rename from core/src/test/resources/XSLTResultTest6.xsl
rename to plugins/xslt/src/test/resources/XSLTResultTest6.xsl
diff --git a/pom.xml b/pom.xml
index c866e545b..dcc4d0ee5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,24 +2,25 @@
 <!--
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
+ * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
+ * regarding copyright ownership. The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
+ * with the License. You may obtain a copy of the License at
  *
  *  http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
+ * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
 
     <parent>
         <groupId>org.apache.struts</groupId>
@@ -32,7 +33,7 @@
     <version>6.2.0-SNAPSHOT</version>
     <packaging>pom</packaging>
     <name>Struts 2</name>
-    <url>http://struts.apache.org/</url>
+    <url>https://struts.apache.org/</url>
     <description>Apache Struts 2</description>
 
     <inceptionYear>2000</inceptionYear>
@@ -91,15 +92,15 @@
     <licenses>
         <license>
             <name>The Apache Software License, Version 2.0</name>
-            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
             <distribution>repo</distribution>
-            <comments />
+            <comments/>
         </license>
     </licenses>
 
     <organization>
         <name>Apache Software Foundation</name>
-        <url>http://www.apache.org</url>
+        <url>https://www.apache.org</url>
     </organization>
 
     <properties>
@@ -271,10 +272,10 @@
                             <exclude>**/TestBean.java</exclude>
                         </excludes>
                         <properties>
-                          <property>
-                            <name>junit</name>
-                            <value>false</value>
-                          </property>
+                            <property>
+                                <name>junit</name>
+                                <value>false</value>
+                            </property>
                         </properties>
                     </configuration>
                 </plugin>
@@ -315,10 +316,10 @@
                         <useDefaultExcludes>true</useDefaultExcludes>
                         <addDefaultLicenseMatchers>false</addDefaultLicenseMatchers>
                         <licenses>
-                            <licens implementation="org.apache.rat.analysis.license.ApacheSoftwareLicense20" />
+                            <licens implementation="org.apache.rat.analysis.license.ApacheSoftwareLicense20"/>
                         </licenses>
                         <licenseFamilies>
-                            <licenseFamily implementation="org.apache.rat.license.Apache20LicenseFamily" />
+                            <licenseFamily implementation="org.apache.rat.license.Apache20LicenseFamily"/>
                         </licenseFamilies>
                         <includes>
                             <include>pom.xml</include>
@@ -367,7 +368,7 @@
                             <id>enforce</id>
                             <configuration>
                                 <rules>
-                                    <dependencyConvergence />
+                                    <dependencyConvergence/>
                                 </rules>
                             </configuration>
                             <goals>
@@ -673,6 +674,12 @@
                 <version>${project.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>org.apache.struts</groupId>
+                <artifactId>struts2-xslt-plugin</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>org.freemarker</groupId>
                 <artifactId>freemarker</artifactId>
@@ -683,7 +690,8 @@
                 <groupId>org.apache.felix</groupId>
                 <artifactId>org.apache.felix.framework</artifactId>
                 <version>6.0.3</version>
-                <scope>provided</scope>  <!-- felix-main provides everything in felix-framework (and more), override here to provent both JARs from being included in the build. -->
+                <scope>provided
+                </scope>  <!-- felix-main provides everything in felix-framework (and more), override here to provent both JARs from being included in the build. -->
             </dependency>
 
             <dependency>
@@ -1045,7 +1053,8 @@
                 <version>4.3.1</version>
                 <exclusions>
                     <!-- The mockito-core artifact and easymock artifact use different versions of objenesis (2.6 vs 3.1).
-                         Excluding the older version here to pass enforcer.  When next upgrading mockito-core, confirm whether this exclusion is still required. -->
+                         Excluding the older version here to pass enforcer. When next upgrading mockito-core,
+                         confirm whether this exclusion is still required. -->
                     <exclusion>
                         <groupId>org.objenesis</groupId>
                         <artifactId>objenesis</artifactId>