mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
Merge branch 'master' of github.com:victorsosa/struts
This commit is contained in:
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet</artifactId>
|
||||
|
||||
@@ -5,11 +5,11 @@ Here you'll find examples of what is possible with the Struts Portlet integratio
|
||||
<ul>
|
||||
<li><a href="<s:url action="formExample"/>">A simple form</a></li>
|
||||
<li><a href="<s:url action="formExamplePrg" method="input"/>">Form example with proper PRG</a></li>
|
||||
<li><a href="<s:url action="formExampleModelDriven" method="input"/>">Model driven example</li>
|
||||
<li><a href="<s:url action="formExampleModelDriven" method="input"/>">Model driven example</a>/li>
|
||||
<li><a href="<s:url action="validationExample"/>">Validation</a></li>
|
||||
<li><a href="<s:url action="tokenExample"/>">Token</a></li>
|
||||
<li><a href="<s:url action="springExample"/>">Spring integration</a></li>
|
||||
<li><a href="<s:url action="fileUpload" method="input"/>">File upload</li>
|
||||
<li><a href="<s:url action="fileUpload" method="input"/>">File upload</a></li>
|
||||
<li><a href="<s:url action="freeMarkerExample"/>">FreeMarker</a></li>
|
||||
<li><a href="<s:url action="velocityHelloWorld"/>">Velocity</a></li>
|
||||
<li><a href="<s:url action="index" namespace="/tiles"/>">Form Example Validation with Tiles</a></li>
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.mortbay.jetty.webapp.WebAppContext;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public abstract class BasePortletTest extends TestCase {
|
||||
|
||||
@@ -20,17 +22,29 @@ public abstract class BasePortletTest extends TestCase {
|
||||
|
||||
public void setUp() throws Exception {
|
||||
System.setProperty("org.apache.pluto.embedded.portletIds", getPortletName());
|
||||
System.setProperty("org.apache.jasper.compiler.disablejsr199", "false");
|
||||
|
||||
server = new Server(port);
|
||||
|
||||
WebAppContext webapp = new WebAppContext("src/main/webapp", contextPath);
|
||||
webapp.setTempDirectory(new File("target/work"));
|
||||
webapp.setDefaultsDescriptor("/WEB-INF/jetty-pluto-web-default.xml");
|
||||
ServletHolder portletServlet = new ServletHolder(new PortletServlet());
|
||||
|
||||
// Set Classloader of Context to be sane (needed for JSTL)
|
||||
// JSP requires a non-System classloader, this simply wraps the
|
||||
// embedded System classloader in a way that makes it suitable
|
||||
// for JSP to use
|
||||
ClassLoader jspClassLoader = new URLClassLoader(new URL[0], this.getClass().getClassLoader());
|
||||
webapp.setClassLoader(jspClassLoader);
|
||||
|
||||
ServletHolder portletServlet = new ServletHolder(new PortletServlet());
|
||||
portletServlet.setInitParameter("portlet-name", getPortletName());
|
||||
portletServlet.setInitOrder(1);
|
||||
webapp.addServlet(portletServlet, "/PlutoInvoker/" + getPortletName());
|
||||
server.addHandler(webapp);
|
||||
server.start();
|
||||
|
||||
server.addHandler(webapp);
|
||||
|
||||
server.start();
|
||||
// Retrieve the actual port that is used, in case a random, free port is
|
||||
// picked
|
||||
int port = server.getConnectors()[0].getLocalPort();
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-showcase</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
<name>Struts 2 Rest Showcase Webapp</name>
|
||||
<description>Struts 2 Rest Showcase Example</description>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-showcase</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-archetypes</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-assembly</artifactId>
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-bom</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Struts 2 Bill of Materials</name>
|
||||
@@ -25,7 +25,7 @@
|
||||
</licenses>
|
||||
|
||||
<properties>
|
||||
<struts-version.version>2.5-SNAPSHOT</struts-version.version>
|
||||
<struts-version.version>2.5.1-SNAPSHOT</struts-version.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-admin-bundle</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-demo-bundle</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ActionConfig extends Located implements Serializable {
|
||||
|
||||
public static final String DEFAULT_METHOD = "execute";
|
||||
public static final String WILDCARD = "*";
|
||||
public static final String REGEX_WILDCARD = "regex:.*";
|
||||
public static final String DEFAULT_METHOD_REGEX = "([A-Za-z0-9_$]*)";
|
||||
|
||||
protected List<InterceptorMapping> interceptors; // a list of interceptorMapping Objects eg. List<InterceptorMapping>
|
||||
protected Map<String,String> params;
|
||||
@@ -53,6 +53,7 @@ public class ActionConfig extends Located implements Serializable {
|
||||
protected String methodName;
|
||||
protected String packageName;
|
||||
protected String name;
|
||||
protected boolean strictMethodInvocation = true;
|
||||
protected AllowedMethods allowedMethods;
|
||||
|
||||
protected ActionConfig(String packageName, String name, String className) {
|
||||
@@ -63,7 +64,6 @@ public class ActionConfig extends Located implements Serializable {
|
||||
results = new LinkedHashMap<>();
|
||||
interceptors = new ArrayList<>();
|
||||
exceptionMappings = new ArrayList<>();
|
||||
allowedMethods = AllowedMethods.build(new HashSet<>(Collections.singletonList(DEFAULT_METHOD)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +80,7 @@ public class ActionConfig extends Located implements Serializable {
|
||||
this.interceptors = new ArrayList<>(orig.interceptors);
|
||||
this.results = new LinkedHashMap<>(orig.results);
|
||||
this.exceptionMappings = new ArrayList<>(orig.exceptionMappings);
|
||||
this.allowedMethods = AllowedMethods.build(orig.allowedMethods.list());
|
||||
this.allowedMethods = orig.allowedMethods;
|
||||
this.location = orig.location;
|
||||
}
|
||||
|
||||
@@ -132,6 +132,10 @@ public class ActionConfig extends Located implements Serializable {
|
||||
return method.equals(methodName != null ? methodName : DEFAULT_METHOD) || allowedMethods.isAllowed(method);
|
||||
}
|
||||
|
||||
public boolean isStrictMethodInvocation() {
|
||||
return strictMethodInvocation;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
@@ -213,6 +217,7 @@ public class ActionConfig extends Located implements Serializable {
|
||||
|
||||
protected ActionConfig target;
|
||||
protected Set<String> allowedMethods;
|
||||
private String methodRegex;
|
||||
|
||||
public Builder(ActionConfig toClone) {
|
||||
target = new ActionConfig(toClone);
|
||||
@@ -328,12 +333,22 @@ public class ActionConfig extends Located implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setStrictMethodInvocation(boolean strictMethodInvocation) {
|
||||
target.strictMethodInvocation = strictMethodInvocation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDefaultMethodRegex(String methodRegex) {
|
||||
this.methodRegex = methodRegex;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ActionConfig build() {
|
||||
target.params = Collections.unmodifiableMap(target.params);
|
||||
target.results = Collections.unmodifiableMap(target.results);
|
||||
target.interceptors = Collections.unmodifiableList(target.interceptors);
|
||||
target.exceptionMappings = Collections.unmodifiableList(target.exceptionMappings);
|
||||
target.allowedMethods = AllowedMethods.build(allowedMethods);
|
||||
target.allowedMethods = AllowedMethods.build(target.strictMethodInvocation, allowedMethods, methodRegex != null ? methodRegex : DEFAULT_METHOD_REGEX);
|
||||
|
||||
ActionConfig result = target;
|
||||
target = new ActionConfig(target);
|
||||
|
||||
@@ -28,44 +28,51 @@ public class AllowedMethods {
|
||||
private static final Logger LOG = LogManager.getLogger(AllowedMethods.class);
|
||||
|
||||
private Set<AllowedMethod> allowedMethods;
|
||||
private final boolean strictMethodInvocation;
|
||||
private String defaultRegex;
|
||||
|
||||
public static AllowedMethods build(Set<String> methods) {
|
||||
public static AllowedMethods build(boolean strictMethodInvocation, Set<String> methods, String defaultRegex) {
|
||||
|
||||
Set<AllowedMethod> allowedMethods = new HashSet<>();
|
||||
for (String method : methods) {
|
||||
boolean isPattern = false;
|
||||
StringBuilder methodPattern = new StringBuilder();
|
||||
int len = method.length();
|
||||
StringBuilder ret = new StringBuilder();
|
||||
char c;
|
||||
for (int x = 0; x < len; x++) {
|
||||
c = method.charAt(x);
|
||||
if (x < len - 2 && c == '{' && '}' == method.charAt(x + 2)) {
|
||||
ret.append("(.*)");
|
||||
methodPattern.append(defaultRegex);
|
||||
isPattern = true;
|
||||
x += 2;
|
||||
} else {
|
||||
ret.append(c);
|
||||
methodPattern.append(c);
|
||||
}
|
||||
}
|
||||
if (isPattern && !method.startsWith("regex:")) {
|
||||
allowedMethods.add(new PatternAllowedMethod(ret.toString(), method));
|
||||
|
||||
if (isPattern && !method.startsWith("regex:") && !strictMethodInvocation) {
|
||||
allowedMethods.add(new PatternAllowedMethod(methodPattern.toString(), method));
|
||||
} else if (method.startsWith("regex:")) {
|
||||
String pattern = method.substring(method.indexOf(":") + 1);
|
||||
allowedMethods.add(new PatternAllowedMethod(pattern, method));
|
||||
} else if (method.contains("*") && !method.startsWith("regex:")) {
|
||||
String pattern = method.replaceAll("\\*", "(.*)");
|
||||
} else if (method.contains("*") && !method.startsWith("regex:") && !strictMethodInvocation) {
|
||||
String pattern = method.replace("*", defaultRegex);
|
||||
allowedMethods.add(new PatternAllowedMethod(pattern, method));
|
||||
} else if (!isPattern) {
|
||||
allowedMethods.add(new LiteralAllowedMethod(method));
|
||||
} else {
|
||||
allowedMethods.add(new LiteralAllowedMethod(ret.toString()));
|
||||
LOG.trace("Ignoring method name: [{}] when SMI is set to [{}]", method, strictMethodInvocation);
|
||||
}
|
||||
}
|
||||
|
||||
LOG.debug("Defined allowed methods: {}", allowedMethods);
|
||||
|
||||
return new AllowedMethods(allowedMethods);
|
||||
return new AllowedMethods(strictMethodInvocation, allowedMethods, defaultRegex);
|
||||
}
|
||||
|
||||
private AllowedMethods(Set<AllowedMethod> methods) {
|
||||
private AllowedMethods(boolean strictMethodInvocation, Set<AllowedMethod> methods, String defaultRegex) {
|
||||
this.strictMethodInvocation = strictMethodInvocation;
|
||||
this.defaultRegex = defaultRegex;
|
||||
this.allowedMethods = Collections.unmodifiableSet(methods);
|
||||
}
|
||||
|
||||
@@ -86,6 +93,14 @@ public class AllowedMethods {
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getDefaultRegex() {
|
||||
return defaultRegex;
|
||||
}
|
||||
|
||||
public boolean isStrictMethodInvocation() {
|
||||
return strictMethodInvocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -139,13 +154,13 @@ public class AllowedMethods {
|
||||
|
||||
PatternAllowedMethod that = (PatternAllowedMethod) o;
|
||||
|
||||
return original.equals(that.original);
|
||||
return allowedMethodPattern.pattern().equals(that.allowedMethodPattern.pattern());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return original.hashCode();
|
||||
return allowedMethodPattern.pattern().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -115,6 +115,7 @@ public class ActionConfigMatcher extends AbstractMatcher<ActionConfig> implement
|
||||
.methodName(methodName)
|
||||
.addParams(params)
|
||||
.addResultConfigs(results)
|
||||
.setStrictMethodInvocation(orig.isStrictMethodInvocation())
|
||||
.addAllowedMethod(orig.getAllowedMethods())
|
||||
.addInterceptors(orig.getInterceptors())
|
||||
.addExceptionMappings(exs)
|
||||
|
||||
@@ -36,6 +36,7 @@ import ognl.PropertyAccessor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -370,11 +371,20 @@ public class DefaultConfiguration implements Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
String methodRegex = container.getInstance(String.class, StrutsConstants.STRUTS_SMI_METHOD_REGEX);
|
||||
if (methodRegex == null) {
|
||||
methodRegex = ActionConfig.DEFAULT_METHOD_REGEX;
|
||||
}
|
||||
|
||||
LOG.debug("Using pattern [{}] to match allowed methods when SMI is disabled!", methodRegex);
|
||||
|
||||
return new ActionConfig.Builder(baseConfig)
|
||||
.addParams(params)
|
||||
.addResultConfigs(results)
|
||||
.defaultClassName(packageContext.getDefaultClassRef()) // fill in default if non class has been provided
|
||||
.interceptors(interceptors)
|
||||
.setStrictMethodInvocation(packageContext.isStrictMethodInvocation())
|
||||
.setDefaultMethodRegex(methodRegex)
|
||||
.addExceptionMappings(packageContext.getAllExceptionMappingConfigs())
|
||||
.build();
|
||||
}
|
||||
|
||||
+5
-2
@@ -464,6 +464,7 @@ public class XmlConfigurationProvider implements ConfigurationProvider {
|
||||
.addInterceptors(interceptorList)
|
||||
.addExceptionMappings(exceptionMappings)
|
||||
.addParams(XmlHelper.getParams(actionElement))
|
||||
.setStrictMethodInvocation(packageContext.isStrictMethodInvocation())
|
||||
.addAllowedMethod(allowedMethods)
|
||||
.location(location)
|
||||
.build();
|
||||
@@ -872,11 +873,13 @@ public class XmlConfigurationProvider implements ConfigurationProvider {
|
||||
// user enabled Strict DMI but didn't defined action specific 'allowed-methods' so we use 'global-allowed-methods' only
|
||||
allowedMethods = new HashSet<>(packageContext.getGlobalAllowedMethods());
|
||||
} else {
|
||||
// Strict DMI is disabled to any method can be called
|
||||
// Strict DMI is disabled so any method can be called
|
||||
allowedMethods = new HashSet<>();
|
||||
allowedMethods.add(ActionConfig.REGEX_WILDCARD);
|
||||
allowedMethods.add(ActionConfig.WILDCARD);
|
||||
}
|
||||
|
||||
LOG.debug("Collected allowed methods: {}", allowedMethods);
|
||||
|
||||
return Collections.unmodifiableSet(allowedMethods);
|
||||
}
|
||||
|
||||
|
||||
@@ -287,7 +287,7 @@ public class OgnlUtil {
|
||||
compileAndExecute(name, context, new OgnlTask<Void>() {
|
||||
public Void execute(Object tree) throws OgnlException {
|
||||
if (isEvalExpression(tree, context)) {
|
||||
throw new OgnlException("Eval expression cannot be used as parameter name");
|
||||
throw new OgnlException("Eval expression/chained expressions cannot be used as parameter name");
|
||||
}
|
||||
Ognl.setValue(tree, context, root, value);
|
||||
return null;
|
||||
@@ -303,7 +303,7 @@ public class OgnlUtil {
|
||||
if (context!=null && context instanceof OgnlContext) {
|
||||
ognlContext = (OgnlContext) context;
|
||||
}
|
||||
return node.isEvalChain(ognlContext);
|
||||
return node.isEvalChain(ognlContext) || node.isSequence(ognlContext);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -360,7 +360,7 @@ public class OgnlUtil {
|
||||
|
||||
private void checkEnableEvalExpression(Object tree, Map<String, Object> context) throws OgnlException {
|
||||
if (!enableEvalExpression && isEvalExpression(tree, context)) {
|
||||
throw new OgnlException("Eval expressions has been disabled!");
|
||||
throw new OgnlException("Eval expressions/chained expressions have been disabled!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ package com.opensymphony.xwork2.validator.validators;
|
||||
* The regular expression used to validate that the string is an email address is:
|
||||
*
|
||||
* <pre>
|
||||
* \\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx)$\\b
|
||||
* \\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx|tech|cat)$\\b
|
||||
* </pre>
|
||||
*
|
||||
* You can also specify expression, caseSensitive and trim params as a OGNL expression, see the example below.
|
||||
@@ -80,7 +80,7 @@ public class EmailValidator extends RegexFieldValidator {
|
||||
|
||||
// see XW-371
|
||||
public static final String EMAIL_ADDRESS_PATTERN =
|
||||
"\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx|tech)$\\b";
|
||||
"\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx|tech|cat)$\\b";
|
||||
|
||||
public EmailValidator() {
|
||||
setRegex(EMAIL_ADDRESS_PATTERN);
|
||||
|
||||
@@ -298,4 +298,5 @@ public final class StrutsConstants {
|
||||
|
||||
public static final String STRUTS_CONTENT_TYPE_MATCHER = "struts.contentTypeMatcher";
|
||||
|
||||
public static final String STRUTS_SMI_METHOD_REGEX = "struts.strictMethodInvocation.methodRegex";
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.RequestUtils;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.util.PrefixTrie;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -136,7 +137,7 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
put(METHOD_PREFIX, new ParameterAction() {
|
||||
public void execute(String key, ActionMapping mapping) {
|
||||
if (allowDynamicMethodCalls) {
|
||||
mapping.setMethod(key.substring(METHOD_PREFIX.length()));
|
||||
mapping.setMethod(cleanupActionName(key.substring(METHOD_PREFIX.length())));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -148,7 +149,7 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
if (allowDynamicMethodCalls) {
|
||||
int bang = name.indexOf('!');
|
||||
if (bang != -1) {
|
||||
String method = name.substring(bang + 1);
|
||||
String method = cleanupActionName(name.substring(bang + 1));
|
||||
mapping.setMethod(method);
|
||||
name = name.substring(0, bang);
|
||||
}
|
||||
@@ -385,14 +386,7 @@ public class DefaultActionMapper implements ActionMapper {
|
||||
if (allowedActionNames.matcher(rawActionName).matches()) {
|
||||
return rawActionName;
|
||||
} else {
|
||||
LOG.warn("Action [{}] does not match allowed action names pattern [{}], cleaning it up!",
|
||||
rawActionName, allowedActionNames);
|
||||
String cleanActionName = rawActionName;
|
||||
for (String chunk : allowedActionNames.split(rawActionName)) {
|
||||
cleanActionName = cleanActionName.replace(chunk, "");
|
||||
}
|
||||
LOG.debug("Cleaned action name [{}]", cleanActionName);
|
||||
return cleanActionName;
|
||||
throw new StrutsException("Action [" + rawActionName + "] does not match allowed action names pattern [" + allowedActionNames + "]!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -73,8 +73,7 @@ class MessageStorePreResultListener implements PreResultListener {
|
||||
try {
|
||||
ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(resultCode);
|
||||
if (resultConfig != null) {
|
||||
isRedirect = ServletRedirectResult.class.getName().equals(resultConfig.getClassName())
|
||||
|| ServletActionRedirectResult.class.getName().equals(resultConfig.getClassName());
|
||||
isRedirect = ServletRedirectResult.class.isAssignableFrom(Class.forName(resultConfig.getClassName()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Cannot read result!", e);
|
||||
|
||||
@@ -404,12 +404,7 @@ public class XSLTResult implements Result {
|
||||
ServletActionContext.getServletContext());
|
||||
}
|
||||
|
||||
protected Templates getTemplates(String path) throws TransformerException, IOException {
|
||||
String pathFromRequest = ServletActionContext.getRequest().getParameter("xslt.location");
|
||||
|
||||
if (pathFromRequest != null)
|
||||
path = pathFromRequest;
|
||||
|
||||
protected Templates getTemplates(final String path) throws TransformerException, IOException {
|
||||
if (path == null)
|
||||
throw new TransformerException("Stylesheet path is null");
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
ognl.OgnlContext,
|
||||
ognl.ClassResolver,
|
||||
ognl.TypeConverter,
|
||||
ognl.MemberAccess,
|
||||
ognl.DefaultMemberAccess,
|
||||
com.opensymphony.xwork2.ognl.SecurityMemberAccess,
|
||||
com.opensymphony.xwork2.ActionContext" />
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
</#if>
|
||||
<#else>
|
||||
<input type="submit"<#rt/>
|
||||
<#if parameters.nameValue?has_content>
|
||||
value="<@s.property value="parameters.nameValue"/>"<#rt/>
|
||||
</#if>
|
||||
</#if>
|
||||
<#if parameters.id?has_content>
|
||||
id="${parameters.id?html}"<#rt/>
|
||||
@@ -68,9 +71,6 @@
|
||||
<#if parameters.name?has_content>
|
||||
name="${parameters.name?html}"<#rt/>
|
||||
</#if>
|
||||
<#if parameters.nameValue?has_content>
|
||||
value="<@s.property value="parameters.nameValue"/>"<#rt/>
|
||||
</#if>
|
||||
<#if parameters.disabled!false>
|
||||
disabled="disabled"<#rt/>
|
||||
</#if>
|
||||
|
||||
@@ -62,11 +62,11 @@
|
||||
class="label"<#t/>
|
||||
</#if>
|
||||
><#t/>
|
||||
<#if parameters.required!false && parameters.requiredPosition!"right" != 'right'>
|
||||
<#if (parameters.required!false) && ((parameters.requiredPosition!"right") != 'right')>
|
||||
<span class="required">*</span><#t/>
|
||||
</#if>
|
||||
${parameters.label?html}<#t/>
|
||||
<#if parameters.required!false && parameters.requiredPosition!"right" == 'right'>
|
||||
<#if (parameters.required!false) && ((parameters.requiredPosition!"right") == 'right')>
|
||||
<span class="required">*</span><#t/>
|
||||
</#if>
|
||||
${parameters.labelseparator!":"?html}<#t/>
|
||||
|
||||
@@ -14,7 +14,7 @@ public class AllowedMethodsTest extends TestCase {
|
||||
literals.add(method);
|
||||
|
||||
// when
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(literals);
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(false, literals, ActionConfig.DEFAULT_METHOD_REGEX);
|
||||
|
||||
// then
|
||||
assertEquals(1, allowedMethods.list().size());
|
||||
@@ -22,14 +22,14 @@ public class AllowedMethodsTest extends TestCase {
|
||||
assertFalse(allowedMethods.isAllowed("someOtherMethod"));
|
||||
}
|
||||
|
||||
public void testWidlcardMethods() throws Exception {
|
||||
public void testWildcardMethodsWithNoSMI() throws Exception {
|
||||
// given
|
||||
String method = "my{1}";
|
||||
Set<String> literals = new HashSet<>();
|
||||
literals.add(method);
|
||||
|
||||
// when
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(literals);
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(false, literals, ActionConfig.DEFAULT_METHOD_REGEX);
|
||||
|
||||
// then
|
||||
assertEquals(1, allowedMethods.list().size());
|
||||
@@ -37,18 +37,50 @@ public class AllowedMethodsTest extends TestCase {
|
||||
assertFalse(allowedMethods.isAllowed("someOtherMethod"));
|
||||
}
|
||||
|
||||
public void testWidlcardWithStarMethods() throws Exception {
|
||||
public void testWildcardMethodsWithSMI() throws Exception {
|
||||
// given
|
||||
Set<String> literals = new HashSet<>();
|
||||
literals.add("my{1}");
|
||||
literals.add("myMethod");
|
||||
|
||||
// when
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(true, literals, ActionConfig.DEFAULT_METHOD_REGEX);
|
||||
|
||||
// then
|
||||
assertEquals(1, allowedMethods.list().size());
|
||||
assertFalse(allowedMethods.isAllowed("my{1}"));
|
||||
assertTrue(allowedMethods.isAllowed("myMethod"));
|
||||
assertFalse(allowedMethods.isAllowed("someOtherMethod"));
|
||||
}
|
||||
|
||||
public void testWildcardWithStarMethodsWithNoSMI() throws Exception {
|
||||
// given
|
||||
String method = "cancel*Action*";
|
||||
Set<String> literals = new HashSet<>();
|
||||
literals.add(method);
|
||||
|
||||
// when
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(false, literals, ActionConfig.DEFAULT_METHOD_REGEX);
|
||||
|
||||
// then
|
||||
assertEquals(1, allowedMethods.list().size());
|
||||
assertTrue(allowedMethods.isAllowed("cancelAction"));
|
||||
assertFalse(allowedMethods.isAllowed("startEvent"));
|
||||
}
|
||||
|
||||
public void testWildcardWithStarMethodsWithSMI() throws Exception {
|
||||
// given
|
||||
String method = "cancel*";
|
||||
Set<String> literals = new HashSet<>();
|
||||
literals.add(method);
|
||||
|
||||
// when
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(literals);
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(true, literals, ActionConfig.DEFAULT_METHOD_REGEX);
|
||||
|
||||
// then
|
||||
assertEquals(1, allowedMethods.list().size());
|
||||
assertTrue(allowedMethods.isAllowed("cancelAction"));
|
||||
assertTrue(allowedMethods.isAllowed("cancel*"));
|
||||
assertFalse(allowedMethods.isAllowed("cancelAction"));
|
||||
assertFalse(allowedMethods.isAllowed("startEvent"));
|
||||
}
|
||||
|
||||
@@ -59,7 +91,7 @@ public class AllowedMethodsTest extends TestCase {
|
||||
literals.add(method);
|
||||
|
||||
// when
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(literals);
|
||||
AllowedMethods allowedMethods = AllowedMethods.build(true, literals, ActionConfig.DEFAULT_METHOD_REGEX);
|
||||
|
||||
// then
|
||||
assertEquals(1, allowedMethods.list().size());
|
||||
|
||||
@@ -156,18 +156,21 @@ public class ActionConfigMatcherTest extends XWorkTestCase {
|
||||
.build())
|
||||
.addInterceptor(new InterceptorMapping(null, null))
|
||||
.addResultConfig(new ResultConfig.Builder("success{1}", "foo.{2}").addParams(params).build())
|
||||
.setStrictMethodInvocation(false)
|
||||
.build();
|
||||
map.put("foo/*/*", config);
|
||||
|
||||
config = new ActionConfig.Builder("package-{1}", "bar/*/**", "bar")
|
||||
.methodName("do{1}_{1}")
|
||||
.addParam("first", "{2}")
|
||||
.setStrictMethodInvocation(false)
|
||||
.build();
|
||||
|
||||
map.put("bar/*/**", config);
|
||||
|
||||
config = new ActionConfig.Builder("package", "eventAdd!*", "bar")
|
||||
.methodName("{1}")
|
||||
.setStrictMethodInvocation(false)
|
||||
.build();
|
||||
|
||||
map.put("addEvent!*", config);
|
||||
|
||||
@@ -744,6 +744,21 @@ public class OgnlUtilTest extends XWorkTestCase {
|
||||
assertEquals(expected.getMessage(), "Method \"getRuntime\" failed for object class java.lang.Runtime");
|
||||
}
|
||||
|
||||
public void testBlockSequenceOfExpressions() throws Exception {
|
||||
Foo foo = new Foo();
|
||||
|
||||
Exception expected = null;
|
||||
try {
|
||||
ognlUtil.setValue("#booScope=@myclass@DEFAULT_SCOPE,#bootScope.init()", ognlUtil.createDefaultContext(foo), foo, true);
|
||||
fail();
|
||||
} catch (OgnlException e) {
|
||||
expected = e;
|
||||
}
|
||||
assertNotNull(expected);
|
||||
assertSame(OgnlException.class, expected.getClass());
|
||||
assertEquals(expected.getMessage(), "Eval expressions/chained expressions have been disabled!");
|
||||
}
|
||||
|
||||
public static class Email {
|
||||
String address;
|
||||
|
||||
|
||||
-1
@@ -91,7 +91,6 @@ public class DefaultExcludedPatternsCheckerTest extends XWorkTestCase {
|
||||
}
|
||||
|
||||
for (String param : params) {
|
||||
System.out.println(param);
|
||||
// when
|
||||
ExcludedPatternsChecker.IsExcluded actual = checker.isExcluded(param);
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ public class EmailValidatorTest extends XWorkTestCase {
|
||||
assertTrue(verifyEmailValidity("tmj'ee@yahoo.com"));
|
||||
assertTrue(verifyEmailValidity("ferda+mravenec@yahoo.com"));
|
||||
assertTrue(verifyEmailValidity("Ferda+Mravenec@yaHoo.CoM"));
|
||||
assertTrue(verifyEmailValidity("user@domainname.tech"));
|
||||
assertTrue(verifyEmailValidity("Ferda+Mravenec@yaHoo.cat"));
|
||||
|
||||
assertFalse(verifyEmailValidity("tm_jee#marry@yahoo.co.uk"));
|
||||
assertFalse(verifyEmailValidity("tm_jee@ yahoo.co.uk"));
|
||||
|
||||
+27
-3
@@ -30,6 +30,7 @@ import com.opensymphony.xwork2.config.ConfigurationManager;
|
||||
import com.opensymphony.xwork2.config.entities.PackageConfig;
|
||||
import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
import org.apache.struts2.result.StrutsResultSupport;
|
||||
import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest;
|
||||
@@ -844,14 +845,37 @@ public class DefaultActionMapperTest extends StrutsInternalTestCase {
|
||||
String actionName = "action";
|
||||
assertEquals(actionName, mapper.cleanupActionName(actionName));
|
||||
|
||||
Throwable expected = null;
|
||||
|
||||
actionName = "${action}";
|
||||
assertEquals("action", mapper.cleanupActionName(actionName));
|
||||
try {
|
||||
mapper.cleanupActionName(actionName);
|
||||
fail();
|
||||
} catch (Throwable t) {
|
||||
expected = t;
|
||||
}
|
||||
assertTrue(expected instanceof StrutsException);
|
||||
assertEquals("Action [${action}] does not match allowed action names pattern [[a-zA-Z0-9._!/\\-]*]!", expected.getMessage());
|
||||
|
||||
actionName = "${${%{action}}}";
|
||||
assertEquals("action", mapper.cleanupActionName(actionName));
|
||||
try {
|
||||
mapper.cleanupActionName(actionName);
|
||||
fail();
|
||||
} catch (Throwable t) {
|
||||
expected = t;
|
||||
}
|
||||
assertTrue(expected instanceof StrutsException);
|
||||
assertEquals("Action [${${%{action}}}] does not match allowed action names pattern [[a-zA-Z0-9._!/\\-]*]!", expected.getMessage());
|
||||
|
||||
actionName = "${#foo='action',#foo}";
|
||||
assertEquals("fooactionfoo", mapper.cleanupActionName(actionName));
|
||||
try {
|
||||
mapper.cleanupActionName(actionName);
|
||||
fail();
|
||||
} catch (Throwable t) {
|
||||
expected = t;
|
||||
}
|
||||
assertTrue(expected instanceof StrutsException);
|
||||
assertEquals("Action [${#foo='action',#foo}] does not match allowed action names pattern [[a-zA-Z0-9._!/\\-]*]!", expected.getMessage());
|
||||
|
||||
actionName = "test-action";
|
||||
assertEquals("test-action", mapper.cleanupActionName(actionName));
|
||||
|
||||
@@ -232,7 +232,7 @@ public class SubmitTest extends AbstractUITagTest {
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
assertEquals("<input type=\"submit\" id=\"myname\" name=\"myname\" value=\"Submit\"/>", writer.toString().trim());
|
||||
assertEquals("<input type=\"submit\" value=\"Submit\" id=\"myname\" name=\"myname\"/>", writer.toString().trim());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -239,6 +239,62 @@ public class TextfieldTest extends AbstractUITagTest {
|
||||
verify(TextFieldTag.class.getResource("Textfield-9.txt"));
|
||||
}
|
||||
|
||||
public void testRequiredLabelPositionDefault() throws Exception {
|
||||
TestAction testAction = (TestAction) action;
|
||||
testAction.setFoo("bar");
|
||||
|
||||
TextFieldTag tag = new TextFieldTag();
|
||||
tag.setPageContext(pageContext);
|
||||
tag.setId("myId");
|
||||
tag.setLabel("mylabel");
|
||||
tag.setName("foo");
|
||||
tag.setValue("bar");
|
||||
tag.setRequiredLabel("true");
|
||||
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
verify(TextFieldTag.class.getResource("Textfield-12.txt"));
|
||||
}
|
||||
|
||||
public void testRequiredLabelPositionRight() throws Exception {
|
||||
TestAction testAction = (TestAction) action;
|
||||
testAction.setFoo("bar");
|
||||
|
||||
TextFieldTag tag = new TextFieldTag();
|
||||
tag.setPageContext(pageContext);
|
||||
tag.setId("myId");
|
||||
tag.setLabel("mylabel");
|
||||
tag.setName("foo");
|
||||
tag.setValue("bar");
|
||||
tag.setRequiredLabel("true");
|
||||
tag.setRequiredPosition("right");
|
||||
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
verify(TextFieldTag.class.getResource("Textfield-12.txt"));
|
||||
}
|
||||
|
||||
public void testRequiredLabelPositionLeft() throws Exception {
|
||||
TestAction testAction = (TestAction) action;
|
||||
testAction.setFoo("bar");
|
||||
|
||||
TextFieldTag tag = new TextFieldTag();
|
||||
tag.setPageContext(pageContext);
|
||||
tag.setId("myId");
|
||||
tag.setLabel("mylabel");
|
||||
tag.setName("foo");
|
||||
tag.setValue("bar");
|
||||
tag.setRequiredLabel("true");
|
||||
tag.setRequiredPosition("left");
|
||||
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
verify(TextFieldTag.class.getResource("Textfield-13.txt"));
|
||||
}
|
||||
|
||||
public void testErrorPositionBottomCssXhtmlTheme() throws Exception {
|
||||
TestAction testAction = (TestAction) action;
|
||||
testAction.setFoo("bar");
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<tr>
|
||||
<td colspan="2"><div class="formButton"><input type="submit" id="myname" name="myname" value="bar" disabled="disabled" tabindex="1"/></div></td>
|
||||
<td colspan="2"><div class="formButton"><input type="submit" value="bar" id="myname" name="myname" disabled="disabled" tabindex="1"/></div></td>
|
||||
</tr>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<tr>
|
||||
<td colspan="2"><div class="formButton"><input type="submit" id="myname" name="myname" value="Submit" title="mytitle"/></div></td>
|
||||
<td colspan="2"><div class="formButton"><input type="submit" value="Submit" id="myname" name="myname" title="mytitle"/></div></td>
|
||||
</tr>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<tr>
|
||||
<td colspan="2"><div class="formButton"><input type="image" alt="bar" id="myname" name="myname" value="bar" disabled="disabled"/></div></td>
|
||||
<td colspan="2"><div class="formButton"><input type="image" alt="bar" id="myname" name="myname" disabled="disabled"/></div></td>
|
||||
</tr>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<tr>
|
||||
<td colspan="2"><div class="formButton"><input type="image" alt="mylabel" src="some.gif" id="myname" name="myname" value="bar"/></div></td>
|
||||
<td colspan="2"><div class="formButton"><input type="image" alt="mylabel" src="some.gif" id="myname" name="myname"/></div></td>
|
||||
</tr>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<tr>
|
||||
<td class="tdLabel">
|
||||
<label for="myId" class="label">
|
||||
mylabel
|
||||
<span class="required">*</span>:
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="foo" value="bar" id="myId"/>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,11 @@
|
||||
<tr>
|
||||
<td class="tdLabel">
|
||||
<label for="myId" class="label">
|
||||
<span class="required">*</span>
|
||||
mylabel:
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="foo" value="bar" id="myId"/>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-cdi-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-config-browser-plugin</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-convention-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -930,7 +930,7 @@ public class PackageBasedActionConfigBuilder implements ActionConfigBuilder {
|
||||
actionConfig.addAllowedMethod(allowedMethods);
|
||||
actionConfig.addAllowedMethod(pkgCfg.getGlobalAllowedMethods());
|
||||
} else {
|
||||
actionConfig.addAllowedMethod(ActionConfig.REGEX_WILDCARD);
|
||||
actionConfig.addAllowedMethod(ActionConfig.WILDCARD);
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-dwr-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-embeddedjsp-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-gxp-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jasperreports-plugin</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-java8-support-plugin</artifactId>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-javatemplates-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jfreechart-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-json-plugin</artifactId>
|
||||
|
||||
@@ -7,7 +7,9 @@ import org.junit.Test;
|
||||
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@@ -90,6 +92,41 @@ public class JSONWriterTest extends StrutsTestCase{
|
||||
TestUtils.assertEquals(JSONWriter.class.getResource("jsonwriter-write-bean-02.txt"), json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteBeanWithList() throws Exception {
|
||||
BeanWithList bean1 = new BeanWithList();
|
||||
bean1.setStringField("str");
|
||||
bean1.setBooleanField(true);
|
||||
bean1.setCharField('s');
|
||||
bean1.setDoubleField(10.1);
|
||||
bean1.setFloatField(1.5f);
|
||||
bean1.setIntField(10);
|
||||
bean1.setLongField(100);
|
||||
bean1.setEnumField(AnEnum.ValueA);
|
||||
bean1.setEnumBean(AnEnumBean.Two);
|
||||
List<String> errors = new ArrayList<String>();
|
||||
errors.add("Field is required");
|
||||
bean1.setErrors(errors);
|
||||
|
||||
JSONWriter jsonWriter = new JSONWriter();
|
||||
jsonWriter.setEnumAsBean(false);
|
||||
jsonWriter.setIgnoreHierarchy(false);
|
||||
String json = jsonWriter.write(bean1);
|
||||
TestUtils.assertEquals(JSONWriter.class.getResource("jsonwriter-write-bean-04.txt"), json);
|
||||
}
|
||||
|
||||
private class BeanWithList extends Bean {
|
||||
private List<String> errors;
|
||||
|
||||
public List<String> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public void setErrors(List<String> errors) {
|
||||
this.errors = errors;
|
||||
}
|
||||
}
|
||||
|
||||
private class AnnotatedBean extends Bean{
|
||||
private URL url;
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"bigDecimal":null,
|
||||
"bigInteger":null,
|
||||
"booleanField":true,
|
||||
"byteField":0,
|
||||
"charField":"s",
|
||||
"doubleField":10.1,
|
||||
"enumBean":"Two",
|
||||
"enumField":"ValueA",
|
||||
"errors":["Field is required"],
|
||||
"floatField":1.5,
|
||||
"intField":10,
|
||||
"longField":100,
|
||||
"objectField":null,
|
||||
"stringField":"str"
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-junit-plugin</artifactId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-oval-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-pell-multipart-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plexus-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-tiles-plugin</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-plugin</artifactId>
|
||||
|
||||
@@ -320,7 +320,7 @@ public class RestActionMapper extends DefaultActionMapper {
|
||||
|
||||
mapping.setName(actionName);
|
||||
if (allowDynamicMethodCalls) {
|
||||
mapping.setMethod(actionMethod);
|
||||
mapping.setMethod(cleanupActionName(actionMethod));
|
||||
} else {
|
||||
mapping.setMethod(null);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-sitegraph-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-sitemesh-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-spring-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-testng-plugin</artifactId>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-tiles-plugin</artifactId>
|
||||
|
||||
@@ -52,4 +52,8 @@ public class StrutsApplicationResource extends PostfixedApplicationResource {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Resource " + getLocalePath() + " at " + url.toString();
|
||||
}
|
||||
}
|
||||
|
||||
+14
-9
@@ -19,6 +19,7 @@
|
||||
|
||||
package org.apache.struts2.tiles;
|
||||
|
||||
import com.opensymphony.xwork2.util.TextParseUtil;
|
||||
import ognl.OgnlException;
|
||||
import ognl.OgnlRuntime;
|
||||
import ognl.PropertyAccessor;
|
||||
@@ -71,6 +72,7 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Dedicated Struts factory to build Tiles container with support for:
|
||||
@@ -176,25 +178,28 @@ public class StrutsTilesContainerFactory extends BasicTilesContainerFactory {
|
||||
|
||||
@Override
|
||||
protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
|
||||
Collection<ApplicationResource> resources = applicationContext.getResources(getTilesDefinitionPattern(applicationContext.getInitParams()));
|
||||
Collection<ApplicationResource> resources = new ArrayList<>();
|
||||
|
||||
Set<String> definitions = getTilesDefinitions(applicationContext.getInitParams());
|
||||
for (String definition : definitions) {
|
||||
resources.addAll(applicationContext.getResources(definition));
|
||||
}
|
||||
|
||||
List<ApplicationResource> filteredResources = new ArrayList<>();
|
||||
if (resources != null) {
|
||||
for (ApplicationResource resource : resources) {
|
||||
if (Locale.ROOT.equals(resource.getLocale())) {
|
||||
filteredResources.add(resource);
|
||||
}
|
||||
for (ApplicationResource resource : resources) {
|
||||
if (Locale.ROOT.equals(resource.getLocale())) {
|
||||
filteredResources.add(resource);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredResources;
|
||||
}
|
||||
|
||||
protected String getTilesDefinitionPattern(Map<String, String> params) {
|
||||
protected Set<String> getTilesDefinitions(Map<String, String> params) {
|
||||
if (params.containsKey(DefinitionsFactory.DEFINITIONS_CONFIG)) {
|
||||
return params.get(DefinitionsFactory.DEFINITIONS_CONFIG);
|
||||
return TextParseUtil.commaDelimitedStringToSet(params.get(DefinitionsFactory.DEFINITIONS_CONFIG));
|
||||
}
|
||||
return TILES_DEFAULT_PATTERN;
|
||||
return TextParseUtil.commaDelimitedStringToSet(TILES_DEFAULT_PATTERN);
|
||||
}
|
||||
|
||||
protected ELAttributeEvaluator createELEvaluator(ApplicationContext applicationContext) {
|
||||
|
||||
+6
-2
@@ -54,8 +54,12 @@ public class StrutsWildcardServletApplicationContext extends ServletApplicationC
|
||||
|
||||
for (Object path : context.getResourcePaths("/")) {
|
||||
try {
|
||||
URL url = new File(context.getRealPath(String.valueOf(path))).toURI().toURL();
|
||||
urls.add(url);
|
||||
String realPath = context.getRealPath(String.valueOf(path));
|
||||
|
||||
if (realPath != null) {
|
||||
URL url = new File(realPath).toURI().toURL();
|
||||
urls.add(url);
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
throw new ConfigurationException(e);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
<version>2.5.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Struts 2</name>
|
||||
<url>http://struts.apache.org/</url>
|
||||
@@ -85,7 +85,7 @@
|
||||
<properties>
|
||||
<currentVersion>${project.version}</currentVersion>
|
||||
<struts2.springPlatformVersion>4.1.6.RELEASE</struts2.springPlatformVersion>
|
||||
<ognl.version>3.1.2</ognl.version>
|
||||
<ognl.version>3.1.4</ognl.version>
|
||||
<asm.version>3.3</asm.version>
|
||||
<asm5.version>5.0.2</asm5.version>
|
||||
<tiles.version>3.0.5</tiles.version>
|
||||
@@ -706,7 +706,7 @@
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<version>3.2.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
|
||||
Reference in New Issue
Block a user