1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.mortbay.resource;
15
16 import java.io.File;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.OutputStream;
20 import java.io.Serializable;
21 import java.net.MalformedURLException;
22 import java.net.URL;
23 import java.net.URLConnection;
24 import java.text.DateFormat;
25 import java.util.Arrays;
26 import java.util.Date;
27
28 import org.mortbay.log.Log;
29 import org.mortbay.util.IO;
30 import org.mortbay.util.Loader;
31 import org.mortbay.util.StringUtil;
32 import org.mortbay.util.URIUtil;
33
34
35
36
37
38
39
40
41 public abstract class Resource implements Serializable
42 {
43 public static boolean __defaultUseCaches = true;
44 Object _associate;
45
46
47
48
49
50
51 public static void setDefaultUseCaches (boolean useCaches)
52 {
53 __defaultUseCaches=useCaches;
54 }
55
56 public static boolean getDefaultUseCaches ()
57 {
58 return __defaultUseCaches;
59 }
60
61
62
63
64
65
66 public static Resource newResource(URL url)
67 throws IOException
68 {
69 return newResource(url, __defaultUseCaches);
70 }
71
72
73
74
75
76
77
78
79 public static Resource newResource(URL url, boolean useCaches)
80 {
81 if (url==null)
82 return null;
83
84 String url_string=url.toExternalForm();
85 if( url_string.startsWith( "file:"))
86 {
87 try
88 {
89 FileResource fileResource= new FileResource(url);
90 return fileResource;
91 }
92 catch(Exception e)
93 {
94 Log.debug(Log.EXCEPTION,e);
95 return new BadResource(url,e.toString());
96 }
97 }
98 else if( url_string.startsWith( "jar:file:"))
99 {
100 return new JarFileResource(url, useCaches);
101 }
102 else if( url_string.startsWith( "jar:"))
103 {
104 return new JarResource(url, useCaches);
105 }
106
107 return new URLResource(url,null,useCaches);
108 }
109
110
111
112
113
114
115
116
117 public static Resource newResource(String resource)
118 throws MalformedURLException, IOException
119 {
120 return newResource(resource, __defaultUseCaches);
121 }
122
123
124
125
126
127
128
129 public static Resource newResource (String resource, boolean useCaches)
130 throws MalformedURLException, IOException
131 {
132 URL url=null;
133 try
134 {
135
136 url = new URL(resource);
137 }
138 catch(MalformedURLException e)
139 {
140 if(!resource.startsWith("ftp:") &&
141 !resource.startsWith("file:") &&
142 !resource.startsWith("jar:"))
143 {
144 try
145 {
146
147 if (resource.startsWith("./"))
148 resource=resource.substring(2);
149
150 File file=new File(resource).getCanonicalFile();
151 url=new URL(URIUtil.encodePath(file.toURL().toString()));
152
153 URLConnection connection=url.openConnection();
154 connection.setUseCaches(useCaches);
155 FileResource fileResource= new FileResource(url,connection,file);
156 return fileResource;
157 }
158 catch(Exception e2)
159 {
160 Log.debug(Log.EXCEPTION,e2);
161 throw e;
162 }
163 }
164 else
165 {
166 Log.warn("Bad Resource: "+resource);
167 throw e;
168 }
169 }
170
171
172 String nurl=url.toString();
173 if (nurl.length()>0 && nurl.charAt(nurl.length()-1)!=resource.charAt(resource.length()-1))
174 {
175 if ((nurl.charAt(nurl.length()-1)!='/' ||
176 nurl.charAt(nurl.length()-2)!=resource.charAt(resource.length()-1))
177 &&
178 (resource.charAt(resource.length()-1)!='/' ||
179 resource.charAt(resource.length()-2)!=nurl.charAt(nurl.length()-1)
180 ))
181 {
182 return new BadResource(url,"Trailing special characters stripped by URL in "+resource);
183 }
184 }
185 return newResource(url);
186 }
187
188
189
190
191
192
193 public static Resource newSystemResource(String resource)
194 throws IOException
195 {
196 URL url=null;
197
198 ClassLoader
199 loader=Thread.currentThread().getContextClassLoader();
200 if (loader!=null)
201 {
202 url=loader.getResource(resource);
203 if (url==null && resource.startsWith("/"))
204 url=loader.getResource(resource.substring(1));
205 }
206 if (url==null)
207 {
208 loader=Resource.class.getClassLoader();
209 if (loader!=null)
210 {
211 url=loader.getResource(resource);
212 if (url==null && resource.startsWith("/"))
213 url=loader.getResource(resource.substring(1));
214 }
215 }
216
217 if (url==null)
218 {
219 url=ClassLoader.getSystemResource(resource);
220 if (url==null && resource.startsWith("/"))
221 url=loader.getResource(resource.substring(1));
222 }
223
224 if (url==null)
225 return null;
226
227 return newResource(url);
228 }
229
230
231
232
233 public static Resource newClassPathResource(String resource)
234 {
235 return newClassPathResource(resource,true,false);
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249
250 public static Resource newClassPathResource(String name,boolean useCaches,boolean checkParents)
251 {
252 URL url=Resource.class.getResource(name);
253
254 if (url==null)
255 {
256 try
257 {
258 url=Loader.getResource(Resource.class,name,checkParents);
259 }
260 catch(ClassNotFoundException e)
261 {
262 url=ClassLoader.getSystemResource(name);
263 }
264 }
265 if (url==null)
266 return null;
267 return newResource(url,useCaches);
268 }
269
270
271
272
273 protected void finalize()
274 {
275 release();
276 }
277
278
279
280
281 public abstract void release();
282
283
284
285
286
287
288 public abstract boolean exists();
289
290
291
292
293
294
295
296
297 public abstract boolean isDirectory();
298
299
300
301
302
303 public abstract long lastModified();
304
305
306
307
308
309
310 public abstract long length();
311
312
313
314
315
316
317 public abstract URL getURL();
318
319
320
321
322
323
324
325 public abstract File getFile()
326 throws IOException;
327
328
329
330
331
332
333 public abstract String getName();
334
335
336
337
338
339
340 public abstract InputStream getInputStream()
341 throws java.io.IOException;
342
343
344
345
346
347 public abstract OutputStream getOutputStream()
348 throws java.io.IOException, SecurityException;
349
350
351
352
353
354 public abstract boolean delete()
355 throws SecurityException;
356
357
358
359
360
361 public abstract boolean renameTo( Resource dest)
362 throws SecurityException;
363
364
365
366
367
368
369 public abstract String[] list();
370
371
372
373
374
375
376
377
378 public abstract Resource addPath(String path)
379 throws IOException,MalformedURLException;
380
381
382
383
384
385
386
387
388 public String encode(String uri)
389 {
390 return URIUtil.encodePath(uri);
391 }
392
393
394 public Object getAssociate()
395 {
396 return _associate;
397 }
398
399
400 public void setAssociate(Object o)
401 {
402 _associate=o;
403 }
404
405
406
407
408
409 public URL getAlias()
410 {
411 return null;
412 }
413
414
415
416
417
418
419
420 public String getListHTML(String base,
421 boolean parent)
422 throws IOException
423 {
424 if (!isDirectory())
425 return null;
426
427 String[] ls = list();
428 if (ls==null)
429 return null;
430 Arrays.sort(ls);
431
432 String decodedBase = URIUtil.decodePath(base);
433 String title = "Directory: "+decodedBase;
434
435 StringBuffer buf=new StringBuffer(4096);
436 buf.append("<HTML><HEAD><TITLE>");
437 buf.append(title);
438 buf.append("</TITLE></HEAD><BODY>\n<H1>");
439 buf.append(title);
440 buf.append("</H1><TABLE BORDER=0>");
441
442 if (parent)
443 {
444 buf.append("<TR><TD><A HREF=");
445 buf.append(URIUtil.addPaths(base,"../"));
446 buf.append(">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n");
447 }
448
449 DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
450 DateFormat.MEDIUM);
451 for (int i=0 ; i< ls.length ; i++)
452 {
453 String encoded=URIUtil.encodePath(ls[i]);
454 Resource item = addPath(ls[i]);
455
456 buf.append("<TR><TD><A HREF=\"");
457 String path=URIUtil.addPaths(base,encoded);
458
459 if (item.isDirectory() && !path.endsWith("/"))
460 path=URIUtil.addPaths(path,URIUtil.SLASH);
461 buf.append(path);
462 buf.append("\">");
463 buf.append(StringUtil.replace(StringUtil.replace(ls[i],"<","<"),">",">"));
464 buf.append(" ");
465 buf.append("</TD><TD ALIGN=right>");
466 buf.append(item.length());
467 buf.append(" bytes </TD><TD>");
468 buf.append(dfmt.format(new Date(item.lastModified())));
469 buf.append("</TD></TR>\n");
470 }
471 buf.append("</TABLE>\n");
472 buf.append("</BODY></HTML>\n");
473
474 return buf.toString();
475 }
476
477
478
479
480
481
482
483 public void writeTo(OutputStream out,long start,long count)
484 throws IOException
485 {
486 InputStream in = getInputStream();
487 try
488 {
489 in.skip(start);
490 if (count<0)
491 IO.copy(in,out);
492 else
493 IO.copy(in,out,count);
494 }
495 finally
496 {
497 in.close();
498 }
499 }
500 }