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.FileOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.net.MalformedURLException;
28 import java.net.URI;
29 import java.net.URISyntaxException;
30 import java.net.URL;
31 import java.net.URLConnection;
32 import java.nio.channels.FileChannel;
33 import java.nio.channels.ReadableByteChannel;
34 import java.nio.file.StandardOpenOption;
35 import java.security.Permission;
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
53 public class FileResource extends URLResource
54 {
55 private static final Logger LOG = Log.getLogger(FileResource.class);
56
57
58 private File _file;
59 private transient URL _alias=null;
60 private transient boolean _aliasChecked=false;
61
62
63 public FileResource(URL url)
64 throws IOException, URISyntaxException
65 {
66 super(url,null);
67
68 try
69 {
70
71 _file =new File(new URI(url.toString()));
72 }
73 catch (URISyntaxException e)
74 {
75 throw e;
76 }
77 catch (Exception e)
78 {
79 LOG.ignore(e);
80 try
81 {
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
96 checkConnection();
97 Permission perm = _connection.getPermission();
98 _file = new File(perm==null?url.getFile():perm.getName());
99 }
100 }
101 if (_file.isDirectory())
102 {
103 if (!_urlString.endsWith("/"))
104 _urlString=_urlString+"/";
105 }
106 else
107 {
108 if (_urlString.endsWith("/"))
109 _urlString=_urlString.substring(0,_urlString.length()-1);
110 }
111
112 }
113
114
115 FileResource(URL url, URLConnection connection, File file)
116 {
117 super(url,connection);
118 _file=file;
119 if (_file.isDirectory() && !_urlString.endsWith("/"))
120 _urlString=_urlString+"/";
121 }
122
123
124 @Override
125 public Resource addPath(String path)
126 throws IOException,MalformedURLException
127 {
128 URLResource r=null;
129 String url=null;
130
131 path = org.eclipse.jetty.util.URIUtil.canonicalPath(path);
132
133 if ("/".equals(path))
134 return this;
135 else if (!isDirectory())
136 {
137 r=(FileResource)super.addPath(path);
138 url=r._urlString;
139 }
140 else
141 {
142 if (path==null)
143 throw new MalformedURLException();
144
145
146 String rel=path;
147 if (path.startsWith("/"))
148 rel = path.substring(1);
149
150 url=URIUtil.addPaths(_urlString,URIUtil.encodePath(rel));
151 r=(URLResource)Resource.newResource(url);
152 }
153
154 String encoded=URIUtil.encodePath(path);
155 int expected=r.toString().length()-encoded.length();
156 int index = r._urlString.lastIndexOf(encoded, expected);
157
158 if (expected!=index && ((expected-1)!=index || path.endsWith("/") || !r.isDirectory()))
159 {
160 if (!(r instanceof BadResource))
161 {
162 ((FileResource)r)._alias=new URL(url);
163 ((FileResource)r)._aliasChecked=true;
164 }
165 }
166 return r;
167 }
168
169
170
171 @Override
172 public URL getAlias()
173 {
174 if (!_aliasChecked)
175 {
176 try
177 {
178 String abs=_file.getAbsolutePath();
179 String can=_file.getCanonicalPath();
180
181 if (abs.length()!=can.length() || !abs.equals(can))
182 _alias=Resource.toURL(new File(can));
183
184 _aliasChecked=true;
185
186 if (_alias!=null && LOG.isDebugEnabled())
187 {
188 LOG.debug("ALIAS abs="+abs);
189 LOG.debug("ALIAS can="+can);
190 }
191 }
192 catch(Exception e)
193 {
194 LOG.warn(Log.EXCEPTION,e);
195 return getURL();
196 }
197 }
198 return _alias;
199 }
200
201
202
203
204
205 @Override
206 public boolean exists()
207 {
208 return _file.exists();
209 }
210
211
212
213
214
215 @Override
216 public long lastModified()
217 {
218 return _file.lastModified();
219 }
220
221
222
223
224
225 @Override
226 public boolean isDirectory()
227 {
228 return _file.isDirectory();
229 }
230
231
232
233
234
235 @Override
236 public long length()
237 {
238 return _file.length();
239 }
240
241
242
243
244
245
246 @Override
247 public String getName()
248 {
249 return _file.getAbsolutePath();
250 }
251
252
253
254
255
256
257 @Override
258 public File getFile()
259 {
260 return _file;
261 }
262
263
264
265
266
267 @Override
268 public InputStream getInputStream() throws IOException
269 {
270 return new FileInputStream(_file);
271 }
272
273
274 @Override
275 public ReadableByteChannel getReadableByteChannel() throws IOException
276 {
277 return FileChannel.open(_file.toPath(),StandardOpenOption.READ);
278 }
279
280
281
282
283
284 @Override
285 public OutputStream getOutputStream()
286 throws java.io.IOException, SecurityException
287 {
288 return new FileOutputStream(_file);
289 }
290
291
292
293
294
295 @Override
296 public boolean delete()
297 throws SecurityException
298 {
299 return _file.delete();
300 }
301
302
303
304
305
306 @Override
307 public boolean renameTo( Resource dest)
308 throws SecurityException
309 {
310 if( dest instanceof FileResource)
311 return _file.renameTo( ((FileResource)dest)._file);
312 else
313 return false;
314 }
315
316
317
318
319
320 @Override
321 public String[] list()
322 {
323 String[] list =_file.list();
324 if (list==null)
325 return null;
326 for (int i=list.length;i-->0;)
327 {
328 if (new File(_file,list[i]).isDirectory() &&
329 !list[i].endsWith("/"))
330 list[i]+="/";
331 }
332 return list;
333 }
334
335
336
337
338
339
340
341 @Override
342 public String encode(String uri)
343 {
344 return uri;
345 }
346
347
348
349
350
351
352 @Override
353 public boolean equals( Object o)
354 {
355 if (this == o)
356 return true;
357
358 if (null == o || ! (o instanceof FileResource))
359 return false;
360
361 FileResource f=(FileResource)o;
362 return f._file == _file || (null != _file && _file.equals(f._file));
363 }
364
365
366
367
368
369 @Override
370 public int hashCode()
371 {
372 return null == _file ? super.hashCode() : _file.hashCode();
373 }
374
375
376 @Override
377 public void copyTo(File destination)
378 throws IOException
379 {
380 if (isDirectory())
381 {
382 IO.copyDir(getFile(),destination);
383 }
384 else
385 {
386 if (destination.exists())
387 throw new IllegalArgumentException(destination+" exists");
388 IO.copy(getFile(),destination);
389 }
390 }
391 }