All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.reflections.ReflectionUtils Maven / Gradle / Ivy

There is a newer version: 1.5.7
Show newest version
package org.reflections;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.reflections.util.ClasspathHelper;

import javax.annotation.Nullable;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import java.util.regex.Pattern;

import static org.reflections.util.Utils.isEmpty;

/** convenient java reflection helper methods
 * 

* 1. some helper methods to get type by name: {@link #forName(String, ClassLoader...)} and {@link #forNames(Iterable, ClassLoader...)} *

* 2. some helper methods to get all types/methods/fields/constructors/properties matching some predicates, generally: *

 Set<?> result = getAllXXX(type/s, withYYY) 
*

where get methods are: *

    *
  • {@link #getAllSuperTypes(Class, com.google.common.base.Predicate...)} *
  • {@link #getAllFields(Class, com.google.common.base.Predicate...)} *
  • {@link #getAllMethods(Class, com.google.common.base.Predicate...)} *
  • {@link #getAllConstructors(Class, com.google.common.base.Predicate...)} *
*

and predicates included here all starts with "with", such as *

    *
  • {@link #withAnnotation(java.lang.annotation.Annotation)} *
  • {@link #withModifier(int)} *
  • {@link #withName(String)} *
  • {@link #withParameters(Class[])} *
  • {@link #withAnyParameterAnnotation(Class)} *
  • {@link #withParametersAssignableTo(Class[])} *
  • {@link #withPrefix(String)} *
  • {@link #withReturnType(Class)} *
  • {@link #withType(Class)} *
  • {@link #withTypeAssignableTo} *
* *


* for example, getting all getters would be: *

 *      Set<Method> getters = getAllMethods(someClasses, 
 *              Predicates.and(
 *                      withModifier(Modifier.PUBLIC), 
 *                      withPrefix("get"), 
 *                      withParametersCount(0)));
 *     
* */ @SuppressWarnings("unchecked") public abstract class ReflectionUtils { /** would include {@code Object.class} when {@link #getAllSuperTypes(Class, com.google.common.base.Predicate[])}. default is false. */ public static boolean includeObject = false; /** get all super types of given {@code type}, including, optionally filtered by {@code predicates} *

include {@code Object.class} if {@link #includeObject} is true */ public static Set> getAllSuperTypes(final Class type, Predicate>... predicates) { Set> result = Sets.newLinkedHashSet(); if (type != null && (includeObject || !type.equals(Object.class))) { result.add(type); result.addAll(getAllSuperTypes(type.getSuperclass())); for (Class ifc : type.getInterfaces()) result.addAll(getAllSuperTypes(ifc)); } return filter(result, predicates); } /** get all methods of given {@code type}, up the super class hierarchy, optionally filtered by {@code predicates} */ public static Set getAllMethods(final Class type, Predicate... predicates) { Set result = Sets.newHashSet(); for (Class t : getAllSuperTypes(type)) { result.addAll(getMethods(t, predicates)); } return result; } /** get methods of given {@code type}, optionally filtered by {@code predicates} */ public static Set getMethods(Class t, Predicate... predicates) { return filter(t.isInterface() ? t.getMethods() : t.getDeclaredMethods(), predicates); } /** get all constructors of given {@code type}, up the super class hierarchy, optionally filtered by {@code predicates} */ public static Set getAllConstructors(final Class type, Predicate... predicates) { Set result = Sets.newHashSet(); for (Class t : getAllSuperTypes(type)) { result.addAll(getConstructors(t, predicates)); } return result; } /** get constructors of given {@code type}, optionally filtered by {@code predicates} */ public static Set getConstructors(Class t, Predicate... predicates) { return ReflectionUtils.filter(t.getDeclaredConstructors(), predicates); //explicit needed only for jdk1.5 } /** get all fields of given {@code type}, up the super class hierarchy, optionally filtered by {@code predicates} */ public static Set getAllFields(final Class type, Predicate... predicates) { Set result = Sets.newHashSet(); for (Class t : getAllSuperTypes(type)) result.addAll(getFields(t, predicates)); return result; } /** get fields of given {@code type}, optionally filtered by {@code predicates} */ public static Set getFields(Class type, Predicate... predicates) { return filter(type.getDeclaredFields(), predicates); } /** get all annotations of given {@code type}, up the super class hierarchy, optionally filtered by {@code predicates} */ public static Set getAllAnnotations(T type, Predicate... predicates) { Set result = Sets.newHashSet(); if (type instanceof Class) { for (Class t : getAllSuperTypes((Class) type)) { result.addAll(getAnnotations(t, predicates)); } } else { result.addAll(getAnnotations(type, predicates)); } return result; } /** get annotations of given {@code type}, optionally honorInherited, optionally filtered by {@code predicates} */ public static Set getAnnotations(T type, Predicate... predicates) { return filter(type.getDeclaredAnnotations(), predicates); } /** filter all given {@code elements} with {@code predicates}, if given */ public static Set getAll(final Set elements, Predicate... predicates) { return isEmpty(predicates) ? elements : Sets.newHashSet(Iterables.filter(elements, Predicates.and(predicates))); } //predicates /** where member name equals given {@code name} */ public static Predicate withName(final String name) { return new Predicate() { public boolean apply(@Nullable T input) { return input != null && input.getName().equals(name); } }; } /** where member name startsWith given {@code prefix} */ public static Predicate withPrefix(final String prefix) { return new Predicate() { public boolean apply(@Nullable T input) { return input != null && input.getName().startsWith(prefix); } }; } /** where member's {@code toString} matches given {@code regex} *

for example: *

     *  getAllMethods(someClass, withPattern("public void .*"))
     * 
* */ public static Predicate withPattern(final String regex) { return new Predicate() { public boolean apply(@Nullable T input) { return Pattern.matches(regex, input.toString()); } }; } /** where element is annotated with given {@code annotation} */ public static Predicate withAnnotation(final Class annotation) { return new Predicate() { public boolean apply(@Nullable T input) { return input != null && input.isAnnotationPresent(annotation); } }; } /** where element is annotated with given {@code annotations} */ public static Predicate withAnnotations(final Class... annotations) { return new Predicate() { public boolean apply(@Nullable T input) { return input != null && Arrays.equals(annotations, annotationTypes(input.getAnnotations())); } }; } /** where element is annotated with given {@code annotation}, including member matching */ public static Predicate withAnnotation(final Annotation annotation) { return new Predicate() { public boolean apply(@Nullable T input) { return input != null && input.isAnnotationPresent(annotation.annotationType()) && areAnnotationMembersMatching(input.getAnnotation(annotation.annotationType()), annotation); } }; } /** where element is annotated with given {@code annotations}, including member matching */ public static Predicate withAnnotations(final Annotation... annotations) { return new Predicate() { public boolean apply(@Nullable T input) { if (input != null) { Annotation[] inputAnnotations = input.getAnnotations(); if (inputAnnotations.length == annotations.length) { for (int i = 0; i < inputAnnotations.length; i++) { if (!areAnnotationMembersMatching(inputAnnotations[i], annotations[i])) return false; } } } return true; } }; } /** when method/constructor parameter types equals given {@code types} */ public static Predicate withParameters(final Class... types) { return new Predicate() { public boolean apply(@Nullable Member input) { return Arrays.equals(parameterTypes(input), types); } }; } /** when member parameter types assignable to given {@code types} */ public static Predicate withParametersAssignableTo(final Class... types) { return new Predicate() { public boolean apply(@Nullable Member input) { if (input != null) { Class[] parameterTypes = parameterTypes(input); if (parameterTypes.length == types.length) { for (int i = 0; i < parameterTypes.length; i++) { if (!parameterTypes[i].isAssignableFrom(types[i]) || (parameterTypes[i] == Object.class && types[i] != Object.class)) { return false; } } return true; } } return false; } }; } /** when method/constructor parameters count equal given {@code count} */ public static Predicate withParametersCount(final int count) { return new Predicate() { public boolean apply(@Nullable Member input) { return input != null && parameterTypes(input).length == count; } }; } /** when method/constructor has any parameter with an annotation matches given {@code annotations} */ public static Predicate withAnyParameterAnnotation(final Class annotationClass) { return new Predicate() { public boolean apply(@Nullable Member input) { return input != null && Iterables.any(annotationTypes(parameterAnnotations(input)), new Predicate>() { public boolean apply(@Nullable Class input) { return input.equals(annotationClass); } }); } }; } /** when method/constructor has any parameter with an annotation matches given {@code annotations}, including member matching */ public static Predicate withAnyParameterAnnotation(final Annotation annotation) { return new Predicate() { public boolean apply(@Nullable Member input) { return input != null && Iterables.any(parameterAnnotations(input), new Predicate() { public boolean apply(@Nullable Annotation input) { return areAnnotationMembersMatching(annotation, input); } }); } }; } /** when field type equal given {@code type} */ public static Predicate withType(final Class type) { return new Predicate() { public boolean apply(@Nullable Field input) { return input != null && input.getType().equals(type); } }; } /** when field type assignable to given {@code type} */ public static Predicate withTypeAssignableTo(final Class type) { return new Predicate() { public boolean apply(@Nullable Field input) { return input != null && type.isAssignableFrom(input.getType()); } }; } /** when method return type equal given {@code type} */ public static Predicate withReturnType(final Class type) { return new Predicate() { public boolean apply(@Nullable Method input) { return input != null && input.getReturnType().equals(type); } }; } /** when method return type assignable from given {@code type} */ public static Predicate withReturnTypeAssignableTo(final Class type) { return new Predicate() { public boolean apply(@Nullable Method input) { return input != null && type.isAssignableFrom(input.getReturnType()); } }; } /** when member modifier matches given {@code mod} *

for example: *

     * withModifier(Modifier.PUBLIC)
     * 
*/ public static Predicate withModifier(final int mod) { return new Predicate() { public boolean apply(@Nullable T input) { return input != null && (input.getModifiers() & mod) != 0; } }; } /** when class modifier matches given {@code mod} *

for example: *

     * withModifier(Modifier.PUBLIC)
     * 
*/ public static Predicate> withClassModifier(final int mod) { return new Predicate>() { public boolean apply(@Nullable Class input) { return input != null && (input.getModifiers() & mod) != 0; } }; } // /** tries to resolve a java type name to a Class *

if optional {@link ClassLoader}s are not specified, then both {@link org.reflections.util.ClasspathHelper#contextClassLoader()} and {@link org.reflections.util.ClasspathHelper#staticClassLoader()} are used * */ public static Class forName(String typeName, ClassLoader... classLoaders) { if (getPrimitiveNames().contains(typeName)) { return getPrimitiveTypes().get(getPrimitiveNames().indexOf(typeName)); } else { String type; if (typeName.contains("[")) { int i = typeName.indexOf("["); type = typeName.substring(0, i); String array = typeName.substring(i).replace("]", ""); if (getPrimitiveNames().contains(type)) { type = getPrimitiveDescriptors().get(getPrimitiveNames().indexOf(type)); } else { type = "L" + type + ";"; } type = array + type; } else { type = typeName; } List reflectionsExceptions = Lists.newArrayList(); for (ClassLoader classLoader : ClasspathHelper.classLoaders(classLoaders)) { if (type.contains("[")) { try { return Class.forName(type, false, classLoader); } catch (Throwable e) { reflectionsExceptions.add(new ReflectionsException("could not get type for name " + typeName, e)); } } try { return classLoader.loadClass(type); } catch (Throwable e) { reflectionsExceptions.add(new ReflectionsException("could not get type for name " + typeName, e)); } } if (Reflections.log != null) { for (ReflectionsException reflectionsException : reflectionsExceptions) { Reflections.log.warn("could not get type for name " + typeName + " from any class loader", reflectionsException); } } return null; } } /** try to resolve all given string representation of types to a list of java types */ public static List> forNames(final Iterable classes, ClassLoader... classLoaders) { List> result = new ArrayList>(); for (String className : classes) { Class type = forName(className, classLoaders); if (type != null) { result.add((Class) type); } } return result; } private static Class[] parameterTypes(Member member) { return member != null ? member.getClass() == Method.class ? ((Method) member).getParameterTypes() : member.getClass() == Constructor.class ? ((Constructor) member).getParameterTypes() : null : null; } private static Set parameterAnnotations(Member member) { Set result = Sets.newHashSet(); Annotation[][] annotations = member instanceof Method ? ((Method) member).getParameterAnnotations() : member instanceof Constructor ? ((Constructor) member).getParameterAnnotations() : null; for (Annotation[] annotation : annotations) Collections.addAll(result, annotation); return result; } private static Set> annotationTypes(Iterable annotations) { Set> result = Sets.newHashSet(); for (Annotation annotation : annotations) result.add(annotation.annotationType()); return result; } private static Class[] annotationTypes(Annotation[] annotations) { Class[] result = new Class[annotations.length]; for (int i = 0; i < annotations.length; i++) result[i] = annotations[i].annotationType(); return result; } // private static List primitiveNames; private static List primitiveTypes; private static List primitiveDescriptors; private static void initPrimitives() { if (primitiveNames == null) { primitiveNames = Lists.newArrayList("boolean", "char", "byte", "short", "int", "long", "float", "double", "void"); primitiveTypes = Lists.newArrayList(boolean.class, char.class, byte.class, short.class, int.class, long.class, float.class, double.class, void.class); primitiveDescriptors = Lists.newArrayList("Z", "C", "B", "S", "I", "J", "F", "D", "V"); } } private static List getPrimitiveNames() { initPrimitives(); return primitiveNames; } private static List getPrimitiveTypes() { initPrimitives(); return primitiveTypes; } private static List getPrimitiveDescriptors() { initPrimitives(); return primitiveDescriptors; } // static Set filter(final T[] elements, Predicate... predicates) { return isEmpty(predicates) ? Sets.newHashSet(elements) : Sets.newHashSet(Iterables.filter(Arrays.asList(elements), Predicates.and(predicates))); } static Set filter(final Iterable elements, Predicate... predicates) { return isEmpty(predicates) ? Sets.newHashSet(elements) : Sets.newHashSet(Iterables.filter(elements, Predicates.and(predicates))); } private static boolean areAnnotationMembersMatching(Annotation annotation1, Annotation annotation2) { if (annotation2 != null && annotation1.annotationType() == annotation2.annotationType()) { for (Method method : annotation1.annotationType().getDeclaredMethods()) { try { if (!method.invoke(annotation1).equals(method.invoke(annotation2))) return false; } catch (Exception e) { throw new ReflectionsException(String.format("could not invoke method %s on annotation %s", method.getName(), annotation1.annotationType()), e); } } return true; } return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy