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 @Override
55 public synchronized void release()
56 {
57 _list=null;
58 _entry=null;
59 _file=null;
60 _jarFile=null;
61 super.release();
62 }
63
64
65 @Override
66 protected boolean checkConnection()
67 {
68 try{
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 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 }
190
191 _exists= ( _directory || _entry!=null);
192 return _exists;
193 }
194
195
196
197
198
199
200
201
202 @Override
203 public boolean isDirectory()
204 {
205 return _urlString.endsWith("/") || exists() && _directory;
206 }
207
208
209
210
211
212 @Override
213 public long lastModified()
214 {
215 if (checkConnection() && _file!=null)
216 return _file.lastModified();
217 return -1;
218 }
219
220
221 @Override
222 public synchronized String[] list()
223 {
224
225 if(isDirectory() && _list==null)
226 {
227 ArrayList list = new ArrayList(32);
228
229 checkConnection();
230
231 JarFile jarFile=_jarFile;
232 if(jarFile==null)
233 {
234 try
235 {
236 JarURLConnection jc=(JarURLConnection)((new URL(_jarUrl)).openConnection());
237 jc.setUseCaches(getUseCaches());
238 jarFile=jc.getJarFile();
239 }
240 catch(Exception e)
241 {
242 Log.ignore(e);
243 }
244 }
245
246 Enumeration e=jarFile.entries();
247 String dir=_urlString.substring(_urlString.indexOf("!/")+2);
248 while(e.hasMoreElements())
249 {
250
251 JarEntry entry = (JarEntry) e.nextElement();
252 String name=entry.getName().replace('\\','/');
253 if(!name.startsWith(dir) || name.length()==dir.length())
254 {
255 continue;
256 }
257 String listName=name.substring(dir.length());
258 int dash=listName.indexOf('/');
259 if (dash>=0)
260 {
261
262
263 if (dash==0 && listName.length()==1)
264 continue;
265
266
267 if (dash==0)
268 listName=listName.substring(dash+1, listName.length());
269 else
270 listName=listName.substring(0,dash+1);
271
272 if (list.contains(listName))
273 continue;
274 }
275
276 list.add(listName);
277 }
278
279 _list=new String[list.size()];
280 list.toArray(_list);
281 }
282 return _list;
283 }
284
285
286
287
288
289 @Override
290 public long length()
291 {
292 if (isDirectory())
293 return -1;
294
295 if (_entry!=null)
296 return _entry.getSize();
297
298 return -1;
299 }
300
301
302
303
304
305
306
307 @Override
308 public String encode(String uri)
309 {
310 return uri;
311 }
312
313
314
315
316
317
318
319
320 public static Resource getNonCachingResource (Resource resource)
321 {
322 if (!(resource instanceof JarFileResource))
323 return resource;
324
325 JarFileResource oldResource = (JarFileResource)resource;
326
327 JarFileResource newResource = new JarFileResource(oldResource.getURL(), false);
328 return newResource;
329
330 }
331
332
333
334
335
336
337
338
339 @Override
340 public boolean isContainedIn (Resource resource)
341 throws MalformedURLException
342 {
343 String string = _urlString;
344 int index = string.indexOf("!/");
345 if (index > 0)
346 string = string.substring(0,index);
347 if (string.startsWith("jar:"))
348 string = string.substring(4);
349 URL url = new URL(string);
350 return url.sameFile(resource.getURL());
351 }
352 }
353
354
355
356
357
358
359
360