From 8ba8ee5fe6298aaa3debfb5a1197abb4cae6ad99 Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Thu, 17 Oct 2024 15:46:25 +1100 Subject: [PATCH 1/6] WW-3714 Deprecate and migrate ValueStack --- .../opensymphony/xwork2/ActionContext.java | 2 +- .../xwork2/ActionEventListener.java | 14 + .../opensymphony/xwork2/ActionInvocation.java | 5 +- .../opensymphony/xwork2/util/ValueStack.java | 254 ++++++++---------- .../apache/struts2/ActionEventListener.java | 2 +- .../org/apache/struts2/ActionInvocation.java | 2 +- .../org/apache/struts2/util/ValueStack.java | 167 ++++++++++++ 7 files changed, 305 insertions(+), 141 deletions(-) create mode 100644 core/src/main/java/org/apache/struts2/util/ValueStack.java diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java index c7864571f1..786c896d2f 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java @@ -43,7 +43,7 @@ private ActionContext(org.apache.struts2.ActionContext actualContext) { super(actualContext.getContextMap()); } - static ActionContext adapt(org.apache.struts2.ActionContext actualContext) { + public static ActionContext adapt(org.apache.struts2.ActionContext actualContext) { return actualContext != null ? new ActionContext(actualContext) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java b/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java index 4d21438486..5bd4f86d5a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java @@ -28,6 +28,20 @@ @Deprecated public interface ActionEventListener extends org.apache.struts2.ActionEventListener { + @Override + default Object prepare(Object action, org.apache.struts2.util.ValueStack stack) { + return prepare(action, ValueStack.adapt(stack)); + } + + @Override + default String handleException(Throwable t, org.apache.struts2.util.ValueStack stack) { + return handleException(t, ValueStack.adapt(stack)); + } + + Object prepare(Object action, ValueStack stack); + + String handleException(Throwable t, ValueStack stack); + static ActionEventListener adapt(org.apache.struts2.ActionEventListener actualListener) { return actualListener != null ? new LegacyAdapter(actualListener) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionInvocation.java b/core/src/main/java/com/opensymphony/xwork2/ActionInvocation.java index 82020bbe12..76929a647f 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionInvocation.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionInvocation.java @@ -38,6 +38,9 @@ public interface ActionInvocation extends org.apache.struts2.ActionInvocation { @Override ActionProxy getProxy(); + @Override + ValueStack getStack(); + @Override default void addPreResultListener(org.apache.struts2.interceptor.PreResultListener listener) { addPreResultListener(PreResultListener.adapt(listener)); @@ -108,7 +111,7 @@ public void setResultCode(String resultCode) { @Override public ValueStack getStack() { - return adaptee.getStack(); + return ValueStack.adapt(adaptee.getStack()); } @Override diff --git a/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java b/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java index 4d02b235fe..9e3e98b57b 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java @@ -23,144 +23,124 @@ import java.util.Map; /** - * ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When - * evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the - * earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending - * on the expression being evaluated). + * @deprecated since 6.7.0, use {@link org.apache.struts2.util.ValueStack} instead. */ -public interface ValueStack { - - String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack"; - - String REPORT_ERRORS_ON_NO_PROP = "com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp"; - - /** - * Gets the context for this value stack. The context holds all the information in the value stack and it's surroundings. - * - * @return the context. - */ - Map getContext(); +@Deprecated +public interface ValueStack extends org.apache.struts2.util.ValueStack { + @Override ActionContext getActionContext(); - /** - * Sets the default type to convert to if no type is provided when getting a value. - * - * @param defaultType the new default type - */ - void setDefaultType(Class defaultType); - - /** - * Set a override map containing key -> values that takes precedent when doing find operations on the ValueStack. - *

- * See the unit test for ValueStackTest for examples. - *

- * - * @param overrides overrides map. - */ - void setExprOverrides(Map overrides); - - /** - * Gets the override map if anyone exists. - * - * @return the override map, null if not set. - */ - Map getExprOverrides(); - - /** - * Get the CompoundRoot which holds the objects pushed onto the stack - * - * @return the root - */ - CompoundRoot getRoot(); - - /** - * Attempts to set a property on a bean in the stack with the given expression using the default search order. - * - * @param expr the expression defining the path to the property to be set. - * @param value the value to be set into the named property - */ - void setValue(String expr, Object value); - - /** - * Attempts to set a property on a bean in the stack with the given expression using the default search order. - * N.B.: unlike #setValue(String,Object) it doesn't allow eval expression. - * @param expr the expression defining the path to the property to be set. - * @param value the value to be set into the named property - */ - void setParameter(String expr, Object value); - - /** - * Attempts to set a property on a bean in the stack with the given expression using the default search order. - * - * @param expr the expression defining the path to the property to be set. - * @param value the value to be set into the named property - * @param throwExceptionOnFailure a flag to tell whether an exception should be thrown if there is no property with - * the given name. - */ - void setValue(String expr, Object value, boolean throwExceptionOnFailure); - - String findString(String expr); - String findString(String expr, boolean throwExceptionOnFailure); - - /** - * Find a value by evaluating the given expression against the stack in the default search order. - * - * @param expr the expression giving the path of properties to navigate to find the property value to return - * @return the result of evaluating the expression - */ - Object findValue(String expr); - - Object findValue(String expr, boolean throwExceptionOnFailure); - - /** - * Find a value by evaluating the given expression against the stack in the default search order. - * - * @param expr the expression giving the path of properties to navigate to find the property value to return - * @param asType the type to convert the return value to - * @return the result of evaluating the expression - */ - Object findValue(String expr, Class asType); - Object findValue(String expr, Class asType, boolean throwExceptionOnFailure); - - /** - * Get the object on the top of the stack without changing the stack. - * - * @return the object on the top. - * @see CompoundRoot#peek() - */ - Object peek(); - - /** - * Get the object on the top of the stack and remove it from the stack. - * - * @return the object on the top of the stack - * @see CompoundRoot#pop() - */ - Object pop(); - - /** - * Put this object onto the top of the stack - * - * @param o the object to be pushed onto the stack - * @see CompoundRoot#push(Object) - */ - void push(Object o); - - /** - * Sets an object on the stack with the given key - * so it is retrievable by {@link #findValue(String)}, {@link #findValue(String, Class)} - * - * @param key the key - * @param o the object - */ - void set(String key, Object o); - - /** - * Get the number of objects in the stack - * - * @return the number of objects in the stack - */ - int size(); - -} \ No newline at end of file + static ValueStack adapt(org.apache.struts2.util.ValueStack actualStack) { + return actualStack != null ? new LegacyAdapter(actualStack) : null; + } + + class LegacyAdapter implements ValueStack { + + private final org.apache.struts2.util.ValueStack adaptee; + + private LegacyAdapter(org.apache.struts2.util.ValueStack adaptee) { + this.adaptee = adaptee; + } + + @Override + public Map getContext() { + return adaptee.getContext(); + } + + @Override + public ActionContext getActionContext() { + return ActionContext.adapt(adaptee.getActionContext()); + } + + @Override + public void setDefaultType(Class defaultType) { + adaptee.setDefaultType(defaultType); + } + + @Override + public void setExprOverrides(Map overrides) { + adaptee.setExprOverrides(overrides); + } + + @Override + public Map getExprOverrides() { + return adaptee.getExprOverrides(); + } + + @Override + public CompoundRoot getRoot() { + return adaptee.getRoot(); + } + + @Override + public void setValue(String expr, Object value) { + adaptee.setValue(expr, value); + } + + @Override + public void setParameter(String expr, Object value) { + adaptee.setParameter(expr, value); + } + + @Override + public void setValue(String expr, Object value, boolean throwExceptionOnFailure) { + adaptee.setValue(expr, value, throwExceptionOnFailure); + } + + @Override + public String findString(String expr) { + return adaptee.findString(expr); + } + + @Override + public String findString(String expr, boolean throwExceptionOnFailure) { + return adaptee.findString(expr, throwExceptionOnFailure); + } + + @Override + public Object findValue(String expr) { + return adaptee.findValue(expr); + } + + @Override + public Object findValue(String expr, boolean throwExceptionOnFailure) { + return adaptee.findValue(expr, throwExceptionOnFailure); + } + + @Override + public Object findValue(String expr, Class asType) { + return adaptee.findValue(expr, asType); + } + + @Override + public Object findValue(String expr, Class asType, boolean throwExceptionOnFailure) { + return adaptee.findValue(expr, asType, throwExceptionOnFailure); + } + + @Override + public Object peek() { + return adaptee.peek(); + } + + @Override + public Object pop() { + return adaptee.pop(); + } + + @Override + public void push(Object o) { + adaptee.push(o); + } + + @Override + public void set(String key, Object o) { + adaptee.set(key, o); + } + + @Override + public int size() { + return adaptee.size(); + } + } +} diff --git a/core/src/main/java/org/apache/struts2/ActionEventListener.java b/core/src/main/java/org/apache/struts2/ActionEventListener.java index 8c01a9a23a..23077cc9ab 100644 --- a/core/src/main/java/org/apache/struts2/ActionEventListener.java +++ b/core/src/main/java/org/apache/struts2/ActionEventListener.java @@ -18,7 +18,7 @@ */ package org.apache.struts2; -import com.opensymphony.xwork2.util.ValueStack; +import org.apache.struts2.util.ValueStack; /** * Provides hooks for handling key action events diff --git a/core/src/main/java/org/apache/struts2/ActionInvocation.java b/core/src/main/java/org/apache/struts2/ActionInvocation.java index e3d446bc05..5fcbc75ec9 100644 --- a/core/src/main/java/org/apache/struts2/ActionInvocation.java +++ b/core/src/main/java/org/apache/struts2/ActionInvocation.java @@ -19,8 +19,8 @@ package org.apache.struts2; import com.opensymphony.xwork2.ActionChainResult; -import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.interceptor.PreResultListener; +import org.apache.struts2.util.ValueStack; /** * An {@link ActionInvocation} represents the execution state of an {@link com.opensymphony.xwork2.Action}. It holds the Interceptors and the Action instance. diff --git a/core/src/main/java/org/apache/struts2/util/ValueStack.java b/core/src/main/java/org/apache/struts2/util/ValueStack.java new file mode 100644 index 0000000000..f7d70a35df --- /dev/null +++ b/core/src/main/java/org/apache/struts2/util/ValueStack.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.util; + +import com.opensymphony.xwork2.util.CompoundRoot; +import org.apache.struts2.ActionContext; + +import java.util.Map; + +/** + * ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When + * evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the + * earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending + * on the expression being evaluated). + */ +public interface ValueStack { + + String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack"; + + String REPORT_ERRORS_ON_NO_PROP = "com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp"; + + /** + * Gets the context for this value stack. The context holds all the information in the value stack and it's surroundings. + * + * @return the context. + */ + Map getContext(); + + ActionContext getActionContext(); + + /** + * Sets the default type to convert to if no type is provided when getting a value. + * + * @param defaultType the new default type + */ + void setDefaultType(Class defaultType); + + /** + * Set a override map containing key -> values that takes precedent when doing find operations on the ValueStack. + *

+ * See the unit test for ValueStackTest for examples. + *

+ * + * @param overrides overrides map. + */ + void setExprOverrides(Map overrides); + + /** + * Gets the override map if anyone exists. + * + * @return the override map, null if not set. + */ + Map getExprOverrides(); + + /** + * Get the CompoundRoot which holds the objects pushed onto the stack + * + * @return the root + */ + CompoundRoot getRoot(); + + /** + * Attempts to set a property on a bean in the stack with the given expression using the default search order. + * + * @param expr the expression defining the path to the property to be set. + * @param value the value to be set into the named property + */ + void setValue(String expr, Object value); + + /** + * Attempts to set a property on a bean in the stack with the given expression using the default search order. + * N.B.: unlike #setValue(String,Object) it doesn't allow eval expression. + * @param expr the expression defining the path to the property to be set. + * @param value the value to be set into the named property + */ + void setParameter(String expr, Object value); + + /** + * Attempts to set a property on a bean in the stack with the given expression using the default search order. + * + * @param expr the expression defining the path to the property to be set. + * @param value the value to be set into the named property + * @param throwExceptionOnFailure a flag to tell whether an exception should be thrown if there is no property with + * the given name. + */ + void setValue(String expr, Object value, boolean throwExceptionOnFailure); + + String findString(String expr); + String findString(String expr, boolean throwExceptionOnFailure); + + /** + * Find a value by evaluating the given expression against the stack in the default search order. + * + * @param expr the expression giving the path of properties to navigate to find the property value to return + * @return the result of evaluating the expression + */ + Object findValue(String expr); + + Object findValue(String expr, boolean throwExceptionOnFailure); + + /** + * Find a value by evaluating the given expression against the stack in the default search order. + * + * @param expr the expression giving the path of properties to navigate to find the property value to return + * @param asType the type to convert the return value to + * @return the result of evaluating the expression + */ + Object findValue(String expr, Class asType); + Object findValue(String expr, Class asType, boolean throwExceptionOnFailure); + + /** + * Get the object on the top of the stack without changing the stack. + * + * @return the object on the top. + * @see CompoundRoot#peek() + */ + Object peek(); + + /** + * Get the object on the top of the stack and remove it from the stack. + * + * @return the object on the top of the stack + * @see CompoundRoot#pop() + */ + Object pop(); + + /** + * Put this object onto the top of the stack + * + * @param o the object to be pushed onto the stack + * @see CompoundRoot#push(Object) + */ + void push(Object o); + + /** + * Sets an object on the stack with the given key + * so it is retrievable by {@link #findValue(String)}, {@link #findValue(String, Class)} + * + * @param key the key + * @param o the object + */ + void set(String key, Object o); + + /** + * Get the number of objects in the stack + * + * @return the number of objects in the stack + */ + int size(); + +} From 111bc256504d114bc1c42fa34e7bb05587398cd9 Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Thu, 17 Oct 2024 16:12:01 +1100 Subject: [PATCH 2/6] WW-3714 Deprecate and migrate assorted marker interfaces --- .../com/opensymphony/xwork2/ModelDriven.java | 16 +-- .../com/opensymphony/xwork2/Preparable.java | 17 +-- .../com/opensymphony/xwork2/Unchainable.java | 7 +- .../com/opensymphony/xwork2/Validateable.java | 15 +- .../xwork2/interceptor/ScopedModelDriven.java | 21 +-- .../xwork2/interceptor/ValidationAware.java | 111 +-------------- .../interceptor/ValidationErrorAware.java | 20 +-- .../interceptor/ValidationWorkflowAware.java | 10 +- .../java/org/apache/struts2/ModelDriven.java | 36 +++++ .../java/org/apache/struts2/Preparable.java | 37 +++++ .../java/org/apache/struts2/Unchainable.java | 27 ++++ .../java/org/apache/struts2/Validateable.java | 35 +++++ .../interceptor/ScopedModelDriven.java | 43 ++++++ .../struts2/interceptor/ValidationAware.java | 131 ++++++++++++++++++ .../interceptor/ValidationErrorAware.java | 40 ++++++ .../interceptor/ValidationWorkflowAware.java | 30 ++++ ...onfigurationProviderOgnlAllowlistTest.java | 12 +- 17 files changed, 412 insertions(+), 196 deletions(-) create mode 100644 core/src/main/java/org/apache/struts2/ModelDriven.java create mode 100644 core/src/main/java/org/apache/struts2/Preparable.java create mode 100644 core/src/main/java/org/apache/struts2/Unchainable.java create mode 100644 core/src/main/java/org/apache/struts2/Validateable.java create mode 100644 core/src/main/java/org/apache/struts2/interceptor/ScopedModelDriven.java create mode 100644 core/src/main/java/org/apache/struts2/interceptor/ValidationAware.java create mode 100644 core/src/main/java/org/apache/struts2/interceptor/ValidationErrorAware.java create mode 100644 core/src/main/java/org/apache/struts2/interceptor/ValidationWorkflowAware.java diff --git a/core/src/main/java/com/opensymphony/xwork2/ModelDriven.java b/core/src/main/java/com/opensymphony/xwork2/ModelDriven.java index c07c6bbe76..f3ae25cab2 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ModelDriven.java +++ b/core/src/main/java/com/opensymphony/xwork2/ModelDriven.java @@ -19,18 +19,8 @@ package com.opensymphony.xwork2; /** - * 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. - * - * @author Jason Carreira + * @deprecated since 6.7.0, use {@link org.apache.struts2.ModelDriven} instead. */ -public interface ModelDriven { - - /** - * Gets the model to be pushed onto the ValueStack instead of the Action itself. - * - * @return the model - */ - T getModel(); - +@Deprecated +public interface ModelDriven extends org.apache.struts2.ModelDriven { } diff --git a/core/src/main/java/com/opensymphony/xwork2/Preparable.java b/core/src/main/java/com/opensymphony/xwork2/Preparable.java index 23fdf68aec..2c03088e8d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/Preparable.java +++ b/core/src/main/java/com/opensymphony/xwork2/Preparable.java @@ -19,19 +19,8 @@ package com.opensymphony.xwork2; /** - * Preparable Actions will have their prepare() method called if the {@link com.opensymphony.xwork2.interceptor.PrepareInterceptor} - * is applied to the ActionConfig. - * - * @author Jason Carreira - * @see com.opensymphony.xwork2.interceptor.PrepareInterceptor + * @deprecated since 6.7.0, use {@link org.apache.struts2.Preparable} instead. */ -public interface Preparable { - - /** - * This method is called to allow the action to prepare itself. - * - * @throws Exception thrown if a system level exception occurs. - */ - void prepare() throws Exception; - +@Deprecated +public interface Preparable extends org.apache.struts2.Preparable { } diff --git a/core/src/main/java/com/opensymphony/xwork2/Unchainable.java b/core/src/main/java/com/opensymphony/xwork2/Unchainable.java index 9f96b92dc8..506f4f2831 100644 --- a/core/src/main/java/com/opensymphony/xwork2/Unchainable.java +++ b/core/src/main/java/com/opensymphony/xwork2/Unchainable.java @@ -19,9 +19,8 @@ package com.opensymphony.xwork2; /** - * Simple marker interface to indicate an object should not have its properties copied during chaining. - * - * @see com.opensymphony.xwork2.interceptor.ChainingInterceptor + * @deprecated since 6.7.0, use {@link org.apache.struts2.Unchainable} instead. */ -public interface Unchainable { +@Deprecated +public interface Unchainable extends org.apache.struts2.Unchainable { } diff --git a/core/src/main/java/com/opensymphony/xwork2/Validateable.java b/core/src/main/java/com/opensymphony/xwork2/Validateable.java index ed72263801..c92170e732 100644 --- a/core/src/main/java/com/opensymphony/xwork2/Validateable.java +++ b/core/src/main/java/com/opensymphony/xwork2/Validateable.java @@ -19,17 +19,8 @@ package com.opensymphony.xwork2; /** - * Provides an interface in which a call for a validation check can be done. - * - * @author Jason Carreira - * @see ActionSupport - * @see com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor + * @deprecated since 6.7.0, use {@link org.apache.struts2.Validateable} instead. */ -public interface Validateable { - - /** - * Performs validation. - */ - void validate(); - +@Deprecated +public interface Validateable extends org.apache.struts2.Validateable { } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDriven.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDriven.java index 42ddb09b32..d5413b4e59 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDriven.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDriven.java @@ -21,23 +21,8 @@ import com.opensymphony.xwork2.ModelDriven; /** - * Adds the ability to set a model, probably retrieved from a given state. + * @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.ScopedModelDriven} instead. */ -public interface ScopedModelDriven extends ModelDriven { - - /** - * @param model sets the model - */ - void setModel(T model); - - /** - * Sets the key under which the model is stored - * @param key The model key - */ - void setScopeKey(String key); - - /** - * @return the key under which the model is stored - */ - String getScopeKey(); +@Deprecated +public interface ScopedModelDriven extends org.apache.struts2.interceptor.ScopedModelDriven, ModelDriven { } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationAware.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationAware.java index 485cb42fb6..c959f19d77 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationAware.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationAware.java @@ -18,114 +18,9 @@ */ package com.opensymphony.xwork2.interceptor; -import java.util.Collection; -import java.util.List; -import java.util.Map; - /** - * ValidationAware classes can accept Action (class level) or field level error messages. Action level messages are kept - * in a Collection. Field level error messages are kept in a Map from String field name to a List of field error msgs. + * @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.ValidationAware} instead. */ -public interface ValidationAware { - - /** - * Set the Collection of Action-level String error messages. - * - * @param errorMessages Collection of String error messages - */ - void setActionErrors(Collection errorMessages); - - /** - * Get the Collection of Action-level error messages for this action. Error messages should not - * be added directly here, as implementations are free to return a new Collection or an - * Unmodifiable Collection. - * - * @return Collection of String error messages - */ - Collection getActionErrors(); - - /** - * Set the Collection of Action-level String messages (not errors). - * - * @param messages Collection of String messages (not errors). - */ - void setActionMessages(Collection messages); - - /** - * Get the Collection of Action-level messages for this action. Messages should not be added - * directly here, as implementations are free to return a new Collection or an Unmodifiable - * Collection. - * - * @return Collection of String messages - */ - Collection getActionMessages(); - - /** - * Set the field error map of fieldname (String) to Collection of String error messages. - * - * @param errorMap field error map - */ - void setFieldErrors(Map> errorMap); - - /** - * Get the field specific errors associated with this action. Error messages should not be added - * directly here, as implementations are free to return a new Collection or an Unmodifiable - * Collection. - * - * @return Map with errors mapped from fieldname (String) to Collection of String error messages - */ - Map> getFieldErrors(); - - /** - * Add an Action-level error message to this Action. - * - * @param anErrorMessage the error message - */ - void addActionError(String anErrorMessage); - - /** - * Add an Action-level message to this Action. - * - * @param aMessage the message - */ - void addActionMessage(String aMessage); - - /** - * Add an error message for a given field. - * - * @param fieldName name of field - * @param errorMessage the error message - */ - void addFieldError(String fieldName, String errorMessage); - - /** - * Check whether there are any Action-level error messages. - * - * @return true if any Action-level error messages have been registered - */ - boolean hasActionErrors(); - - /** - * Checks whether there are any Action-level messages. - * - * @return true if any Action-level messages have been registered - */ - boolean hasActionMessages(); - - /** - * Checks whether there are any action errors or field errors. - * - * @return (hasActionErrors() || hasFieldErrors()) - */ - default boolean hasErrors() { - return hasActionErrors() || hasFieldErrors(); - } - - /** - * Check whether there are any field errors associated with this action. - * - * @return whether there are any field errors - */ - boolean hasFieldErrors(); - +@Deprecated +public interface ValidationAware extends org.apache.struts2.interceptor.ValidationAware { } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationErrorAware.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationErrorAware.java index 4d04fa6dc6..184cf13399 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationErrorAware.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationErrorAware.java @@ -19,22 +19,8 @@ package com.opensymphony.xwork2.interceptor; /** - * ValidationErrorAware classes can be notified about validation errors - * before {@link com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor} will return 'inputResultName' result - * to allow change or not the result name - * - * This interface can be only applied to action which already implements {@link ValidationAware} interface! - * - * @since 2.3.15 + * @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.ValidationErrorAware} instead. */ -public interface ValidationErrorAware { - - /** - * Allows to notify action about occurred action/field errors - * - * @param currentResultName current result name, action can change it or return the same - * @return new result name or passed currentResultName - */ - String actionErrorOccurred(final String currentResultName); - +@Deprecated +public interface ValidationErrorAware extends org.apache.struts2.interceptor.ValidationErrorAware { } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationWorkflowAware.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationWorkflowAware.java index b6c25ed318..fc0218d43a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationWorkflowAware.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationWorkflowAware.java @@ -19,12 +19,8 @@ package com.opensymphony.xwork2.interceptor; /** - * ValidationWorkflowAware classes can programmatically change result name when errors occurred - * - * This interface can be only applied to action which already implements {@link ValidationAware} interface! + * @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.ValidationWorkflowAware} instead. */ -public interface ValidationWorkflowAware { - - String getInputResultName(); - +@Deprecated +public interface ValidationWorkflowAware extends org.apache.struts2.interceptor.ValidationWorkflowAware { } diff --git a/core/src/main/java/org/apache/struts2/ModelDriven.java b/core/src/main/java/org/apache/struts2/ModelDriven.java new file mode 100644 index 0000000000..0704109f15 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/ModelDriven.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2; + +/** + * 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. + * + * @author Jason Carreira + */ +public interface ModelDriven { + + /** + * Gets the model to be pushed onto the ValueStack instead of the Action itself. + * + * @return the model + */ + T getModel(); + +} diff --git a/core/src/main/java/org/apache/struts2/Preparable.java b/core/src/main/java/org/apache/struts2/Preparable.java new file mode 100644 index 0000000000..70b0f464dd --- /dev/null +++ b/core/src/main/java/org/apache/struts2/Preparable.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2; + +/** + * Preparable Actions will have their prepare() method called if the {@link com.opensymphony.xwork2.interceptor.PrepareInterceptor} + * is applied to the ActionConfig. + * + * @author Jason Carreira + * @see com.opensymphony.xwork2.interceptor.PrepareInterceptor + */ +public interface Preparable { + + /** + * This method is called to allow the action to prepare itself. + * + * @throws Exception thrown if a system level exception occurs. + */ + void prepare() throws Exception; + +} diff --git a/core/src/main/java/org/apache/struts2/Unchainable.java b/core/src/main/java/org/apache/struts2/Unchainable.java new file mode 100644 index 0000000000..02e0101422 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/Unchainable.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2; + +/** + * Simple marker interface to indicate an object should not have its properties copied during chaining. + * + * @see com.opensymphony.xwork2.interceptor.ChainingInterceptor + */ +public interface Unchainable { +} diff --git a/core/src/main/java/org/apache/struts2/Validateable.java b/core/src/main/java/org/apache/struts2/Validateable.java new file mode 100644 index 0000000000..d563e7905d --- /dev/null +++ b/core/src/main/java/org/apache/struts2/Validateable.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2; + +/** + * Provides an interface in which a call for a validation check can be done. + * + * @author Jason Carreira + * @see com.opensymphony.xwork2.ActionSupport + * @see com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor + */ +public interface Validateable { + + /** + * Performs validation. + */ + void validate(); + +} diff --git a/core/src/main/java/org/apache/struts2/interceptor/ScopedModelDriven.java b/core/src/main/java/org/apache/struts2/interceptor/ScopedModelDriven.java new file mode 100644 index 0000000000..d18ef08801 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/ScopedModelDriven.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.interceptor; + +import org.apache.struts2.ModelDriven; + +/** + * Adds the ability to set a model, probably retrieved from a given state. + */ +public interface ScopedModelDriven extends ModelDriven { + + /** + * @param model sets the model + */ + void setModel(T model); + + /** + * Sets the key under which the model is stored + * @param key The model key + */ + void setScopeKey(String key); + + /** + * @return the key under which the model is stored + */ + String getScopeKey(); +} diff --git a/core/src/main/java/org/apache/struts2/interceptor/ValidationAware.java b/core/src/main/java/org/apache/struts2/interceptor/ValidationAware.java new file mode 100644 index 0000000000..a1e611a1cc --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/ValidationAware.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.interceptor; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * ValidationAware classes can accept Action (class level) or field level error messages. Action level messages are kept + * in a Collection. Field level error messages are kept in a Map from String field name to a List of field error msgs. + */ +public interface ValidationAware { + + /** + * Set the Collection of Action-level String error messages. + * + * @param errorMessages Collection of String error messages + */ + void setActionErrors(Collection errorMessages); + + /** + * Get the Collection of Action-level error messages for this action. Error messages should not + * be added directly here, as implementations are free to return a new Collection or an + * Unmodifiable Collection. + * + * @return Collection of String error messages + */ + Collection getActionErrors(); + + /** + * Set the Collection of Action-level String messages (not errors). + * + * @param messages Collection of String messages (not errors). + */ + void setActionMessages(Collection messages); + + /** + * Get the Collection of Action-level messages for this action. Messages should not be added + * directly here, as implementations are free to return a new Collection or an Unmodifiable + * Collection. + * + * @return Collection of String messages + */ + Collection getActionMessages(); + + /** + * Set the field error map of fieldname (String) to Collection of String error messages. + * + * @param errorMap field error map + */ + void setFieldErrors(Map> errorMap); + + /** + * Get the field specific errors associated with this action. Error messages should not be added + * directly here, as implementations are free to return a new Collection or an Unmodifiable + * Collection. + * + * @return Map with errors mapped from fieldname (String) to Collection of String error messages + */ + Map> getFieldErrors(); + + /** + * Add an Action-level error message to this Action. + * + * @param anErrorMessage the error message + */ + void addActionError(String anErrorMessage); + + /** + * Add an Action-level message to this Action. + * + * @param aMessage the message + */ + void addActionMessage(String aMessage); + + /** + * Add an error message for a given field. + * + * @param fieldName name of field + * @param errorMessage the error message + */ + void addFieldError(String fieldName, String errorMessage); + + /** + * Check whether there are any Action-level error messages. + * + * @return true if any Action-level error messages have been registered + */ + boolean hasActionErrors(); + + /** + * Checks whether there are any Action-level messages. + * + * @return true if any Action-level messages have been registered + */ + boolean hasActionMessages(); + + /** + * Checks whether there are any action errors or field errors. + * + * @return (hasActionErrors() || hasFieldErrors()) + */ + default boolean hasErrors() { + return hasActionErrors() || hasFieldErrors(); + } + + /** + * Check whether there are any field errors associated with this action. + * + * @return whether there are any field errors + */ + boolean hasFieldErrors(); + +} diff --git a/core/src/main/java/org/apache/struts2/interceptor/ValidationErrorAware.java b/core/src/main/java/org/apache/struts2/interceptor/ValidationErrorAware.java new file mode 100644 index 0000000000..7722ed9ec6 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/ValidationErrorAware.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.interceptor; + +/** + * ValidationErrorAware classes can be notified about validation errors + * before {@link com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor} will return 'inputResultName' result + * to allow change or not the result name + * + * This interface can be only applied to action which already implements {@link ValidationAware} interface! + * + * @since 2.3.15 + */ +public interface ValidationErrorAware { + + /** + * Allows to notify action about occurred action/field errors + * + * @param currentResultName current result name, action can change it or return the same + * @return new result name or passed currentResultName + */ + String actionErrorOccurred(final String currentResultName); + +} diff --git a/core/src/main/java/org/apache/struts2/interceptor/ValidationWorkflowAware.java b/core/src/main/java/org/apache/struts2/interceptor/ValidationWorkflowAware.java new file mode 100644 index 0000000000..e3f4a43850 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/ValidationWorkflowAware.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.interceptor; + +/** + * ValidationWorkflowAware classes can programmatically change result name when errors occurred + * + * This interface can be only applied to action which already implements {@link ValidationAware} interface! + */ +public interface ValidationWorkflowAware { + + String getInputResultName(); + +} diff --git a/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java b/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java index 0349f6812b..2379216bc5 100644 --- a/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationProviderOgnlAllowlistTest.java @@ -65,7 +65,9 @@ public void allowlist() throws Exception { Class.forName("org.apache.struts2.interceptor.Interceptor"), Class.forName("org.apache.struts2.interceptor.ConditionalInterceptor"), Class.forName("org.apache.struts2.Result"), - Class.forName("org.apache.struts2.Action") + Class.forName("org.apache.struts2.Action"), + Class.forName("org.apache.struts2.Validateable"), + Class.forName("org.apache.struts2.interceptor.ValidationAware") ); } @@ -93,7 +95,9 @@ public void allowlist_1only() throws Exception { Class.forName("org.apache.struts2.interceptor.Interceptor"), Class.forName("org.apache.struts2.interceptor.ConditionalInterceptor"), Class.forName("org.apache.struts2.Result"), - Class.forName("org.apache.struts2.Action") + Class.forName("org.apache.struts2.Action"), + Class.forName("org.apache.struts2.Validateable"), + Class.forName("org.apache.struts2.interceptor.ValidationAware") ); } @@ -120,7 +124,9 @@ public void allowlist_2only() throws Exception { Class.forName("org.apache.struts2.interceptor.Interceptor"), Class.forName("org.apache.struts2.interceptor.ConditionalInterceptor"), Class.forName("org.apache.struts2.Result"), - Class.forName("org.apache.struts2.Action") + Class.forName("org.apache.struts2.Action"), + Class.forName("org.apache.struts2.Validateable"), + Class.forName("org.apache.struts2.interceptor.ValidationAware") ); } } From dfd07190bdb0dde410b8bb0478e6f105dbb569ba Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Thu, 17 Oct 2024 17:27:47 +1100 Subject: [PATCH 3/6] WW-3714 Update new ActionContext with new ValueStack --- .../main/java/com/opensymphony/xwork2/ActionContext.java | 8 ++++++-- core/src/main/java/org/apache/struts2/ActionContext.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java index 786c896d2f..1e6d1efbd1 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java @@ -163,15 +163,19 @@ public Map getSession() { return super.getSession(); } - @Override public ActionContext withValueStack(ValueStack valueStack) { + return withValueStack((org.apache.struts2.util.ValueStack) valueStack); + } + + @Override + public ActionContext withValueStack(org.apache.struts2.util.ValueStack valueStack) { super.withValueStack(valueStack); return this; } @Override public ValueStack getValueStack() { - return super.getValueStack(); + return ValueStack.adapt(super.getValueStack()); } @Override diff --git a/core/src/main/java/org/apache/struts2/ActionContext.java b/core/src/main/java/org/apache/struts2/ActionContext.java index bfde35f124..79f7552d52 100644 --- a/core/src/main/java/org/apache/struts2/ActionContext.java +++ b/core/src/main/java/org/apache/struts2/ActionContext.java @@ -20,9 +20,9 @@ import com.opensymphony.xwork2.conversion.impl.ConversionData; import com.opensymphony.xwork2.inject.Container; -import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.dispatcher.mapper.ActionMapping; +import org.apache.struts2.util.ValueStack; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; From 7ce8f484e0eb929b11532caa5864aba314149f0e Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Thu, 17 Oct 2024 16:51:29 +1100 Subject: [PATCH 4/6] WW-3714 Shortcut adapters --- core/src/main/java/com/opensymphony/xwork2/ActionContext.java | 3 +++ .../main/java/com/opensymphony/xwork2/ActionEventListener.java | 3 +++ .../main/java/com/opensymphony/xwork2/ActionInvocation.java | 3 +++ core/src/main/java/com/opensymphony/xwork2/ActionProxy.java | 3 +++ core/src/main/java/com/opensymphony/xwork2/Result.java | 3 +++ .../com/opensymphony/xwork2/interceptor/PreResultListener.java | 3 +++ .../src/main/java/com/opensymphony/xwork2/util/ValueStack.java | 3 +++ 7 files changed, 21 insertions(+) diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java index 1e6d1efbd1..ac9026b6f4 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java @@ -44,6 +44,9 @@ private ActionContext(org.apache.struts2.ActionContext actualContext) { } public static ActionContext adapt(org.apache.struts2.ActionContext actualContext) { + if (actualContext instanceof ActionContext) { + return (ActionContext) actualContext; + } return actualContext != null ? new ActionContext(actualContext) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java b/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java index 5bd4f86d5a..28d46e9923 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionEventListener.java @@ -43,6 +43,9 @@ default String handleException(Throwable t, org.apache.struts2.util.ValueStack s String handleException(Throwable t, ValueStack stack); static ActionEventListener adapt(org.apache.struts2.ActionEventListener actualListener) { + if (actualListener instanceof ActionEventListener) { + return (ActionEventListener) actualListener; + } return actualListener != null ? new LegacyAdapter(actualListener) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionInvocation.java b/core/src/main/java/com/opensymphony/xwork2/ActionInvocation.java index 76929a647f..81e55d592d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionInvocation.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionInvocation.java @@ -63,6 +63,9 @@ default void init(org.apache.struts2.ActionProxy proxy) { void init(ActionProxy proxy); static ActionInvocation adapt(org.apache.struts2.ActionInvocation actualInvocation) { + if (actualInvocation instanceof ActionInvocation) { + return (ActionInvocation) actualInvocation; + } return actualInvocation != null ? new LegacyAdapter(actualInvocation) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionProxy.java b/core/src/main/java/com/opensymphony/xwork2/ActionProxy.java index 18a1e6a6e3..c3905a1a09 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionProxy.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionProxy.java @@ -27,6 +27,9 @@ public interface ActionProxy extends org.apache.struts2.ActionProxy { ActionInvocation getInvocation(); static ActionProxy adapt(org.apache.struts2.ActionProxy actualProxy) { + if (actualProxy instanceof ActionProxy) { + return (ActionProxy) actualProxy; + } return actualProxy != null ? new LegacyAdapter(actualProxy) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/Result.java b/core/src/main/java/com/opensymphony/xwork2/Result.java index 294ada4d71..36a93438a7 100644 --- a/core/src/main/java/com/opensymphony/xwork2/Result.java +++ b/core/src/main/java/com/opensymphony/xwork2/Result.java @@ -34,6 +34,9 @@ default void execute(org.apache.struts2.ActionInvocation invocation) throws Exce void execute(ActionInvocation invocation) throws Exception; static Result adapt(org.apache.struts2.Result actualResult) { + if (actualResult instanceof Result) { + return (Result) actualResult; + } return actualResult != null ? new LegacyAdapter(actualResult) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/PreResultListener.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/PreResultListener.java index 469d3521bd..25ba59a42c 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/PreResultListener.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/PreResultListener.java @@ -36,6 +36,9 @@ default void beforeResult(org.apache.struts2.ActionInvocation invocation, String void beforeResult(ActionInvocation invocation, String resultCode); static PreResultListener adapt(org.apache.struts2.interceptor.PreResultListener actualListener) { + if (actualListener instanceof PreResultListener) { + return (PreResultListener) actualListener; + } return actualListener != null ? new LegacyAdapter(actualListener) : null; } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java b/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java index 9e3e98b57b..22f5bc428b 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/ValueStack.java @@ -32,6 +32,9 @@ public interface ValueStack extends org.apache.struts2.util.ValueStack { ActionContext getActionContext(); static ValueStack adapt(org.apache.struts2.util.ValueStack actualStack) { + if (actualStack instanceof ValueStack) { + return (ValueStack) actualStack; + } return actualStack != null ? new LegacyAdapter(actualStack) : null; } From ebedd7391fec19a039d00190d97bbd5705f2f45d Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Thu, 17 Oct 2024 19:28:41 +1100 Subject: [PATCH 5/6] WW-3714 Marker interface migration follow-up --- .../xwork2/interceptor/AliasInterceptor.java | 9 ++-- .../interceptor/ChainingInterceptor.java | 15 ++++-- .../ConversionErrorInterceptor.java | 1 + .../DefaultWorkflowInterceptor.java | 3 ++ .../interceptor/ModelDrivenInterceptor.java | 2 +- .../interceptor/PrepareInterceptor.java | 4 +- .../ScopedModelDrivenInterceptor.java | 1 + .../StaticParametersInterceptor.java | 3 +- .../util/StrutsLocalizedTextProvider.java | 6 +-- .../validator/ValidationInterceptor.java | 52 +++++++++---------- .../AbstractFileUploadInterceptor.java | 1 - .../ActionFileUploadInterceptor.java | 1 - .../interceptor/MessageStoreInterceptor.java | 5 +- .../MessageStorePreResultListener.java | 1 - .../BeanValidationInterceptor.java | 2 +- .../struts2/validators/DWRValidator.java | 2 +- .../org/apache/struts2/json/JSONResult.java | 2 +- .../json/JSONValidationInterceptor.java | 8 +-- .../OValValidationInterceptor.java | 3 +- .../struts2/rest/ContentTypeInterceptor.java | 2 +- .../struts2/rest/RestActionInvocation.java | 12 +++-- .../struts2/rest/RestWorkflowInterceptor.java | 2 +- .../struts2/rest/handler/XStreamHandler.java | 2 +- 23 files changed, 73 insertions(+), 66 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java index 9edafe3fc4..334525d277 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java @@ -20,21 +20,22 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.LocalizedTextProvider; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.security.AcceptedPatternsChecker; import com.opensymphony.xwork2.security.ExcludedPatternsChecker; import com.opensymphony.xwork2.util.ClearableValueStack; import com.opensymphony.xwork2.util.Evaluated; -import com.opensymphony.xwork2.LocalizedTextProvider; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.ValueStackFactory; import com.opensymphony.xwork2.util.reflection.ReflectionContextState; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.StrutsConstants; import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.dispatcher.Parameter; -import org.apache.struts2.StrutsConstants; +import org.apache.struts2.interceptor.ValidationAware; import java.util.Map; @@ -108,7 +109,7 @@ public class AliasInterceptor extends AbstractInterceptor { @Inject(StrutsConstants.STRUTS_DEVMODE) public void setDevMode(String mode) { this.devMode = Boolean.parseBoolean(mode); - } + } @Inject public void setValueStackFactory(ValueStackFactory valueStackFactory) { @@ -225,7 +226,7 @@ public void setAliasesKey(String aliasesKey) { LOG.debug("invalid alias expression: {}", aliasesKey); } } - + return invocation.invoke(); } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java index 31b0075a35..7284dc037d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java @@ -21,18 +21,23 @@ import com.opensymphony.xwork2.ActionChainResult; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Result; -import com.opensymphony.xwork2.Unchainable; import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.util.ProxyUtil; import com.opensymphony.xwork2.util.CompoundRoot; +import com.opensymphony.xwork2.util.ProxyUtil; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; import com.opensymphony.xwork2.util.reflection.ReflectionProvider; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.struts2.StrutsConstants; +import org.apache.struts2.Unchainable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; /** diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java index ee8e392815..b549cc0196 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java @@ -24,6 +24,7 @@ import com.opensymphony.xwork2.conversion.impl.XWorkConverter; import com.opensymphony.xwork2.util.ValueStack; import org.apache.commons.text.StringEscapeUtils; +import org.apache.struts2.interceptor.ValidationAware; import java.util.HashMap; import java.util.Map; diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java index d2cbd0b780..05749ae195 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java @@ -25,6 +25,9 @@ import org.apache.commons.lang3.reflect.MethodUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.interceptor.ValidationAware; +import org.apache.struts2.interceptor.ValidationErrorAware; +import org.apache.struts2.interceptor.ValidationWorkflowAware; /** * diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java index fa90a315ca..f513deb1c6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java @@ -19,9 +19,9 @@ package com.opensymphony.xwork2.interceptor; import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.util.CompoundRoot; import com.opensymphony.xwork2.util.ValueStack; +import org.apache.struts2.ModelDriven; /** * diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java index 4516d760c6..e4d5af634f 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java @@ -19,9 +19,7 @@ package com.opensymphony.xwork2.interceptor; import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.Preparable; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; +import org.apache.struts2.Preparable; import java.lang.reflect.InvocationTargetException; diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java index 22da179d46..ae2266be0e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java @@ -24,6 +24,7 @@ import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.inject.Inject; import org.apache.struts2.StrutsException; +import org.apache.struts2.interceptor.ScopedModelDriven; import java.lang.reflect.Method; import java.util.Map; diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java index 9d32a8a184..d560e1dd44 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java @@ -20,11 +20,11 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.LocalizedTextProvider; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.Parameterizable; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ClearableValueStack; -import com.opensymphony.xwork2.LocalizedTextProvider; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.ValueStackFactory; @@ -34,6 +34,7 @@ import org.apache.logging.log4j.Logger; import org.apache.struts2.StrutsConstants; import org.apache.struts2.dispatcher.HttpParameters; +import org.apache.struts2.interceptor.ValidationAware; import java.util.Collections; import java.util.Map; diff --git a/core/src/main/java/com/opensymphony/xwork2/util/StrutsLocalizedTextProvider.java b/core/src/main/java/com/opensymphony/xwork2/util/StrutsLocalizedTextProvider.java index 48acc42740..60ef3477a3 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/StrutsLocalizedTextProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/StrutsLocalizedTextProvider.java @@ -20,11 +20,11 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.conversion.impl.XWorkConverter; import com.opensymphony.xwork2.util.reflection.ReflectionProviderFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.ModelDriven; import java.beans.PropertyDescriptor; import java.util.Locale; @@ -135,7 +135,7 @@ public String findText(Class aClass, String aTextName, Locale locale) { * object. If so, repeat the entire process from the beginning with the object's class as * aClass and "address.state" as the message key. *
  • If not found, look for the message in aClass' package hierarchy.
  • - *
  • If still not found, look for the message in the default resource bundles + *
  • If still not found, look for the message in the default resource bundles * (Note: the lookup is not repeated again if {@link #searchDefaultBundlesFirst} was true).
  • *
  • Return defaultMessage
  • * @@ -190,7 +190,7 @@ public String findText(Class aClass, String aTextName, Locale locale, String def * object. If so, repeat the entire process from the beginning with the object's class as * aClass and "address.state" as the message key. *
  • If not found, look for the message in aClass' package hierarchy.
  • - *
  • If still not found, look for the message in the default resource bundles + *
  • If still not found, look for the message in the default resource bundles * (Note: the lookup is not repeated again if {@link #searchDefaultBundlesFirst} was true).
  • *
  • Return defaultMessage
  • * diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java index b0852ed035..cc22250e3f 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java @@ -20,13 +20,13 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; -import com.opensymphony.xwork2.Validateable; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; import com.opensymphony.xwork2.interceptor.PrefixMethodInvocationUtil; import com.opensymphony.xwork2.interceptor.ValidationAware; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.Validateable; /** * @@ -71,9 +71,9 @@ *
  • programmatic - Defaults to true. If true and the action is Validateable call validate(), * and any method that starts with "validate". *
  • - * + * *
  • declarative - Defaults to true. Perform validation based on xml or annotations.
  • - * + * * * * @@ -90,14 +90,14 @@ * *
      * 
    - * 
    + *
      * <action name="someAction" class="com.examples.SomeAction">
      *     <interceptor-ref name="params"/>
      *     <interceptor-ref name="validation"/>
      *     <interceptor-ref name="workflow"/>
      *     <result name="success">good_result.ftl</result>
      * </action>
    - * 
    + *
      * <-- in the following case myMethod of the action class will not
      *        get validated -->
      * <action name="someAction" class="com.examples.SomeAction">
    @@ -108,7 +108,7 @@
      *     <interceptor-ref name="workflow"/>
      *     <result name="success">good_result.ftl</result>
      * </action>
    - * 
    + *
      * <-- in the following case only annotated methods of the action class will
      *        be validated -->
      * <action name="someAction" class="com.examples.SomeAction">
    @@ -138,9 +138,9 @@ public class ValidationInterceptor extends MethodFilterInterceptor {
         private final static String ALT_VALIDATE_PREFIX = "validateDo";
     
         private boolean validateAnnotatedMethodOnly;
    -    
    +
         private ActionValidatorManager actionValidatorManager;
    -    
    +
         private boolean alwaysInvokeValidate = true;
         private boolean programmatic = true;
         private boolean declarative = true;
    @@ -149,11 +149,11 @@ public class ValidationInterceptor extends MethodFilterInterceptor {
         public void setActionValidatorManager(ActionValidatorManager mgr) {
             this.actionValidatorManager = mgr;
         }
    -    
    +
         /**
          * Determines if {@link Validateable}'s validate() should be called,
          * as well as methods whose name that start with "validate". Defaults to "true".
    -     * 
    +     *
          * @param programmatic true then validate() is invoked.
          */
         public void setProgrammatic(boolean programmatic) {
    @@ -161,9 +161,9 @@ public void setProgrammatic(boolean programmatic) {
         }
     
         /**
    -     * Determines if validation based on annotations or xml should be performed. Defaults 
    +     * Determines if validation based on annotations or xml should be performed. Defaults
          * to "true".
    -     * 
    +     *
          * @param declarative true then perform validation based on annotations or xml.
          */
         public void setDeclarative(boolean declarative) {
    @@ -171,9 +171,9 @@ public void setDeclarative(boolean declarative) {
         }
     
         /**
    -     * Determines if {@link Validateable}'s validate() should always 
    +     * Determines if {@link Validateable}'s validate() should always
          * be invoked. Default to "true".
    -     * 
    +     *
          * @param alwaysInvokeValidate true then validate() is always invoked.
          */
         public void setAlwaysInvokeValidate(String alwaysInvokeValidate) {
    @@ -218,7 +218,7 @@ protected void doBeforeInvocation(ActionInvocation invocation) throws Exception
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Validating {}/{} with method {}.", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName(), method);
             }
    -        
    +
     
             if (declarative) {
                if (validateAnnotatedMethodOnly) {
    @@ -226,12 +226,12 @@ protected void doBeforeInvocation(ActionInvocation invocation) throws Exception
                } else {
                    actionValidatorManager.validate(action, context);
                }
    -       }    
    -        
    +       }
    +
             if (action instanceof Validateable && programmatic) {
                 // keep exception that might occured in validateXXX or validateDoXXX
    -            Exception exception = null; 
    -            
    +            Exception exception = null;
    +
                 Validateable validateable = (Validateable) action;
                 LOG.debug("Invoking validate() on action {}", validateable);
     
    @@ -239,19 +239,19 @@ protected void doBeforeInvocation(ActionInvocation invocation) throws Exception
                     PrefixMethodInvocationUtil.invokePrefixMethod(invocation, new String[]{VALIDATE_PREFIX, ALT_VALIDATE_PREFIX});
                 }
                 catch(Exception e) {
    -                // If any exception occurred while doing reflection, we want 
    +                // If any exception occurred while doing reflection, we want
                     // validate() to be executed
                     LOG.warn("an exception occured while executing the prefix method", e);
                     exception = e;
                 }
    -            
    -            
    +
    +
                 if (alwaysInvokeValidate) {
                     validateable.validate();
                 }
    -            
    -            if (exception != null) { 
    -                // rethrow if something is wrong while doing validateXXX / validateDoXXX 
    +
    +            if (exception != null) {
    +                // rethrow if something is wrong while doing validateXXX / validateDoXXX
                     throw exception;
                 }
             }
    @@ -262,7 +262,7 @@ protected String doIntercept(ActionInvocation invocation) throws Exception {
             doBeforeInvocation(invocation);
             return invocation.invoke();
         }
    -    
    +
         /**
          * 

    * Returns the context that will be used by the diff --git a/core/src/main/java/org/apache/struts2/interceptor/AbstractFileUploadInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/AbstractFileUploadInterceptor.java index 1113f44916..ecebd3748f 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/AbstractFileUploadInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/AbstractFileUploadInterceptor.java @@ -25,7 +25,6 @@ import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; -import com.opensymphony.xwork2.interceptor.ValidationAware; import com.opensymphony.xwork2.util.TextParseUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/core/src/main/java/org/apache/struts2/interceptor/ActionFileUploadInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/ActionFileUploadInterceptor.java index c42d125af0..681a8ab92e 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/ActionFileUploadInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/ActionFileUploadInterceptor.java @@ -20,7 +20,6 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; -import com.opensymphony.xwork2.interceptor.ValidationAware; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.action.UploadedFilesAware; diff --git a/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java index 1596be5898..1d15228282 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java @@ -18,14 +18,11 @@ */ package org.apache.struts2.interceptor; -import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.interceptor.ValidationAware; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.dispatcher.HttpParameters; - import org.apache.struts2.result.ServletRedirectResult; import java.util.ArrayList; @@ -58,7 +55,7 @@ * *

    * In the 'AUTOMATIC' mode, the interceptor will always retrieve the stored action's message / errors - * and field errors and put them back into the {@link ValidationAware} action, and after Action execution, + * and field errors and put them back into the {@link ValidationAware} action, and after Action execution, * if the {@link com.opensymphony.xwork2.Result} is an instance of {@link ServletRedirectResult}, the action's message / errors * and field errors into automatically be stored in the HTTP session.. *

    diff --git a/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java b/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java index bf40e148bb..6c6dc8041d 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java +++ b/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java @@ -21,7 +21,6 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.config.entities.ResultConfig; import com.opensymphony.xwork2.interceptor.PreResultListener; -import com.opensymphony.xwork2.interceptor.ValidationAware; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.ServletActionContext; diff --git a/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/validation/interceptor/BeanValidationInterceptor.java b/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/validation/interceptor/BeanValidationInterceptor.java index 75c25f9c35..e36e3c63cf 100644 --- a/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/validation/interceptor/BeanValidationInterceptor.java +++ b/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/validation/interceptor/BeanValidationInterceptor.java @@ -20,7 +20,6 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; -import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.TextProviderFactory; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; @@ -33,6 +32,7 @@ import org.apache.logging.log4j.Logger; import org.apache.struts.beanvalidation.constraints.ValidationGroup; import org.apache.struts.beanvalidation.validation.constant.ValidatorConstants; +import org.apache.struts2.ModelDriven; import org.apache.struts2.interceptor.validation.SkipValidation; import javax.validation.ConstraintViolation; diff --git a/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java b/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java index f189cd1820..46c2953b58 100644 --- a/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java +++ b/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java @@ -24,7 +24,6 @@ import com.opensymphony.xwork2.DefaultActionInvocation; import com.opensymphony.xwork2.ValidationAwareSupport; import com.opensymphony.xwork2.config.entities.ActionConfig; -import com.opensymphony.xwork2.interceptor.ValidationAware; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.dispatcher.ApplicationMap; @@ -32,6 +31,7 @@ import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.dispatcher.RequestMap; import org.apache.struts2.dispatcher.SessionMap; +import org.apache.struts2.interceptor.ValidationAware; import org.directwebremoting.WebContextFactory; import javax.servlet.ServletContext; diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java index 2161ef0c16..6d9a8d0264 100644 --- a/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java +++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java @@ -20,7 +20,6 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.Result; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; @@ -29,6 +28,7 @@ import org.apache.commons.lang3.StringUtils; 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.json.smd.SMDGenerator; diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java index 4e59389047..354780b380 100644 --- a/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java +++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONValidationInterceptor.java @@ -20,13 +20,13 @@ import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ModelDriven; -import com.opensymphony.xwork2.interceptor.ValidationAware; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; import org.apache.commons.text.StringEscapeUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.struts2.ModelDriven; import org.apache.struts2.ServletActionContext; +import org.apache.struts2.interceptor.ValidationAware; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; diff --git a/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java b/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java index 0bb2bba884..0350c027dc 100644 --- a/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java +++ b/plugins/oval/src/main/java/org/apache/struts2/oval/interceptor/OValValidationInterceptor.java @@ -21,9 +21,7 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; -import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.TextProviderFactory; -import com.opensymphony.xwork2.Validateable; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; import com.opensymphony.xwork2.interceptor.PrefixMethodInvocationUtil; @@ -48,6 +46,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.Validateable; import org.apache.struts2.oval.annotation.Profiles; import java.lang.reflect.Field; diff --git a/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java b/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java index 03d299c869..01a28e6c57 100644 --- a/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java +++ b/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java @@ -19,9 +19,9 @@ package org.apache.struts2.rest; import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; +import org.apache.struts2.ModelDriven; import org.apache.struts2.ServletActionContext; import org.apache.struts2.rest.handler.ContentTypeHandler; diff --git a/plugins/rest/src/main/java/org/apache/struts2/rest/RestActionInvocation.java b/plugins/rest/src/main/java/org/apache/struts2/rest/RestActionInvocation.java index 286c80db14..076f94d87a 100644 --- a/plugins/rest/src/main/java/org/apache/struts2/rest/RestActionInvocation.java +++ b/plugins/rest/src/main/java/org/apache/struts2/rest/RestActionInvocation.java @@ -18,19 +18,23 @@ */ package org.apache.struts2.rest; -import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.Action; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.DefaultActionInvocation; +import com.opensymphony.xwork2.Result; import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.ResultConfig; import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.interceptor.ValidationAware; import org.apache.commons.lang3.BooleanUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.ModelDriven; import org.apache.struts2.ServletActionContext; -import org.apache.struts2.result.HttpHeaderResult; +import org.apache.struts2.interceptor.ValidationAware; import org.apache.struts2.rest.handler.ContentTypeHandler; import org.apache.struts2.rest.handler.HtmlHandler; +import org.apache.struts2.result.HttpHeaderResult; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -74,7 +78,7 @@ public void setDefaultErrorResultName(String defaultErrorResultName) { /** * If set to true (by default) blocks returning content from any other methods than GET, * if set to false, the content can be returned for any kind of method - * + * * @param restrictToGet true or false */ @Inject(value = RestConstants.REST_CONTENT_RESTRICT_TO_GET, required = false) diff --git a/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java b/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java index 6a981c8e53..3bfbe779c4 100644 --- a/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java +++ b/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java @@ -23,10 +23,10 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; -import com.opensymphony.xwork2.interceptor.ValidationAware; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.dispatcher.mapper.ActionMapping; +import org.apache.struts2.interceptor.ValidationAware; import java.util.HashMap; import java.util.Map; diff --git a/plugins/rest/src/main/java/org/apache/struts2/rest/handler/XStreamHandler.java b/plugins/rest/src/main/java/org/apache/struts2/rest/handler/XStreamHandler.java index 13831093f8..b482c0715a 100644 --- a/plugins/rest/src/main/java/org/apache/struts2/rest/handler/XStreamHandler.java +++ b/plugins/rest/src/main/java/org/apache/struts2/rest/handler/XStreamHandler.java @@ -19,7 +19,6 @@ package org.apache.struts2.rest.handler; import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ModelDriven; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.StaxDriver; import com.thoughtworks.xstream.security.ArrayTypePermission; @@ -29,6 +28,7 @@ import com.thoughtworks.xstream.security.TypePermission; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.ModelDriven; import org.apache.struts2.rest.handler.xstream.XStreamAllowedClassNames; import org.apache.struts2.rest.handler.xstream.XStreamAllowedClasses; import org.apache.struts2.rest.handler.xstream.XStreamPermissionProvider; From 2757c23572f56335219fdad5cad285e79dcbbcfa Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Tue, 22 Oct 2024 16:48:49 +1100 Subject: [PATCH 6/6] WW-3714 Fix replacement ValidationAware marker not recognised --- .../xwork2/interceptor/ValidationAware.java | 80 +++++++++++++++++++ .../opensymphony/xwork2/util/DebugUtils.java | 2 +- .../validator/DelegatingValidatorContext.java | 18 ++++- .../struts2/interceptor/TokenInterceptor.java | 1 - .../struts2/junit/StrutsJUnit4TestCase.java | 2 +- 5 files changed, 96 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationAware.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationAware.java index c959f19d77..aa9e6f5ff4 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationAware.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationAware.java @@ -18,9 +18,89 @@ */ package com.opensymphony.xwork2.interceptor; +import java.util.Collection; +import java.util.List; +import java.util.Map; + /** * @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.ValidationAware} instead. */ @Deprecated public interface ValidationAware extends org.apache.struts2.interceptor.ValidationAware { + + static ValidationAware adapt(org.apache.struts2.interceptor.ValidationAware actualValidation) { + if (actualValidation instanceof ValidationAware) { + return (ValidationAware) actualValidation; + } + return actualValidation != null ? new LegacyAdapter(actualValidation) : null; + } + + class LegacyAdapter implements ValidationAware { + + private final org.apache.struts2.interceptor.ValidationAware adaptee; + + private LegacyAdapter(org.apache.struts2.interceptor.ValidationAware adaptee) { + this.adaptee = adaptee; + } + + @Override + public void setActionErrors(Collection errorMessages) { + adaptee.setActionErrors(errorMessages); + } + + @Override + public Collection getActionErrors() { + return adaptee.getActionErrors(); + } + + @Override + public void setActionMessages(Collection messages) { + adaptee.setActionMessages(messages); + } + + @Override + public Collection getActionMessages() { + return adaptee.getActionMessages(); + } + + @Override + public void setFieldErrors(Map> errorMap) { + adaptee.setFieldErrors(errorMap); + } + + @Override + public Map> getFieldErrors() { + return adaptee.getFieldErrors(); + } + + @Override + public void addActionError(String anErrorMessage) { + adaptee.addActionError(anErrorMessage); + } + + @Override + public void addActionMessage(String aMessage) { + adaptee.addActionMessage(aMessage); + } + + @Override + public void addFieldError(String fieldName, String errorMessage) { + adaptee.addFieldError(fieldName, errorMessage); + } + + @Override + public boolean hasActionErrors() { + return adaptee.hasActionErrors(); + } + + @Override + public boolean hasActionMessages() { + return adaptee.hasActionMessages(); + } + + @Override + public boolean hasFieldErrors() { + return adaptee.hasFieldErrors(); + } + } } diff --git a/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java b/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java index 3fdf8b0a70..ff7042b596 100644 --- a/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java +++ b/core/src/main/java/com/opensymphony/xwork2/util/DebugUtils.java @@ -19,8 +19,8 @@ package com.opensymphony.xwork2.util; import com.opensymphony.xwork2.TextProvider; -import com.opensymphony.xwork2.interceptor.ValidationAware; import org.apache.logging.log4j.Logger; +import org.apache.struts2.interceptor.ValidationAware; /** * @since 6.5.0 diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java b/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java index bc8c88875c..b0b41e7196 100644 --- a/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java @@ -18,13 +18,23 @@ */ package com.opensymphony.xwork2.validator; -import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.CompositeTextProvider; +import com.opensymphony.xwork2.LocaleProvider; +import com.opensymphony.xwork2.LocaleProviderFactory; +import com.opensymphony.xwork2.StrutsTextProviderFactory; +import com.opensymphony.xwork2.TextProvider; +import com.opensymphony.xwork2.TextProviderFactory; import com.opensymphony.xwork2.interceptor.ValidationAware; import com.opensymphony.xwork2.util.ValueStack; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; /** * A default implementation of the {@link ValidatorContext} interface. @@ -233,8 +243,8 @@ protected static LocaleProvider makeLocaleProvider(Object object) { } protected static ValidationAware makeValidationAware(Object object) { - if (object instanceof ValidationAware) { - return (ValidationAware) object; + if (object instanceof org.apache.struts2.interceptor.ValidationAware) { + return ValidationAware.adapt((org.apache.struts2.interceptor.ValidationAware) object); } else { return new LoggingValidationAware(object); } diff --git a/core/src/main/java/org/apache/struts2/interceptor/TokenInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/TokenInterceptor.java index c6859d05ba..b67ef6422d 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/TokenInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/TokenInterceptor.java @@ -21,7 +21,6 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.TextProvider; import com.opensymphony.xwork2.TextProviderFactory; -import com.opensymphony.xwork2.interceptor.ValidationAware; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; import org.apache.logging.log4j.LogManager; diff --git a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsJUnit4TestCase.java b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsJUnit4TestCase.java index ee486d6cc9..93a08e3996 100644 --- a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsJUnit4TestCase.java +++ b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsJUnit4TestCase.java @@ -22,7 +22,6 @@ import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ActionProxyFactory; import com.opensymphony.xwork2.config.Configuration; -import com.opensymphony.xwork2.interceptor.ValidationAware; import com.opensymphony.xwork2.interceptor.annotations.After; import com.opensymphony.xwork2.interceptor.annotations.Before; import org.apache.commons.lang3.StringUtils; @@ -31,6 +30,7 @@ import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.mapper.ActionMapping; +import org.apache.struts2.interceptor.ValidationAware; import org.apache.struts2.util.StrutsTestCaseHelper; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.mock.web.MockHttpServletRequest;