/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.util; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.io.IOUtils; /** * Create a ClassLoader which loads classes using a CLASSPATH like String. If * the String looks like a URL to a file (e.g. starts with <code>file://</code>) * the file will be read with each line representing an path on the classpath. * * @author Edwin Chan */ public class ClasspathClassLoader extends URLClassLoader { private static final Logger LOG = Logger.getLogger(ClasspathClassLoader.class.getName()); static { registerAsParallelCapable(); } public ClasspathClassLoader(String classpath, ClassLoader parent) throws IOException { super(initURLs(classpath), parent); } private static URL[] initURLs(String classpath) throws IOException { if (classpath == null) { throw new IllegalArgumentException("classpath argument cannot be null"); } final List<URL> urls = new ArrayList<>(); if (classpath.startsWith("file://")) { // Treat as file URL addFileURLs(urls, new URL(classpath)); } else { // Treat as classpath addClasspathURLs(urls, classpath); } return urls.toArray(new URL[urls.size()]); } private static void addClasspathURLs(final List<URL> urls, final String classpath) throws MalformedURLException { StringTokenizer toker = new StringTokenizer(classpath, File.pathSeparator); while (toker.hasMoreTokens()) { String token = toker.nextToken(); LOG.log(Level.FINE, "Adding classpath entry: <{0}>", token); urls.add(createURLFromPath(token)); } } private static void addFileURLs(List<URL> urls, URL fileURL) throws IOException { BufferedReader in = null; try { in = new BufferedReader(new InputStreamReader(fileURL.openStream())); String line; while ((line = in.readLine()) != null) { LOG.log(Level.FINE, "Read classpath entry line: <{0}>", line); line = line.trim(); if (line.length() > 0) { LOG.log(Level.FINE, "Adding classpath entry: <{0}>", line); urls.add(createURLFromPath(line)); } } } finally { IOUtils.closeQuietly(in); } } private static URL createURLFromPath(String path) throws MalformedURLException { File file = new File(path); return file.getAbsoluteFile().toURI().toURL(); } /** * {@inheritDoc} */ @Override public String toString() { StringBuilder sb = new StringBuilder(getClass().getSimpleName()); sb.append("[["); StringUtil.asStringOn(sb, getURLs(), ":"); sb.append("] parent: ").append(getParent()).append(']'); return sb.toString(); } }