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