1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.bcel.util;
19
20 import java.io.DataInputStream;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FilenameFilter;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.Serializable;
27 import java.net.MalformedURLException;
28 import java.net.URL;
29 import java.util.ArrayList;
30 import java.util.Enumeration;
31 import java.util.List;
32 import java.util.Locale;
33 import java.util.StringTokenizer;
34 import java.util.Vector;
35 import java.util.zip.ZipEntry;
36 import java.util.zip.ZipFile;
37
38
39
40
41
42
43
44
45 public class ClassPath implements Serializable {
46
47 private static final long serialVersionUID = 2099441438483340671L;
48 public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath();
49 private PathEntry[] paths;
50 private String class_path;
51 private ClassPath parent;
52
53 public ClassPath(ClassPath parent, String class_path) {
54 this(class_path);
55 this.parent = parent;
56 }
57
58
59
60
61
62
63 public ClassPath(String class_path) {
64 this.class_path = class_path;
65 List<PathEntry> vec = new ArrayList<PathEntry>();
66 for (StringTokenizer tok = new StringTokenizer(class_path, System
67 .getProperty("path.separator")); tok.hasMoreTokens();) {
68 String path = tok.nextToken();
69 if (!path.equals("")) {
70 File file = new File(path);
71 try {
72 if (file.exists()) {
73 if (file.isDirectory()) {
74 vec.add(new Dir(path));
75 } else {
76 vec.add(new Zip(new ZipFile(file)));
77 }
78 }
79 } catch (IOException e) {
80 System.err.println("CLASSPATH component " + file + ": " + e);
81 }
82 }
83 }
84 paths = new PathEntry[vec.size()];
85 vec.toArray(paths);
86 }
87
88
89
90
91
92
93 @Deprecated
94 public ClassPath() {
95 this(getClassPath());
96 }
97
98
99
100
101 @Override
102 public String toString() {
103 if (parent != null) {
104 return parent.toString() + File.pathSeparator + class_path;
105 }
106 return class_path;
107 }
108
109 @Override
110 public int hashCode() {
111 if (parent != null) {
112 return class_path.hashCode() + parent.hashCode();
113 }
114 return class_path.hashCode();
115 }
116
117
118 @Override
119 public boolean equals( Object o ) {
120 if (o instanceof ClassPath) {
121 ClassPath cp = (ClassPath)o;
122 return class_path.equals(cp.toString());
123 }
124 return false;
125 }
126
127
128 private static final void getPathComponents( String path, List<String> list ) {
129 if (path != null) {
130 StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);
131 while (tok.hasMoreTokens()) {
132 String name = tok.nextToken();
133 File file = new File(name);
134 if (file.exists()) {
135 list.add(name);
136 }
137 }
138 }
139 }
140
141
142
143
144
145
146
147 public static final String getClassPath() {
148 String class_path = System.getProperty("java.class.path");
149 String boot_path = System.getProperty("sun.boot.class.path");
150 String ext_path = System.getProperty("java.ext.dirs");
151 List<String> list = new ArrayList<String>();
152 getPathComponents(class_path, list);
153 getPathComponents(boot_path, list);
154 List<String> dirs = new ArrayList<String>();
155 getPathComponents(ext_path, dirs);
156 for (String d : dirs) {
157 File ext_dir = new File(d);
158 String[] extensions = ext_dir.list(new FilenameFilter() {
159
160 public boolean accept( File dir, String name ) {
161 name = name.toLowerCase(Locale.ENGLISH);
162 return name.endsWith(".zip") || name.endsWith(".jar");
163 }
164 });
165 if (extensions != null) {
166 for (int i = 0; i < extensions.length; i++) {
167 list.add(ext_dir.getPath() + File.separatorChar + extensions[i]);
168 }
169 }
170 }
171 StringBuilder buf = new StringBuilder();
172 String separator = "";
173 for (String path : list) {
174 buf.append(separator);
175 separator = File.pathSeparator;
176 buf.append(path);
177 }
178 return buf.toString().intern();
179 }
180
181
182
183
184
185
186 public InputStream getInputStream( String name ) throws IOException {
187 return getInputStream(name.replace('.', '/'), ".class");
188 }
189
190
191
192
193
194
195
196
197
198 public InputStream getInputStream( String name, String suffix ) throws IOException {
199 InputStream is = null;
200 try {
201 is = getClass().getClassLoader().getResourceAsStream(name + suffix);
202 } catch (Exception e) {
203 }
204 if (is != null) {
205 return is;
206 }
207 return getClassFile(name, suffix).getInputStream();
208 }
209
210
211
212
213
214 public InputStream getResourceAsStream(String name) {
215 for (int i = 0; i < paths.length; i++) {
216 InputStream is;
217 if ((is = paths[i].getResourceAsStream(name)) != null) {
218 return is;
219 }
220 }
221 return null;
222 }
223
224
225
226
227
228 public URL getResource(String name) {
229 for (int i = 0; i < paths.length; i++) {
230 URL url;
231 if ((url = paths[i].getResource(name)) != null) {
232 return url;
233 }
234 }
235 return null;
236 }
237
238
239
240
241
242
243 public Enumeration<URL> getResources(String name) {
244 Vector<URL> results = new Vector<URL>();
245 for (int i = 0; i < paths.length; i++) {
246 URL url;
247 if ((url = paths[i].getResource(name)) != null) {
248 results.add(url);
249 }
250 }
251 return results.elements();
252 }
253
254
255
256
257
258
259 public ClassFile getClassFile( String name, String suffix ) throws IOException {
260 for (int i = 0; i < paths.length; i++) {
261 ClassFile cf = null;
262
263 if(parent != null) {
264 cf = parent.getClassFileInternal(name, suffix);
265 }
266
267 if(cf == null) {
268 cf = getClassFileInternal(name,suffix);
269 }
270
271 if(cf != null) {
272 return cf;
273 }
274 }
275
276 throw new IOException("Couldn't find: " + name + suffix);
277 }
278
279 private ClassFile getClassFileInternal(String name, String suffix) throws IOException {
280
281 for(int i=0; i < paths.length; i++) {
282 ClassFile cf = paths[i].getClassFile(name, suffix);
283
284 if(cf != null) {
285 return cf;
286 }
287 }
288
289 return null;
290 }
291
292
293
294
295
296
297 public ClassFile getClassFile( String name ) throws IOException {
298 return getClassFile(name, ".class");
299 }
300
301
302
303
304
305
306
307 public byte[] getBytes( String name, String suffix ) throws IOException {
308 DataInputStream dis = null;
309 try {
310 InputStream is = getInputStream(name, suffix);
311 if (is == null) {
312 throw new IOException("Couldn't find: " + name + suffix);
313 }
314 dis = new DataInputStream(is);
315 byte[] bytes = new byte[is.available()];
316 dis.readFully(bytes);
317 return bytes;
318 } finally {
319 if (dis != null) {
320 dis.close();
321 }
322 }
323 }
324
325
326
327
328
329 public byte[] getBytes( String name ) throws IOException {
330 return getBytes(name, ".class");
331 }
332
333
334
335
336
337
338 public String getPath( String name ) throws IOException {
339 int index = name.lastIndexOf('.');
340 String suffix = "";
341 if (index > 0) {
342 suffix = name.substring(index);
343 name = name.substring(0, index);
344 }
345 return getPath(name, suffix);
346 }
347
348
349
350
351
352
353
354 public String getPath( String name, String suffix ) throws IOException {
355 return getClassFile(name, suffix).getPath();
356 }
357
358 private static abstract class PathEntry implements Serializable {
359
360 private static final long serialVersionUID = 6828494485207666122L;
361 abstract ClassFile getClassFile( String name, String suffix ) throws IOException;
362 abstract URL getResource(String name);
363 abstract InputStream getResourceAsStream(String name);
364 }
365
366
367
368 public interface ClassFile {
369
370
371
372 public abstract InputStream getInputStream() throws IOException;
373
374
375
376
377 public abstract String getPath();
378
379
380
381
382
383 public abstract String getBase();
384
385
386
387
388 public abstract long getTime();
389
390
391
392
393 public abstract long getSize();
394 }
395
396 private static class Dir extends PathEntry {
397
398 private static final long serialVersionUID = 4374062802142373088L;
399 private String dir;
400
401
402 Dir(String d) {
403 dir = d;
404 }
405
406 @Override
407 URL getResource(String name) {
408
409 final File file = new File(dir + File.separatorChar + name.replace('/', File.separatorChar));
410 try {
411 return file.exists() ? file.toURL() : null;
412 } catch (MalformedURLException e) {
413 return null;
414 }
415 }
416
417 @Override
418 InputStream getResourceAsStream(String name) {
419
420 final File file = new File(dir + File.separatorChar + name.replace('/', File.separatorChar));
421 try {
422 return file.exists() ? new FileInputStream(file) : null;
423 } catch (IOException e) {
424 return null;
425 }
426 }
427
428 @Override
429 ClassFile getClassFile( String name, String suffix ) throws IOException {
430 final File file = new File(dir + File.separatorChar
431 + name.replace('.', File.separatorChar) + suffix);
432 return file.exists() ? new ClassFile() {
433
434 public InputStream getInputStream() throws IOException {
435 return new FileInputStream(file);
436 }
437
438
439 public String getPath() {
440 try {
441 return file.getCanonicalPath();
442 } catch (IOException e) {
443 return null;
444 }
445 }
446
447
448 public long getTime() {
449 return file.lastModified();
450 }
451
452
453 public long getSize() {
454 return file.length();
455 }
456
457
458 public String getBase() {
459 return dir;
460 }
461 } : null;
462 }
463
464
465 @Override
466 public String toString() {
467 return dir;
468 }
469 }
470
471 private static class Zip extends PathEntry {
472
473 private static final long serialVersionUID = -2210747632897905532L;
474 private ZipFile zip;
475
476
477 Zip(ZipFile z) {
478 zip = z;
479 }
480
481 @Override
482 URL getResource(String name) {
483 final ZipEntry entry = zip.getEntry(name);
484 try {
485 return (entry != null) ? new URL("jar:file:" + zip.getName() + "!/" + name) : null;
486 } catch (MalformedURLException e) {
487 return null;
488 }
489 }
490
491 @Override
492 InputStream getResourceAsStream(String name) {
493 final ZipEntry entry = zip.getEntry(name);
494 try {
495 return (entry != null) ? zip.getInputStream(entry) : null;
496 } catch (IOException e) {
497 return null;
498 }
499 }
500
501 @Override
502 ClassFile getClassFile( String name, String suffix ) throws IOException {
503 final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix);
504
505 if (entry == null)
506 return null;
507
508 return new ClassFile() {
509
510 public InputStream getInputStream() throws IOException {
511 return zip.getInputStream(entry);
512 }
513
514
515 public String getPath() {
516 return entry.toString();
517 }
518
519
520 public long getTime() {
521 return entry.getTime();
522 }
523
524
525 public long getSize() {
526 return entry.getSize();
527 }
528
529
530 public String getBase() {
531 return zip.getName();
532 }
533 };
534 }
535 }
536 }