From da0934f69a1992e6008e5976f0f22fb5a94e723d Mon Sep 17 00:00:00 2001 From: Kusal Kithul-Godage Date: Thu, 17 Oct 2024 16:26:01 +1100 Subject: [PATCH] WW-3714 Deprecate and migrate AbstractInterceptor and MethodFilterInterceptor --- .../interceptor/AbstractInterceptor.java | 32 +--- .../interceptor/MethodFilterInterceptor.java | 45 +++--- .../MethodFilterInterceptorUtil.java | 128 +-------------- .../interceptor/AbstractInterceptor.java | 61 ++++++++ .../interceptor/MethodFilterInterceptor.java | 123 +++++++++++++++ .../MethodFilterInterceptorUtil.java | 148 ++++++++++++++++++ 6 files changed, 366 insertions(+), 171 deletions(-) create mode 100644 core/src/main/java/org/apache/struts2/interceptor/AbstractInterceptor.java create mode 100644 core/src/main/java/org/apache/struts2/interceptor/MethodFilterInterceptor.java create mode 100644 core/src/main/java/org/apache/struts2/interceptor/MethodFilterInterceptorUtil.java diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java index 21e459c291..69c6674621 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/AbstractInterceptor.java @@ -21,41 +21,23 @@ import com.opensymphony.xwork2.ActionInvocation; /** - * Provides default implementations of optional lifecycle methods + * @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.AbstractInterceptor} instead. */ -public abstract class AbstractInterceptor implements ConditionalInterceptor { - - private boolean disabled; - - /** - * Does nothing - */ - public void init() { - } - - /** - * Does nothing - */ - public void destroy() { - } +@Deprecated +public abstract class AbstractInterceptor extends org.apache.struts2.interceptor.AbstractInterceptor implements ConditionalInterceptor { /** * Override to handle interception */ public abstract String intercept(ActionInvocation invocation) throws Exception; - /** - * Allows to skip executing a given interceptor, just define {@code true} - * or use other way to override interceptor's parameters, see - * docs. - * @param disable if set to true, execution of a given interceptor will be skipped. - */ - public void setDisabled(String disable) { - this.disabled = Boolean.parseBoolean(disable); + @Override + public String intercept(org.apache.struts2.ActionInvocation invocation) throws Exception { + return intercept(ActionInvocation.adapt(invocation)); } @Override public boolean shouldIntercept(ActionInvocation invocation) { - return !this.disabled; + return shouldIntercept((org.apache.struts2.ActionInvocation) invocation); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptor.java index e96951cfa1..bcce3da12d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptor.java @@ -31,56 +31,59 @@ * *

* MethodFilterInterceptor is an abstract Interceptor used as - * a base class for interceptors that will filter execution based on method + * a base class for interceptors that will filter execution based on method * names according to specified included/excluded method lists. - * + * *

- * + * * Settable parameters are as follows: - * + * * - * + * *

- * - * NOTE: If method name are available in both includeMethods and - * excludeMethods, it will be considered as an included method: + * + * NOTE: If method name are available in both includeMethods and + * excludeMethods, it will be considered as an included method: * includeMethods takes precedence over excludeMethods. - * + * *

- * + * * Interceptors that extends this capability include: - * + * * - * + * * - * + * * @author Alexandru Popescu * @author Rainer Hermanns - * + * * @see org.apache.struts2.interceptor.TokenInterceptor * @see org.apache.struts2.interceptor.TokenSessionStoreInterceptor * @see com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor * @see com.opensymphony.xwork2.validator.ValidationInterceptor + * + * @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.MethodFilterInterceptor} instead. */ +@Deprecated public abstract class MethodFilterInterceptor extends AbstractInterceptor { private static final Logger LOG = LogManager.getLogger(MethodFilterInterceptor.class); - + protected Set excludeMethods = Collections.emptySet(); protected Set includeMethods = Collections.emptySet(); public void setExcludeMethods(String excludeMethods) { this.excludeMethods = TextParseUtil.commaDelimitedStringToSet(excludeMethods); } - + public Set getExcludeMethodsSet() { return excludeMethods; } @@ -88,7 +91,7 @@ public Set getExcludeMethodsSet() { public void setIncludeMethods(String includeMethods) { this.includeMethods = TextParseUtil.commaDelimitedStringToSet(includeMethods); } - + public Set getIncludeMethodsSet() { return includeMethods; } @@ -97,7 +100,7 @@ public Set getIncludeMethodsSet() { public String intercept(ActionInvocation invocation) throws Exception { if (applyInterceptor(invocation)) { return doIntercept(invocation); - } + } return invocation.invoke(); } @@ -110,14 +113,14 @@ protected boolean applyInterceptor(ActionInvocation invocation) { } return applyMethod; } - + /** * Subclasses must override to implement the interceptor logic. - * + * * @param invocation the action invocation * @return the result of invocation * @throws Exception in case of any errors */ protected abstract String doIntercept(ActionInvocation invocation) throws Exception; - + } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java index beacb87844..7e1a2c4348 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java @@ -18,131 +18,9 @@ */ package com.opensymphony.xwork2.interceptor; -import com.opensymphony.xwork2.util.TextParseUtil; -import com.opensymphony.xwork2.util.WildcardHelper; - -import java.util.HashMap; -import java.util.Set; - /** - * Utility class contains common methods used by - * {@link com.opensymphony.xwork2.interceptor.MethodFilterInterceptor}. - * - * @author tm_jee + * @deprecated since 6.7.0, use {@link org.apache.struts2.interceptor.MethodFilterInterceptorUtil} instead. */ -public class MethodFilterInterceptorUtil { - - /** - * Static method to decide if the specified method should be - * apply (not filtered) depending on the set of excludeMethods and - * includeMethods. - * - *
    - *
  • - * includeMethods takes precedence over excludeMethods - *
  • - *
- * Note: Supports wildcard listings in includeMethods/excludeMethods - * - * @param excludeMethods list of methods to exclude. - * @param includeMethods list of methods to include. - * @param method the specified method to check - * @return true if the method should be applied. - */ - public static boolean applyMethod(Set excludeMethods, Set includeMethods, String method) { - - // quick check to see if any actual pattern matching is needed - boolean needsPatternMatch = false; - for (String includeMethod : includeMethods) { - if (!"*".equals(includeMethod) && includeMethod.contains("*")) { - needsPatternMatch = true; - break; - } - } - - for (String excludeMethod : excludeMethods) { - if (!"*".equals(excludeMethod) && excludeMethod.contains("*")) { - needsPatternMatch = true; - break; - } - } - - // this section will try to honor the original logic, while - // still allowing for wildcards later - if (!needsPatternMatch && (includeMethods.contains("*") || includeMethods.size() == 0) ) { - if (excludeMethods != null - && excludeMethods.contains(method) - && !includeMethods.contains(method) ) { - return false; - } - } - - // test the methods using pattern matching - WildcardHelper wildcard = new WildcardHelper(); - String methodCopy ; - if (method == null ) { // no method specified - methodCopy = ""; - } - else { - methodCopy = new String(method); - } - for (String pattern : includeMethods) { - if (pattern.contains("*")) { - int[] compiledPattern = wildcard.compilePattern(pattern); - HashMap matchedPatterns = new HashMap<>(); - boolean matches = wildcard.match(matchedPatterns, methodCopy, compiledPattern); - if (matches) { - return true; // run it, includeMethods takes precedence - } - } - else { - if (pattern.equals(methodCopy)) { - return true; // run it, includeMethods takes precedence - } - } - } - if (excludeMethods.contains("*") ) { - return false; - } - - // CHECK ME: Previous implementation used include method - for ( String pattern : excludeMethods) { - if (pattern.contains("*")) { - int[] compiledPattern = wildcard.compilePattern(pattern); - HashMap matchedPatterns = new HashMap<>(); - boolean matches = wildcard.match(matchedPatterns, methodCopy, compiledPattern); - if (matches) { - // if found, and wasn't included earlier, don't run it - return false; - } - } - else { - if (pattern.equals(methodCopy)) { - // if found, and wasn't included earlier, don't run it - return false; - } - } - } - - - // default fall-back from before changes - return includeMethods.size() == 0 || includeMethods.contains(method) || includeMethods.contains("*"); - } - - /** - * Same as {@link #applyMethod(Set, Set, String)}, except that excludeMethods - * and includeMethods are supplied as comma separated string. - * - * @param excludeMethods comma seperated string of methods to exclude. - * @param includeMethods comma seperated string of methods to include. - * @param method the specified method to check - * @return true if the method should be applied. - */ - public static boolean applyMethod(String excludeMethods, String includeMethods, String method) { - Set includeMethodsSet = TextParseUtil.commaDelimitedStringToSet(includeMethods == null? "" : includeMethods); - Set excludeMethodsSet = TextParseUtil.commaDelimitedStringToSet(excludeMethods == null? "" : excludeMethods); - - return applyMethod(excludeMethodsSet, includeMethodsSet, method); - } - +@Deprecated +public class MethodFilterInterceptorUtil extends org.apache.struts2.interceptor.MethodFilterInterceptorUtil { } diff --git a/core/src/main/java/org/apache/struts2/interceptor/AbstractInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/AbstractInterceptor.java new file mode 100644 index 0000000000..ddb48a0d79 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/AbstractInterceptor.java @@ -0,0 +1,61 @@ +/* + * 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; + +/** + * Provides default implementations of optional lifecycle methods + */ +public abstract class AbstractInterceptor implements ConditionalInterceptor { + + private boolean disabled; + + /** + * Does nothing + */ + public void init() { + } + + /** + * Does nothing + */ + public void destroy() { + } + + /** + * Override to handle interception + */ + public abstract String intercept(ActionInvocation invocation) throws Exception; + + /** + * Allows to skip executing a given interceptor, just define {@code true} + * or use other way to override interceptor's parameters, see + * docs. + * @param disable if set to true, execution of a given interceptor will be skipped. + */ + public void setDisabled(String disable) { + this.disabled = Boolean.parseBoolean(disable); + } + + @Override + public boolean shouldIntercept(ActionInvocation invocation) { + return !this.disabled; + } +} diff --git a/core/src/main/java/org/apache/struts2/interceptor/MethodFilterInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/MethodFilterInterceptor.java new file mode 100644 index 0000000000..1ffe682619 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/MethodFilterInterceptor.java @@ -0,0 +1,123 @@ +/* + * 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 com.opensymphony.xwork2.util.TextParseUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.struts2.ActionInvocation; + +import java.util.Collections; +import java.util.Set; + +/** + * + * + *

+ * MethodFilterInterceptor is an abstract Interceptor used as + * a base class for interceptors that will filter execution based on method + * names according to specified included/excluded method lists. + * + *

+ * + * Settable parameters are as follows: + * + *
    + *
  • excludeMethods - method names to be excluded from interceptor processing
  • + *
  • includeMethods - method names to be included in interceptor processing
  • + *
+ * + *

+ * + * NOTE: If method name are available in both includeMethods and + * excludeMethods, it will be considered as an included method: + * includeMethods takes precedence over excludeMethods. + * + *

+ * + * Interceptors that extends this capability include: + * + *
    + *
  • TokenInterceptor
  • + *
  • TokenSessionStoreInterceptor
  • + *
  • DefaultWorkflowInterceptor
  • + *
  • ValidationInterceptor
  • + *
+ * + * + * + * @author Alexandru Popescu + * @author Rainer Hermanns + * + * @see TokenInterceptor + * @see TokenSessionStoreInterceptor + * @see com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor + * @see com.opensymphony.xwork2.validator.ValidationInterceptor + */ +public abstract class MethodFilterInterceptor extends AbstractInterceptor { + + private static final Logger LOG = LogManager.getLogger(MethodFilterInterceptor.class); + + protected Set excludeMethods = Collections.emptySet(); + protected Set includeMethods = Collections.emptySet(); + + public void setExcludeMethods(String excludeMethods) { + this.excludeMethods = TextParseUtil.commaDelimitedStringToSet(excludeMethods); + } + + public Set getExcludeMethodsSet() { + return excludeMethods; + } + + public void setIncludeMethods(String includeMethods) { + this.includeMethods = TextParseUtil.commaDelimitedStringToSet(includeMethods); + } + + public Set getIncludeMethodsSet() { + return includeMethods; + } + + @Override + public String intercept(ActionInvocation invocation) throws Exception { + if (applyInterceptor(invocation)) { + return doIntercept(invocation); + } + return invocation.invoke(); + } + + protected boolean applyInterceptor(ActionInvocation invocation) { + String method = invocation.getProxy().getMethod(); + // ValidationInterceptor + boolean applyMethod = MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, method); + if (!applyMethod) { + LOG.debug("Skipping Interceptor... Method [{}] found in exclude list.", method); + } + return applyMethod; + } + + /** + * Subclasses must override to implement the interceptor logic. + * + * @param invocation the action invocation + * @return the result of invocation + * @throws Exception in case of any errors + */ + protected abstract String doIntercept(ActionInvocation invocation) throws Exception; + +} diff --git a/core/src/main/java/org/apache/struts2/interceptor/MethodFilterInterceptorUtil.java b/core/src/main/java/org/apache/struts2/interceptor/MethodFilterInterceptorUtil.java new file mode 100644 index 0000000000..2a43ba2ffa --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/MethodFilterInterceptorUtil.java @@ -0,0 +1,148 @@ +/* + * 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 com.opensymphony.xwork2.util.TextParseUtil; +import com.opensymphony.xwork2.util.WildcardHelper; + +import java.util.HashMap; +import java.util.Set; + +/** + * Utility class contains common methods used by + * {@link MethodFilterInterceptor}. + * + * @author tm_jee + */ +public class MethodFilterInterceptorUtil { + + /** + * Static method to decide if the specified method should be + * apply (not filtered) depending on the set of excludeMethods and + * includeMethods. + * + *
    + *
  • + * includeMethods takes precedence over excludeMethods + *
  • + *
+ * Note: Supports wildcard listings in includeMethods/excludeMethods + * + * @param excludeMethods list of methods to exclude. + * @param includeMethods list of methods to include. + * @param method the specified method to check + * @return true if the method should be applied. + */ + public static boolean applyMethod(Set excludeMethods, Set includeMethods, String method) { + + // quick check to see if any actual pattern matching is needed + boolean needsPatternMatch = false; + for (String includeMethod : includeMethods) { + if (!"*".equals(includeMethod) && includeMethod.contains("*")) { + needsPatternMatch = true; + break; + } + } + + for (String excludeMethod : excludeMethods) { + if (!"*".equals(excludeMethod) && excludeMethod.contains("*")) { + needsPatternMatch = true; + break; + } + } + + // this section will try to honor the original logic, while + // still allowing for wildcards later + if (!needsPatternMatch && (includeMethods.contains("*") || includeMethods.size() == 0) ) { + if (excludeMethods != null + && excludeMethods.contains(method) + && !includeMethods.contains(method) ) { + return false; + } + } + + // test the methods using pattern matching + WildcardHelper wildcard = new WildcardHelper(); + String methodCopy ; + if (method == null ) { // no method specified + methodCopy = ""; + } + else { + methodCopy = new String(method); + } + for (String pattern : includeMethods) { + if (pattern.contains("*")) { + int[] compiledPattern = wildcard.compilePattern(pattern); + HashMap matchedPatterns = new HashMap<>(); + boolean matches = wildcard.match(matchedPatterns, methodCopy, compiledPattern); + if (matches) { + return true; // run it, includeMethods takes precedence + } + } + else { + if (pattern.equals(methodCopy)) { + return true; // run it, includeMethods takes precedence + } + } + } + if (excludeMethods.contains("*") ) { + return false; + } + + // CHECK ME: Previous implementation used include method + for ( String pattern : excludeMethods) { + if (pattern.contains("*")) { + int[] compiledPattern = wildcard.compilePattern(pattern); + HashMap matchedPatterns = new HashMap<>(); + boolean matches = wildcard.match(matchedPatterns, methodCopy, compiledPattern); + if (matches) { + // if found, and wasn't included earlier, don't run it + return false; + } + } + else { + if (pattern.equals(methodCopy)) { + // if found, and wasn't included earlier, don't run it + return false; + } + } + } + + + // default fall-back from before changes + return includeMethods.size() == 0 || includeMethods.contains(method) || includeMethods.contains("*"); + } + + /** + * Same as {@link #applyMethod(Set, Set, String)}, except that excludeMethods + * and includeMethods are supplied as comma separated string. + * + * @param excludeMethods comma seperated string of methods to exclude. + * @param includeMethods comma seperated string of methods to include. + * @param method the specified method to check + * @return true if the method should be applied. + */ + public static boolean applyMethod(String excludeMethods, String includeMethods, String method) { + Set includeMethodsSet = TextParseUtil.commaDelimitedStringToSet(includeMethods == null? "" : includeMethods); + Set excludeMethodsSet = TextParseUtil.commaDelimitedStringToSet(excludeMethods == null? "" : excludeMethods); + + return applyMethod(excludeMethodsSet, includeMethodsSet, method); + } + +}