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

kusal pushed a commit to branch WW-5429-param-anno-log
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 3506020b8d5ac85cd12211c3ad7db11ae73c0ee4
Author: Kusal Kithul-Godage <g...@kusal.io>
AuthorDate: Tue Jun 18 19:07:50 2024 +1000

    WW-5429 Log parameter annotation issues at ERROR level when in DevMode
---
 .../com/opensymphony/xwork2/util/DebugUtils.java   | 24 +++++++++++
 .../parameter/ParametersInterceptor.java           | 49 ++++++++++++----------
 2 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java 
b/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java
new file mode 100644
index 000000000..5978067f8
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java
@@ -0,0 +1,24 @@
+package com.opensymphony.xwork2.util;
+
+import com.opensymphony.xwork2.TextProvider;
+import com.opensymphony.xwork2.interceptor.ValidationAware;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * @since 6.5.0
+ */
+public class DebugUtils {
+
+    public static void notifyDeveloperOfError(Logger log, Object action, 
String message) {
+        if (action instanceof TextProvider) {
+            TextProvider tp = (TextProvider) action;
+            message = tp.getText("devmode.notification", "Developer 
Notification:\n{0}", new String[]{message});
+        }
+        log.error(message);
+        if (action instanceof ValidationAware) {
+            ValidationAware validationAware = (ValidationAware) action;
+            validationAware.addActionMessage(message);
+        }
+    }
+
+}
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 e9215e533..8a9fb81f2 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,10 +20,8 @@ package org.apache.struts2.interceptor.parameter;
 
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.TextProvider;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
-import com.opensymphony.xwork2.interceptor.ValidationAware;
 import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
 import com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker;
 import com.opensymphony.xwork2.security.ExcludedPatternsChecker;
@@ -56,7 +54,6 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Map;
@@ -67,6 +64,8 @@ import java.util.regex.Pattern;
 
 import static 
com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker.NESTING_CHARS;
 import static 
com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker.NESTING_CHARS_STR;
+import static com.opensymphony.xwork2.util.DebugUtils.notifyDeveloperOfError;
+import static java.lang.String.format;
 import static java.util.Collections.unmodifiableSet;
 import static java.util.stream.Collectors.joining;
 import static org.apache.commons.lang3.StringUtils.indexOfAny;
@@ -318,18 +317,7 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
 
     protected void notifyDeveloperParameterException(Object action, String 
property, String message) {
         String logMsg = "Unexpected Exception caught setting '" + property + 
"' on '" + action.getClass() + ": " + message;
-        if (action instanceof TextProvider) {
-            TextProvider tp = (TextProvider) action;
-            logMsg = tp.getText("devmode.notification", "Developer 
Notification:\n{0}", new String[]{logMsg});
-        }
-        LOG.error(logMsg);
-
-        if (action instanceof ValidationAware) {
-            ValidationAware validationAware = (ValidationAware) action;
-            Collection<String> messages = validationAware.getActionMessages();
-            messages.add(message);
-            validationAware.setActionMessages(messages);
-        }
+        notifyDeveloperOfError(LOG, action, logMsg);
     }
 
     /**
@@ -388,23 +376,37 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
             return hasValidAnnotatedField(action, rootProperty, paramDepth);
         }
 
-        if (hasValidAnnotatedPropertyDescriptor(propDescOpt.get(), 
paramDepth)) {
+        if (hasValidAnnotatedPropertyDescriptor(action, propDescOpt.get(), 
paramDepth)) {
             return true;
         }
 
         return hasValidAnnotatedField(action, rootProperty, paramDepth);
     }
 
+    /**
+     * @deprecated since 6.5.0, use {@link 
#hasValidAnnotatedPropertyDescriptor(Object, PropertyDescriptor, long)}
+     * instead.
+     */
+    @Deprecated
     protected boolean hasValidAnnotatedPropertyDescriptor(PropertyDescriptor 
propDesc, long paramDepth) {
+        return hasValidAnnotatedPropertyDescriptor(null, propDesc, paramDepth);
+    }
+
+    protected boolean hasValidAnnotatedPropertyDescriptor(Object action, 
PropertyDescriptor propDesc, long paramDepth) {
         Method relevantMethod = paramDepth == 0 ? propDesc.getWriteMethod() : 
propDesc.getReadMethod();
         if (relevantMethod == null) {
             return false;
         }
         if (getPermittedInjectionDepth(relevantMethod) < paramDepth) {
-            LOG.debug(
-                    "Parameter injection for method [{}] on action [{}] 
rejected. Ensure it is annotated with @StrutsParameter with an appropriate 
'depth'.",
+            String logMessage = format(
+                    "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) {
+                notifyDeveloperOfError(LOG, action, logMessage);
+            } else {
+                LOG.debug(logMessage);
+            }
             return false;
         }
         if (paramDepth >= 1) {
@@ -455,10 +457,15 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
             return false;
         }
         if (getPermittedInjectionDepth(field) < paramDepth) {
-            LOG.debug(
-                    "Parameter injection for field [{}] on action [{}] 
rejected. Ensure it is annotated with @StrutsParameter with an appropriate 
'depth'.",
+            String logMessage = format(
+                    "Parameter injection for field [%s] on action [%s] 
rejected. Ensure it is annotated with @StrutsParameter with an appropriate 
'depth'.",
                     fieldName,
                     action.getClass().getName());
+            if (devMode) {
+                notifyDeveloperOfError(LOG, action, logMessage);
+            } else {
+                LOG.debug(logMessage);
+            }
             return false;
         }
         if (paramDepth >= 1) {
@@ -533,7 +540,7 @@ public class ParametersInterceptor extends 
MethodFilterInterceptor {
             return "NONE";
         }
         return parameters.entrySet().stream()
-                .map(entry -> String.format("%s => %s ", entry.getKey(), 
entry.getValue().getValue()))
+                .map(entry -> format("%s => %s ", entry.getKey(), 
entry.getValue().getValue()))
                 .collect(joining());
     }
 

Reply via email to