From 36a890ba69ac80f5a279478f9229b7b4ff8912cd Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Thu, 17 Oct 2024 20:05:59 +1100 Subject: [PATCH 1/2] WW-3714 Add factory support for new Interceptor, Result interfaces --- .../factory/DefaultInterceptorFactory.java | 13 ++++--- .../xwork2/factory/DefaultResultFactory.java | 12 ++++++- .../interceptor/ConditionalInterceptor.java | 23 +++++++++++++ .../xwork2/interceptor/Interceptor.java | 34 +++++++++++++++++++ .../struts2/factory/StrutsResultFactory.java | 13 +++++-- 5 files changed, 88 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/factory/DefaultInterceptorFactory.java b/core/src/main/java/com/opensymphony/xwork2/factory/DefaultInterceptorFactory.java index a1d9ee2ce7..580464130e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/factory/DefaultInterceptorFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/factory/DefaultInterceptorFactory.java @@ -70,13 +70,18 @@ public Interceptor buildInterceptor(InterceptorConfig interceptorConfig, Map extraCo Result result = null; if (resultClassName != null) { - result = (Result) objectFactory.buildBean(resultClassName, extraContext); + Object o = objectFactory.buildBean(resultClassName, extraContext); + if (o instanceof Result) { + result = (Result) o; + } else if (o instanceof org.apache.struts2.Result) { + result = Result.adapt((org.apache.struts2.Result) o); + } + if (result == null) { + throw new ConfigurationException("Class [" + resultClassName + "] does not implement Result", resultConfig); + } + Map params = resultConfig.getParams(); if (params != null) { for (Map.Entry paramEntry : params.entrySet()) { diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ConditionalInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ConditionalInterceptor.java index 83c2bcb3e1..0e83f64b2e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ConditionalInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ConditionalInterceptor.java @@ -28,9 +28,32 @@ @Deprecated public interface ConditionalInterceptor extends org.apache.struts2.interceptor.ConditionalInterceptor, Interceptor { + @Override default boolean shouldIntercept(org.apache.struts2.ActionInvocation invocation) { return shouldIntercept(ActionInvocation.adapt(invocation)); } boolean shouldIntercept(ActionInvocation invocation); + + static ConditionalInterceptor adapt(org.apache.struts2.interceptor.ConditionalInterceptor actualInterceptor) { + if (actualInterceptor instanceof ConditionalInterceptor) { + return (ConditionalInterceptor) actualInterceptor; + } + return actualInterceptor != null ? new LegacyAdapter(actualInterceptor) : null; + } + + class LegacyAdapter extends Interceptor.LegacyAdapter implements ConditionalInterceptor { + + private final org.apache.struts2.interceptor.ConditionalInterceptor adaptee; + + private LegacyAdapter(org.apache.struts2.interceptor.ConditionalInterceptor adaptee) { + super(adaptee); + this.adaptee = adaptee; + } + + @Override + public boolean shouldIntercept(ActionInvocation invocation) { + return adaptee.shouldIntercept(invocation); + } + } } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java index 628dda6f5e..e6ff42998e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java @@ -34,4 +34,38 @@ default String intercept(org.apache.struts2.ActionInvocation invocation) throws } String intercept(ActionInvocation invocation) throws Exception; + + static Interceptor adapt(org.apache.struts2.interceptor.Interceptor actualInterceptor) { + if (actualInterceptor instanceof org.apache.struts2.interceptor.ConditionalInterceptor) { + return ConditionalInterceptor.adapt((org.apache.struts2.interceptor.ConditionalInterceptor) actualInterceptor); + } + if (actualInterceptor instanceof Interceptor) { + return (Interceptor) actualInterceptor; + } + return actualInterceptor != null ? new LegacyAdapter(actualInterceptor) : null; + } + + class LegacyAdapter implements Interceptor { + + private final org.apache.struts2.interceptor.Interceptor adaptee; + + protected LegacyAdapter(org.apache.struts2.interceptor.Interceptor adaptee) { + this.adaptee = adaptee; + } + + @Override + public String intercept(ActionInvocation invocation) throws Exception { + return adaptee.intercept(invocation); + } + + @Override + public void destroy() { + adaptee.destroy(); + } + + @Override + public void init() { + adaptee.init(); + } + } } diff --git a/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java b/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java index 0a758f2138..2818f33dda 100644 --- a/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java +++ b/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java @@ -20,13 +20,14 @@ import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.Result; +import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.entities.ResultConfig; import com.opensymphony.xwork2.factory.ResultFactory; import com.opensymphony.xwork2.inject.Inject; +import com.opensymphony.xwork2.result.ParamNameAwareResult; import com.opensymphony.xwork2.util.reflection.ReflectionException; import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler; import com.opensymphony.xwork2.util.reflection.ReflectionProvider; -import com.opensymphony.xwork2.result.ParamNameAwareResult; import java.util.Map; @@ -53,7 +54,15 @@ public Result buildResult(ResultConfig resultConfig, Map extraCo Result result = null; if (resultClassName != null) { - result = (Result) objectFactory.buildBean(resultClassName, extraContext); + Object o = objectFactory.buildBean(resultClassName, extraContext); + if (o instanceof Result) { + result = (Result) o; + } else if (o instanceof org.apache.struts2.Result) { + result = Result.adapt((org.apache.struts2.Result) o); + } + if (result == null) { + throw new ConfigurationException("Class [" + resultClassName + "] does not implement Result", resultConfig); + } Map params = resultConfig.getParams(); if (params != null) { setParameters(extraContext, result, params); From b622e5d725857664cfb5905c0d4501911fa5596f Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Tue, 22 Oct 2024 13:50:45 +1100 Subject: [PATCH 2/2] WW-3714 Ensure ReflectionExceptionHandler, WithLazyParams, ParamNameAwareResult marker interfaces respected --- .../xwork2/DefaultActionInvocation.java | 3 ++ .../xwork2/factory/DefaultResultFactory.java | 23 ++++++------- .../xwork2/interceptor/Interceptor.java | 4 +++ .../xwork2/interceptor/WithLazyParams.java | 5 ++- .../struts2/factory/StrutsResultFactory.java | 33 ++++++++++++++++--- 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java b/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java index 772e0adb07..84accbef79 100644 --- a/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java +++ b/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java @@ -248,6 +248,9 @@ public String invoke() throws Exception { Interceptor interceptor = interceptorMapping.getInterceptor(); if (interceptor instanceof WithLazyParams) { interceptor = lazyParamInjector.injectParams(interceptor, interceptorMapping.getParams(), invocationContext); + } else if (interceptor instanceof Interceptor.LegacyAdapter && ((Interceptor.LegacyAdapter) interceptor).getAdaptee() instanceof WithLazyParams) { + org.apache.struts2.interceptor.Interceptor adaptee = ((Interceptor.LegacyAdapter) interceptor).getAdaptee(); + lazyParamInjector.injectParams(adaptee, interceptorMapping.getParams(), invocationContext); } if (interceptor instanceof ConditionalInterceptor) { resultCode = executeConditional((ConditionalInterceptor) interceptor); diff --git a/core/src/main/java/com/opensymphony/xwork2/factory/DefaultResultFactory.java b/core/src/main/java/com/opensymphony/xwork2/factory/DefaultResultFactory.java index 5466a52ea2..42527494e1 100644 --- a/core/src/main/java/com/opensymphony/xwork2/factory/DefaultResultFactory.java +++ b/core/src/main/java/com/opensymphony/xwork2/factory/DefaultResultFactory.java @@ -53,27 +53,28 @@ public Result buildResult(ResultConfig resultConfig, Map extraCo if (resultClassName != null) { Object o = objectFactory.buildBean(resultClassName, extraContext); - if (o instanceof Result) { - result = (Result) o; - } else if (o instanceof org.apache.struts2.Result) { - result = Result.adapt((org.apache.struts2.Result) o); - } - if (result == null) { - throw new ConfigurationException("Class [" + resultClassName + "] does not implement Result", resultConfig); - } Map params = resultConfig.getParams(); if (params != null) { for (Map.Entry paramEntry : params.entrySet()) { try { - reflectionProvider.setProperty(paramEntry.getKey(), paramEntry.getValue(), result, extraContext, true); + reflectionProvider.setProperty(paramEntry.getKey(), paramEntry.getValue(), o, extraContext, true); } catch (ReflectionException ex) { - if (result instanceof ReflectionExceptionHandler) { - ((ReflectionExceptionHandler) result).handle(ex); + if (o instanceof ReflectionExceptionHandler) { + ((ReflectionExceptionHandler) o).handle(ex); } } } } + + if (o instanceof Result) { + result = (Result) o; + } else if (o instanceof org.apache.struts2.Result) { + result = Result.adapt((org.apache.struts2.Result) o); + } + if (result == null) { + throw new ConfigurationException("Class [" + resultClassName + "] does not implement Result", resultConfig); + } } return result; diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java index e6ff42998e..4287ca8c0a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java @@ -53,6 +53,10 @@ protected LegacyAdapter(org.apache.struts2.interceptor.Interceptor adaptee) { this.adaptee = adaptee; } + public org.apache.struts2.interceptor.Interceptor getAdaptee() { + return adaptee; + } + @Override public String intercept(ActionInvocation invocation) throws Exception { return adaptee.intercept(invocation); diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/WithLazyParams.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/WithLazyParams.java index 3e111d69c8..5b9401d3d5 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/WithLazyParams.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/WithLazyParams.java @@ -70,11 +70,14 @@ public void setOgnlUtil(OgnlUtil ognlUtil) { } public Interceptor injectParams(Interceptor interceptor, Map params, ActionContext invocationContext) { + return (Interceptor) injectParams((org.apache.struts2.interceptor.Interceptor) interceptor, params, invocationContext); + } + + public org.apache.struts2.interceptor.Interceptor injectParams(org.apache.struts2.interceptor.Interceptor interceptor, Map params, ActionContext invocationContext) { for (Map.Entry entry : params.entrySet()) { Object paramValue = textParser.evaluate(new char[]{ '$' }, entry.getValue(), valueEvaluator, TextParser.DEFAULT_LOOP_COUNT); ognlUtil.setProperty(entry.getKey(), paramValue, interceptor, invocationContext.getContextMap()); } - return interceptor; } } diff --git a/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java b/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java index 2818f33dda..8a653bdaf3 100644 --- a/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java +++ b/core/src/main/java/org/apache/struts2/factory/StrutsResultFactory.java @@ -55,6 +55,10 @@ public Result buildResult(ResultConfig resultConfig, Map extraCo if (resultClassName != null) { Object o = objectFactory.buildBean(resultClassName, extraContext); + Map params = resultConfig.getParams(); + if (params != null) { + setParameters(extraContext, o, params); + } if (o instanceof Result) { result = (Result) o; } else if (o instanceof org.apache.struts2.Result) { @@ -63,15 +67,23 @@ public Result buildResult(ResultConfig resultConfig, Map extraCo if (result == null) { throw new ConfigurationException("Class [" + resultClassName + "] does not implement Result", resultConfig); } - Map params = resultConfig.getParams(); - if (params != null) { - setParameters(extraContext, result, params); - } } return result; } protected void setParameters(Map extraContext, Result result, Map params) { + setParametersHelper(extraContext, result, params); + } + + protected void setParameters(Map extraContext, Object result, Map params) { + if (result instanceof Result) { + setParameters(extraContext, (Result) result, params); + } else { + setParametersHelper(extraContext, result, params); + } + } + + private void setParametersHelper(Map extraContext, Object result, Map params) { for (Map.Entry paramEntry : params.entrySet()) { try { String name = paramEntry.getKey(); @@ -86,6 +98,18 @@ protected void setParameters(Map extraContext, Result result, Ma } protected void setParameter(Result result, String name, String value, Map extraContext) { + setParameterHelper(result, name, value, extraContext); + } + + private void setParameter(Object result, String name, String value, Map extraContext) { + if (result instanceof Result) { + setParameter((Result) result, name, value, extraContext); + } else { + setParameterHelper(result, name, value, extraContext); + } + } + + private void setParameterHelper(Object result, String name, String value, Map extraContext) { if (result instanceof ParamNameAwareResult) { if (((ParamNameAwareResult) result).acceptableParameterName(name, value)) { reflectionProvider.setProperty(name, value, result, extraContext, true); @@ -94,5 +118,4 @@ protected void setParameter(Result result, String name, String value, Map