/** get resources relative paths where simple name (key) matches given namePredicate * <p>depends on ResourcesScanner configured * */ public Set<String> getResources(final Predicate<String> namePredicate) { Iterable<String> resources = Iterables.filter(store.get(index(ResourcesScanner.class)).keySet(), namePredicate); return Sets.newHashSet(store.get(index(ResourcesScanner.class), resources)); }
/** get parameter names of given {@code method} * <p>depends on MethodParameterNamesScanner configured */ public List<String> getMethodParamNames(Method method) { Iterable<String> names = store.get(index(MethodParameterNamesScanner.class), name(method)); return !Iterables.isEmpty(names) ? Arrays.asList(Iterables.getOnlyElement(names).split(", ")) : Arrays.<String>asList(); }
/** get parameter names of given {@code constructor} * <p>depends on MethodParameterNamesScanner configured */ public List<String> getConstructorParamNames(Constructor constructor) { Iterable<String> names = store.get(index(MethodParameterNamesScanner.class), Utils.name(constructor)); return !Iterables.isEmpty(names) ? Arrays.asList(Iterables.getOnlyElement(names).split(", ")) : Arrays.<String>asList(); }
/** get all types scanned. this is effectively similar to getting all subtypes of Object. * <p>depends on SubTypesScanner configured with {@code SubTypesScanner(false)}, otherwise {@code ReflectionsException} is thrown * <p><i>note using this might be a bad practice. it is better to get types matching some criteria, * such as {@link #getSubTypesOf(Class)} or {@link #getTypesAnnotatedWith(Class)}</i> * @return Set of String, and not of Class, in order to avoid definition of all types in PermGen */ public Set<String> getAllTypes() { Set<String> allTypes = Sets.newHashSet(store.getAll(index(SubTypesScanner.class), Object.class.getName())); if (allTypes.isEmpty()) { throw new ReflectionsException("Couldn't find subtypes of Object. " + "Make sure SubTypesScanner initialized to include Object class - new SubTypesScanner(false)"); } return allTypes; }
protected Iterable<String> getAllAnnotated(Iterable<String> annotated, boolean inherited, boolean honorInherited) { if (honorInherited) { if (inherited) { Iterable<String> subTypes = store.get(index(SubTypesScanner.class), filter(annotated, new Predicate<String>() { public boolean apply(@Nullable String input) { final Class<?> type = forName(input, loaders()); return type != null && !type.isInterface(); } })); return concat(subTypes, store.getAll(index(SubTypesScanner.class), subTypes)); } else { return annotated; } } else { Iterable<String> subTypes = concat(annotated, store.getAll(index(TypeAnnotationsScanner.class), annotated)); return concat(subTypes, store.getAll(index(SubTypesScanner.class), subTypes)); } }
/** * gets all sub types in hierarchy of a given type * <p/>depends on SubTypesScanner configured */ public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type) { return Sets.newHashSet(ReflectionUtils.<T>forNames( store.getAll(index(SubTypesScanner.class), Arrays.asList(type.getName())), loaders())); }
/** * get all fields annotated with a given annotation * <p/>depends on FieldAnnotationsScanner configured */ public Set<Field> getFieldsAnnotatedWith(final Class<? extends Annotation> annotation) { final Set<Field> result = Sets.newHashSet(); for (String annotated : store.get(index(FieldAnnotationsScanner.class), annotation.getName())) { result.add(getFieldFromString(annotated, loaders())); } return result; }
/** * expand super types after scanning, for super types that were not scanned. * this is helpful in finding the transitive closure without scanning all 3rd party dependencies. * it uses {@link ReflectionUtils#getSuperTypes(Class)}. * <p> * for example, for classes A,B,C where A supertype of B, B supertype of C: * <ul> * <li>if scanning C resulted in B (B->C in store), but A was not scanned (although A supertype of B) - then getSubTypes(A) will not return C</li> * <li>if expanding supertypes, B will be expanded with A (A->B in store) - then getSubTypes(A) will return C</li> * </ul> */ public void expandSuperTypes() { if (store.keySet().contains(index(SubTypesScanner.class))) { Multimap<String, String> mmap = store.get(index(SubTypesScanner.class)); Sets.SetView<String> keys = Sets.difference(mmap.keySet(), Sets.newHashSet(mmap.values())); Multimap<String, String> expand = HashMultimap.create(); for (String key : keys) { final Class<?> type = forName(key); if (type != null) { expandSupertypes(expand, key, type); } } mmap.putAll(expand); } }
/** * get all methods annotated with a given annotation * <p/>depends on MethodAnnotationsScanner configured */ public Set<Method> getMethodsAnnotatedWith(final Class<? extends Annotation> annotation) { Iterable<String> methods = store.get(index(MethodAnnotationsScanner.class), annotation.getName()); return getMethodsFromDescriptors(methods, loaders()); }
/** * get all constructors annotated with a given annotation * <p/>depends on MethodAnnotationsScanner configured */ public Set<Constructor> getConstructorsAnnotatedWith(final Class<? extends Annotation> annotation) { Iterable<String> methods = store.get(index(MethodAnnotationsScanner.class), annotation.getName()); return getConstructorsFromDescriptors(methods, loaders()); }
/** get methods with any parameter annotated with given annotation */ public Set<Method> getMethodsWithAnyParamAnnotated(Class<? extends Annotation> annotation) { return getMethodsFromDescriptors(store.get(index(MethodParameterScanner.class), annotation.getName()), loaders()); }
/** get constructors with any parameter annotated with given annotation */ public Set<Constructor> getConstructorsWithAnyParamAnnotated(Class<? extends Annotation> annotation) { return getConstructorsFromDescriptors(store.get(index(MethodParameterScanner.class), annotation.getName()), loaders()); }
/** * get types annotated with a given annotation, both classes and annotations, including annotation member values matching * <p>{@link java.lang.annotation.Inherited} is honored according to given honorInherited * <p/>depends on TypeAnnotationsScanner configured */ public Set<Class<?>> getTypesAnnotatedWith(final Annotation annotation, boolean honorInherited) { Iterable<String> annotated = store.get(index(TypeAnnotationsScanner.class), annotation.annotationType().getName()); Iterable<Class<?>> filter = filter(forNames(annotated, loaders()), withAnnotation(annotation)); Iterable<String> classes = getAllAnnotated(names(filter), annotation.annotationType().isAnnotationPresent(Inherited.class), honorInherited); return Sets.newHashSet(concat(filter, forNames(filter(classes, not(in(Sets.newHashSet(annotated)))), loaders()))); }
/** * get types annotated with a given annotation, both classes and annotations * <p>{@link java.lang.annotation.Inherited} is honored according to given honorInherited. * <p>when honoring @Inherited, meta-annotation should only effect annotated super classes and it's sub types * <p>when not honoring @Inherited, meta annotation effects all subtypes, including annotations interfaces and classes * <p><i>Note that this (@Inherited) meta-annotation type has no effect if the annotated type is used for anything other then a class. * Also, this meta-annotation causes annotations to be inherited only from superclasses; annotations on implemented interfaces have no effect.</i> * <p/>depends on TypeAnnotationsScanner and SubTypesScanner configured */ public Set<Class<?>> getTypesAnnotatedWith(final Class<? extends Annotation> annotation, boolean honorInherited) { Iterable<String> annotated = store.get(index(TypeAnnotationsScanner.class), annotation.getName()); Iterable<String> classes = getAllAnnotated(annotated, annotation.isAnnotationPresent(Inherited.class), honorInherited); return Sets.newHashSet(concat(forNames(annotated, loaders()), forNames(classes, loaders()))); }
/** get all given {@code method} usages in methods and constructors * <p>depends on MemberUsageScanner configured */ public Set<Member> getMethodUsage(Method method) { return getMembersFromDescriptors(store.get(index(MemberUsageScanner.class), name(method))); }
/** get all given {@code field} usages in methods and constructors * <p>depends on MemberUsageScanner configured */ public Set<Member> getFieldUsage(Field field) { return getMembersFromDescriptors(store.get(index(MemberUsageScanner.class), name(field))); }
/** get all given {@code constructors} usages in methods and constructors * <p>depends on MemberUsageScanner configured */ public Set<Member> getConstructorUsage(Constructor constructor) { return getMembersFromDescriptors(store.get(index(MemberUsageScanner.class), name(constructor))); }
/** get constructors with parameter types matching given {@code types}*/ public Set<Constructor> getConstructorsMatchParams(Class<?>... types) { return getConstructorsFromDescriptors(store.get(index(MethodParameterScanner.class), names(types).toString()), loaders()); }
/** get methods with parameter types matching given {@code types}*/ public Set<Method> getMethodsMatchParams(Class<?>... types) { return getMethodsFromDescriptors(store.get(index(MethodParameterScanner.class), names(types).toString()), loaders()); }
/** get methods with return type match given type */ public Set<Method> getMethodsReturn(Class returnType) { return getMethodsFromDescriptors(store.get(index(MethodParameterScanner.class), names(returnType)), loaders()); }