/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jada.ngeditor.model.utils;
import jada.ngeditor.model.elements.GElement;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.jdesktop.el.impl.util.ReflectionUtil;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.FilterBuilder;
/**
* <b>Notice<\b> This class is an early implementation , could change every time.
* @author cris
*/
public class ClassUtils {
private static void log(String msg) {
//System.out.println("ClassDiscovery: " + msg);
}
private static Class<?> loadClass(String className) {
try {
return Class.forName(className);
}
catch (ClassNotFoundException e) {
throw new RuntimeException("Unexpected ClassNotFoundException loading class '" + className + "'");
}
}
private static void processDirectory(File directory, String pkgname, ArrayList<Class<?>> classes) {
log("Reading Directory '" + directory + "'");
// Get the list of the files contained in the package
String[] files = directory.list();
for (int i = 0; i < files.length; i++) {
String fileName = files[i];
String className = null;
// we are only interested in .class files
if (fileName.endsWith(".class")) {
// removes the .class extension
className = pkgname + '.' + fileName.substring(0, fileName.length() - 6);
}
log("FileName '" + fileName + "' => class '" + className + "'");
if (className != null) {
classes.add(loadClass(className));
}
File subdir = new File(directory, fileName);
if (subdir.isDirectory()) {
processDirectory(subdir, pkgname + '.' + fileName, classes);
}
}
}
private static void processJarfile(URL resource, String pkgname, ArrayList<Class<?>> classes) {
String relPath = pkgname.replace('.', '/');
String resPath = resource.getPath();
String jarPath = resPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", "");
log("Reading JAR file: '" + jarPath + "'");
JarFile jarFile;
try {
jarFile = new JarFile(jarPath);
} catch (IOException e) {
throw new RuntimeException("Unexpected IOException reading JAR File '" + jarPath + "'", e);
}
Enumeration<JarEntry> entries = jarFile.entries();
while(entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String entryName = entry.getName();
String className = null;
if(entryName.endsWith(".class") && entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) {
className = entryName.replace('/', '.').replace('\\', '.').replace(".class", "");
}
log("JarEntry '" + entryName + "' => class '" + className + "'");
if (className != null) {
classes.add(loadClass(className));
}
}
}
public static ArrayList<Class<?>> getClassesForPackage(String pkg) {
ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
String pkgname = pkg;
String relPath = pkgname.replace('.', '/');
// Get a File object for the package
URL resource = ClassLoader.getSystemClassLoader().getResource(relPath);
if (resource == null) {
throw new RuntimeException("Unexpected problem: No resource for " + relPath);
}
log("Package: '" + pkgname + "' becomes Resource: '" + resource.toString() + "'");
resource.getPath();
if(resource.toString().startsWith("jar:")) {
processJarfile(resource, pkgname, classes);
} else {
processDirectory(new File(resource.getPath()), pkgname, classes);
}
return classes;
}
public static Set<Class<? extends GElement>> findAllGElements(){
Reflections reflections = new Reflections ("jada.ngeditor.model",ClasspathHelper.forClass(GElement.class),
new SubTypesScanner(false));
Set<Class<? extends GElement>> subTypesOf = reflections.getSubTypesOf(GElement.class);
return subTypesOf;
}
public static void main(String[] args) throws IOException, ClassNotFoundException{
ArrayList<Class<?>> classesForPackage = ClassUtils.getClassesForPackage("jada.ngeditor.model");
for(Class c : classesForPackage){
System.out.println(c.getName());
}
}
public static Class[] getClasses(String pkg){
return getClasses(pkg,new NullPredicate());
}
public static Class[] getClasses(String pkg, Predicate<Class> predicate) {
ArrayList<Class<?>> result = new ArrayList<Class<?>>();
ArrayList<Class<?>> classesForPackage = ClassUtils.getClassesForPackage(pkg);
for(Class c : classesForPackage){
if(predicate.apply(c)){
result.add(c);
}
}
return (Class[]) result.toArray(new Class[0]);
}
public static class NullPredicate implements Predicate<Class> {
public static NullPredicate instance = new NullPredicate();
@Override
public boolean apply(Class object) {
return true;
}
}
public static interface Predicate<T>{
public boolean apply(T object);
}
}