All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.loguno.processor.utils.ScanPackageUtils Maven / Gradle / Ivy

The newest version!
package org.loguno.processor.utils;

import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import org.loguno.processor.handlers.AnnotationHandler;
import org.loguno.processor.handlers.Handler;

import javax.annotation.processing.Messager;
import javax.tools.Diagnostic;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.net.*;
import java.util.*;
import java.util.function.Function;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@UtilityClass
public class ScanPackageUtils {

    private final String HANDLERS_PACKAGE = "org.loguno.processor.handlers";

    public Stream> getHandlersClasses() {
        return getClasses(HANDLERS_PACKAGE);
    }

    private ClassLoader CLASSLOADER = ScanPackageUtils.class.getClassLoader();

    @SneakyThrows
    private Stream> getClasses(String packageName) {

        final String path = packageName.replace('.', '/');

        Collection urls = forPackage(HANDLERS_PACKAGE);
        Stream.Builder> builder = Stream.builder();

        for (URL url : urls) {

            String protocol = url.getProtocol();

            if (protocol.endsWith("jar")) {
                JarFile file = getJar(url);
                for (Enumeration entry = file.entries(); entry.hasMoreElements(); ) {
                    JarEntry jarEntry = entry.nextElement();
                    if (!jarEntry.isDirectory()
                            && jarEntry.getName().endsWith(".class")
                            && jarEntry.getName().startsWith(path)) {

                        String name = jarEntry.getName().replace("/", ".");
                        Class aClass = getClass(name);
                        builder.add(aClass);
                    }
                }
            }


            if (protocol.endsWith("file")) {
                String path1 = url.toURI().getSchemeSpecificPart();
                java.io.File file = new java.io.File(path1 + path);
                if (file.isDirectory()) {
                    File[] files = file.listFiles();
                    for (File f : files) {
                        if (!f.isDirectory()
                                && f.getName().endsWith(".class")) {
                            String name = f.getName().replace("/", ".");
                            Class aClass = getClass(HANDLERS_PACKAGE + "." + name);
                            builder.add(aClass);
                        }
                    }
                }
            }
        }
        return builder.build();
    }

    @SneakyThrows
    private Class getClass(final String classFullName) {
        return Class.forName(classFullName.substring(0, classFullName.length() - 6));
    }


    @SneakyThrows
    private JarFile getJar(URL url) {

        URLConnection urlConnection = url.openConnection();
        if (urlConnection instanceof JarURLConnection) {
            return ((JarURLConnection) urlConnection).getJarFile();
        }
        throw new RuntimeException("That is not JarURLConnection " + url);
    }

    private static Collection forPackage(String name) {
        return forResource(resourceName(name));
    }

    @SneakyThrows
    private static Collection forResource(String resourceName) {
        final List result = new ArrayList<>();

        final Enumeration urls = CLASSLOADER.getResources(resourceName);
        while (urls.hasMoreElements()) {
            final URL url = urls.nextElement();
            int index = url.toExternalForm().lastIndexOf(resourceName);
            if (index != -1) {
                // Add old url as contextUrl to support exotic url handlers
                result.add(new URL(url, url.toExternalForm().substring(0, index)));
            } else {
                result.add(url);
            }
        }

        return distinctUrls(result);
    }

    private static String resourceName(String name) {
        if (name != null) {
            String resourceName = name.replace(".", "/");
            resourceName = resourceName.replace("\\", "/");
            if (resourceName.startsWith("/")) {
                resourceName = resourceName.substring(1);
            }
            return resourceName;
        }
        return null;
    }

    private static Collection distinctUrls(Collection urls) {
        Map distinct = new LinkedHashMap<>(urls.size());
        for (URL url : urls) {
            distinct.put(url.toExternalForm(), url);
        }
        return distinct.values();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy