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

kusal pushed a commit to branch fix/WW-5468-modeldriven-kusal
in repository https://gitbox.apache.org/repos/asf/struts.git

commit f67f593bdb96398996fd663fefc2c1ddedc1740a
Author: Kusal Kithul-Godage <g...@kusal.io>
AuthorDate: Fri Oct 11 20:56:33 2024 +1100

    WW-5468 Alternate fix for ModelDriven Action parameters
---
 core/src/main/java/com/opensymphony/xwork2/ModelDriven.java |  6 ++++++
 .../interceptor/parameter/ParametersInterceptor.java        |  8 +++++++-
 .../parameter/StrutsParameterAnnotationTest.java            | 13 ++++++++++---
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/core/src/main/java/com/opensymphony/xwork2/ModelDriven.java 
b/core/src/main/java/com/opensymphony/xwork2/ModelDriven.java
index c07c6bbe7..fc7f9a348 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ModelDriven.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ModelDriven.java
@@ -18,6 +18,8 @@
  */
 package com.opensymphony.xwork2;
 
+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 353f3cb82..5ff5be262 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
@@ -20,6 +20,7 @@ package org.apache.struts2.interceptor.parameter;
 
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ModelDriven;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
 import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
@@ -348,6 +349,11 @@ 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)) {
+            return hasValidAnnotatedMember("model", action, paramDepth + 1);
+        }
+
         if (requireAnnotationsTransitionMode && paramDepth == 0) {
             return true;
         }
@@ -401,7 +407,7 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
             return false;
         }
         if (paramDepth >= 1) {
-            allowlistClass(relevantMethod.getReturnType());
+            allowlistClass(propDesc.getPropertyType());
         }
         if (paramDepth >= 2) {
             allowlistReturnTypeIfParameterized(relevantMethod);
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 eb44fc6fe..256b16eca 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,7 +18,9 @@
  */
 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 org.apache.commons.lang3.ClassUtils;
@@ -64,6 +66,7 @@ public class StrutsParameterAnnotationTest {
     @After
     public void tearDown() throws Exception {
         threadAllowlist.clearAllowlist();
+        ActionContext.clear();
     }
 
     private void testParameter(Object action, String paramName, boolean 
shouldContain) {
@@ -261,8 +264,13 @@ public class StrutsParameterAnnotationTest {
 
     @Test
     public void publicModelPojo() {
-        
parametersInterceptor.setRequireAnnotationsTransitionMode(Boolean.TRUE.toString());
-        testParameter(new ModelAction(), "name", true);
+        var action = new ModelAction();
+        var 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));
     }
 
@@ -352,7 +360,6 @@ public class StrutsParameterAnnotationTest {
 
     static class ModelAction implements ModelDriven<Pojo> {
 
-        @StrutsParameter
         public Pojo getModel() {
             return new Pojo();
         }

Reply via email to