You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by ku...@apache.org on 2024/11/01 08:20:09 UTC
(struts) branch WW-5468-modeldriven-strutsparameter-fix created (now 7cdcd84b8)
This is an automated email from the ASF dual-hosted git repository.
kusal pushed a change to branch WW-5468-modeldriven-strutsparameter-fix
in repository https://gitbox.apache.org/repos/asf/struts.git
at 7cdcd84b8 Merge pull request #1072 from apache/fix/WW-5468-modeldriven-2
This branch includes the following new commits:
new 7cdcd84b8 Merge pull request #1072 from apache/fix/WW-5468-modeldriven-2
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(struts) 01/01: Merge pull request #1072 from apache/fix/WW-5468-modeldriven-2
Posted by ku...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kusal pushed a commit to branch WW-5468-modeldriven-strutsparameter-fix
in repository https://gitbox.apache.org/repos/asf/struts.git
commit 7cdcd84b838eaea5a3f10af5ea64e6856dc3c27d
Author: Kusal Kithul-Godage <gi...@kusal.io>
AuthorDate: Mon Oct 14 18:59:11 2024 +1100
Merge pull request #1072 from apache/fix/WW-5468-modeldriven-2
WW-5468 Exempt ModelDriven Actions from @StrutsParameter requirement
---
.../showcase/modelDriven/ModelDrivenAction.java | 2 +-
.../main/java/org/apache/struts2/ModelDriven.java | 6 +
.../parameter/ParametersInterceptor.java | 45 ++-
.../com/opensymphony/xwork2/ModelDrivenAction.java | 3 +-
.../xwork2/ModelDrivenAnnotationAction.java | 3 +-
.../interceptor/ModelDrivenInterceptorTest.java | 2 +-
.../xwork2/test/ModelDrivenAction2.java | 4 +-
.../xwork2/test/ModelDrivenAnnotationAction2.java | 4 +-
.../xwork2/test/subtest/NullModelDrivenAction.java | 3 +-
.../validator/VisitorValidatorModelAction.java | 5 +-
.../parameter/StrutsParameterAnnotationTest.java | 36 +-
.../apache/struts2/result/StreamResultTest.java | 6 +-
.../beanvalidation/actions/ModelDrivenAction.java | 2 -
.../actions/ValidateGroupAction.java | 2 -
.../apache/struts2/junit/StrutsRestTestCase.java | 3 +-
.../struts2/rest/RestActionInvocationTest.java | 400 ++++++++++-----------
.../com/opensymphony/xwork2/ModelDrivenAction.java | 3 +-
17 files changed, 281 insertions(+), 248 deletions(-)
diff --git a/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/ModelDrivenAction.java b/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/ModelDrivenAction.java
index 60692b0e6..0fae6c481 100644
--- a/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/ModelDrivenAction.java
+++ b/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/ModelDrivenAction.java
@@ -42,7 +42,7 @@ public class ModelDrivenAction extends ActionSupport implements ModelDriven {
}
@Override
- public Object getModel() {
+ public Gangster getModel() {
return new Gangster();
}
}
diff --git a/core/src/main/java/org/apache/struts2/ModelDriven.java b/core/src/main/java/org/apache/struts2/ModelDriven.java
index 0704109f1..993a6f5eb 100644
--- a/core/src/main/java/org/apache/struts2/ModelDriven.java
+++ b/core/src/main/java/org/apache/struts2/ModelDriven.java
@@ -18,6 +18,8 @@
*/
package org.apache.struts2;
+import org.apache.struts2.interceptor.parameter.StrutsParameter;
+
/**
* ModelDriven Actions provide a model object to be pushed onto the ValueStack
* in addition to the Action itself, allowing a FormBean type approach like Struts.
@@ -28,9 +30,13 @@ public interface ModelDriven<T> {
/**
* Gets the model to be pushed onto the ValueStack instead of the Action itself.
+ * <p>
+ * Please be aware that all setters and getters of every depth on the object returned by this method are available
+ * for user parameter injection!
*
* @return the model
*/
+ @StrutsParameter(depth = Integer.MAX_VALUE)
T getModel();
}
diff --git a/core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java
index 239bc6d6c..9f6ff8f53 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.apache.struts2.ModelDriven;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.action.NoParameters;
import org.apache.struts2.action.ParameterNameAware;
@@ -348,7 +349,15 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
}
long paramDepth = name.codePoints().mapToObj(c -> (char) c).filter(NESTING_CHARS::contains).count();
+
+ if (action instanceof ModelDriven<?> && !ActionContext.getContext().getValueStack().peek().equals(action)) {
+ LOG.debug("Model driven Action detected, exempting from @StrutsParameter annotation requirement and OGNL allowlisting model type");
+ // (Exempted by annotation on com.opensymphony.xwork2.ModelDriven#getModel)
+ return hasValidAnnotatedMember("model", action, paramDepth + 1);
+ }
+
if (requireAnnotationsTransitionMode && paramDepth == 0) {
+ LOG.debug("Annotation transition mode enabled, exempting non-nested parameter [{}] from @StrutsParameter annotation requirement", name);
return true;
}
@@ -365,6 +374,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
* save computation by checking this last.
*/
protected boolean hasValidAnnotatedMember(String rootProperty, Object action, long paramDepth) {
+ LOG.debug("Checking Action [{}] for a matching, correctly annotated member for property [{}]",
+ action.getClass().getSimpleName(), rootProperty);
BeanInfo beanInfo = getBeanInfo(action);
if (beanInfo == null) {
return hasValidAnnotatedField(action, rootProperty, paramDepth);
@@ -399,7 +410,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
}
if (getPermittedInjectionDepth(relevantMethod) < paramDepth) {
String logMessage = format(
- "Parameter injection for method [%s] on action [%s] rejected. Ensure it is annotated with @StrutsParameter with an appropriate 'depth'.",
+ "Parameter injection for method [%s] on Action [%s] rejected. Ensure it is annotated with @StrutsParameter with an appropriate 'depth'.",
relevantMethod.getName(),
relevantMethod.getDeclaringClass().getName());
if (devMode) {
@@ -409,8 +420,10 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
}
return false;
}
+ LOG.debug("Success: Matching annotated method [{}] found for property [{}] of depth [{}] on Action [{}]",
+ relevantMethod.getName(), propDesc.getName(), paramDepth, action.getClass().getSimpleName());
if (paramDepth >= 1) {
- allowlistClass(relevantMethod.getReturnType());
+ allowlistClass(propDesc.getPropertyType());
}
if (paramDepth >= 2) {
allowlistReturnTypeIfParameterized(relevantMethod);
@@ -447,19 +460,23 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
}
protected boolean hasValidAnnotatedField(Object action, String fieldName, long paramDepth) {
+ LOG.debug("No matching annotated method found for property [{}] of depth [{}] on Action [{}], now also checking for public field",
+ fieldName, paramDepth, action.getClass().getSimpleName());
Field field;
try {
field = action.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
+ LOG.debug("Matching field for property [{}] not found on Action [{}]", fieldName, action.getClass().getSimpleName());
return false;
}
if (!Modifier.isPublic(field.getModifiers())) {
+ LOG.debug("Matching field [{}] is not public on Action [{}]", field.getName(), action.getClass().getSimpleName());
return false;
}
if (getPermittedInjectionDepth(field) < paramDepth) {
String logMessage = format(
- "Parameter injection for field [%s] on action [%s] rejected. Ensure it is annotated with @StrutsParameter with an appropriate 'depth'.",
- fieldName,
+ "Parameter injection for field [%s] on Action [%s] rejected. Ensure it is annotated with @StrutsParameter with an appropriate 'depth'.",
+ field.getName(),
action.getClass().getName());
if (devMode) {
notifyDeveloperOfError(LOG, action, logMessage);
@@ -468,6 +485,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
}
return false;
}
+ LOG.debug("Success: Matching annotated public field [{}] found for property of depth [{}] on Action [{}]",
+ field.getName(), paramDepth, action.getClass().getSimpleName());
if (paramDepth >= 1) {
allowlistClass(field.getType());
}
@@ -629,7 +648,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
if (!result.isAccepted()) {
if (devMode) {
LOG.warn("Parameter [{}] didn't match accepted pattern [{}]! See Accepted / Excluded patterns at\n" +
- "https://struts.apache.org/security/#accepted--excluded-patterns",
+ "https://struts.apache.org/security/#accepted--excluded-patterns",
paramName, result.getAcceptedPattern());
} else {
LOG.debug("Parameter [{}] didn't match accepted pattern [{}]!", paramName, result.getAcceptedPattern());
@@ -644,8 +663,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
if (result.isExcluded()) {
if (devMode) {
LOG.warn("Parameter [{}] matches excluded pattern [{}]! See Accepted / Excluded patterns at\n" +
- "https://struts.apache.org/security/#accepted--excluded-patterns",
- paramName, result.getExcludedPattern());
+ "https://struts.apache.org/security/#accepted--excluded-patterns",
+ paramName, result.getExcludedPattern());
} else {
LOG.debug("Parameter [{}] matches excluded pattern [{}]!", paramName, result.getExcludedPattern());
}
@@ -663,8 +682,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
if (excludedValuePattern.matcher(value).matches()) {
if (devMode) {
LOG.warn("Parameter value [{}] matches excluded pattern [{}]! See Accepting/Excluding parameter values at\n" +
- "https://struts.apache.org/core-developers/parameters-interceptor#excluding-parameter-values",
- value, excludedValuePatterns);
+ "https://struts.apache.org/core-developers/parameters-interceptor#excluding-parameter-values",
+ value, excludedValuePatterns);
} else {
LOG.debug("Parameter value [{}] matches excluded pattern [{}]", value, excludedValuePattern);
}
@@ -686,8 +705,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
}
if (devMode) {
LOG.warn("Parameter value [{}] didn't match accepted pattern [{}]! See Accepting/Excluding parameter values at\n" +
- "https://struts.apache.org/core-developers/parameters-interceptor#excluding-parameter-values",
- value, acceptedValuePatterns);
+ "https://struts.apache.org/core-developers/parameters-interceptor#excluding-parameter-values",
+ value, acceptedValuePatterns);
} else {
LOG.debug("Parameter value [{}] was not accepted!", value);
}
@@ -757,7 +776,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
LOG.debug("Sets accepted value patterns to [{}], note this may impact the safety of your application!", patterns);
} else {
LOG.warn("Replacing accepted patterns [{}] with [{}], be aware that this may impact safety of your application!",
- acceptedValuePatterns, patterns);
+ acceptedValuePatterns, patterns);
}
acceptedValuePatterns = new HashSet<>(patterns.size());
try {
@@ -782,7 +801,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
LOG.debug("Setting excluded value patterns to [{}]", patterns);
} else {
LOG.warn("Replacing excluded value patterns [{}] with [{}], be aware that this may impact safety of your application!",
- excludedValuePatterns, patterns);
+ excludedValuePatterns, patterns);
}
excludedValuePatterns = new HashSet<>(patterns.size());
try {
diff --git a/core/src/test/java/com/opensymphony/xwork2/ModelDrivenAction.java b/core/src/test/java/com/opensymphony/xwork2/ModelDrivenAction.java
index 6ffcad2ff..e300d036b 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ModelDrivenAction.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ModelDrivenAction.java
@@ -44,9 +44,8 @@ public class ModelDrivenAction extends ActionSupport implements ModelDriven {
/**
* @return the model to be pushed onto the ValueStack after the Action itself
*/
- @StrutsParameter(depth = 2)
@Override
- public Object getModel() {
+ public TestBean getModel() {
return model;
}
}
diff --git a/core/src/test/java/com/opensymphony/xwork2/ModelDrivenAnnotationAction.java b/core/src/test/java/com/opensymphony/xwork2/ModelDrivenAnnotationAction.java
index 5549b60b1..f05641732 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ModelDrivenAnnotationAction.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ModelDrivenAnnotationAction.java
@@ -44,9 +44,8 @@ public class ModelDrivenAnnotationAction extends ActionSupport implements ModelD
/**
* @return the model to be pushed onto the ValueStack after the Action itself
*/
- @StrutsParameter(depth = 2)
@Override
- public Object getModel() {
+ public AnnotatedTestBean getModel() {
return model;
}
}
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java
index 65b21c86d..f6513f5f2 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java
@@ -178,7 +178,7 @@ public class ModelDrivenInterceptorTest extends XWorkTestCase {
}
- public class ModelDrivenAction extends ActionSupport implements ModelDriven {
+ public class ModelDrivenAction extends ActionSupport implements ModelDriven<Object> {
@Override
public Object getModel() {
diff --git a/core/src/test/java/com/opensymphony/xwork2/test/ModelDrivenAction2.java b/core/src/test/java/com/opensymphony/xwork2/test/ModelDrivenAction2.java
index 0c445860b..5e29e6899 100644
--- a/core/src/test/java/com/opensymphony/xwork2/test/ModelDrivenAction2.java
+++ b/core/src/test/java/com/opensymphony/xwork2/test/ModelDrivenAction2.java
@@ -19,7 +19,6 @@
package com.opensymphony.xwork2.test;
import com.opensymphony.xwork2.ModelDrivenAction;
-import org.apache.struts2.interceptor.parameter.StrutsParameter;
/**
@@ -35,9 +34,8 @@ public class ModelDrivenAction2 extends ModelDrivenAction {
/**
* @return the model to be pushed onto the ValueStack after the Action itself
*/
- @StrutsParameter(depth = 3)
@Override
- public Object getModel() {
+ public TestBean2 getModel() {
return model;
}
}
diff --git a/core/src/test/java/com/opensymphony/xwork2/test/ModelDrivenAnnotationAction2.java b/core/src/test/java/com/opensymphony/xwork2/test/ModelDrivenAnnotationAction2.java
index 7c26dcfab..b2fcdf542 100644
--- a/core/src/test/java/com/opensymphony/xwork2/test/ModelDrivenAnnotationAction2.java
+++ b/core/src/test/java/com/opensymphony/xwork2/test/ModelDrivenAnnotationAction2.java
@@ -19,7 +19,6 @@
package com.opensymphony.xwork2.test;
import com.opensymphony.xwork2.ModelDrivenAnnotationAction;
-import org.apache.struts2.interceptor.parameter.StrutsParameter;
/**
@@ -36,9 +35,8 @@ public class ModelDrivenAnnotationAction2 extends ModelDrivenAnnotationAction {
/**
* @return the model to be pushed onto the ValueStack after the Action itself
*/
- @StrutsParameter(depth = 3)
@Override
- public Object getModel() {
+ public AnnotationTestBean2 getModel() {
return model;
}
}
diff --git a/core/src/test/java/com/opensymphony/xwork2/test/subtest/NullModelDrivenAction.java b/core/src/test/java/com/opensymphony/xwork2/test/subtest/NullModelDrivenAction.java
index be0916d9d..3551a4643 100644
--- a/core/src/test/java/com/opensymphony/xwork2/test/subtest/NullModelDrivenAction.java
+++ b/core/src/test/java/com/opensymphony/xwork2/test/subtest/NullModelDrivenAction.java
@@ -19,6 +19,7 @@
package com.opensymphony.xwork2.test.subtest;
import com.opensymphony.xwork2.ModelDrivenAction;
+import com.opensymphony.xwork2.TestBean;
/**
* Extends ModelDrivenAction to return a null model.
@@ -31,7 +32,7 @@ public class NullModelDrivenAction extends ModelDrivenAction {
* @return the model to be pushed onto the ValueStack instead of the Action itself
*/
@Override
- public Object getModel() {
+ public TestBean getModel() {
return null;
}
}
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/VisitorValidatorModelAction.java b/core/src/test/java/com/opensymphony/xwork2/validator/VisitorValidatorModelAction.java
index 9f5baeee0..9ec226f98 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/VisitorValidatorModelAction.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/VisitorValidatorModelAction.java
@@ -19,7 +19,7 @@
package com.opensymphony.xwork2.validator;
import com.opensymphony.xwork2.ModelDriven;
-import org.apache.struts2.interceptor.parameter.StrutsParameter;
+import com.opensymphony.xwork2.TestBean;
/**
@@ -33,9 +33,8 @@ public class VisitorValidatorModelAction extends VisitorValidatorTestAction impl
/**
* @return the model to be pushed onto the ValueStack instead of the Action itself
*/
- @StrutsParameter(depth = 2)
@Override
- public Object getModel() {
+ public TestBean getModel() {
return getBean();
}
}
diff --git a/core/src/test/java/org/apache/struts2/interceptor/parameter/StrutsParameterAnnotationTest.java b/core/src/test/java/org/apache/struts2/interceptor/parameter/StrutsParameterAnnotationTest.java
index 53fa14717..dfcecddcb 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/parameter/StrutsParameterAnnotationTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/parameter/StrutsParameterAnnotationTest.java
@@ -18,8 +18,12 @@
*/
package org.apache.struts2.interceptor.parameter;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ModelDriven;
+import com.opensymphony.xwork2.StubValueStack;
import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
import com.opensymphony.xwork2.security.NotExcludedAcceptedPatternsChecker;
+import com.opensymphony.xwork2.util.ValueStack;
import org.apache.commons.lang3.ClassUtils;
import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.dispatcher.Parameter;
@@ -63,6 +67,7 @@ public class StrutsParameterAnnotationTest {
@After
public void tearDown() throws Exception {
threadAllowlist.clearAllowlist();
+ ActionContext.clear();
}
private void testParameter(Object action, String paramName, boolean shouldContain) {
@@ -80,7 +85,7 @@ public class StrutsParameterAnnotationTest {
}
}
- private Set<Class<?>> getParentClasses(Class<?> ...clazzes) {
+ private Set<Class<?>> getParentClasses(Class<?>... clazzes) {
Set<Class<?>> set = new HashSet<>();
for (Class<?> clazz : clazzes) {
set.add(clazz);
@@ -258,8 +263,21 @@ public class StrutsParameterAnnotationTest {
testParameter(new MethodAction(), "publicStrNotAnnotated", true);
}
+ @Test
+ public void publicModelPojo() {
+ ModelAction action = new ModelAction();
+
+ // Emulate ModelDrivenInterceptor running previously
+ ValueStack valueStack = new StubValueStack();
+ valueStack.push(action.getModel());
+ ActionContext.of().withValueStack(valueStack).bind();
+
+ testParameter(action, "name", true);
+ testParameter(action, "name.nested", true);
+ assertThat(threadAllowlist.getAllowlist()).containsExactlyInAnyOrderElementsOf(getParentClasses(Object.class, Pojo.class));
+ }
- class FieldAction {
+ static class FieldAction {
@StrutsParameter
private String privateStr;
@@ -275,7 +293,7 @@ public class StrutsParameterAnnotationTest {
public Pojo publicPojoDepthZero;
@StrutsParameter(depth = 1)
- public Pojo publicPojoDepthOne ;
+ public Pojo publicPojoDepthOne;
@StrutsParameter(depth = 2)
public Pojo publicPojoDepthTwo;
@@ -290,7 +308,7 @@ public class StrutsParameterAnnotationTest {
public Map<String, Pojo> publicPojoMapDepthTwo;
}
- class MethodAction {
+ static class MethodAction {
@StrutsParameter
private void setPrivateStr(String str) {
@@ -343,6 +361,14 @@ public class StrutsParameterAnnotationTest {
}
}
- class Pojo {
+ static class ModelAction implements ModelDriven<Pojo> {
+
+ @Override
+ public Pojo getModel() {
+ return new Pojo();
+ }
+ }
+
+ static class Pojo {
}
}
diff --git a/core/src/test/java/org/apache/struts2/result/StreamResultTest.java b/core/src/test/java/org/apache/struts2/result/StreamResultTest.java
index 5661db5d3..a02781812 100644
--- a/core/src/test/java/org/apache/struts2/result/StreamResultTest.java
+++ b/core/src/test/java/org/apache/struts2/result/StreamResultTest.java
@@ -37,7 +37,6 @@ import static com.opensymphony.xwork2.security.DefaultNotExcludedAcceptedPattern
/**
* Unit test for {@link StreamResult}.
- *
*/
public class StreamResultTest extends StrutsInternalTestCase {
@@ -126,12 +125,12 @@ public class StreamResultTest extends StrutsInternalTestCase {
result.doExecute("helloworld", mai);
- //check that that headers are not set by default
+ //check that that headers are not set by default
assertNull(response.getHeader("Pragma"));
assertNull(response.getHeader("Cache-Control"));
}
- public void testAllowCacheFalse() throws Exception {
+ public void testAllowCacheFalse() throws Exception {
result.setInputName("streamForImage");
result.setAllowCaching(false);
result.doExecute("helloworld", mai);
@@ -266,7 +265,6 @@ public class StreamResultTest extends StrutsInternalTestCase {
}
-
protected void tearDown() throws Exception {
super.tearDown();
response = null;
diff --git a/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/actions/ModelDrivenAction.java b/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/actions/ModelDrivenAction.java
index 9b32fa24b..3964ed397 100644
--- a/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/actions/ModelDrivenAction.java
+++ b/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/actions/ModelDrivenAction.java
@@ -21,7 +21,6 @@ package org.apache.struts.beanvalidation.actions;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.apache.struts.beanvalidation.models.Person;
-import org.apache.struts2.interceptor.parameter.StrutsParameter;
import javax.validation.Valid;
@@ -30,7 +29,6 @@ public class ModelDrivenAction extends ActionSupport implements ModelDriven<Pers
@Valid
private final Person model = new Person();
- @StrutsParameter(depth = 2)
@Override
public Person getModel() {
return model;
diff --git a/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/actions/ValidateGroupAction.java b/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/actions/ValidateGroupAction.java
index 7d3540551..ff63256dc 100644
--- a/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/actions/ValidateGroupAction.java
+++ b/plugins/bean-validation/src/test/java/org/apache/struts/beanvalidation/actions/ValidateGroupAction.java
@@ -22,7 +22,6 @@ import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.apache.struts.beanvalidation.constraints.ValidationGroup;
import org.apache.struts.beanvalidation.models.Person;
-import org.apache.struts2.interceptor.parameter.StrutsParameter;
import javax.validation.Valid;
@@ -31,7 +30,6 @@ public class ValidateGroupAction extends ActionSupport implements ModelDriven<Pe
@Valid
private final Person model = new Person();
- @StrutsParameter(depth = 2)
@Override
public Person getModel() {
return model;
diff --git a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsRestTestCase.java b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsRestTestCase.java
index 80a954f8e..82656edae 100644
--- a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsRestTestCase.java
+++ b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsRestTestCase.java
@@ -23,7 +23,6 @@ import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.ActionProxyFactory;
import com.opensymphony.xwork2.config.Configuration;
import org.apache.struts2.ServletActionContext;
-import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -75,7 +74,7 @@ public class StrutsRestTestCase<T> extends StrutsJUnit4TestCase<T> {
ActionMapping mapping = getActionMapping(request);
assertNotNull(mapping);
- Dispatcher.getInstance().serviceAction(request, response, mapping);
+ dispatcher.serviceAction(request, response, mapping);
if (response.getStatus() != HttpServletResponse.SC_OK)
throw new ServletException("Error code [" + response.getStatus() + "], Error: ["
diff --git a/plugins/rest/src/test/java/org/apache/struts2/rest/RestActionInvocationTest.java b/plugins/rest/src/test/java/org/apache/struts2/rest/RestActionInvocationTest.java
index 6f22a583e..432cb4a58 100644
--- a/plugins/rest/src/test/java/org/apache/struts2/rest/RestActionInvocationTest.java
+++ b/plugins/rest/src/test/java/org/apache/struts2/rest/RestActionInvocationTest.java
@@ -32,7 +32,6 @@ import com.opensymphony.xwork2.ognl.OgnlUtil;
import com.opensymphony.xwork2.util.XWorkTestCaseHelper;
import junit.framework.TestCase;
import org.apache.struts2.ServletActionContext;
-import org.apache.struts2.interceptor.parameter.StrutsParameter;
import org.apache.struts2.result.HttpHeaderResult;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -47,97 +46,97 @@ import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;
public class RestActionInvocationTest extends TestCase {
- RestActionInvocation restActionInvocation;
- MockHttpServletRequest request;
- MockHttpServletResponse response;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- restActionInvocation = new RestActionInvocationTester();
- request = new MockHttpServletRequest();
- response = new MockHttpServletResponse();
- ServletActionContext.setRequest(request);
- ServletActionContext.setResponse(response);
-
- }
-
- /**
- * Test the correct action results: null, String, HttpHeaders, Result
- * @throws Exception
- */
- public void testSaveResult() throws Exception {
-
- Object methodResult = "index";
- ActionConfig actionConfig = restActionInvocation.getProxy().getConfig();
- assertEquals("index", restActionInvocation.saveResult(actionConfig, methodResult));
-
- setUp();
- methodResult = new DefaultHttpHeaders("show");
- assertEquals("show", restActionInvocation.saveResult(actionConfig, methodResult));
- assertEquals(methodResult, restActionInvocation.httpHeaders);
-
- setUp();
- methodResult = new HttpHeaderResult(HttpServletResponse.SC_ACCEPTED);
- assertEquals(null, restActionInvocation.saveResult(actionConfig, methodResult));
- assertEquals(methodResult, restActionInvocation.createResult());
-
- setUp();
- try {
- methodResult = new Object();
- restActionInvocation.saveResult(actionConfig, methodResult);
-
- // ko
- assertFalse(true);
-
- } catch (ConfigurationException c) {
- // ok, object not allowed
- }
- }
-
- /**
- * Test the target selection: exception, error messages, model and null
- * @throws Exception
- */
- public void testSelectTarget() throws Exception {
-
- // Exception
- Exception e = new Exception();
- restActionInvocation.getStack().set("exception", e);
- restActionInvocation.selectTarget();
- assertEquals(e, restActionInvocation.target);
-
- // Error messages
- setUp();
- String actionMessage = "Error!";
- RestActionSupport action = (RestActionSupport)restActionInvocation.getAction();
- action.addActionError(actionMessage);
- Map<String, Object> errors = new HashMap<String, Object>();
- List<String> list = new ArrayList<String>();
- list.add(actionMessage);
- errors.put("actionErrors", list);
- restActionInvocation.selectTarget();
- assertEquals(errors, restActionInvocation.target);
-
- // Model with get and no content in post, put, delete
- setUp();
- RestAction restAction = (RestAction)restActionInvocation.getAction();
- List<String> model = new ArrayList<String>();
- model.add("Item");
- restAction.model = model;
- request.setMethod("GET");
- restActionInvocation.selectTarget();
- assertEquals(model, restActionInvocation.target);
- request.setMethod("POST");
- restActionInvocation.selectTarget();
- assertEquals(null, restActionInvocation.target);
- request.setMethod("PUT");
- restActionInvocation.selectTarget();
- assertEquals(null, restActionInvocation.target);
- request.setMethod("DELETE");
- restActionInvocation.selectTarget();
- assertEquals(null, restActionInvocation.target);
+ RestActionInvocation restActionInvocation;
+ MockHttpServletRequest request;
+ MockHttpServletResponse response;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ restActionInvocation = new RestActionInvocationTester();
+ request = new MockHttpServletRequest();
+ response = new MockHttpServletResponse();
+ ServletActionContext.setRequest(request);
+ ServletActionContext.setResponse(response);
+
+ }
+
+ /**
+ * Test the correct action results: null, String, HttpHeaders, Result
+ * @throws Exception
+ */
+ public void testSaveResult() throws Exception {
+
+ Object methodResult = "index";
+ ActionConfig actionConfig = restActionInvocation.getProxy().getConfig();
+ assertEquals("index", restActionInvocation.saveResult(actionConfig, methodResult));
+
+ setUp();
+ methodResult = new DefaultHttpHeaders("show");
+ assertEquals("show", restActionInvocation.saveResult(actionConfig, methodResult));
+ assertEquals(methodResult, restActionInvocation.httpHeaders);
+
+ setUp();
+ methodResult = new HttpHeaderResult(HttpServletResponse.SC_ACCEPTED);
+ assertEquals(null, restActionInvocation.saveResult(actionConfig, methodResult));
+ assertEquals(methodResult, restActionInvocation.createResult());
+
+ setUp();
+ try {
+ methodResult = new Object();
+ restActionInvocation.saveResult(actionConfig, methodResult);
+
+ // ko
+ assertFalse(true);
+
+ } catch (ConfigurationException c) {
+ // ok, object not allowed
+ }
+ }
+
+ /**
+ * Test the target selection: exception, error messages, model and null
+ * @throws Exception
+ */
+ public void testSelectTarget() throws Exception {
+
+ // Exception
+ Exception e = new Exception();
+ restActionInvocation.getStack().set("exception", e);
+ restActionInvocation.selectTarget();
+ assertEquals(e, restActionInvocation.target);
+
+ // Error messages
+ setUp();
+ String actionMessage = "Error!";
+ RestActionSupport action = (RestActionSupport)restActionInvocation.getAction();
+ action.addActionError(actionMessage);
+ Map<String, Object> errors = new HashMap<String, Object>();
+ List<String> list = new ArrayList<String>();
+ list.add(actionMessage);
+ errors.put("actionErrors", list);
+ restActionInvocation.selectTarget();
+ assertEquals(errors, restActionInvocation.target);
+
+ // Model with get and no content in post, put, delete
+ setUp();
+ RestAction restAction = (RestAction)restActionInvocation.getAction();
+ List<String> model = new ArrayList<String>();
+ model.add("Item");
+ restAction.model = model;
+ request.setMethod("GET");
+ restActionInvocation.selectTarget();
+ assertEquals(model, restActionInvocation.target);
+ request.setMethod("POST");
+ restActionInvocation.selectTarget();
+ assertEquals(null, restActionInvocation.target);
+ request.setMethod("PUT");
+ restActionInvocation.selectTarget();
+ assertEquals(null, restActionInvocation.target);
+ request.setMethod("DELETE");
+ restActionInvocation.selectTarget();
+ assertEquals(null, restActionInvocation.target);
// disable content restriction to GET only
model = new ArrayList<String>();
@@ -151,102 +150,100 @@ public class RestActionInvocationTest extends TestCase {
assertEquals(model.get(0), "Item1");
}
- /**
- * Test the not modified status code.
- * @throws Exception
- */
- public void testResultNotModified() throws Exception {
+ /**
+ * Test the not modified status code.
+ * @throws Exception
+ */
+ public void testResultNotModified() throws Exception {
+
+ request.addHeader("If-None-Match", "123");
+ request.setMethod("GET");
+
+ RestAction restAction = (RestAction)restActionInvocation.getAction();
+ List<String> model = new ArrayList<String>() {
+ @Override
+ public int hashCode() {
+ return 123;
+ }
+ };
+ model.add("Item");
+ restAction.model = model;
+
+ restActionInvocation.processResult();
+ assertEquals(SC_NOT_MODIFIED, response.getStatus());
+
+ }
+
+ /**
+ * Test the default error result.
+ * @throws Exception
+ */
+ public void testDefaultErrorResult() throws Exception {
+
+ // Exception
+ Exception e = new Exception();
+ restActionInvocation.getStack().set("exception", e);
+ request.setMethod("GET");
+
+ RestAction restAction = (RestAction)restActionInvocation.getAction();
+ List<String> model = new ArrayList<String>();
+ model.add("Item");
+ restAction.model = model;
+
+ restActionInvocation.setDefaultErrorResultName("default-error");
+ ResultConfig resultConfig = new ResultConfig.Builder("default-error",
+ "org.apache.struts2.result.HttpHeaderResult")
+ .addParam("status", "123").build();
+ ActionConfig actionConfig = new ActionConfig.Builder("org.apache.rest",
+ "RestAction", "org.apache.rest.RestAction")
+ .addResultConfig(resultConfig)
+ .build();
+ ((MockActionProxy)restActionInvocation.getProxy()).setConfig(actionConfig);
+
+ restActionInvocation.processResult();
+ assertEquals(123, response.getStatus());
+
+ }
+
+ public void testNoResult() throws Exception {
- request.addHeader("If-None-Match", "123");
- request.setMethod("GET");
+ RestAction restAction = (RestAction)restActionInvocation.getAction();
+ List<String> model = new ArrayList<String>();
+ model.add("Item");
+ restAction.model = model;
+ request.setMethod("GET");
+ restActionInvocation.setResultCode("index");
- RestAction restAction = (RestAction)restActionInvocation.getAction();
- List<String> model = new ArrayList<String>() {
- @Override
- public int hashCode() {
- return 123;
- }
- };
- model.add("Item");
- restAction.model = model;
+ try {
+ restActionInvocation.processResult();
- restActionInvocation.processResult();
- assertEquals(SC_NOT_MODIFIED, response.getStatus());
+ // ko
+ assertFalse(true);
+
+ } catch (ConfigurationException c) {
+ // ok, no result
+ }
}
- /**
- * Test the default error result.
- * @throws Exception
- */
- public void testDefaultErrorResult() throws Exception {
-
- // Exception
- Exception e = new Exception();
- restActionInvocation.getStack().set("exception", e);
- request.setMethod("GET");
-
- RestAction restAction = (RestAction)restActionInvocation.getAction();
- List<String> model = new ArrayList<String>();
- model.add("Item");
- restAction.model = model;
-
- restActionInvocation.setDefaultErrorResultName("default-error");
- ResultConfig resultConfig = new ResultConfig.Builder("default-error",
- "org.apache.struts2.result.HttpHeaderResult")
- .addParam("status", "123").build();
- ActionConfig actionConfig = new ActionConfig.Builder("org.apache.rest",
- "RestAction", "org.apache.rest.RestAction")
- .addResultConfig(resultConfig)
- .build();
- ((MockActionProxy)restActionInvocation.getProxy()).setConfig(actionConfig);
-
- restActionInvocation.processResult();
- assertEquals(123, response.getStatus());
-
- }
-
- public void testNoResult() throws Exception {
-
- RestAction restAction = (RestAction)restActionInvocation.getAction();
- List<String> model = new ArrayList<String>();
- model.add("Item");
- restAction.model = model;
- request.setMethod("GET");
- restActionInvocation.setResultCode("index");
-
- try {
- restActionInvocation.processResult();
-
- // ko
- assertFalse(true);
-
- } catch (ConfigurationException c) {
- // ok, no result
- }
-
- }
-
- /**
- * Test the global execution
- * @throws Exception
- */
- public void testInvoke() throws Exception {
-
- // Default index method return 'success'
- ((MockActionProxy)restActionInvocation.getProxy()).setMethod("index");
-
- // Define result 'success'
- ResultConfig resultConfig = new ResultConfig.Builder("success",
- "org.apache.struts2.result.HttpHeaderResult")
- .addParam("status", "123").build();
- ActionConfig actionConfig = new ActionConfig.Builder("org.apache.rest",
- "RestAction", "org.apache.rest.RestAction")
- .addResultConfig(resultConfig)
- .build();
- ((MockActionProxy)restActionInvocation.getProxy()).setConfig(actionConfig);
-
- request.setMethod("GET");
+ /**
+ * Test the global execution
+ * @throws Exception
+ */
+ public void testInvoke() throws Exception {
+
+ // Default index method return 'success'
+ ((MockActionProxy)restActionInvocation.getProxy()).setMethod("index");
+
+ // Define result 'success'
+ ResultConfig resultConfig = new ResultConfig.Builder("success", "org.apache.struts2.result.HttpHeaderResult")
+ .addParam("status", "123").build();
+ ActionConfig actionConfig = new ActionConfig.Builder("org.apache.rest", "RestAction", "org.apache.rest.RestAction")
+ .addResultConfig(resultConfig)
+ .build();
+ ((MockActionProxy)restActionInvocation.getProxy()).setConfig(actionConfig);
+
+ request.setMethod("GET");
restActionInvocation.setOgnlUtil(new OgnlUtil());
restActionInvocation.invoke();
@@ -256,31 +253,31 @@ public class RestActionInvocationTest extends TestCase {
class RestActionInvocationTester extends RestActionInvocation {
- RestActionInvocationTester() {
- super(new HashMap<String, Object>(), true);
- List<InterceptorMapping> interceptorMappings = new ArrayList<InterceptorMapping>();
+ RestActionInvocationTester() {
+ super(new HashMap<>(), true);
+ List<InterceptorMapping> interceptorMappings = new ArrayList<>();
MockInterceptor mockInterceptor = new MockInterceptor();
mockInterceptor.setFoo("interceptor");
mockInterceptor.setExpectedFoo("interceptor");
interceptorMappings.add(new InterceptorMapping("interceptor", mockInterceptor));
interceptors = interceptorMappings.iterator();
MockActionProxy actionProxy = new MockActionProxy();
- ActionConfig actionConfig = new ActionConfig.Builder("org.apache.rest",
- "RestAction", "org.apache.rest.RestAction").build();
+ ActionConfig actionConfig = new ActionConfig.Builder(
+ "org.apache.rest", "RestAction", "org.apache.rest.RestAction").build();
actionProxy.setConfig(actionConfig);
proxy = actionProxy;
action = new RestAction();
setMimeTypeHandlerSelector(new DefaultContentTypeHandlerManager());
unknownHandlerManager = new DefaultUnknownHandlerManager();
- try {
- XWorkTestCaseHelper.setUp();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- invocationContext = ActionContext.getContext();
- container = ActionContext.getContext().getContainer();
- stack = ActionContext.getContext().getValueStack();
- objectFactory = container.getInstance(ObjectFactory.class);
+ try {
+ XWorkTestCaseHelper.setUp();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ invocationContext = ActionContext.getContext();
+ container = ActionContext.getContext().getContainer();
+ stack = ActionContext.getContext().getValueStack();
+ objectFactory = container.getInstance(ObjectFactory.class);
}
@@ -288,13 +285,12 @@ public class RestActionInvocationTest extends TestCase {
static class RestAction extends RestActionSupport implements ModelDriven<List<String>> {
- List<String> model;
+ List<String> model;
- @StrutsParameter(depth = 1)
- @Override
- public List<String> getModel() {
- return model;
- }
+ @Override
+ public List<String> getModel() {
+ return model;
+ }
}
}
diff --git a/plugins/spring/src/test/java/com/opensymphony/xwork2/ModelDrivenAction.java b/plugins/spring/src/test/java/com/opensymphony/xwork2/ModelDrivenAction.java
index 6ffcad2ff..e300d036b 100644
--- a/plugins/spring/src/test/java/com/opensymphony/xwork2/ModelDrivenAction.java
+++ b/plugins/spring/src/test/java/com/opensymphony/xwork2/ModelDrivenAction.java
@@ -44,9 +44,8 @@ public class ModelDrivenAction extends ActionSupport implements ModelDriven {
/**
* @return the model to be pushed onto the ValueStack after the Action itself
*/
- @StrutsParameter(depth = 2)
@Override
- public Object getModel() {
+ public TestBean getModel() {
return model;
}
}