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.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
19 package org.eclipse.jetty.util.resource;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.MalformedURLException;
26 import java.net.URISyntaxException;
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;
42 import org.eclipse.jetty.util.StringUtil;
43 import org.eclipse.jetty.util.log.Log;
44 import org.eclipse.jetty.util.log.Logger;
47 * Java NIO Path equivalent of FileResource.
49 public class PathResource extends Resource
51 private static final Logger LOG = Log.getLogger(PathResource.class);
53 private final Path path;
54 private final URI uri;
55 private LinkOption linkOptions[] = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
57 public PathResource(File file)
62 public PathResource(Path path)
65 assertValidPath(path);
66 this.uri = this.path.toUri();
69 public PathResource(URI uri) throws IOException
71 if (!uri.isAbsolute())
73 throw new IllegalArgumentException("not an absolute uri");
76 if (!uri.getScheme().equalsIgnoreCase("file"))
78 throw new IllegalArgumentException("not file: scheme");
84 path = new File(uri).toPath();
86 catch (InvalidPathException e)
90 catch (IllegalArgumentException e)
97 throw new IOException("Unable to build Path from: " + uri,e);
101 this.uri = path.toUri();
104 public PathResource(URL url) throws IOException, URISyntaxException
110 public Resource addPath(String apath) throws IOException, MalformedURLException
112 return new PathResource(this.path.getFileSystem().getPath(path.toString(), apath));
115 private void assertValidPath(Path path)
117 String str = path.toString();
118 int idx = StringUtil.indexOfControlChars(str);
121 throw new InvalidPathException(str, "Invalid Character at index " + idx);
128 // not applicable for FileSytem / Path
132 public boolean delete() throws SecurityException
136 return Files.deleteIfExists(path);
138 catch (IOException e)
146 public boolean equals(Object obj)
156 if (getClass() != obj.getClass())
160 PathResource other = (PathResource)obj;
163 if (other.path != null)
168 else if (!path.equals(other.path))
176 public boolean exists()
178 return Files.exists(path,linkOptions);
182 public File getFile() throws IOException
184 return path.toFile();
187 public boolean getFollowLinks()
189 return (linkOptions != null) && (linkOptions.length > 0) && (linkOptions[0] == LinkOption.NOFOLLOW_LINKS);
193 public InputStream getInputStream() throws IOException
195 return Files.newInputStream(path,StandardOpenOption.READ);
199 public String getName()
201 return path.toAbsolutePath().toString();
205 public ReadableByteChannel getReadableByteChannel() throws IOException
207 return FileChannel.open(path,StandardOpenOption.READ);
221 return path.toUri().toURL();
223 catch (MalformedURLException e)
230 public int hashCode()
232 final int prime = 31;
234 result = (prime * result) + ((path == null)?0:path.hashCode());
239 public boolean isContainedIn(Resource r) throws MalformedURLException
241 // not applicable for FileSystem / path
246 public boolean isDirectory()
248 return Files.isDirectory(path,linkOptions);
252 public long lastModified()
256 FileTime ft = Files.getLastModifiedTime(path,linkOptions);
257 return ft.toMillis();
259 catch (IOException e)
271 return Files.size(path);
273 catch (IOException e)
275 // in case of error, use File.length logic of 0L
281 public URI getAlias()
283 if (Files.isSymbolicLink(path))
287 return path.toRealPath().toUri();
289 catch (IOException e)
302 public String[] list()
304 try (DirectoryStream<Path> dir = Files.newDirectoryStream(path))
306 List<String> entries = new ArrayList<>();
307 for (Path entry : dir)
309 String name = entry.getFileName().toString();
311 if (Files.isDirectory(entry))
318 int size = entries.size();
319 return entries.toArray(new String[size]);
321 catch (DirectoryIteratorException e)
325 catch (IOException e)
333 public boolean renameTo(Resource dest) throws SecurityException
335 if (dest instanceof PathResource)
337 PathResource destRes = (PathResource)dest;
340 Path result = Files.move(path,destRes.path,StandardCopyOption.ATOMIC_MOVE);
341 return Files.exists(result,linkOptions);
343 catch (IOException e)
355 public void setFollowLinks(boolean followLinks)
359 linkOptions = new LinkOption[0];
363 linkOptions = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };