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
38 addFileURLs(urls, new URL(classpath));
39 } else {
40
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 in.close();
69 } finally {
70 if (in != null) {
71 try {
72 in.close();
73 } catch (IOException e) {
74 LOG.log(Level.SEVERE, "IOException while closing InputStream", e);
75 }
76 }
77 }
78 }
79
80 private static URL createURLFromPath(String path) throws MalformedURLException {
81 File file = new File(path);
82 return file.getAbsoluteFile().toURI().toURL();
83 }
84 }