WW-4744: Remove copied Spring's code (also from PR#117)

Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/2d5f0aaa
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/2d5f0aaa
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/2d5f0aaa

Branch: refs/heads/master
Commit: 2d5f0aaa667dca310007f224efbbb622bad5a472
Parents: e1bb1a7
Author: Yasser Zamani <[email protected]>
Authored: Sun Mar 26 18:07:58 2017 +0430
Committer: Yasser Zamani <[email protected]>
Committed: Sun Mar 26 18:07:58 2017 +0430

----------------------------------------------------------------------
 .../interceptor/DefaultWorkflowInterceptor.java |   6 +-
 .../AnnotationWorkflowInterceptor.java          |  11 +-
 .../xwork2/util/AnnotationUtils.java            | 254 ++++++-----------
 .../xwork2/util/ReflectionUtils.java            | 274 -------------------
 .../AnnotationValidationInterceptor.java        |   5 -
 .../xwork2/util/AnnotationUtilsTest.java        |  18 +-
 .../interceptor/BeanValidationInterceptor.java  |   1 -
 7 files changed, 93 insertions(+), 476 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/2d5f0aaa/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java
----------------------------------------------------------------------
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 38fa810..f9bcbd8 100644
--- 
a/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java
+++ 
b/core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java
@@ -18,8 +18,8 @@ package com.opensymphony.xwork2.interceptor;
 import com.opensymphony.xwork2.Action;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.interceptor.annotations.InputConfig;
-import com.opensymphony.xwork2.util.ReflectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.MethodUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import com.opensymphony.xwork2.util.AnnotationUtils;
@@ -211,9 +211,7 @@ public class DefaultWorkflowInterceptor extends 
MethodFilterInterceptor {
         InputConfig annotation = 
AnnotationUtils.findAnnotation(action.getClass().getMethod(method, 
EMPTY_CLASS_ARRAY), InputConfig.class);
         if (annotation != null) {
             if (StringUtils.isNotEmpty(annotation.methodName())) {
-                Method m = ReflectionUtils.findMethod(action.getClass(), 
annotation.methodName());
-                ReflectionUtils.makeAccessible(m);
-                resultName = (String) ReflectionUtils.invokeMethod(m, action);
+                resultName = (String) MethodUtils.invokeMethod(action, true, 
annotation.methodName());
             } else {
                 resultName = annotation.resultName();
             }

http://git-wip-us.apache.org/repos/asf/struts/blob/2d5f0aaa/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
 
b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
index 122d245..38e3503 100644
--- 
a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
+++ 
b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
@@ -20,7 +20,7 @@ import com.opensymphony.xwork2.XWorkException;
 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
 import com.opensymphony.xwork2.interceptor.PreResultListener;
 import com.opensymphony.xwork2.util.AnnotationUtils;
-import com.opensymphony.xwork2.util.ReflectionUtils;
+import org.apache.commons.lang3.reflect.MethodUtils;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -123,8 +123,7 @@ public class AnnotationWorkflowInterceptor extends 
AbstractInterceptor implement
                 }
             });
             for (Method m : methods) {
-                ReflectionUtils.makeAccessible(m);
-                final String resultCode = (String) 
ReflectionUtils.invokeMethod(m, action);
+                final String resultCode = (String) 
MethodUtils.invokeMethod(action, true, m.getName());
                 if (resultCode != null) {
                     // shortcircuit execution
                     return resultCode;
@@ -146,8 +145,7 @@ public class AnnotationWorkflowInterceptor extends 
AbstractInterceptor implement
                 }
             });
             for (Method m : methods) {
-                ReflectionUtils.makeAccessible(m);
-                ReflectionUtils.invokeMethod(m, action);
+                MethodUtils.invokeMethod(action, true, m.getName());
             }
         }
 
@@ -183,8 +181,7 @@ public class AnnotationWorkflowInterceptor extends 
AbstractInterceptor implement
             });
             for (Method m : methods) {
                 try {
-                    ReflectionUtils.makeAccessible(m);
-                    ReflectionUtils.invokeMethod(m, action);
+                    MethodUtils.invokeMethod(action, true, m.getName());
                 } catch (Exception e) {
                     throw new XWorkException(e);
                 }

http://git-wip-us.apache.org/repos/asf/struts/blob/2d5f0aaa/core/src/main/java/com/opensymphony/xwork2/util/AnnotationUtils.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/util/AnnotationUtils.java 
b/core/src/main/java/com/opensymphony/xwork2/util/AnnotationUtils.java
index 87442c4..6e3836f 100644
--- a/core/src/main/java/com/opensymphony/xwork2/util/AnnotationUtils.java
+++ b/core/src/main/java/com/opensymphony/xwork2/util/AnnotationUtils.java
@@ -1,6 +1,5 @@
 /*
  * Copyright 2002-2006,2009 The Apache Software Foundation.
- * Copyright 2002-2014 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,17 +16,16 @@
 package com.opensymphony.xwork2.util;
 
 import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.ClassUtils;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -40,12 +38,6 @@ import java.util.regex.Pattern;
  * @author Rainer Hermanns
  * @author Zsolt Szasz, zsolt at lorecraft dot com
  * @author Dan Oxlade, dan d0t oxlade at gmail d0t c0m
- * @author Rob Harrop
- * @author Juergen Hoeller
- * @author Sam Brannen
- * @author Mark Fisher
- * @author Chris Beams
- * @author Phillip Webb
  * @version $Id$
  */
 public class AnnotationUtils {
@@ -53,12 +45,6 @@ public class AnnotationUtils {
     private static final Pattern SETTER_PATTERN = 
Pattern.compile("set([A-Z][A-Za-z0-9]*)$");
     private static final Pattern GETTER_PATTERN = 
Pattern.compile("(get|is|has)([A-Z][A-Za-z0-9]*)$");
 
-    private static final Map<AnnotationCacheKey, Annotation> 
findAnnotationCache =
-            new ConcurrentHashMap<AnnotationCacheKey, Annotation>(256);
-
-    private static final Map<Class<?>, Boolean> annotatedInterfaceCache =
-            new ConcurrentHashMap<Class<?>, Boolean>(256);
-
     /**
      * Adds all fields with the specified Annotation of class clazz and its 
superclasses to allFields
      *
@@ -131,136 +117,101 @@ public class AnnotationUtils {
      * @param annotation the {@link Annotation}s to find
      * @return A {@link Collection}&lt;{@link AnnotatedElement}&gt; containing 
all of the
      * method {@link AnnotatedElement}s matching the specified {@link 
Annotation}s
+     * @deprecated Will be removed after release of <a 
href="https://github.com/apache/commons-lang/pull/261";>LANG-1317</a>
      */
-    public static Collection<Method> getAnnotatedMethods(Class clazz, final 
Class<? extends Annotation>... annotation) {
-        final Collection<Method> toReturn = new HashSet<>();
-
-        ReflectionUtils.doWithMethods(clazz, new 
ReflectionUtils.MethodCallback() {
-            @Override
-            public void doWith(Method method) throws IllegalArgumentException {
+    public static Collection<Method> getAnnotatedMethods(Class clazz, Class<? 
extends Annotation>... annotation) {
+        List<Class<?>> allSuperclasses = ClassUtils.getAllSuperclasses(clazz);
+        allSuperclasses.add(0, clazz);
+        int sci = 0;
+        List<Class<?>> allInterfaces = ClassUtils.getAllInterfaces(clazz);
+        int ifi = 0;
+        final List<Method> annotatedMethods = new ArrayList<>();
+        while (ifi < allInterfaces.size() ||
+                sci < allSuperclasses.size()) {
+            Class<?> acls;
+            if (ifi >= allInterfaces.size()) {
+                acls = allSuperclasses.get(sci++);
+            }
+            else if (sci >= allSuperclasses.size()) {
+                acls = allInterfaces.get(ifi++);
+            }
+            else if (sci <= ifi) {
+                acls = allSuperclasses.get(sci++);
+            }
+            else {
+                acls = allInterfaces.get(ifi++);
+            }
+            final Method[] allMethods = acls.getDeclaredMethods();
+            for (final Method method : allMethods) {
                 if (ArrayUtils.isEmpty(annotation) && 
ArrayUtils.isNotEmpty(method.getAnnotations())) {
-                    toReturn.add(method);
-                    return;
+                    annotatedMethods.add(method);
+                    continue;
                 }
                 for (Class<? extends Annotation> c : annotation) {
-                    if (null != findAnnotation(method, c)) {
-                        toReturn.add(method);
-                        break;
+                    if (method.getAnnotation(c) != null) {
+                        annotatedMethods.add(method);
                     }
                 }
             }
-        });
+        }
 
-        return toReturn;
+        return annotatedMethods;
     }
 
     /**
-     * Find a single {@link Annotation} of {@code annotationType} from the 
supplied
-     * {@link Method}, traversing its super methods (i.e., from superclasses 
and
-     * interfaces) if no annotation can be found on the given method itself.
-     * <p>Annotations on methods are not inherited by default, so we need to 
handle
-     * this explicitly.
-     *
-     * @param method         the method to look for annotations on
-     * @param annotationType the annotation type to look for
-     * @return the annotation found, or {@code null} if none
+     * <p>BFS to find the annotation object that is present on the given 
method or any equivalent method in
+     * super classes and interfaces, with the given annotation type. Returns 
null if the annotation type was not present
+     * on any of them.</p>
+     * @param <A>
+     *            the annotation type
+     * @param method
+     *            the {@link Method} to query
+     * @param annotationCls
+     *            the {@link Annotation} to check if is present on the method
+     * @return an Annotation (possibly null).
+     * @deprecated Will be removed after release of <a 
href="https://github.com/apache/commons-lang/pull/261";>LANG-1317</a>
      */
-    public static <A extends Annotation> A findAnnotation(Method method, 
Class<A> annotationType) {
-        AnnotationCacheKey cacheKey = new AnnotationCacheKey(method, 
annotationType);
-        A result = (A) findAnnotationCache.get(cacheKey);
-        if (result == null) {
-            result = getAnnotation(method, annotationType);
-            Class<?> clazz = method.getDeclaringClass();
-            if (result == null) {
-                result = searchOnInterfaces(method, annotationType, 
clazz.getInterfaces());
-            }
-            while (result == null) {
-                clazz = clazz.getSuperclass();
-                if (clazz == null || clazz.equals(Object.class)) {
-                    break;
+    public static <A extends Annotation> A findAnnotation(final Method method, 
final Class<A> annotationCls) {
+        A annotation = method.getAnnotation(annotationCls);
+
+        if(annotation == null) {
+            Class<?> mcls = method.getDeclaringClass();
+            List<Class<?>> allSuperclasses = 
ClassUtils.getAllSuperclasses(mcls);
+            int sci = 0;
+            List<Class<?>> allInterfaces = ClassUtils.getAllInterfaces(mcls);
+            int ifi = 0;
+            while (ifi < allInterfaces.size() ||
+                    sci < allSuperclasses.size()) {
+                Class<?> acls;
+                if(ifi >= allInterfaces.size()) {
+                    acls = allSuperclasses.get(sci++);
                 }
-                try {
-                    Method equivalentMethod = 
clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
-                    result = getAnnotation(equivalentMethod, annotationType);
-                } catch (NoSuchMethodException ex) {
-                    // No equivalent method found
+                else if(sci >= allSuperclasses.size()) {
+                    acls = allInterfaces.get(ifi++);
                 }
-                if (result == null) {
-                    result = searchOnInterfaces(method, annotationType, 
clazz.getInterfaces());
+                else if(ifi <= sci) {
+                    acls = allInterfaces.get(ifi++);
                 }
-            }
-            if (result != null) {
-                findAnnotationCache.put(cacheKey, result);
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Get a single {@link Annotation} of {@code annotationType} from the 
supplied
-     * Method, Constructor or Field. Meta-annotations will be searched if the 
annotation
-     * is not declared locally on the supplied element.
-     *
-     * @param annotatedElement the Method, Constructor or Field from which to 
get the annotation
-     * @param annotationType   the annotation type to look for, both locally 
and as a meta-annotation
-     * @return the matching annotation, or {@code null} if none found
-     */
-    public static <T extends Annotation> T getAnnotation(AnnotatedElement 
annotatedElement, Class<T> annotationType) {
-        try {
-            T ann = annotatedElement.getAnnotation(annotationType);
-            if (ann == null) {
-                for (Annotation metaAnn : annotatedElement.getAnnotations()) {
-                    ann = 
metaAnn.annotationType().getAnnotation(annotationType);
-                    if (ann != null) {
-                        break;
-                    }
+                else {
+                    acls = allSuperclasses.get(sci++);
                 }
-            }
-            return ann;
-        } catch (Exception ex) {
-            // Assuming nested Class values not resolvable within annotation 
attributes...
-            return null;
-        }
-    }
-
-    private static <A extends Annotation> A searchOnInterfaces(Method method, 
Class<A> annotationType, Class<?>... ifcs) {
-        A annotation = null;
-        for (Class<?> iface : ifcs) {
-            if (isInterfaceWithAnnotatedMethods(iface)) {
+                Method equivalentMethod = null;
                 try {
-                    Method equivalentMethod = 
iface.getMethod(method.getName(), method.getParameterTypes());
-                    annotation = getAnnotation(equivalentMethod, 
annotationType);
-                } catch (NoSuchMethodException ex) {
-                    // Skip this interface - it doesn't have the method...
+                    equivalentMethod = 
acls.getDeclaredMethod(method.getName(), method.getParameterTypes());
+                } catch (NoSuchMethodException e) {
+                    // If not found, just keep on breadth first search
                 }
-                if (annotation != null) {
-                    break;
+                if(equivalentMethod != null) {
+                    annotation = equivalentMethod.getAnnotation(annotationCls);
+                    if(annotation != null) {
+                        break;
+                    }
                 }
             }
         }
         return annotation;
     }
 
-    private static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
-        Boolean flag = annotatedInterfaceCache.get(iface);
-        if (flag != null) {
-            return flag;
-        }
-        boolean found = false;
-        for (Method ifcMethod : iface.getMethods()) {
-            try {
-                if (ifcMethod.getAnnotations().length > 0) {
-                    found = true;
-                    break;
-                }
-            } catch (Exception ex) {
-                // Assuming nested Class values not resolvable within 
annotation attributes...
-            }
-        }
-        annotatedInterfaceCache.put(iface, found);
-        return found;
-    }
-
     /**
      * Returns the property name for a method.
      * This method is independent from property fields.
@@ -295,61 +246,20 @@ public class AnnotationUtils {
      * @return The annotation or null.
      */
     public static <T extends Annotation> T findAnnotation(Class<?> clazz, 
Class<T> annotationClass) {
-        AnnotationCacheKey cacheKey = new AnnotationCacheKey(clazz, 
annotationClass);
-        T ann = (T) findAnnotationCache.get(cacheKey);
-        if (ann == null) {
+        T ann = clazz.getAnnotation(annotationClass);
+        while (ann == null && clazz != null) {
             ann = clazz.getAnnotation(annotationClass);
-            while (ann == null && clazz != null) {
-                ann = clazz.getAnnotation(annotationClass);
-                if (ann == null) {
-                    ann = clazz.getPackage().getAnnotation(annotationClass);
-                }
-                if (ann == null) {
-                    clazz = clazz.getSuperclass();
-                    if (clazz != null) {
-                        ann = clazz.getAnnotation(annotationClass);
-                    }
-                }
+            if (ann == null) {
+                ann = clazz.getPackage().getAnnotation(annotationClass);
             }
-            if (ann != null) {
-                findAnnotationCache.put(cacheKey, ann);
+            if (ann == null) {
+                clazz = clazz.getSuperclass();
+                if (clazz != null) {
+                    ann = clazz.getAnnotation(annotationClass);
+                }
             }
         }
 
         return ann;
     }
-
-
-    /**
-     * Cache key for the AnnotatedElement cache.
-     */
-    private static class AnnotationCacheKey {
-
-        private final AnnotatedElement element;
-
-        private final Class<? extends Annotation> annotationType;
-
-        public AnnotationCacheKey(AnnotatedElement element, Class<? extends 
Annotation> annotationType) {
-            this.element = element;
-            this.annotationType = annotationType;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (!(other instanceof AnnotationCacheKey)) {
-                return false;
-            }
-            AnnotationCacheKey otherKey = (AnnotationCacheKey) other;
-            return (this.element.equals(otherKey.element) &&
-                    this.annotationType.equals(otherKey.annotationType));
-        }
-
-        @Override
-        public int hashCode() {
-            return (this.element.hashCode() * 29 + 
this.annotationType.hashCode());
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/2d5f0aaa/core/src/main/java/com/opensymphony/xwork2/util/ReflectionUtils.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/util/ReflectionUtils.java 
b/core/src/main/java/com/opensymphony/xwork2/util/ReflectionUtils.java
deleted file mode 100644
index 08bd933..0000000
--- a/core/src/main/java/com/opensymphony/xwork2/util/ReflectionUtils.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright 2002-2015 The Apache Software Foundation.
- * Copyright 2002-2015 the original author or authors.
- *
- * Licensed 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 com.opensymphony.xwork2.util;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Simple utility class for working with the reflection API and handling
- * reflection exceptions.
- *
- * <p>Only intended for internal use.
- *
- * @author Juergen Hoeller
- * @author Rob Harrop
- * @author Rod Johnson
- * @author Costin Leau
- * @author Sam Brannen
- * @author Chris Beams
- */
-public abstract class ReflectionUtils {
-
-    /**
-     * Cache for {@link Class#getDeclaredMethods()}, allowing for fast 
iteration.
-     */
-    private static final Map<Class<?>, Method[]> declaredMethodsCache =
-            new ConcurrentHashMap<Class<?>, Method[]>(256);
-
-    /**
-     * Perform the given callback operation on all matching methods of the 
given
-     * class and superclasses.
-     * <p>The same named method occurring on subclass and superclass will 
appear
-     * twice, unless excluded by a {@link MethodFilter}.
-     * @param clazz the class to introspect
-     * @param mc the callback to invoke for each method
-     * @see #doWithMethods(Class, MethodCallback, MethodFilter)
-     */
-    public static void doWithMethods(Class<?> clazz, MethodCallback mc) {
-        doWithMethods(clazz, mc, null);
-    }
-
-    /**
-     * Perform the given callback operation on all matching methods of the 
given
-     * class and superclasses (or given interface and super-interfaces).
-     * <p>The same named method occurring on subclass and superclass will 
appear
-     * twice, unless excluded by the specified {@link MethodFilter}.
-     * @param clazz the class to introspect
-     * @param mc the callback to invoke for each method
-     * @param mf the filter that determines the methods to apply the callback 
to
-     */
-    public static void doWithMethods(Class<?> clazz, MethodCallback mc, 
MethodFilter mf) {
-        // Keep backing up the inheritance hierarchy.
-        Method[] methods = getDeclaredMethods(clazz);
-        for (Method method : methods) {
-            if (mf != null && !mf.matches(method)) {
-                continue;
-            }
-            try {
-                mc.doWith(method);
-            }
-            catch (IllegalAccessException ex) {
-                throw new IllegalStateException("Not allowed to access method 
'" + method.getName() + "': " + ex);
-            }
-        }
-        if (clazz.getSuperclass() != null) {
-            doWithMethods(clazz.getSuperclass(), mc, mf);
-        }
-        else if (clazz.isInterface()) {
-            for (Class<?> superIfc : clazz.getInterfaces()) {
-                doWithMethods(superIfc, mc, mf);
-            }
-        }
-    }
-
-    /**
-     * Make the given method accessible, explicitly setting it accessible if
-     * necessary. The {@code setAccessible(true)} method is only called
-     * when actually necessary, to avoid unnecessary conflicts with a JVM
-     * SecurityManager (if active).
-     * @param method the method to make accessible
-     * @see java.lang.reflect.Method#setAccessible
-     */
-    public static void makeAccessible(Method method) {
-        if ((!Modifier.isPublic(method.getModifiers()) ||
-                !Modifier.isPublic(method.getDeclaringClass().getModifiers())) 
&& !method.isAccessible()) {
-            method.setAccessible(true);
-        }
-    }
-
-    /**
-     * Attempt to find a {@link Method} on the supplied class with the 
supplied name
-     * and no parameters. Searches all superclasses up to {@code Object}.
-     * <p>Returns {@code null} if no {@link Method} can be found.
-     * @param clazz the class to introspect
-     * @param name the name of the method
-     * @return the Method object, or {@code null} if none found
-     */
-    public static Method findMethod(Class<?> clazz, String name) {
-        return findMethod(clazz, name, new Class<?>[0]);
-    }
-
-    /**
-     * Attempt to find a {@link Method} on the supplied class with the 
supplied name
-     * and parameter types. Searches all superclasses up to {@code Object}.
-     * <p>Returns {@code null} if no {@link Method} can be found.
-     * @param clazz the class to introspect
-     * @param name the name of the method
-     * @param paramTypes the parameter types of the method
-     * (may be {@code null} to indicate any signature)
-     * @return the Method object, or {@code null} if none found
-     */
-    public static Method findMethod(Class<?> clazz, String name, Class<?>... 
paramTypes) {
-        Class<?> searchType = clazz;
-        while (searchType != null) {
-            Method[] methods = (searchType.isInterface() ? 
searchType.getMethods() : getDeclaredMethods(searchType));
-            for (Method method : methods) {
-                if (name.equals(method.getName()) &&
-                        (paramTypes == null || Arrays.equals(paramTypes, 
method.getParameterTypes()))) {
-                    return method;
-                }
-            }
-            searchType = searchType.getSuperclass();
-        }
-        return null;
-    }
-
-    /**
-     * Invoke the specified {@link Method} against the supplied target object 
with no arguments.
-     * The target object can be {@code null} when invoking a static {@link 
Method}.
-     * <p>Thrown exceptions are handled via a call to {@link 
#handleReflectionException}.
-     * @param method the method to invoke
-     * @param target the target object to invoke the method on
-     * @return the invocation result, if any
-     * @see #invokeMethod(java.lang.reflect.Method, Object, Object[])
-     */
-    public static Object invokeMethod(Method method, Object target) {
-        return invokeMethod(method, target, new Object[0]);
-    }
-
-    /**
-     * Invoke the specified {@link Method} against the supplied target object 
with the
-     * supplied arguments. The target object can be {@code null} when invoking 
a
-     * static {@link Method}.
-     * <p>Thrown exceptions are handled via a call to {@link 
#handleReflectionException}.
-     * @param method the method to invoke
-     * @param target the target object to invoke the method on
-     * @param args the invocation arguments (may be {@code null})
-     * @return the invocation result, if any
-     */
-    public static Object invokeMethod(Method method, Object target, Object... 
args) {
-        try {
-            return method.invoke(target, args);
-        }
-        catch (Exception ex) {
-            handleReflectionException(ex);
-        }
-        throw new IllegalStateException("Should never get here");
-    }
-
-    /**
-     * Handle the given reflection exception. Should only be called if no
-     * checked exception is expected to be thrown by the target method.
-     * <p>Throws the underlying RuntimeException or Error in case of an
-     * InvocationTargetException with such a root cause. Throws an
-     * IllegalStateException with an appropriate message else.
-     * @param ex the reflection exception to handle
-     */
-    public static void handleReflectionException(Exception ex) {
-        if (ex instanceof NoSuchMethodException) {
-            throw new IllegalStateException("Method not found: " + 
ex.getMessage());
-        }
-        if (ex instanceof IllegalAccessException) {
-            throw new IllegalStateException("Could not access method: " + 
ex.getMessage());
-        }
-        if (ex instanceof InvocationTargetException) {
-            handleInvocationTargetException((InvocationTargetException) ex);
-        }
-        if (ex instanceof RuntimeException) {
-            throw (RuntimeException) ex;
-        }
-        throw new UndeclaredThrowableException(ex);
-    }
-
-    /**
-     * Handle the given invocation target exception. Should only be called if 
no
-     * checked exception is expected to be thrown by the target method.
-     * <p>Throws the underlying RuntimeException or Error in case of such a 
root
-     * cause. Throws an IllegalStateException else.
-     * @param ex the invocation target exception to handle
-     */
-    public static void 
handleInvocationTargetException(InvocationTargetException ex) {
-        rethrowRuntimeException(ex.getTargetException());
-    }
-
-    /**
-     * Rethrow the given {@link Throwable exception}, which is presumably the
-     * <em>target exception</em> of an {@link InvocationTargetException}. 
Should
-     * only be called if no checked exception is expected to be thrown by the
-     * target method.
-     * <p>Rethrows the underlying exception cast to an {@link 
RuntimeException} or
-     * {@link Error} if appropriate; otherwise, throws an
-     * {@link IllegalStateException}.
-     * @param ex the exception to rethrow
-     * @throws RuntimeException the rethrown exception
-     */
-    public static void rethrowRuntimeException(Throwable ex) {
-        if (ex instanceof RuntimeException) {
-            throw (RuntimeException) ex;
-        }
-        if (ex instanceof Error) {
-            throw (Error) ex;
-        }
-        throw new UndeclaredThrowableException(ex);
-    }
-
-    /**
-     * This variant retrieves {@link Class#getDeclaredMethods()} from a local 
cache
-     * in order to avoid the JVM's SecurityManager check and defensive array 
copying.
-     */
-    private static Method[] getDeclaredMethods(Class<?> clazz) {
-        Method[] result = declaredMethodsCache.get(clazz);
-        if (result == null) {
-            result = clazz.getDeclaredMethods();
-            declaredMethodsCache.put(clazz, result);
-        }
-        return result;
-    }
-
-
-    /**
-     * Action to take on each method.
-     */
-    public interface MethodCallback {
-
-        /**
-         * Perform an operation using the given method.
-         * @param method the method to operate on
-         */
-        void doWith(Method method) throws IllegalArgumentException, 
IllegalAccessException;
-    }
-
-
-    /**
-     * Callback optionally used to filter methods to be operated on by a 
method callback.
-     */
-    public interface MethodFilter {
-
-        /**
-         * Determine whether the given method matches.
-         * @param method the method to check
-         */
-        boolean matches(Method method);
-    }
-}

http://git-wip-us.apache.org/repos/asf/struts/blob/2d5f0aaa/core/src/main/java/org/apache/struts2/interceptor/validation/AnnotationValidationInterceptor.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/validation/AnnotationValidationInterceptor.java
 
b/core/src/main/java/org/apache/struts2/interceptor/validation/AnnotationValidationInterceptor.java
index 26e1545..b9ba26c 100644
--- 
a/core/src/main/java/org/apache/struts2/interceptor/validation/AnnotationValidationInterceptor.java
+++ 
b/core/src/main/java/org/apache/struts2/interceptor/validation/AnnotationValidationInterceptor.java
@@ -23,17 +23,12 @@ package org.apache.struts2.interceptor.validation;
 
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.config.ConfigurationException;
-import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.util.AnnotationUtils;
 import com.opensymphony.xwork2.validator.ValidationInterceptor;
-import org.apache.commons.lang3.BooleanUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.struts2.StrutsConstants;
 
 import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collection;
 
 /**
  * Extends the xwork validation interceptor to also check for a @SkipValidation

http://git-wip-us.apache.org/repos/asf/struts/blob/2d5f0aaa/core/src/test/java/com/opensymphony/xwork2/util/AnnotationUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/com/opensymphony/xwork2/util/AnnotationUtilsTest.java 
b/core/src/test/java/com/opensymphony/xwork2/util/AnnotationUtilsTest.java
index 7412116..1b6e0d5 100644
--- a/core/src/test/java/com/opensymphony/xwork2/util/AnnotationUtilsTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/util/AnnotationUtilsTest.java
@@ -3,13 +3,13 @@ package com.opensymphony.xwork2.util;
 import com.opensymphony.xwork2.util.annotation.Dummy2Class;
 import com.opensymphony.xwork2.util.annotation.DummyClass;
 import com.opensymphony.xwork2.util.annotation.DummyClassExt;
+import com.opensymphony.xwork2.util.annotation.DummyInterface;
 import com.opensymphony.xwork2.util.annotation.MyAnnotation;
 import com.opensymphony.xwork2.util.annotation.MyAnnotation2;
 import com.opensymphony.xwork2.util.annotation.MyAnnotationI;
 
 import junit.framework.TestCase;
 
-import java.lang.annotation.Retention;
 import java.lang.reflect.AnnotatedElement;
 import java.util.Collection;
 
@@ -18,15 +18,6 @@ import java.util.Collection;
  */
 public class AnnotationUtilsTest extends TestCase {
 
-    public void testGetAnnotationMeta() throws Exception {
-        
assertNotNull(AnnotationUtils.getAnnotation(DummyClass.class.getMethod("methodWithAnnotation"),
 Retention.class));
-    }
-
-    public void testGetAnnotation() throws Exception {
-        
assertNull(AnnotationUtils.getAnnotation(DummyClass.class.getMethod("methodWithAnnotation"),
 Deprecated.class));
-        
assertNotNull(AnnotationUtils.getAnnotation(DummyClass.class.getMethod("methodWithAnnotation"),
 MyAnnotation.class));
-    }
-
     public void testFindAnnotationFromSuperclass() throws Exception {
         
assertNotNull(AnnotationUtils.findAnnotation(DummyClassExt.class.getMethod("methodWithAnnotation"),
 MyAnnotation.class));
     }
@@ -43,15 +34,16 @@ public class AnnotationUtilsTest extends TestCase {
     public void testGetAnnotatedMethodsIncludingSuperclassAndInterface() 
throws Exception {
 
         Collection<? extends AnnotatedElement> ans = 
AnnotationUtils.getAnnotatedMethods(DummyClassExt.class, Deprecated.class, 
MyAnnotation.class, MyAnnotation2.class, MyAnnotationI.class);
-        assertEquals(5, ans.size());
+        assertEquals(4, ans.size());
     }
 
     @SuppressWarnings("unchecked")
     public void testGetAnnotatedMethodsWithoutAnnotationArgs() throws 
Exception {
         Collection<? extends AnnotatedElement> ans = 
AnnotationUtils.getAnnotatedMethods(DummyClass.class);
-        assertTrue(ans.size() == 2);
+        assertEquals(3, ans.size());
         
assertTrue(ans.contains(DummyClass.class.getMethod("methodWithAnnotation")));
         
assertTrue(ans.contains(DummyClass.class.getDeclaredMethod("privateMethodWithAnnotation")));
+        
assertTrue(ans.contains(DummyInterface.class.getDeclaredMethod("interfaceMethodWithAnnotation")));
     }
 
     @SuppressWarnings("unchecked")
@@ -69,7 +61,7 @@ public class AnnotationUtilsTest extends TestCase {
         assertEquals(2, ans.size());
 
         ans = AnnotationUtils.getAnnotatedMethods(DummyClassExt.class, 
MyAnnotation.class, MyAnnotation2.class);
-        assertEquals(4, ans.size());
+        assertEquals(3, ans.size());
     }
 
     public void testFindAnnotationOnClass() {

http://git-wip-us.apache.org/repos/asf/struts/blob/2d5f0aaa/plugins/bean-validation/src/main/java/org/apache/struts/beanvalidation/validation/interceptor/BeanValidationInterceptor.java
----------------------------------------------------------------------
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 6059070..a20d134 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
@@ -39,7 +39,6 @@ import 
org.apache.struts2.interceptor.validation.SkipValidation;
 import javax.validation.ConstraintViolation;
 import javax.validation.Validator;
 import java.lang.reflect.Method;
-import java.util.Collection;
 import java.util.Set;
 
 /**

Reply via email to