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}<{@link AnnotatedElement}> 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; /**
