1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.start;
15
16 import java.io.File;
17 import java.io.IOException;
18 import java.io.PrintStream;
19 import java.io.UnsupportedEncodingException;
20 import java.net.MalformedURLException;
21 import java.net.URL;
22 import java.net.URLClassLoader;
23 import java.util.StringTokenizer;
24 import java.util.Vector;
25
26
27
28
29
30 public class Classpath {
31
32 private final Vector<File> _elements = new Vector<File>();
33
34 public Classpath()
35 {}
36
37 public Classpath(String initial)
38 {
39 addClasspath(initial);
40 }
41
42 public File[] getElements()
43 {
44 return _elements.toArray(new File[_elements.size()]);
45 }
46
47 public int count()
48 {
49 return _elements.size();
50 }
51
52 public boolean addComponent(String component)
53 {
54 if ((component != null)&&(component.length()>0)) {
55 try {
56 File f = new File(component);
57 if (f.exists())
58 {
59 File key = f.getCanonicalFile();
60 if (!_elements.contains(key))
61 {
62 _elements.add(key);
63 return true;
64 }
65 }
66 } catch (IOException e) {}
67 }
68 return false;
69 }
70
71 public boolean addComponent(File component)
72 {
73 if (component != null) {
74 try {
75 if (component.exists()) {
76 File key = component.getCanonicalFile();
77 if (!_elements.contains(key)) {
78 _elements.add(key);
79 return true;
80 }
81 }
82 } catch (IOException e) {}
83 }
84 return false;
85 }
86
87 public boolean addClasspath(String s)
88 {
89 boolean added=false;
90 if (s != null)
91 {
92 StringTokenizer t = new StringTokenizer(s, File.pathSeparator);
93 while (t.hasMoreTokens())
94 {
95 added|=addComponent(t.nextToken());
96 }
97 }
98 return added;
99 }
100
101 public void dump(PrintStream out)
102 {
103 int i = 0;
104 for (File element : _elements)
105 {
106 out.printf("%2d: %s\n",i++,element.getAbsolutePath());
107 }
108 }
109
110 @Override
111 public String toString()
112 {
113 StringBuffer cp = new StringBuffer(1024);
114 int cnt = _elements.size();
115 if (cnt >= 1) {
116 cp.append( ((_elements.elementAt(0))).getPath() );
117 }
118 for (int i=1; i < cnt; i++) {
119 cp.append(File.pathSeparatorChar);
120 cp.append( ((_elements.elementAt(i))).getPath() );
121 }
122 return cp.toString();
123 }
124
125 public ClassLoader getClassLoader() {
126 int cnt = _elements.size();
127 URL[] urls = new URL[cnt];
128 for (int i=0; i < cnt; i++) {
129 try {
130 String u=((_elements.elementAt(i))).toURL().toString();
131 urls[i] = new URL(encodeFileURL(u));
132 } catch (MalformedURLException e) {}
133 }
134
135 ClassLoader parent = Thread.currentThread().getContextClassLoader();
136 if (parent == null) {
137 parent = Classpath.class.getClassLoader();
138 }
139 if (parent == null) {
140 parent = ClassLoader.getSystemClassLoader();
141 }
142 return new Loader(urls, parent);
143 }
144
145 private static class Loader extends URLClassLoader
146 {
147 Loader(URL[] urls, ClassLoader parent)
148 {
149 super(urls, parent);
150 }
151
152 @Override
153 public String toString()
154 {
155 return "startJarLoader@"+Long.toHexString(hashCode());
156 }
157 }
158
159 public static String encodeFileURL(String path)
160 {
161 byte[] bytes;
162 try
163 {
164 bytes=path.getBytes("utf-8");
165 }
166 catch (UnsupportedEncodingException e)
167 {
168 bytes=path.getBytes();
169 }
170
171 StringBuffer buf = new StringBuffer(bytes.length*2);
172 buf.append("file:");
173
174 synchronized(buf)
175 {
176 for (int i=5;i<bytes.length;i++)
177 {
178 byte b=bytes[i];
179 switch(b)
180 {
181 case '%':
182 buf.append("%25");
183 continue;
184 case ' ':
185 buf.append("%20");
186 continue;
187 case '/':
188 case '.':
189 case '-':
190 case '_':
191 buf.append((char)b);
192 continue;
193 default:
194
195 if (Character.isJavaIdentifierPart((char)b))
196 {
197 if(b>='a' && b<='z' || b>='A' && b<='Z' || b>='0' && b<='9')
198 {
199 buf.append((char)b);
200 continue;
201 }
202 }
203 buf.append('%');
204 buf.append(Integer.toHexString((0xf0&b)>>4));
205 buf.append(Integer.toHexString((0x0f&b)));
206 continue;
207 }
208 }
209 }
210
211 return buf.toString();
212 }
213
214
215
216
217
218
219
220
221 public void overlay(Classpath cpOther)
222 {
223 for (File otherElement : cpOther._elements)
224 {
225 if (this._elements.contains(otherElement))
226 {
227
228 continue;
229 }
230 this._elements.add(otherElement);
231 }
232 }
233
234 public boolean isEmpty()
235 {
236 return (_elements == null) || (_elements.isEmpty());
237 }
238 }