View Javadoc

    1   package net.sourceforge.pmd.util;
    2
    3   import java.io.BufferedReader;
    4   import java.io.File;
    5   import java.io.IOException;
    6   import java.io.InputStreamReader;
    7   import java.net.MalformedURLException;
    8   import java.net.URL;
    9   import java.net.URLClassLoader;
    10  import java.util.ArrayList;
    11  import java.util.List;
    12  import java.util.StringTokenizer;
    13  import java.util.logging.Level;
    14  import java.util.logging.Logger;
    15
    16  /**
    17   * Create a ClassLoader which loads classes using a CLASSPATH like String.
    18   * If the String looks like a URL to a file (e.g. starts with <code>file://</code>)
    19   * the file will be read with each line representing an path on the classpath.
    20   *
    21   * @author Edwin Chan
    22   */
    23  public class ClasspathClassLoader extends URLClassLoader {
    24
    25      private static final Logger LOG = Logger.getLogger(ClasspathClassLoader.class.getName());
    26
    27      public ClasspathClassLoader(String classpath, ClassLoader parent) throws IOException {
    28          super(initURLs(classpath), parent);
    29      }
    30
    31      private static URL[] initURLs(String classpath) throws IOException {
    32          if (classpath == null) {
    33              throw new IllegalArgumentException("classpath argument cannot be null");
    34          }
    35          final List<URL> urls = new ArrayList<URL>();
    36          if (classpath.startsWith("file://")) {
    37              // Treat as file URL
    38              addFileURLs(urls, new URL(classpath));
    39          } else {
    40              // Treat as classpath
    41              addClasspathURLs(urls, classpath);
    42          }
    43          return urls.toArray(new URL[urls.size()]);
    44      }
    45
    46      private static void addClasspathURLs(final List<URL> urls, final String classpath) throws MalformedURLException {
    47          StringTokenizer toker = new StringTokenizer(classpath, File.pathSeparator);
    48          while (toker.hasMoreTokens()) {
    49              String token = toker.nextToken();
    50              LOG.log(Level.FINE, "Adding classpath entry: <{0}>", token);
    51              urls.add(createURLFromPath(token));
    52          }
    53      }
    54
    55      private static void addFileURLs(List<URL> urls, URL fileURL) throws IOException {
    56          BufferedReader in = null;
    57          try {
    58              in = new BufferedReader(new InputStreamReader(fileURL.openStream()));
    59              String line;
    60              while ((line = in.readLine()) != null) {
    61                  LOG.log(Level.FINE, "Read classpath entry line: <{0}>", line);
    62                  line = line.trim();
    63                  if (line.length() > 0) {
    64                      LOG.log(Level.FINE, "Adding classpath entry: <{0}>", line);
    65                      urls.add(createURLFromPath(line));
    66                  }
    67              }
    68          } finally {
    69          	IOUtil.closeQuietly(in);
    70          }
    71      }
    72
    73      private static URL createURLFromPath(String path) throws MalformedURLException {
    74          File file = new File(path);
    75          return file.getAbsoluteFile().toURI().toURL();
    76      }
    77
    78      /**
    79       * {@inheritDoc}
    80       */
    81      @Override
    82      public String toString() {
    83          StringBuilder sb = new StringBuilder(getClass().getSimpleName());
    84          sb.append("[[");
    85          StringUtil.asStringOn(sb, getURLs(), ":");
    86          sb.append("] parent: ");
    87          sb.append(getParent());
    88          sb.append(']');
    89
    90          return sb.toString();
    91      }
    92  }