Java tutorial
/** * Copyright (c) 2014 by the original author or authors. * * This code is free software; you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package ch.sdi.core.util; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.util.StringUtils; /** * Provides some static methods for dealing with classes * <p> * * @version 1.0 (07.11.2014) * @author Heri */ public class ClassUtil { /** logger for this class */ private static Logger myLog = LogManager.getLogger(ClassUtil.class); /** * Constructor * */ public ClassUtil() { super(); } /** * Lists all types in the given package (recursive) which are annotated by the given annotation and * are assignable from given class. * <p> * All types which match the criteria are returned, no further checks (interface, abstract, embedded, * etc. are performed. * <p> * * @param aClass * the desired (base) class * @param aAnnotation * the desired annotation type * @param aRoot * the package name where to start the search. Must not be empty. And not start * with 'org.springframework' (cannot parse springs library itself). * @return a list of found types */ @SuppressWarnings("unchecked") public static <T> Collection<Class<T>> findCandidatesByAnnotation(Class<T> aClass, Class<? extends Annotation> aAnnotation, String aRoot) { Collection<Class<T>> result = new ArrayList<Class<T>>(); Collection<? extends Class<?>> candidates = findCandidatesByAnnotation(aAnnotation, aRoot); candidates.stream().peek(c -> myLog.trace("inspecting candidate " + c.getName())) .filter(c -> aClass.isAssignableFrom(c)) .peek(c -> myLog.debug("candidate " + c.getName() + " is of desired type")) .forEach(c -> result.add((Class<T>) c)); return result; } /** * Lists all types in the given package (recursive) which are annotated by the given annotation. * <p> * All types which match the criteria are returned, no further checks (interface, abstract, embedded, etc. * are performed. * <p> * * @param aAnnotation * the desired annotation type * @param aRoot * the package name where to start the search. Must not be empty. And not start * with 'org.springframework' (cannot parse springs library itself). * @return a list of found types */ public static Collection<? extends Class<?>> findCandidatesByAnnotation(Class<? extends Annotation> aAnnotation, String aRoot) { if (!StringUtils.hasText(aRoot)) { throw new IllegalArgumentException("aRoot must not be empty (cannot parse spring library classes)"); } // if StringUtils.hasText( aRoot ) if (aRoot.startsWith("org.springframework")) { throw new IllegalArgumentException("cannot parse spring library classes"); } // if StringUtils.hasText( aRoot ) List<Class<?>> result = new ArrayList<Class<?>>(); MyClassScanner scanner = new MyClassScanner(); scanner.addIncludeFilter(new AnnotationTypeFilter(aAnnotation)); Set<BeanDefinition> canditates = scanner.findCandidateComponents(aRoot); for (BeanDefinition beanDefinition : canditates) { try { String classname = beanDefinition.getBeanClassName(); Class<?> clazz = Class.forName(classname); result.add(clazz); } catch (ClassNotFoundException t) { myLog.error("Springs type scanner returns a class name whose class cannot be evaluated!!!", t); } } return result; } static class MyClassScanner extends ClassPathScanningCandidateComponentProvider { /** * Constructor */ public MyClassScanner() { super(false); } @Override protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) { return true; } }; }