diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java index c7864571f..786c896d2 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 @@ public class ActionContext extends org.apache.struts2.ActionContext { 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 4d2143848..5bd4f86d5 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 @@ import com.opensymphony.xwork2.util.ValueStack; @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 82020bbe1..76929a647 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 interface ActionInvocation extends org.apache.struts2.ActionInvocation { @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 4d02b235f..9e3e98b57 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 com.opensymphony.xwork2.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). + * @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); + static ValueStack adapt(org.apache.struts2.util.ValueStack actualStack) { + return actualStack != null ? new LegacyAdapter(actualStack) : null; + } - /** - * 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); + class LegacyAdapter implements ValueStack { - /** - * Gets the override map if anyone exists. - * - * @return the override map, null if not set. - */ - Map getExprOverrides(); + private final org.apache.struts2.util.ValueStack adaptee; - /** - * Get the CompoundRoot which holds the objects pushed onto the stack - * - * @return the root - */ - CompoundRoot getRoot(); + private LegacyAdapter(org.apache.struts2.util.ValueStack adaptee) { + this.adaptee = adaptee; + } - /** - * 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); + @Override + public Map getContext() { + return adaptee.getContext(); + } - /** - * 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); + @Override + public ActionContext getActionContext() { + return ActionContext.adapt(adaptee.getActionContext()); + } - /** - * 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); + @Override + public void setDefaultType(Class defaultType) { + adaptee.setDefaultType(defaultType); + } - String findString(String expr); - String findString(String expr, boolean throwExceptionOnFailure); + @Override + public void setExprOverrides(Map overrides) { + adaptee.setExprOverrides(overrides); + } - /** - * 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); + @Override + public Map getExprOverrides() { + return adaptee.getExprOverrides(); + } - Object findValue(String expr, boolean throwExceptionOnFailure); + @Override + public CompoundRoot getRoot() { + return adaptee.getRoot(); + } - /** - * 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); + @Override + public void setValue(String expr, Object value) { + adaptee.setValue(expr, value); + } - /** - * Get the object on the top of the stack without changing the stack. - * - * @return the object on the top. - * @see CompoundRoot#peek() - */ - Object peek(); + @Override + public void setParameter(String expr, Object value) { + adaptee.setParameter(expr, value); + } - /** - * 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(); + @Override + public void setValue(String expr, Object value, boolean throwExceptionOnFailure) { + adaptee.setValue(expr, value, throwExceptionOnFailure); + } - /** - * 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); + @Override + public String findString(String expr) { + return adaptee.findString(expr); + } - /** - * 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); + @Override + public String findString(String expr, boolean throwExceptionOnFailure) { + return adaptee.findString(expr, throwExceptionOnFailure); + } - /** - * Get the number of objects in the stack - * - * @return the number of objects in the stack - */ - int size(); + @Override + public Object findValue(String expr) { + return adaptee.findValue(expr); + } -} \ No newline at end of file + @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 8c01a9a23..23077cc9a 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 e3d446bc0..5fcbc75ec 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 000000000..f7d70a35d --- /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(); + +}