1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jetty.util.resource;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.net.JarURLConnection;
18 import java.net.MalformedURLException;
19 import java.net.URL;
20 import java.util.ArrayList;
21 import java.util.Enumeration;
22 import java.util.jar.JarEntry;
23 import java.util.jar.JarFile;
24
25 import org.eclipse.jetty.util.log.Log;
26
27
28 class JarFileResource extends JarResource
29 {
30
31 transient JarFile _jarFile;
32 transient File _file;
33 transient String[] _list;
34 transient JarEntry _entry;
35 transient boolean _directory;
36 transient String _jarUrl;
37 transient String _path;
38 transient boolean _exists;
39
40
41
42 JarFileResource(URL url)
43 {
44 super(url);
45 }
46
47 JarFileResource(URL url, boolean useCaches)
48 {
49 super(url, useCaches);
50 }
51
52
53
54 public synchronized void release()
55 {
56 _list=null;
57 _entry=null;
58 _file=null;
59 _jarFile=null;
60 super.release();
61 }
62
63
64 protected boolean checkConnection()
65 {
66 try{
67 super.checkConnection();
68 }
69 finally
70 {
71 if (_jarConnection==null)
72 {
73 _entry=null;
74 _file=null;
75 _jarFile=null;
76 _list=null;
77 }
78 }
79 return _jarFile!=null;
80 }
81
82
83
84 protected void newConnection()
85 throws IOException
86 {
87 super.newConnection();
88
89 _entry=null;
90 _file=null;
91 _jarFile=null;
92 _list=null;
93
94 int sep = _urlString.indexOf("!/");
95 _jarUrl=_urlString.substring(0,sep+2);
96 _path=_urlString.substring(sep+2);
97 if (_path.length()==0)
98 _path=null;
99 _jarFile=_jarConnection.getJarFile();
100 _file=new File(_jarFile.getName());
101 }
102
103
104
105
106
107
108 public boolean exists()
109 {
110 if (_exists)
111 return true;
112
113 if (_urlString.endsWith("!/"))
114 {
115
116 String file_url=_urlString.substring(4,_urlString.length()-2);
117 try{return newResource(file_url).exists();}
118 catch(Exception e) {Log.ignore(e); return false;}
119 }
120
121 boolean check=checkConnection();
122
123
124 if (_jarUrl!=null && _path==null)
125 {
126
127 _directory=check;
128 return true;
129 }
130 else
131 {
132
133 JarFile jarFile=null;
134 if (check)
135
136 jarFile=_jarFile;
137 else
138 {
139
140 try
141 {
142 JarURLConnection c=(JarURLConnection)((new URL(_jarUrl)).openConnection());
143 c.setUseCaches(getUseCaches());
144 jarFile=c.getJarFile();
145 }
146 catch(Exception e)
147 {
148 Log.ignore(e);
149 }
150 }
151
152
153 if (jarFile!=null && _entry==null && !_directory)
154 {
155
156 Enumeration e=jarFile.entries();
157 while(e.hasMoreElements())
158 {
159 JarEntry entry = (JarEntry) e.nextElement();
160 String name=entry.getName().replace('\\','/');
161
162
163 if (name.equals(_path))
164 {
165 _entry=entry;
166
167 _directory=_path.endsWith("/");
168 break;
169 }
170 else if (_path.endsWith("/"))
171 {
172 if (name.startsWith(_path))
173 {
174 _directory=true;
175 break;
176 }
177 }
178 else if (name.startsWith(_path) && name.length()>_path.length() && name.charAt(_path.length())=='/')
179 {
180 _directory=true;
181 break;
182 }
183 }
184 }
185 }
186
187 _exists= ( _directory || _entry!=null);
188 return _exists;
189 }
190
191
192
193
194
195
196
197
198 public boolean isDirectory()
199 {
200 return _urlString.endsWith("/") || exists() && _directory;
201 }
202
203
204
205
206
207 public long lastModified()
208 {
209 if (checkConnection() && _file!=null)
210 return _file.lastModified();
211 return -1;
212 }
213
214
215 public synchronized String[] list()
216 {
217
218 if(isDirectory() && _list==null)
219 {
220 ArrayList list = new ArrayList(32);
221
222 checkConnection();
223
224 JarFile jarFile=_jarFile;
225 if(jarFile==null)
226 {
227 try
228 {
229 JarURLConnection jc=(JarURLConnection)((new URL(_jarUrl)).openConnection());
230 jc.setUseCaches(getUseCaches());
231 jarFile=jc.getJarFile();
232 }
233 catch(Exception e)
234 {
235 Log.ignore(e);
236 }
237 }
238
239 Enumeration e=jarFile.entries();
240 String dir=_urlString.substring(_urlString.indexOf("!/")+2);
241 while(e.hasMoreElements())
242 {
243
244 JarEntry entry = (JarEntry) e.nextElement();
245 String name=entry.getName().replace('\\','/');
246 if(!name.startsWith(dir) || name.length()==dir.length())
247 {
248 continue;
249 }
250 String listName=name.substring(dir.length());
251 int dash=listName.indexOf('/');
252 if (dash>=0)
253 {
254
255
256 if (dash==0 && listName.length()==1)
257 continue;
258
259
260 if (dash==0)
261 listName=listName.substring(dash+1, listName.length());
262 else
263 listName=listName.substring(0,dash+1);
264
265 if (list.contains(listName))
266 continue;
267 }
268
269 list.add(listName);
270 }
271
272 _list=new String[list.size()];
273 list.toArray(_list);
274 }
275 return _list;
276 }
277
278
279
280
281
282 public long length()
283 {
284 if (isDirectory())
285 return -1;
286
287 if (_entry!=null)
288 return _entry.getSize();
289
290 return -1;
291 }
292
293
294
295
296
297
298
299 public String encode(String uri)
300 {
301 return uri;
302 }
303
304
305
306
307
308
309
310
311 public static Resource getNonCachingResource (Resource resource)
312 {
313 if (!(resource instanceof JarFileResource))
314 return resource;
315
316 JarFileResource oldResource = (JarFileResource)resource;
317
318 JarFileResource newResource = new JarFileResource(oldResource.getURL(), false);
319 return newResource;
320
321 }
322
323
324
325
326
327
328
329
330 public boolean isContainedIn (Resource resource)
331 throws MalformedURLException
332 {
333 String string = _urlString;
334 int index = string.indexOf("!/");
335 if (index > 0)
336 string = string.substring(0,index);
337 if (string.startsWith("jar:"))
338 string = string.substring(4);
339 URL url = new URL(string);
340 return url.sameFile(resource.getURL());
341 }
342 }
343
344
345
346
347
348
349
350