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