Merge pull request #641 from apache/WW-5264-xslt

[WW-5264] Moves XSLT result into a dedicated plugin
This commit is contained in:
Lukasz Lenart
2022-12-09 10:07:03 +01:00
committed by GitHub
41 changed files with 488 additions and 358 deletions
+5
View File
@@ -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>
+5
View File
@@ -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>
@@ -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";
@@ -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));
+1 -1
View File
@@ -38,7 +38,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>
+1
View File
@@ -58,6 +58,7 @@
<module>testng</module>
<module>tiles</module>
<module>velocity</module>
<module>xslt</module>
</modules>
<dependencies>
+3
View File
@@ -0,0 +1,3 @@
# Struts 2 XSLT plugin
The XSLT plugin provides XSLT result.
+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/*
* 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
* 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
*
* 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
* 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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.2.0-SNAPSHOT</version>
</parent>
<artifactId>struts2-xslt-plugin</artifactId>
<packaging>jar</packaging>
<name>Struts 2 XSLT Plugin</name>
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-junit-plugin</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
@@ -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;
}
@@ -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();
}
@@ -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());
}
}
@@ -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;
@@ -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;
@@ -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);
}
@@ -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)
children.add(childAdapter);
log.debug("{} adding adapter: {}", this, childAdapter);
if (childAdapter != null) {
children.add(childAdapter);
}
LOG.debug("{} adding adapter: {}", this, childAdapter);
}
return children;
@@ -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(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Map value) {
setContext( adapterFactory, parent, propertyName, value );
public MapAdapter() {
}
public Map map() {
return (Map)getPropertyValue();
public MapAdapter(AdapterFactory adapterFactory, AdapterNode parent, String propertyName, Map<?, ?> value) {
setContext(adapterFactory, parent, propertyName, value);
}
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);
@@ -64,19 +65,20 @@ public class MapAdapter extends AbstractAdapterElement {
}
static class EntryElement extends AbstractAdapterElement {
Object key, value;
Object key;
Object 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;
}
@Override
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;
}
}
@@ -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();
}
}
@@ -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,15 +92,10 @@ 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.
public NodeList getElementsByTagName(String name) {
return super.getElementsByTagName(name);
}
public String getAttributeNS(String namespaceURI, String localName) {
return element().getAttributeNS(namespaceURI, localName);
}
@@ -103,12 +104,7 @@ public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
return (Attr) wrap(element().getAttributeNodeNS(namespaceURI, localName));
}
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 +155,7 @@ public class ProxyElementAdapter extends ProxyNodeAdapter implements Element {
// end DOM level 3 methods
@Override
public String toString() {
return "ProxyElement for: " + element();
}
@@ -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;
@@ -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());
protected ProxyNodeAdapter(AdapterFactory factory, AdapterNode parent, Node value) {
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,71 @@ 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();
}
@Override
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();
}
@@ -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();
}
@@ -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 ServletContext sc;
private static final String PROTOCOL = "response:";
public ServletURIResolver(ServletContext sc) {
log.trace("ServletURIResolver: {}", sc);
this.sc = sc;
private final ServletContext servletContext;
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);
}
}
@@ -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.Collections;
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()});
return Collections.singletonList(getRootElement());
}
@Override
public NodeList getChildNodes() {
return new NodeList() {
public Node item(int i) {
@@ -110,14 +110,17 @@ public class SimpleAdapterDocument extends AbstractAdapterNode implements Docume
return null;
}
@Override
public NodeList getElementsByTagName(String string) {
return null;
}
@Override
public NodeList getElementsByTagNameNS(String string, String string1) {
return null;
}
@Override
public Node getFirstChild() {
return getRootElement();
}
@@ -126,14 +129,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 +184,7 @@ public class SimpleAdapterDocument extends AbstractAdapterNode implements Docume
return null;
}
@Override
public boolean hasChildNodes() {
return true;
}
@@ -186,10 +193,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;
}
@@ -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();
}
@@ -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;
@@ -34,7 +34,7 @@ public class SimpleTextNode extends AbstractAdapterNode implements Node, Text {
}
public void setData(String string) throws DOMException {
throw new StrutsException("Operation not supported");
throw operationNotSupported();
}
public String getData() throws 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();
}
@@ -62,19 +65,19 @@ public class SimpleTextNode extends AbstractAdapterNode implements Node, Text {
}
public void deleteData(int i, int i1) throws DOMException {
throw new StrutsException("Operation not supported");
throw operationNotSupported();
}
public void insertData(int i, String string) throws DOMException {
throw new StrutsException("Operation not supported");
throw operationNotSupported();
}
public void replaceData(int i, int i1, String string) throws DOMException {
throw new StrutsException("Operation not supported");
throw operationNotSupported();
}
public Text splitText(int i) throws DOMException {
throw new StrutsException("Operation not supported");
throw operationNotSupported();
}
public String substringData(int beginIndex, int endIndex) throws DOMException {
@@ -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());
}
@@ -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;
@@ -27,7 +27,6 @@ import org.apache.commons.lang3.BooleanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsException;
import javax.servlet.http.HttpServletResponse;
@@ -62,7 +61,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";
@@ -87,16 +86,6 @@ public class XSLTResult implements Result {
*/
private String stylesheetLocation;
/**
* Indicates the property name patterns which should be exposed to the xml.
*/
private String matchingPattern;
/**
* Indicates the property name patterns which should be excluded from the xml.
*/
private String excludingPattern;
/**
* Indicates the ognl expression representing the bean which is to be exposed as xml.
*/
@@ -110,7 +99,7 @@ public class XSLTResult implements Result {
private String encoding = "UTF-8";
private boolean parse;
private AdapterFactory adapterFactory;
private transient AdapterFactory adapterFactory;
public XSLTResult() {
}
@@ -120,7 +109,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);
}
@@ -313,7 +302,7 @@ public class XSLTResult implements Result {
return templates;
}
protected Source getDOMSourceForStack(Object value) throws IllegalAccessException, InstantiationException {
protected Source getDOMSourceForStack(Object value) {
return new DOMSource(getAdapterFactory().adaptDocument("result", value));
}
}
@@ -0,0 +1,31 @@
/*
* 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
* 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
*
* 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
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.result.xslt;
public final class XsltConstants {
/**
* Avoids creating instance
*/
private XsltConstants() {}
/** Whether XSLT templates should not be cached */
public static final String STRUTS_XSLT_NOCACHE = "struts.xslt.nocache";
}
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
/*
* 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
* 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
*
* 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
* specific language governing permissions and limitations
* under the License.
*/
-->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
"https://struts.apache.org/dtds/struts-6.0.dtd">
<struts>
<package name="xslt-default" extends="struts-default">
<result-types>
<result-type name="xslt" class="org.apache.struts2.result.xslt.XSLTResult"/>
</result-types>
</package>
</struts>
@@ -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;
+27 -18
View File
@@ -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>