private <T extends Entity> Class<? extends T> getFromAnnotation(Class<T> type) { ImplementedBy annotation = type.getAnnotation(org.apache.brooklyn.api.entity.ImplementedBy.class); if (annotation == null) return null; Class<? extends Entity> value = annotation.value(); checkIsImplementation(type, value); return (Class<? extends T>) value; }
private <T extends Entity> Class<? super T> getInterfaceWithAnnotationMatching(Class<T> implClazz) { // getInterfaces() only looks at one level of interfaces (i.e. not interfaces declared on supertypes) // so if an impl indirectly extends the interface we need to look deeper. // -- see also Reflections.getInterfacesIncludingClassAncestors and usages of that (duplication?) Set<Class<?>> visited = Sets.newLinkedHashSet(); Deque<Class<?>> tovisit = new LinkedList<Class<?>>(); tovisit.add(implClazz); while (!tovisit.isEmpty()) { Class<?> contender = tovisit.pop(); if (contender == null || visited.contains(contender)) continue; visited.add(contender); if (contender.isInterface()) { ImplementedBy annotation = contender.getAnnotation(org.apache.brooklyn.api.entity.ImplementedBy.class); Class<? extends Entity> value = (annotation == null) ? null : annotation.value(); if (implClazz.equals(value)) return (Class<? super T>) contender; } tovisit.addAll(Arrays.asList(contender.getInterfaces())); tovisit.add(contender.getSuperclass()); } throw new IllegalArgumentException("Interfaces of "+implClazz+" not annotated with @"+ImplementedBy.class.getSimpleName()+" matching this class"); }
private <T extends BrooklynObject> List<Class<? extends T>> getTypes(List<URL> urls, Class<T> type, Boolean catalogOnlyOverride) { // TODO this only really works if you give it lots of URLs - see comment on "--jar" argument // NB if the ReflectionScanner class is given "null" then it will scan, better than INITIAL_CLASSPATH FluentIterable<Class<? extends T>> fluent = FluentIterable.from(ClassFinder.findClasses(urls, type)); if (typeRegex != null) { fluent = fluent.filter(ClassFinder.withClassNameMatching(typeRegex)); } if (catalogOnlyOverride == null ? !allClasses : catalogOnlyOverride) { fluent = fluent.filter(ClassFinder.withAnnotation(Catalog.class)); } List<Class<? extends T>> filtered = fluent.toList(); Collection<Class<? extends T>> result; if (!includeImpls) { result = MutableSet.copyOf(filtered); for (Class<? extends T> clazz : filtered) { ImplementedBy implementedBy = clazz.getAnnotation(ImplementedBy.class); if (implementedBy != null) { result.remove(implementedBy.value()); } } } else { result = filtered; } itemCount += result.size(); return ImmutableList.copyOf(result); }