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