/* This file is part of Wattzap Community Edition. * * Wattzap Community Edtion is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Wattzap Community Edition is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Wattzap. If not, see <http://www.gnu.org/licenses/>. */ package com.wattzap.utils; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; /** * Loads classes from package with specified annotation class. * * @author David George * * (c) 19th September, 2014; David George / Wattzap.com * */ public class ReflexiveClassLoader { private static Logger logger = LogManager.getLogger("ReflexiveClassLoader"); public static List<Class> getClassNamesFromPackage(String packageName, Class annotationType) throws IOException, URISyntaxException, ClassNotFoundException, InstantiationException, IllegalAccessException { List<Class> classes = new ArrayList<Class>(); ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); URL packageURL; packageName = packageName.replace(".", "/"); packageURL = classLoader.getResource(packageName); if (packageURL.getProtocol().equals("jar")) { logger.debug("Scanning Jar"); String jarFileName; JarFile jf; Enumeration<JarEntry> jarEntries; String entryName; // build jar file name, then loop through zipped entries jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8"); jarFileName = jarFileName.substring(5, jarFileName.indexOf("!")); jf = new JarFile(jarFileName); jarEntries = jf.entries(); while (jarEntries.hasMoreElements()) { entryName = jarEntries.nextElement().getName(); // only check class names in current package if (entryName.startsWith(packageName) && entryName.indexOf('/', packageName.length() + 1) == -1 && entryName.lastIndexOf('.') != -1) { entryName = entryName.substring(0, entryName.lastIndexOf('.')); entryName = entryName.replace("/", "."); Class c = Class.forName(entryName); Annotation[] annotations = c.getAnnotations(); for (Annotation a : annotations) { if (a.annotationType() == annotationType) { classes.add(c); } }// for } }// while jf.close(); // loop through files in classpath } else { logger.debug("Scanning classpath"); URI uri = new URI(packageURL.toString()); File folder = new File(uri.getPath()); // won't work with path which contains blank (%20) // File folder = new File(packageURL.getFile()); File[] contenuti = folder.listFiles(); String entryName; for (File actual : contenuti) { entryName = actual.getName(); if (entryName.endsWith(".class")) { entryName = packageName + "." + entryName .substring(0, entryName.lastIndexOf('.')); entryName = entryName.replace("/", "."); Class c = Class.forName(entryName); Annotation[] annotations = c.getAnnotations(); for (Annotation a : annotations) { if (a.annotationType() == annotationType) { classes.add(c); } }// for } } } return classes; } }