package net.bytebuddy.build.gradle; import net.bytebuddy.ByteBuddy; import org.gradle.api.GradleException; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.*; /** * A class loader resolver for creating class loaders for given class paths. */ public class ClassLoaderResolver implements Closeable { /** * A mapping of files collections to previously created class loaders. */ private final Map<Set<? extends File>, ClassLoader> classLoaders; /** * Creates a new class loader resolver. */ public ClassLoaderResolver() { classLoaders = new HashMap<Set<? extends File>, ClassLoader>(); } /** * Resolves a class path to a class loader. If a class loader for the same file collection was created * previously, the previous class loader is returned. * * @param classPath The class path to consider. * @return A class loader for the supplied class path. */ public ClassLoader resolve(Iterable<? extends File> classPath) { Set<File> classPathList = new LinkedHashSet<File>(); for (File file : classPath) { classPathList.add(file); } return resolve(classPathList); } /** * Resolves a class path to a class loader. If a class loader for the same file collection was created * previously, the previous class loader is returned. * * @param classPath The class path to consider. * @return A class loader for the supplied class path. */ private ClassLoader resolve(Set<? extends File> classPath) { ClassLoader classLoader = classLoaders.get(classPath); if (classLoader == null) { classLoader = doResolve(classPath); classLoaders.put(classPath, classLoader); } return classLoader; } /** * Resolves a class path to a class loader. * * @param classPath The class path to consider. * @return A class loader for the supplied class path. */ private ClassLoader doResolve(Set<? extends File> classPath) { List<URL> urls = new ArrayList<URL>(classPath.size()); for (File file : classPath) { try { urls.add(file.toURI().toURL()); } catch (MalformedURLException exception) { throw new GradleException("Cannot resolve " + file + " as URL", exception); } } return new URLClassLoader(urls.toArray(new URL[urls.size()]), ByteBuddy.class.getClassLoader()); } @Override public void close() throws IOException { for (ClassLoader classLoader : classLoaders.values()) { if (classLoader instanceof Closeable) { // URLClassLoaders are only closeable since Java 1.7. ((Closeable) classLoader).close(); } } } @Override public String toString() { return "ClassLoaderResolver{" + "classLoaders=" + classLoaders + '}'; } }