Monday, August 17, 2015

Filter by package and type

This is an attempt to filter the classes in during the run-time. Finally succeeded  with a help of online resources and several attempts.

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ClassCheck {

    private static final Logger LOGGER = Logger.getLogger(ClassCheck.class.getName());
    private static final char DOT = '.';
    private static final char SLASH = '/';
    private static final String CLASS_SUFFIX = ".class";
    private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?";
    private ClassCheck() {}

    /**
     * @param scannedPackage : Package to analyzed
     * @return list of classes in a package
     */
    public static List<Class<?>> find(String scannedPackage, Class... type) {

        URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPackage.replace(DOT, SLASH));
        if (scannedUrl == null) {
            throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPackage.replace(DOT, SLASH), scannedPackage));
        }
        File scannedDir = new File(scannedUrl.getFile());
        List<Class<?>> classes = new ArrayList<>();
        for (File file : scannedDir.listFiles()) {
            classes.addAll(find(file, scannedPackage, type));
        }
        return classes;
    }

    public static List<Class<?>> find(File file, String scannedPackage, Class... type) {
        List<Class<?>> classes = new ArrayList<>();
        String resource = scannedPackage + DOT + file.getName();
        if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                classes.addAll(find(child, resource, type));
            }
        } else if (resource.endsWith(CLASS_SUFFIX)) {
            int endIndex = resource.length() - CLASS_SUFFIX.length();
            String className = resource.substring(0, endIndex);
            try {
                if (type.length > 0) {
                    for (Class c : type) {
                        Class toCheck = Class.forName(className);
                        if (c!=toCheck && c.isAssignableFrom(toCheck)) {
                            classes.add(toCheck);
                            break;
                        }
                    }
                } else {
                    classes.add(Class.forName(className));
                }
            } catch (ClassNotFoundException e) {
                LOGGER.log(Level.WARNING, "Class not found", e);
            }
        }
        return classes;
    }
}

No comments:

Post a Comment