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