LANG-1317: Add MethodUtils#findAnnotation and extend MethodUtils#getMethodsWithAnnotation for non-public, super-class and interface methods
Add changes.xml entry and minimal clean-up. Project: http://git-wip-us.apache.org/repos/asf/commons-lang/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-lang/commit/314b6b56 Tree: http://git-wip-us.apache.org/repos/asf/commons-lang/tree/314b6b56 Diff: http://git-wip-us.apache.org/repos/asf/commons-lang/diff/314b6b56 Branch: refs/heads/release Commit: 314b6b56bec4af56dba667d66a25c1613f4bc800 Parents: 46007c1 Author: pascalschumacher <pascalschumac...@gmx.net> Authored: Fri Apr 21 10:45:03 2017 +0200 Committer: pascalschumacher <pascalschumac...@gmx.net> Committed: Fri Apr 21 10:45:03 2017 +0200 ---------------------------------------------------------------------- src/changes/changes.xml | 1 + .../commons/lang3/reflect/MethodUtils.java | 60 ++++++++++---------- 2 files changed, 31 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-lang/blob/314b6b56/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index e50441b..f4df009 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -85,6 +85,7 @@ The <action> type attribute can be add,update,fix,remove. <action issue="LANG-1310" type="fix" dev="pschumacher" due-to="Don Jeba">MethodUtils.invokeMethod throws ArrayStoreException if using varargs arguments and smaller types than the method defines</action> <action issue="LANG-1313" type="add" dev="pschumacher" due-to="Tomschi">Add ArchUtils - An utility class for the "os.arch" system property</action> <action issue="LANG-1272" type="add" dev="ebourg">Add shuffle methods to ArrayUtils</action> + <action issue="LANG-1317" type="add" dev="pschumacher" due-to="Yasser Zamani">Add MethodUtils#findAnnotation and extend MethodUtils#getMethodsWithAnnotation for non-public, super-class and interface methods</action> </release> <release version="3.5" date="2016-10-13" description="New features including Java 9 detection"> http://git-wip-us.apache.org/repos/asf/commons-lang/blob/314b6b56/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java b/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java index 55b5cb1..107f317 100644 --- a/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java +++ b/src/main/java/org/apache/commons/lang3/reflect/MethodUtils.java @@ -866,9 +866,9 @@ public class MethodUtils { * @param annotationCls * the {@link java.lang.annotation.Annotation} that must be present on a method to be matched * @param searchSupers - * determines if also a lookup in the entire inheritance hierarchy of the given class should be performed + * determines if a lookup in the entire inheritance hierarchy of the given class should be performed * @param ignoreAccess - * determines if also non public methods should be considered + * determines if non public methods should be considered * @return an array of Methods (possibly empty). * @throws IllegalArgumentException * if the class or annotation are {@code null} @@ -888,9 +888,9 @@ public class MethodUtils { * @param annotationCls * the {@link Annotation} that must be present on a method to be matched * @param searchSupers - * determines if also a lookup in the entire inheritance hierarchy of the given class should be performed + * determines if a lookup in the entire inheritance hierarchy of the given class should be performed * @param ignoreAccess - * determines if also non public methods should be considered + * determines if non public methods should be considered * @return a list of Methods (possibly empty). * @throws IllegalArgumentException * if the class or annotation are {@code null} @@ -904,7 +904,7 @@ public class MethodUtils { Validate.isTrue(annotationCls != null, "The annotation class must not be null"); List<Class<?>> classes = (searchSupers ? getAllSuperclassesAndInterfaces(cls) : new ArrayList<Class<?>>()); - classes.add(0, cls); + classes.add(cls); final List<Method> annotatedMethods = new ArrayList<>(); for (Class<?> acls : classes) { final Method[] methods = (ignoreAccess ? acls.getDeclaredMethods() : acls.getMethods()); @@ -918,12 +918,12 @@ public class MethodUtils { } /** - * <p>Gets 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> + * <p>Gets the annotation object with the given annotation type that is present on the given method + * or optionally on any equivalent method in super classes and interfaces. Returns null if the annotation + * type was not present.</p> * * <p>Stops searching for an annotation once the first annotation of the specified type has been - * found. i.e, additional annotations of the specified type will be silently ignored.</p> + * found. Additional annotations of the specified type will be silently ignored.</p> * @param <A> * the annotation type * @param method @@ -931,7 +931,8 @@ public class MethodUtils { * @param annotationCls * the {@link Annotation} to check if is present on the method * @param searchSupers - * determines if lookup in the entire inheritance hierarchy of the given class if was not directly present + * determines if a lookup in the entire inheritance hierarchy of the given class is performed + * if the annotation was not directly present * @param ignoreAccess * determines if underlying method has to be accessible * @return the first matching annotation, or {@code null} if not found @@ -944,13 +945,13 @@ public class MethodUtils { Validate.isTrue(method != null, "The method must not be null"); Validate.isTrue(annotationCls != null, "The annotation class must not be null"); - if(!ignoreAccess && !MemberUtils.isAccessible(method)) { + if (!ignoreAccess && !MemberUtils.isAccessible(method)) { return null; } A annotation = method.getAnnotation(annotationCls); - if(annotation == null && searchSupers) { + if (annotation == null && searchSupers) { Class<?> mcls = method.getDeclaringClass(); List<Class<?>> classes = getAllSuperclassesAndInterfaces(mcls); for (Class<?> acls : classes) { @@ -959,7 +960,7 @@ public class MethodUtils { equivalentMethod = (ignoreAccess ? acls.getDeclaredMethod(method.getName(), method.getParameterTypes()) : acls.getMethod(method.getName(), method.getParameterTypes())); } catch (NoSuchMethodException e) { - // If not found, just keep on search + // if not found, just keep searching continue; } annotation = equivalentMethod.getAnnotation(annotationCls); @@ -981,34 +982,33 @@ public class MethodUtils { * @return the combined {@code List} of superclasses and interfaces in order * going up from this one * {@code null} if null input - * @since 3.6 */ private static List<Class<?>> getAllSuperclassesAndInterfaces(final Class<?> cls) { if (cls == null) { return null; } - final List<Class<?>> classes = new ArrayList<>(); + final List<Class<?>> allSuperClassesAndInterfaces = new ArrayList<>(); List<Class<?>> allSuperclasses = ClassUtils.getAllSuperclasses(cls); - int sci = 0; + int superClassIndex = 0; List<Class<?>> allInterfaces = ClassUtils.getAllInterfaces(cls); - int ifi = 0; - while (ifi < allInterfaces.size() || - sci < allSuperclasses.size()) { + int interfaceIndex = 0; + while (interfaceIndex < allInterfaces.size() || + superClassIndex < allSuperclasses.size()) { Class<?> acls; - if (ifi >= allInterfaces.size()) { - acls = allSuperclasses.get(sci++); - } else if (sci >= allSuperclasses.size()) { - acls = allInterfaces.get(ifi++); - } else if (ifi < sci) { - acls = allInterfaces.get(ifi++); - } else if (sci < ifi) { - acls = allSuperclasses.get(sci++); + if (interfaceIndex >= allInterfaces.size()) { + acls = allSuperclasses.get(superClassIndex++); + } else if (superClassIndex >= allSuperclasses.size()) { + acls = allInterfaces.get(interfaceIndex++); + } else if (interfaceIndex < superClassIndex) { + acls = allInterfaces.get(interfaceIndex++); + } else if (superClassIndex < interfaceIndex) { + acls = allSuperclasses.get(superClassIndex++); } else { - acls = allInterfaces.get(ifi++); + acls = allInterfaces.get(interfaceIndex++); } - classes.add(acls); + allSuperClassesAndInterfaces.add(acls); } - return classes; + return allSuperClassesAndInterfaces; } }