001 package net.sourceforge.pmd.util;
002
003 import java.io.BufferedReader;
004 import java.io.File;
005 import java.io.IOException;
006 import java.io.InputStreamReader;
007 import java.net.MalformedURLException;
008 import java.net.URL;
009 import java.net.URLClassLoader;
010 import java.util.ArrayList;
011 import java.util.List;
012 import java.util.StringTokenizer;
013 import java.util.logging.Level;
014 import java.util.logging.Logger;
015
016 /**
017 * Create a ClassLoader which loads classes using a CLASSPATH like String.
018 * If the String looks like a URL to a file (e.g. starts with <code>file://</code>)
019 * the file will be read with each line representing an path on the classpath.
020 *
021 * @author Edwin Chan
022 */
023 public class ClasspathClassLoader extends URLClassLoader {
024
025 private static final Logger LOG = Logger.getLogger(ClasspathClassLoader.class.getName());
026
027 public ClasspathClassLoader(String classpath, ClassLoader parent) throws IOException {
028 super(initURLs(classpath), parent);
029 }
030
031 private static URL[] initURLs(String classpath) throws IOException {
032 if (classpath == null) {
033 throw new IllegalArgumentException("classpath argument cannot be null");
034 }
035 final List<URL> urls = new ArrayList<URL>();
036 if (classpath.startsWith("file://")) {
037 // Treat as file URL
038 addFileURLs(urls, new URL(classpath));
039 } else {
040 // Treat as classpath
041 addClasspathURLs(urls, classpath);
042 }
043 return urls.toArray(new URL[urls.size()]);
044 }
045
046 private static void addClasspathURLs(final List<URL> urls, final String classpath) throws MalformedURLException {
047 StringTokenizer toker = new StringTokenizer(classpath, File.pathSeparator);
048 while (toker.hasMoreTokens()) {
049 String token = toker.nextToken();
050 LOG.log(Level.FINE, "Adding classpath entry: <{0}>", token);
051 urls.add(createURLFromPath(token));
052 }
053 }
054
055 private static void addFileURLs(List<URL> urls, URL fileURL) throws IOException {
056 BufferedReader in = null;
057 try {
058 in = new BufferedReader(new InputStreamReader(fileURL.openStream()));
059 String line;
060 while ((line = in.readLine()) != null) {
061 LOG.log(Level.FINE, "Read classpath entry line: <{0}>", line);
062 line = line.trim();
063 if (line.length() > 0) {
064 LOG.log(Level.FINE, "Adding classpath entry: <{0}>", line);
065 urls.add(createURLFromPath(line));
066 }
067 }
068 in.close();
069 } finally {
070 if (in != null) {
071 try {
072 in.close();
073 } catch (IOException e) {
074 LOG.log(Level.SEVERE, "IOException while closing InputStream", e);
075 }
076 }
077 }
078 }
079
080 private static URL createURLFromPath(String path) throws MalformedURLException {
081 File file = new File(path);
082 return file.getAbsoluteFile().toURI().toURL();
083 }
084
085 /**
086 * {@inheritDoc}
087 */
088 @Override
089 public String toString() {
090 StringBuilder sb = new StringBuilder();
091 sb.append(getClass().getSimpleName());
092 sb.append("[[");
093 boolean first = true;
094 for (URL url : getURLs()) {
095 if (!first) {
096 sb.append(':');
097 }
098 first = false;
099 sb.append(url);
100 }
101 sb.append("] parent: ");
102 sb.append(getParent());
103 sb.append(']');
104
105 return sb.toString();
106 }
107 }
|