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