/** * 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>if expanding supertypes, B will be expanded with A (A->B in store) - then getSubTypes(A) * will return C * </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) { expandSupertypes(expand, key, forName(key)); } mmap.putAll(expand); } }
/** * get types annotated with a given annotation, both classes and annotations, including annotation * member values matching * * <p>{@link 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 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; }
/** * get types annotated with a given annotation, both classes and annotations * * <p>{@link 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 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; }
/** * 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)); }
/** * 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())); }