Source code: nice/tools/util/ClassLoader.java
1 /**************************************************************************/
2 /* N I C E */
3 /* A high-level object-oriented research language */
4 /* (c) Daniel Bonniot 2002 */
5 /* */
6 /* This program is free software; you can redistribute it and/or modify */
7 /* it under the terms of the GNU General Public License as published by */
8 /* the Free Software Foundation; either version 2 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /**************************************************************************/
12
13 package nice.tools.util;
14
15 import gnu.bytecode.*;
16 import java.util.LinkedList;
17 import java.util.Map;
18 import java.util.jar.JarFile;
19 import java.util.jar.JarEntry;
20 import java.io.*;
21
22 /**
23 A ClassLoader located classes on its classpath and returns
24 their representation as a gnu.bytecode.ClassType.
25
26 @version $Date: 2002/09/09 12:59:25 $
27 @author Daniel Bonniot (bonniot@users.sourceforge.net)
28 */
29
30 public class ClassLoader
31 {
32 public ClassLoader(String classpath, Registrar registrar)
33 {
34 this.registrar = registrar;
35 this.locations = splitPath(classpath);
36 }
37
38 public ClassType load(String className)
39 {
40 String filesystemName = className.replace('.', File.separatorChar) + ".class";
41 String jarName = className.replace('.', '/') + ".class";
42
43 for (int i = 0; i < locations.length; i++)
44 {
45 InputStream input = null;
46
47 if (locations[i] instanceof File)
48 {
49 File dir = (File) locations[i];
50 File file = new File(dir, filesystemName);
51 try {
52 input = new FileInputStream(file);
53 }
54 catch(FileNotFoundException ex) {
55 }
56 }
57 else
58 {
59 JarFile jar = (JarFile) locations[i];
60 JarEntry e = jar.getJarEntry(jarName);
61 if (e != null)
62 try {
63 input = jar.getInputStream(e);
64 }
65 catch(java.io.IOException ex) {
66 }
67 }
68
69 if (input != null)
70 {
71 ClassType res = new ClassType();
72 registrar.register(className, res);
73 try {
74 new ClassFileInput(res, input);
75 return res;
76 }
77 catch (IOException ex) {
78 }
79 }
80 }
81
82 return null;
83 }
84
85 /****************************************************************
86 * Private implementation
87 ****************************************************************/
88
89 /** where to find compiled packages. */
90 private final Object[] locations;
91
92 /** Map from class names to types.
93 Used to avoid loading several copies of the same class.
94 */
95 private final Registrar registrar;
96
97 public abstract static class Registrar
98 {
99 public abstract void register(String className, ClassType type);
100 }
101
102 private static Object[] splitPath (String path)
103 {
104 LinkedList res = new LinkedList();
105
106 int start = 0;
107 // skip starting separators
108 while (start < path.length() &&
109 path.charAt(start) == File.pathSeparatorChar)
110 start++;
111
112 while(start < path.length())
113 {
114 int end = path.indexOf(File.pathSeparatorChar, start);
115 if (end == -1)
116 end = path.length();
117
118 String pathComponent = path.substring(start, end);
119 if (pathComponent.length() > 0)
120 {
121 File f = nice.tools.util.System.getFile(pathComponent);
122 // Ignore non-existing directories and archives
123 if (f.exists())
124 {
125 if (pathComponent.endsWith(".jar"))
126 try{
127 res.add(new JarFile(f));
128 }
129 catch(IOException e){}
130 else
131 res.add(f);
132 }
133 }
134 start = end + 1;
135 }
136
137 return res.toArray(new Object[res.size()]);
138 }
139
140 }