1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.maven.exceptions.runtime;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Enumeration;
25 import java.util.List;
26 import java.util.NoSuchElementException;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import de.smartics.maven.exceptions.util.FileNameUtils;
32
33
34
35
36 public class ProjectClassLoader extends AbstractProjectClassLoader
37 {
38
39
40
41
42
43
44
45
46
47 private final List<File> rootDirectories;
48
49
50
51
52
53
54
55
56
57
58
59 public ProjectClassLoader(final List<File> rootDirectories)
60 {
61 this(Thread.currentThread().getContextClassLoader(), rootDirectories);
62 }
63
64
65
66
67
68
69
70
71 public ProjectClassLoader(final Collection<String> rootDirectoryNames)
72 {
73 this(initDirectories(LogFactory.getLog(ProjectClassLoader.class),
74 rootDirectoryNames));
75 }
76
77 @Override
78 protected URL findResource(final String name)
79 {
80 for (File directoryOrArchive : rootDirectories)
81 {
82 try
83 {
84 if (directoryOrArchive.isDirectory())
85 {
86 final File resourceFile = new File(directoryOrArchive, name);
87 if (resourceFile.canRead())
88 {
89 return resourceFile.toURI().toURL();
90 }
91 }
92 else
93 {
94 String resourceName = name;
95 final int index = name.lastIndexOf('.');
96 if (index != -1)
97 {
98 resourceName = name.substring(0, index);
99 }
100 resourceName = resourceName.replace('/', '.');
101 return loadResourceFromLibrary(resourceName, name, directoryOrArchive);
102 }
103 }
104 catch (final IOException e)
105 {
106
107 }
108 }
109 return super.findResource(name);
110 }
111
112 @Override
113 protected Enumeration<URL> findResources(final String name)
114 {
115 return new Enumeration<URL>()
116 {
117 private URL element = findResource(name);
118
119 public boolean hasMoreElements()
120 {
121 return this.element != null;
122 }
123
124 public URL nextElement()
125 {
126 if (this.element != null)
127 {
128 final URL element = this.element;
129 this.element = null;
130 return element;
131 }
132 throw new NoSuchElementException();
133 }
134 };
135 }
136
137
138
139
140
141
142
143
144 public ProjectClassLoader(final ClassLoader parent,
145 final Collection<String> rootDirectoryNames)
146 {
147 this(parent, initDirectories(LogFactory.getLog(ProjectClassLoader.class),
148 rootDirectoryNames));
149 }
150
151
152
153
154
155
156
157 public ProjectClassLoader(final ClassLoader parent,
158 final List<File> rootDirectories)
159 {
160 super(parent);
161 this.rootDirectories = Collections.unmodifiableList(rootDirectories);
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 private static List<File> initDirectories(final Log log,
179 final Collection<String> directoryNames)
180 {
181 final List<File> directories = new ArrayList<File>(directoryNames.size());
182 for (final String directoryName : directoryNames)
183 {
184 final File directory = new File(directoryName);
185 if (directory.canRead()
186 && (directory.isDirectory() || directory.isFile()
187 && FileNameUtils
188 .isArchive(directoryName)))
189 {
190 directories.add(directory);
191 }
192 else
193 {
194 if (log.isDebugEnabled())
195 {
196 final String message =
197 "Cannot access '" + directoryName
198 + "' as directory or Java archive."
199 + " Ignoring as classpath root.";
200 log.debug(message);
201 }
202 }
203 }
204 return directories;
205 }
206
207
208
209
210
211
212
213
214 @Override
215 protected Class<?> findClass(final String name) throws ClassNotFoundException
216 {
217 for (File directoryOrArchive : rootDirectories)
218 {
219 try
220 {
221 final String fileName = name.replace('.', '/') + ".class";
222 if (directoryOrArchive.isDirectory())
223 {
224 final File classFile = new File(directoryOrArchive, fileName);
225 if (classFile.canRead())
226 {
227 return loadClassFile(name, classFile);
228 }
229 }
230 else
231 {
232 return loadClassFromLibrary(name, fileName, directoryOrArchive);
233 }
234 }
235 catch (final ClassNotFoundException e)
236 {
237
238 }
239 }
240 return super.findClass(name);
241 }
242
243
244
245 }