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

io.remotecontrol.groovy.client.InnerClosureClassDefinitionsFinder Maven / Gradle / Ivy

package io.remotecontrol.groovy.client;

import groovy.lang.Closure;
import io.remotecontrol.util.IoUtil;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class InnerClosureClassDefinitionsFinder {

    private final URLClassLoader classLoader;

    public InnerClosureClassDefinitionsFinder(ClassLoader classLoader) {
        if (!(classLoader instanceof URLClassLoader)) {
            throw new IllegalArgumentException("Only URLClassLoaders are supported");
        }

        this.classLoader = ((URLClassLoader) (classLoader));
    }

    @SuppressWarnings("NestedBlockDepth")
    public List find(Class clazz) throws IOException {
        List classes = new ArrayList();
        String innerClassPrefix = toInnerClassPrefix(clazz);
        String packageDirPath = toPackageDirPath(clazz);
        String innerClassPrefixWithPackage = packageDirPath + "/" + innerClassPrefix;
        String ownerClassFileName = innerClassPrefix + ".class";

        for (URLClassLoader loader : calculateEffectiveClassLoaderHierarchy()) {
            for (URL url : loader.getURLs()) {
                if (!url.getProtocol().equals("file")) {
                    // we only support searching the filesystem right not
                    continue;
                }

                File root;
                try {
                    root = new File(url.toURI());
                } catch (URISyntaxException e) {
                    throw new RuntimeException(e);
                }

                if (!root.exists()) {
                    // may have been removed, just skip it
                    continue;
                }

                if (root.isDirectory()) {
                    File packageDir = packageDirPath != null ? new File(root, packageDirPath) : root;
                    if (packageDir.exists()) {
                        for (String classFileName : packageDir.list()) {
                            if (classFileName.startsWith(innerClassPrefix) && classFileName.endsWith(".class") && classFileName.length() != ownerClassFileName.length()) {
                                File file = new File(packageDir, classFileName);
                                classes.add(IoUtil.read(file));
                            }
                        }
                    }
                } else if (root.getName().endsWith(".jar") || root.getName().endsWith(".zip")) {
                    ZipFile jarFile = new ZipFile(root);

                    try {
                        Object packageDir = packageDirPath == null ? root : jarFile.getEntry(packageDirPath);
                        if (packageDir != null) {
                            Enumeration entries = jarFile.entries();
                            while (entries.hasMoreElements()) {
                                ZipEntry entry = entries.nextElement();
                                String name = entry.getName();
                                if (name.startsWith(innerClassPrefixWithPackage) && name.endsWith(".class") && !name.endsWith(ownerClassFileName)) {
                                    InputStream inputStream = jarFile.getInputStream(entry);
                                    classes.add(IoUtil.read(inputStream));
                                }
                            }
                        }
                    } finally {
                        jarFile.close();
                    }
                }
            }
        }


        return classes;
    }

    protected List calculateEffectiveClassLoaderHierarchy() {
        List hierarchy = new ArrayList();
        URLClassLoader current = classLoader;
        while (current != null && current instanceof URLClassLoader) {
            hierarchy.add(current);
            current = ((URLClassLoader) (current.getParent()));
        }

        return hierarchy;
    }

    protected String toPackageDirPath(Class clazz) {
        Package pkg = clazz.getPackage();
        return pkg == null ? "" : pkg.getName().replace(".", "/");
    }

    protected String toInnerClassPrefix(Class clazz) {
        final Package var = clazz.getPackage();
        final String packageName = (var == null ? null : var.getName());
        String fixedName = clazz.getName().replace("$_$", "$_");
        if (packageName == null) {
            return fixedName;
        } else {
            return fixedName.substring(packageName.length() + 1);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy