]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/util/resource/PathResource.java
updating jetty to jetty-9.2.16.v2016040
[gigi.git] / lib / jetty / org / eclipse / jetty / util / resource / PathResource.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.util.resource;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.MalformedURLException;
25 import java.net.URI;
26 import java.net.URISyntaxException;
27 import java.net.URL;
28 import java.nio.channels.FileChannel;
29 import java.nio.channels.ReadableByteChannel;
30 import java.nio.file.DirectoryIteratorException;
31 import java.nio.file.DirectoryStream;
32 import java.nio.file.Files;
33 import java.nio.file.InvalidPathException;
34 import java.nio.file.LinkOption;
35 import java.nio.file.Path;
36 import java.nio.file.StandardCopyOption;
37 import java.nio.file.StandardOpenOption;
38 import java.nio.file.attribute.FileTime;
39 import java.util.ArrayList;
40 import java.util.List;
41
42 import org.eclipse.jetty.util.StringUtil;
43 import org.eclipse.jetty.util.log.Log;
44 import org.eclipse.jetty.util.log.Logger;
45
46 /**
47  * Java NIO Path equivalent of FileResource.
48  */
49 public class PathResource extends Resource
50 {
51     private static final Logger LOG = Log.getLogger(PathResource.class);
52
53     private final Path path;
54     private final URI uri;
55     private LinkOption linkOptions[] = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
56
57     public PathResource(File file)
58     {
59         this(file.toPath());
60     }
61
62     public PathResource(Path path)
63     {
64         this.path = path;
65         assertValidPath(path);
66         this.uri = this.path.toUri();
67     }
68
69     public PathResource(URI uri) throws IOException
70     {
71         if (!uri.isAbsolute())
72         {
73             throw new IllegalArgumentException("not an absolute uri");
74         }
75
76         if (!uri.getScheme().equalsIgnoreCase("file"))
77         {
78             throw new IllegalArgumentException("not file: scheme");
79         }
80
81         Path path;
82         try
83         {
84             path = new File(uri).toPath();
85         }
86         catch (InvalidPathException e)
87         {
88             throw e;
89         }
90         catch (IllegalArgumentException e)
91         {
92             throw e;
93         }
94         catch (Exception e)
95         {
96             LOG.ignore(e);
97             throw new IOException("Unable to build Path from: " + uri,e);
98         }
99
100         this.path = path;
101         this.uri = path.toUri();
102     }
103
104     public PathResource(URL url) throws IOException, URISyntaxException
105     {
106         this(url.toURI());
107     }
108
109     @Override
110     public Resource addPath(String apath) throws IOException, MalformedURLException
111     {
112         return new PathResource(this.path.getFileSystem().getPath(path.toString(), apath));
113     }
114
115     private void assertValidPath(Path path)
116     {
117         String str = path.toString();
118         int idx = StringUtil.indexOfControlChars(str);
119         if(idx >= 0)
120         {
121             throw new InvalidPathException(str, "Invalid Character at index " + idx);
122         }
123     }
124
125     @Override
126     public void close()
127     {
128         // not applicable for FileSytem / Path
129     }
130
131     @Override
132     public boolean delete() throws SecurityException
133     {
134         try
135         {
136             return Files.deleteIfExists(path);
137         }
138         catch (IOException e)
139         {
140             LOG.ignore(e);
141             return false;
142         }
143     }
144
145     @Override
146     public boolean equals(Object obj)
147     {
148         if (this == obj)
149         {
150             return true;
151         }
152         if (obj == null)
153         {
154             return false;
155         }
156         if (getClass() != obj.getClass())
157         {
158             return false;
159         }
160         PathResource other = (PathResource)obj;
161         if (path == null)
162         {
163             if (other.path != null)
164             {
165                 return false;
166             }
167         }
168         else if (!path.equals(other.path))
169         {
170             return false;
171         }
172         return true;
173     }
174
175     @Override
176     public boolean exists()
177     {
178         return Files.exists(path,linkOptions);
179     }
180
181     @Override
182     public File getFile() throws IOException
183     {
184         return path.toFile();
185     }
186
187     public boolean getFollowLinks()
188     {
189         return (linkOptions != null) && (linkOptions.length > 0) && (linkOptions[0] == LinkOption.NOFOLLOW_LINKS);
190     }
191
192     @Override
193     public InputStream getInputStream() throws IOException
194     {
195         return Files.newInputStream(path,StandardOpenOption.READ);
196     }
197
198     @Override
199     public String getName()
200     {
201         return path.toAbsolutePath().toString();
202     }
203
204     @Override
205     public ReadableByteChannel getReadableByteChannel() throws IOException
206     {
207         return FileChannel.open(path,StandardOpenOption.READ);
208     }
209
210     @Override
211     public URI getURI()
212     {
213         return this.uri;
214     }
215
216     @Override
217     public URL getURL()
218     {
219         try
220         {
221             return path.toUri().toURL();
222         }
223         catch (MalformedURLException e)
224         {
225             return null;
226         }
227     }
228
229     @Override
230     public int hashCode()
231     {
232         final int prime = 31;
233         int result = 1;
234         result = (prime * result) + ((path == null)?0:path.hashCode());
235         return result;
236     }
237
238     @Override
239     public boolean isContainedIn(Resource r) throws MalformedURLException
240     {
241         // not applicable for FileSystem / path
242         return false;
243     }
244
245     @Override
246     public boolean isDirectory()
247     {
248         return Files.isDirectory(path,linkOptions);
249     }
250
251     @Override
252     public long lastModified()
253     {
254         try
255         {
256             FileTime ft = Files.getLastModifiedTime(path,linkOptions);
257             return ft.toMillis();
258         }
259         catch (IOException e)
260         {
261             LOG.ignore(e);
262             return 0;
263         }
264     }
265
266     @Override
267     public long length()
268     {
269         try
270         {
271             return Files.size(path);
272         }
273         catch (IOException e)
274         {
275             // in case of error, use File.length logic of 0L
276             return 0L;
277         }
278     }
279
280     @Override
281     public URI getAlias()
282     {
283         if (Files.isSymbolicLink(path))
284         {
285             try
286             {
287                 return path.toRealPath().toUri();
288             }
289             catch (IOException e)
290             {
291                 LOG.debug(e);
292                 return null;
293             }
294         }
295         else
296         {
297             return null;
298         }
299     }
300
301     @Override
302     public String[] list()
303     {
304         try (DirectoryStream<Path> dir = Files.newDirectoryStream(path))
305         {
306             List<String> entries = new ArrayList<>();
307             for (Path entry : dir)
308             {
309                 String name = entry.getFileName().toString();
310
311                 if (Files.isDirectory(entry))
312                 {
313                     name += "/";
314                 }
315
316                 entries.add(name);
317             }
318             int size = entries.size();
319             return entries.toArray(new String[size]);
320         }
321         catch (DirectoryIteratorException e)
322         {
323             LOG.debug(e);
324         }
325         catch (IOException e)
326         {
327             LOG.debug(e);
328         }
329         return null;
330     }
331
332     @Override
333     public boolean renameTo(Resource dest) throws SecurityException
334     {
335         if (dest instanceof PathResource)
336         {
337             PathResource destRes = (PathResource)dest;
338             try
339             {
340                 Path result = Files.move(path,destRes.path,StandardCopyOption.ATOMIC_MOVE);
341                 return Files.exists(result,linkOptions);
342             }
343             catch (IOException e)
344             {
345                 LOG.ignore(e);
346                 return false;
347             }
348         }
349         else
350         {
351             return false;
352         }
353     }
354
355     public void setFollowLinks(boolean followLinks)
356     {
357         if (followLinks)
358         {
359             linkOptions = new LinkOption[0];
360         }
361         else
362         {
363             linkOptions = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
364         }
365     }
366 }