1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.util.resource;
20
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.net.MalformedURLException;
26 import java.net.URI;
27 import java.net.URISyntaxException;
28 import java.net.URL;
29 import java.net.URLConnection;
30 import java.nio.channels.FileChannel;
31 import java.nio.channels.ReadableByteChannel;
32 import java.nio.file.StandardOpenOption;
33 import java.security.Permission;
34
35 import javax.management.RuntimeErrorException;
36
37 import org.eclipse.jetty.util.IO;
38 import org.eclipse.jetty.util.URIUtil;
39 import org.eclipse.jetty.util.log.Log;
40 import org.eclipse.jetty.util.log.Logger;
41
42
43
44
45
46
47
48
49
50
51
52 public class FileResource extends Resource
53 {
54 private static final Logger LOG = Log.getLogger(FileResource.class);
55
56
57 private final File _file;
58 private final String _uri;
59 private final URL _alias;
60
61
62 public FileResource(URL url)
63 throws IOException, URISyntaxException
64 {
65 File file;
66 try
67 {
68
69 file =new File(url.toURI());
70 }
71 catch (URISyntaxException e)
72 {
73 throw e;
74 }
75 catch (Exception e)
76 {
77 if (!url.toString().startsWith("file:"))
78 throw new IllegalArgumentException("!file:");
79
80 LOG.ignore(e);
81 try
82 {
83
84 String file_url="file:"+URIUtil.encodePath(url.toString().substring(5));
85 URI uri = new URI(file_url);
86 if (uri.getAuthority()==null)
87 file = new File(uri);
88 else
89 file = new File("//"+uri.getAuthority()+URIUtil.decodePath(url.getFile()));
90 }
91 catch (Exception e2)
92 {
93 LOG.ignore(e2);
94
95 URLConnection connection=url.openConnection();
96 Permission perm = connection.getPermission();
97 file = new File(perm==null?url.getFile():perm.getName());
98 }
99 }
100
101 _file=file;
102 _uri=normalizeURI(_file,url.toURI());
103 _alias=checkAlias(_file);
104 }
105
106
107 public FileResource(URI uri)
108 {
109 File file=new File(uri);
110 _file=file;
111 URI file_uri=_file.toURI();
112 _uri=normalizeURI(_file,uri);
113
114 if (!_uri.equals(file_uri) && !_uri.toString().equals(file_uri.toString()))
115 {
116
117 if (!file_uri.toString().equals(URIUtil.decodePath(uri.toString())))
118 {
119 try
120 {
121 _alias=_file.toURI().toURL();
122 }
123 catch (MalformedURLException e)
124 {
125 throw new IllegalArgumentException(e);
126 }
127 }
128 else
129 _alias=checkAlias(_file);
130 }
131 else
132 _alias=checkAlias(_file);
133 }
134
135
136 FileResource(File file)
137 {
138 _file=file;
139 _uri=normalizeURI(_file,_file.toURI());
140 _alias=checkAlias(_file);
141 }
142
143
144 private static String normalizeURI(File file, URI uri)
145 {
146 String u =uri.toASCIIString();
147 if (file.isDirectory())
148 {
149 if(!u.endsWith("/"))
150 u+="/";
151 }
152 else if (file.exists() && u.endsWith("/"))
153 u=u.substring(0,u.length()-1);
154 return u;
155 }
156
157
158 private static URL checkAlias(File file)
159 {
160 try
161 {
162 String abs=file.getAbsolutePath();
163 String can=file.getCanonicalPath();
164
165 if (!abs.equals(can))
166 {
167 LOG.debug("ALIAS abs={} can={}",abs,can);
168 return new File(can).toURI().toURL();
169 }
170 }
171 catch(IOException e)
172 {
173 LOG.warn("bad alias for {}: {}",file,e.toString());
174 LOG.debug(e);
175 try
176 {
177 return new URL("http://eclipse.org/bad/canonical/alias");
178 }
179 catch(Exception e2)
180 {
181 LOG.ignore(e2);
182 throw new RuntimeException(e);
183 }
184 }
185
186 return null;
187 }
188
189
190 @Override
191 public Resource addPath(String path)
192 throws IOException,MalformedURLException
193 {
194 path = org.eclipse.jetty.util.URIUtil.canonicalPath(path);
195
196 if (path==null)
197 throw new MalformedURLException();
198
199 if ("/".equals(path))
200 return this;
201
202 path=URIUtil.encodePath(path);
203
204 URI uri;
205 try
206 {
207 if (_file.isDirectory())
208 {
209
210 uri=new URI(URIUtil.addPaths(_uri,path));
211 }
212 else
213 {
214 uri=new URI(_uri+path);
215 }
216 }
217 catch(final URISyntaxException e)
218 {
219 throw new MalformedURLException(){{initCause(e);}};
220 }
221
222 return new FileResource(uri);
223 }
224
225
226
227 @Override
228 public URL getAlias()
229 {
230 return _alias;
231 }
232
233
234
235
236
237 @Override
238 public boolean exists()
239 {
240 return _file.exists();
241 }
242
243
244
245
246
247 @Override
248 public long lastModified()
249 {
250 return _file.lastModified();
251 }
252
253
254
255
256
257 @Override
258 public boolean isDirectory()
259 {
260 return _file.exists() && _file.isDirectory() || _uri.endsWith("/");
261 }
262
263
264
265
266
267 @Override
268 public long length()
269 {
270 return _file.length();
271 }
272
273
274
275
276
277
278 @Override
279 public String getName()
280 {
281 return _file.getAbsolutePath();
282 }
283
284
285
286
287
288
289 @Override
290 public File getFile()
291 {
292 return _file;
293 }
294
295
296
297
298
299 @Override
300 public InputStream getInputStream() throws IOException
301 {
302 return new FileInputStream(_file);
303 }
304
305
306 @Override
307 public ReadableByteChannel getReadableByteChannel() throws IOException
308 {
309 return FileChannel.open(_file.toPath(),StandardOpenOption.READ);
310 }
311
312
313
314
315
316 @Override
317 public boolean delete()
318 throws SecurityException
319 {
320 return _file.delete();
321 }
322
323
324
325
326
327 @Override
328 public boolean renameTo( Resource dest)
329 throws SecurityException
330 {
331 if( dest instanceof FileResource)
332 return _file.renameTo( ((FileResource)dest)._file);
333 else
334 return false;
335 }
336
337
338
339
340
341 @Override
342 public String[] list()
343 {
344 String[] list =_file.list();
345 if (list==null)
346 return null;
347 for (int i=list.length;i-->0;)
348 {
349 if (new File(_file,list[i]).isDirectory() &&
350 !list[i].endsWith("/"))
351 list[i]+="/";
352 }
353 return list;
354 }
355
356
357
358
359
360
361 @Override
362 public boolean equals( Object o)
363 {
364 if (this == o)
365 return true;
366
367 if (null == o || ! (o instanceof FileResource))
368 return false;
369
370 FileResource f=(FileResource)o;
371 return f._file == _file || (null != _file && _file.equals(f._file));
372 }
373
374
375
376
377
378 @Override
379 public int hashCode()
380 {
381 return null == _file ? super.hashCode() : _file.hashCode();
382 }
383
384
385 @Override
386 public void copyTo(File destination)
387 throws IOException
388 {
389 if (isDirectory())
390 {
391 IO.copyDir(getFile(),destination);
392 }
393 else
394 {
395 if (destination.exists())
396 throw new IllegalArgumentException(destination+" exists");
397 IO.copy(getFile(),destination);
398 }
399 }
400
401 @Override
402 public boolean isContainedIn(Resource r) throws MalformedURLException
403 {
404 return false;
405 }
406
407 @Override
408 public void close()
409 {
410 }
411
412 @Override
413 public URL getURL()
414 {
415 try
416 {
417 return new URL(_uri);
418 }
419 catch (MalformedURLException e)
420 {
421 throw new IllegalStateException(e);
422 }
423 }
424
425 @Override
426 public String toString()
427 {
428 return _uri;
429 }
430
431 }