Merge pull request #1081 from apache/kusal-depr-apis-3

WW-3714 Deprecate and repackage common APIs part 2
This commit is contained in:
Kusal Kithul-Godage
2024-10-22 18:03:00 +11:00
committed by GitHub
13 changed files with 388 additions and 164 deletions
@@ -43,7 +43,7 @@ public class ActionContext extends org.apache.struts2.ActionContext {
super(actualContext.getContextMap());
}
private static ActionContext adapt(org.apache.struts2.ActionContext actualContext) {
static ActionContext adapt(org.apache.struts2.ActionContext actualContext) {
return actualContext != null ? new ActionContext(actualContext) : null;
}
@@ -77,15 +77,19 @@ public class ActionContext extends org.apache.struts2.ActionContext {
return this;
}
@Override
public ActionContext withActionInvocation(ActionInvocation actionInvocation) {
return withActionInvocation((org.apache.struts2.ActionInvocation) actionInvocation);
}
@Override
public ActionContext withActionInvocation(org.apache.struts2.ActionInvocation actionInvocation) {
super.withActionInvocation(actionInvocation);
return this;
}
@Override
public ActionInvocation getActionInvocation() {
return super.getActionInvocation();
return ActionInvocation.adapt(super.getActionInvocation());
}
@Override
@@ -22,158 +22,102 @@ import com.opensymphony.xwork2.interceptor.PreResultListener;
import com.opensymphony.xwork2.util.ValueStack;
/**
* An {@link ActionInvocation} represents the execution state of an {@link Action}. It holds the Interceptors and the Action instance.
* By repeated re-entrant execution of the <code>invoke()</code> method, initially by the {@link ActionProxy}, then by the Interceptors, the
* Interceptors are all executed, and then the {@link Action} and the {@link Result}.
* {@inheritDoc}
*
* @author Jason Carreira
* @see com.opensymphony.xwork2.ActionProxy
* @deprecated since 6.7.0, use {@link org.apache.struts2.ActionInvocation} instead.
*/
public interface ActionInvocation {
@Deprecated
public interface ActionInvocation extends org.apache.struts2.ActionInvocation {
/**
* Get the Action associated with this ActionInvocation.
*
* @return the Action
*/
Object getAction();
/**
* Gets whether this ActionInvocation has executed before.
* This will be set after the Action and the Result have executed.
*
* @return <tt>true</tt> if this ActionInvocation has executed before.
*/
boolean isExecuted();
/**
* Gets the ActionContext associated with this ActionInvocation. The ActionProxy is
* responsible for setting this ActionContext onto the ThreadLocal before invoking
* the ActionInvocation and resetting the old ActionContext afterwards.
*
* @return the ActionContext.
*/
@Override
ActionContext getInvocationContext();
/**
* Get the ActionProxy holding this ActionInvocation.
*
* @return the ActionProxy.
*/
ActionProxy getProxy();
/**
* If the ActionInvocation has been executed before and the Result is an instance of {@link ActionChainResult}, this method
* will walk down the chain of <code>ActionChainResult</code>s until it finds a non-chain result, which will be returned. If the
* ActionInvocation's result has not been executed before, the Result instance will be created and populated with
* the result params.
*
* @return the result.
* @throws Exception can be thrown.
*/
@Override
Result getResult() throws Exception;
/**
* Gets the result code returned from this ActionInvocation.
*
* @return the result code
*/
String getResultCode();
@Override
default void addPreResultListener(org.apache.struts2.interceptor.PreResultListener listener) {
addPreResultListener(PreResultListener.adapt(listener));
}
/**
* Sets the result code, possibly overriding the one returned by the
* action.
*
* <p>
* The "intended" purpose of this method is to allow PreResultListeners to
* override the result code returned by the Action.
* </p>
*
* <p>
* If this method is used before the Action executes, the Action's returned
* result code will override what was set. However the Action could (if
* specifically coded to do so) inspect the ActionInvocation to see that
* someone "upstream" (e.g. an Interceptor) had suggested a value as the
* result, and it could therefore return the same value itself.
* </p>
*
* <p>
* If this method is called between the Action execution and the Result
* execution, then the value set here will override the result code the
* action had returned. Creating an Interceptor that implements
* {@link PreResultListener} will give you this opportunity.
* </p>
*
* <p>
* If this method is called after the Result has been executed, it will
* have the effect of raising an IllegalStateException.
* </p>
*
* @param resultCode the result code.
* @throws IllegalStateException if called after the Result has been executed.
* @see #isExecuted()
*/
void setResultCode(String resultCode);
/**
* Gets the ValueStack associated with this ActionInvocation.
*
* @return the ValueStack
*/
ValueStack getStack();
/**
* Register a {@link PreResultListener} to be notified after the Action is executed and
* before the Result is executed.
*
* <p>
* The ActionInvocation implementation must guarantee that listeners will be called in
* the order in which they are registered.
* </p>
*
* <p>
* Listener registration and execution does not need to be thread-safe.
* </p>
*
* @param listener the listener to add.
*/
void addPreResultListener(PreResultListener listener);
/**
* Invokes the next step in processing this ActionInvocation.
*
* <p>
* If there are more Interceptors, this will call the next one. If Interceptors choose not to short-circuit
* ActionInvocation processing and return their own return code, they will call invoke() to allow the next Interceptor
* to execute. If there are no more Interceptors to be applied, the Action is executed.
* If the {@link ActionProxy#getExecuteResult()} method returns <tt>true</tt>, the Result is also executed.
* </p>
*
* @throws Exception can be thrown.
* @return the return code.
*/
String invoke() throws Exception;
static ActionInvocation adapt(org.apache.struts2.ActionInvocation actualInvocation) {
return actualInvocation != null ? new LegacyAdapter(actualInvocation) : null;
}
/**
* Invokes only the Action (not Interceptors or Results).
*
* <p>
* This is useful in rare situations where advanced usage with the interceptor/action/result workflow is
* being manipulated for certain functionality.
* </p>
*
* @return the return code.
* @throws Exception can be thrown.
*/
String invokeActionOnly() throws Exception;
class LegacyAdapter implements ActionInvocation {
/**
* Sets the action event listener to respond to key action events.
*
* @param listener the listener.
*/
void setActionEventListener(ActionEventListener listener);
private final org.apache.struts2.ActionInvocation adaptee;
void init(ActionProxy proxy) ;
private LegacyAdapter(org.apache.struts2.ActionInvocation adaptee) {
this.adaptee = adaptee;
}
@Override
public Object getAction() {
return adaptee.getAction();
}
@Override
public boolean isExecuted() {
return adaptee.isExecuted();
}
@Override
public ActionContext getInvocationContext() {
return ActionContext.adapt(adaptee.getInvocationContext());
}
@Override
public ActionProxy getProxy() {
return adaptee.getProxy();
}
@Override
public Result getResult() throws Exception {
return Result.adapt(adaptee.getResult());
}
@Override
public String getResultCode() {
return adaptee.getResultCode();
}
@Override
public void setResultCode(String resultCode) {
adaptee.setResultCode(resultCode);
}
@Override
public ValueStack getStack() {
return adaptee.getStack();
}
@Override
public void addPreResultListener(PreResultListener listener) {
adaptee.addPreResultListener(listener);
}
@Override
public String invoke() throws Exception {
return adaptee.invoke();
}
@Override
public String invokeActionOnly() throws Exception {
return adaptee.invokeActionOnly();
}
@Override
public void setActionEventListener(ActionEventListener listener) {
adaptee.setActionEventListener(listener);
}
@Override
public void init(ActionProxy proxy) {
adaptee.init(proxy);
}
}
}
@@ -25,4 +25,29 @@ package com.opensymphony.xwork2;
*/
@Deprecated
public interface Result extends org.apache.struts2.Result {
@Override
default void execute(org.apache.struts2.ActionInvocation invocation) throws Exception {
execute(ActionInvocation.adapt(invocation));
}
void execute(ActionInvocation invocation) throws Exception;
static Result adapt(org.apache.struts2.Result actualResult) {
return actualResult != null ? new LegacyAdapter(actualResult) : null;
}
class LegacyAdapter implements Result {
private final org.apache.struts2.Result adaptee;
private LegacyAdapter(org.apache.struts2.Result adaptee) {
this.adaptee = adaptee;
}
@Override
public void execute(ActionInvocation invocation) throws Exception {
adaptee.execute(ActionInvocation.adapt(invocation));
}
}
}
@@ -18,6 +18,8 @@
*/
package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
/**
* {@inheritDoc}
*
@@ -25,4 +27,10 @@ package com.opensymphony.xwork2.interceptor;
*/
@Deprecated
public interface ConditionalInterceptor extends org.apache.struts2.interceptor.ConditionalInterceptor, Interceptor {
default boolean shouldIntercept(org.apache.struts2.ActionInvocation invocation) {
return shouldIntercept(ActionInvocation.adapt(invocation));
}
boolean shouldIntercept(ActionInvocation invocation);
}
@@ -18,6 +18,8 @@
*/
package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
/**
* {@inheritDoc}
*
@@ -25,4 +27,11 @@ package com.opensymphony.xwork2.interceptor;
*/
@Deprecated
public interface Interceptor extends org.apache.struts2.interceptor.Interceptor {
@Override
default String intercept(org.apache.struts2.ActionInvocation invocation) throws Exception {
return intercept(ActionInvocation.adapt(invocation));
}
String intercept(ActionInvocation invocation) throws Exception;
}
@@ -21,21 +21,35 @@ package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
/**
* PreResultListeners may be registered with an {@link ActionInvocation} to get a callback after the
* {@link com.opensymphony.xwork2.Action} has been executed but before the {@link com.opensymphony.xwork2.Result}
* is executed.
* {@inheritDoc}
*
* @author Jason Carreira
* @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.PreResultListener} instead.
*/
public interface PreResultListener {
@Deprecated
public interface PreResultListener extends org.apache.struts2.interceptor.PreResultListener {
@Override
default void beforeResult(org.apache.struts2.ActionInvocation invocation, String resultCode) {
beforeResult(ActionInvocation.adapt(invocation), resultCode);
}
/**
* This callback method will be called after the {@link com.opensymphony.xwork2.Action} execution and
* before the {@link com.opensymphony.xwork2.Result} execution.
*
* @param invocation the action invocation
* @param resultCode the result code returned by the action (eg. <code>success</code>).
*/
void beforeResult(ActionInvocation invocation, String resultCode);
static PreResultListener adapt(org.apache.struts2.interceptor.PreResultListener actualListener) {
return actualListener != null ? new LegacyAdapter(actualListener) : null;
}
class LegacyAdapter implements PreResultListener {
private final org.apache.struts2.interceptor.PreResultListener adaptee;
private LegacyAdapter(org.apache.struts2.interceptor.PreResultListener adaptee) {
this.adaptee = adaptee;
}
@Override
public void beforeResult(ActionInvocation invocation, String resultCode) {
adaptee.beforeResult(invocation, resultCode);
}
}
}
@@ -18,8 +18,6 @@
*/
package org.apache.struts2;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.conversion.impl.ConversionData;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.util.ValueStack;
@@ -0,0 +1,182 @@
/*
* 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;
import com.opensymphony.xwork2.ActionChainResult;
import com.opensymphony.xwork2.ActionEventListener;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.struts2.interceptor.PreResultListener;
/**
* An {@link ActionInvocation} represents the execution state of an {@link com.opensymphony.xwork2.Action}. It holds the Interceptors and the Action instance.
* By repeated re-entrant execution of the <code>invoke()</code> method, initially by the {@link ActionProxy}, then by the Interceptors, the
* Interceptors are all executed, and then the {@link Action} and the {@link com.opensymphony.xwork2.Result}.
*
* @author Jason Carreira
* @see ActionProxy
*/
public interface ActionInvocation {
/**
* Get the Action associated with this ActionInvocation.
*
* @return the Action
*/
Object getAction();
/**
* Gets whether this ActionInvocation has executed before.
* This will be set after the Action and the Result have executed.
*
* @return <tt>true</tt> if this ActionInvocation has executed before.
*/
boolean isExecuted();
/**
* Gets the ActionContext associated with this ActionInvocation. The ActionProxy is
* responsible for setting this ActionContext onto the ThreadLocal before invoking
* the ActionInvocation and resetting the old ActionContext afterwards.
*
* @return the ActionContext.
*/
ActionContext getInvocationContext();
/**
* Get the ActionProxy holding this ActionInvocation.
*
* @return the ActionProxy.
*/
ActionProxy getProxy();
/**
* If the ActionInvocation has been executed before and the Result is an instance of {@link ActionChainResult}, this method
* will walk down the chain of <code>ActionChainResult</code>s until it finds a non-chain result, which will be returned. If the
* ActionInvocation's result has not been executed before, the Result instance will be created and populated with
* the result params.
*
* @return the result.
* @throws Exception can be thrown.
*/
Result getResult() throws Exception;
/**
* Gets the result code returned from this ActionInvocation.
*
* @return the result code
*/
String getResultCode();
/**
* Sets the result code, possibly overriding the one returned by the
* action.
*
* <p>
* The "intended" purpose of this method is to allow PreResultListeners to
* override the result code returned by the Action.
* </p>
*
* <p>
* If this method is used before the Action executes, the Action's returned
* result code will override what was set. However the Action could (if
* specifically coded to do so) inspect the ActionInvocation to see that
* someone "upstream" (e.g. an Interceptor) had suggested a value as the
* result, and it could therefore return the same value itself.
* </p>
*
* <p>
* If this method is called between the Action execution and the Result
* execution, then the value set here will override the result code the
* action had returned. Creating an Interceptor that implements
* {@link PreResultListener} will give you this opportunity.
* </p>
*
* <p>
* If this method is called after the Result has been executed, it will
* have the effect of raising an IllegalStateException.
* </p>
*
* @param resultCode the result code.
* @throws IllegalStateException if called after the Result has been executed.
* @see #isExecuted()
*/
void setResultCode(String resultCode);
/**
* Gets the ValueStack associated with this ActionInvocation.
*
* @return the ValueStack
*/
ValueStack getStack();
/**
* Register a {@link PreResultListener} to be notified after the Action is executed and
* before the Result is executed.
*
* <p>
* The ActionInvocation implementation must guarantee that listeners will be called in
* the order in which they are registered.
* </p>
*
* <p>
* Listener registration and execution does not need to be thread-safe.
* </p>
*
* @param listener the listener to add.
*/
void addPreResultListener(PreResultListener listener);
/**
* Invokes the next step in processing this ActionInvocation.
*
* <p>
* If there are more Interceptors, this will call the next one. If Interceptors choose not to short-circuit
* ActionInvocation processing and return their own return code, they will call invoke() to allow the next Interceptor
* to execute. If there are no more Interceptors to be applied, the Action is executed.
* If the {@link ActionProxy#getExecuteResult()} method returns <tt>true</tt>, the Result is also executed.
* </p>
*
* @throws Exception can be thrown.
* @return the return code.
*/
String invoke() throws Exception;
/**
* Invokes only the Action (not Interceptors or Results).
*
* <p>
* This is useful in rare situations where advanced usage with the interceptor/action/result workflow is
* being manipulated for certain functionality.
* </p>
*
* @return the return code.
* @throws Exception can be thrown.
*/
String invokeActionOnly() throws Exception;
/**
* Sets the action event listener to respond to key action events.
*
* @param listener the listener.
*/
void setActionEventListener(ActionEventListener listener);
void init(ActionProxy proxy) ;
}
@@ -18,9 +18,6 @@
*/
package org.apache.struts2;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import java.io.Serializable;
/**
@@ -18,7 +18,7 @@
*/
package org.apache.struts2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import org.apache.struts2.ActionInvocation;
/**
* A marking interface, when implemented allows to conditionally execute a given interceptor
@@ -18,7 +18,7 @@
*/
package org.apache.struts2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import org.apache.struts2.ActionInvocation;
import java.io.Serializable;
@@ -0,0 +1,41 @@
/*
* 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.ActionInvocation;
/**
* PreResultListeners may be registered with an {@link ActionInvocation} to get a callback after the
* {@link com.opensymphony.xwork2.Action} has been executed but before the {@link com.opensymphony.xwork2.Result}
* is executed.
*
* @author Jason Carreira
*/
public interface PreResultListener {
/**
* This callback method will be called after the {@link com.opensymphony.xwork2.Action} execution and
* before the {@link com.opensymphony.xwork2.Result} execution.
*
* @param invocation the action invocation
* @param resultCode the result code returned by the action (eg. <code>success</code>).
*/
void beforeResult(ActionInvocation invocation, String resultCode);
}
@@ -403,6 +403,7 @@ public class ActionTagTest extends AbstractTagTest {
public void testExecuteButResetReturnSameInvocation() throws Exception {
Mock mockActionInv = new Mock(ActionInvocation.class);
mockActionInv.matchAndReturn("invoke", "TEST");
ActionTag tag = new ActionTag();
tag.setPageContext(pageContext);
tag.setNamespace("");
@@ -419,7 +420,7 @@ public class ActionTagTest extends AbstractTagTest {
ActionComponent component = (ActionComponent) tag.getComponent();
tag.doEndTag();
assertSame(oldInvocation, ActionContext.getContext().getActionInvocation());
assertEquals(oldInvocation.invoke(), ActionContext.getContext().getActionInvocation().invoke());
// Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
ActionTag freshTag = new ActionTag();
@@ -432,6 +433,7 @@ public class ActionTagTest extends AbstractTagTest {
public void testExecuteButResetReturnSameInvocation_clearTagStateSet() throws Exception {
Mock mockActionInv = new Mock(ActionInvocation.class);
mockActionInv.matchAndReturn("invoke", "TEST");
ActionTag tag = new ActionTag();
tag.setPerformClearTagStateForTagPoolingServers(true); // Explicitly request tag state clearing.
tag.setPageContext(pageContext);
@@ -450,7 +452,7 @@ public class ActionTagTest extends AbstractTagTest {
ActionComponent component = (ActionComponent) tag.getComponent();
tag.doEndTag();
assertTrue(oldInvocation == ActionContext.getContext().getActionInvocation());
assertEquals(oldInvocation.invoke(), ActionContext.getContext().getActionInvocation().invoke());
// Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
ActionTag freshTag = new ActionTag();