package io.kaif.web.v1; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.util.ClassUtils; import org.springframework.util.SystemPropertyUtils; /** * see http://stackoverflow.com/questions/1456930/how-do-i-read-all-classes-from-a-java-package-in-the-classpath */ public class ClassScanner { public static List<Class> searchAnnotatedClasses(String basePackage, Class<?> annotation) throws IOException, ClassNotFoundException { ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory( resourcePatternResolver); List<Class> candidates = new ArrayList<>(); String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + "**/*.class"; Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); for (Resource resource : resources) { if (resource.isReadable()) { MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource); if (isCandidate(metadataReader, annotation)) { candidates.add(Class.forName(metadataReader.getClassMetadata().getClassName())); } } } return candidates; } private static String resolveBasePackage(String basePackage) { return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders( basePackage)); } @SuppressWarnings("unchecked") private static boolean isCandidate(MetadataReader metadataReader, Class<?> annotation) throws ClassNotFoundException { try { Class c = Class.forName(metadataReader.getClassMetadata().getClassName()); if (c.getAnnotation(annotation) != null) { return true; } } catch (Throwable e) { } return false; } }