View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.provider.local;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.nio.file.Files;
25  import java.nio.file.StandardOpenOption;
26  
27  import org.apache.commons.vfs2.FileObject;
28  import org.apache.commons.vfs2.FileSystemException;
29  import org.apache.commons.vfs2.FileType;
30  import org.apache.commons.vfs2.RandomAccessContent;
31  import org.apache.commons.vfs2.provider.AbstractFileName;
32  import org.apache.commons.vfs2.provider.AbstractFileObject;
33  import org.apache.commons.vfs2.provider.UriParser;
34  import org.apache.commons.vfs2.util.FileObjectUtils;
35  import org.apache.commons.vfs2.util.RandomAccessMode;
36  
37  /**
38   * A file object implementation which uses direct file access.
39   */
40  public class LocalFile extends AbstractFileObject<LocalFileSystem> {
41  
42      private final String rootFile;
43  
44      private File file;
45  
46      /**
47       * Creates a non-root file.
48       *
49       * @param fileSystem the file system this file belongs to.
50       * @param rootFile the root file for the file system.
51       * @param name the file name on this file system.
52       */
53      protected LocalFile(final LocalFileSystem fileSystem, final String rootFile, final AbstractFileName name) {
54          super(name, fileSystem);
55          this.rootFile = rootFile;
56      }
57  
58      /**
59       * Attaches this file object to its file resource.
60       */
61      @Override
62      protected void doAttach() throws Exception {
63          if (file == null) {
64              // Remove the "file:///"
65              // LocalFileName localFileName = (LocalFileName) getName();
66              final String fileName = rootFile + getName().getPathDecoded();
67              // fileName = UriParser.decode(fileName);
68              file = new File(fileName);
69          }
70      }
71  
72      /**
73       * Creates this folder.
74       */
75      @Override
76      protected void doCreateFolder() throws Exception {
77          if (!file.mkdirs()) {
78              throw new FileSystemException("vfs.provider.local/create-folder.error", file);
79          }
80      }
81  
82      /**
83       * Deletes this file, and all children.
84       */
85      @Override
86      protected void doDelete() throws Exception {
87          if (!file.delete()) {
88              throw new FileSystemException("vfs.provider.local/delete-file.error", file);
89          }
90      }
91  
92      /**
93       * Returns the size of the file content (in bytes).
94       */
95      @Override
96      protected long doGetContentSize() throws Exception {
97          return file.length();
98      }
99  
100     /**
101      * Creates an input stream to read the content from.
102      */
103     @Override
104     protected InputStream doGetInputStream(final int bufferSize) throws Exception {
105         return new FileInputStream(file);
106     }
107 
108     /**
109      * Gets the last modified time of this file.
110      */
111     @Override
112     protected long doGetLastModifiedTime() throws FileSystemException {
113         // Workaround OpenJDK 8 and 9 bug JDK-8177809
114         // https://bugs.openjdk.java.net/browse/JDK-8177809
115         try {
116             return Files.getLastModifiedTime(file.toPath()).toMillis();
117         } catch (final IOException e) {
118             throw new FileSystemException(file.toString(), e);
119         }
120     }
121 
122     /**
123      * Creates an output stream to write the file content to.
124      */
125     @Override
126     protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception {
127         return Files.newOutputStream(file.toPath(), bAppend ? StandardOpenOption.APPEND : StandardOpenOption.CREATE);
128     }
129 
130     @Override
131     protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
132         return new LocalFileRandomAccessContent(file, mode);
133     }
134 
135     /**
136      * Returns the file's type.
137      */
138     @Override
139     protected FileType doGetType() {
140         if (!file.exists()) {
141             return FileType.IMAGINARY;
142         }
143         if (file.isDirectory()) {
144             return FileType.FOLDER;
145         }
146         return FileType.FILE;
147     }
148 
149     /**
150      * Determines if this file is hidden.
151      */
152     @Override
153     protected boolean doIsExecutable() {
154         return file.canExecute();
155     }
156 
157     /**
158      * Determines if this file is hidden.
159      */
160     @Override
161     protected boolean doIsHidden() {
162         return file.isHidden();
163     }
164 
165     /**
166      * Determines if this file can be read.
167      */
168     @Override
169     protected boolean doIsReadable() throws FileSystemException {
170         return file.canRead();
171     }
172 
173     @Override
174     protected boolean doIsSameFile(final FileObject destFile) throws FileSystemException {
175         if (!FileObjectUtils.isInstanceOf(destFile, LocalFile.class)) {
176             return false;
177         }
178 
179         final LocalFile./../../org/apache/commons/vfs2/provider/local/LocalFile.html#LocalFile">LocalFile destLocalFile = (LocalFile) FileObjectUtils.getAbstractFileObject(destFile);
180         if (!exists() || !destLocalFile.exists()) {
181             return false;
182         }
183 
184         try {
185             return file.getCanonicalPath().equals(destLocalFile.file.getCanonicalPath());
186         } catch (final IOException e) {
187             throw new FileSystemException(e);
188         }
189     }
190 
191     /**
192      * Determines if this file is a symbolic link.
193      * 
194      * @since 2.4
195      */
196     @Override
197     protected boolean doIsSymbolicLink() throws FileSystemException {
198         return Files.isSymbolicLink(file.toPath());
199     }
200 
201     /**
202      * Determines if this file can be written to.
203      */
204     @Override
205     protected boolean doIsWriteable() throws FileSystemException {
206         return file.canWrite();
207     }
208 
209     /**
210      * Returns the children of the file.
211      */
212     @Override
213     protected String[] doListChildren() throws Exception {
214         return UriParser.encode(file.list());
215     }
216 
217     /**
218      * rename this file
219      */
220     @Override
221     protected void doRename(final FileObject newFile) throws Exception {
222         final LocalFile../../../org/apache/commons/vfs2/provider/local/LocalFile.html#LocalFile">LocalFile newLocalFile = (LocalFile) FileObjectUtils.getAbstractFileObject(newFile);
223 
224         if (!file.renameTo(newLocalFile.getLocalFile())) {
225             throw new FileSystemException("vfs.provider.local/rename-file.error", file.toString(), newFile.toString());
226         }
227     }
228 
229     @Override
230     protected boolean doSetExecutable(final boolean executable, final boolean ownerOnly) throws Exception {
231         return file.setExecutable(executable, ownerOnly);
232     }
233 
234     /**
235      * Sets the last modified time of this file.
236      *
237      * @since 2.0
238      */
239     @Override
240     protected boolean doSetLastModifiedTime(final long modtime) throws FileSystemException {
241         return file.setLastModified(modtime);
242     }
243 
244     @Override
245     protected boolean doSetReadable(final boolean readable, final boolean ownerOnly) throws Exception {
246         return file.setReadable(readable, ownerOnly);
247     }
248 
249     @Override
250     protected boolean doSetWritable(final boolean writable, final boolean ownerOnly) throws Exception {
251         return file.setWritable(writable, ownerOnly);
252     }
253 
254     /**
255      * Gets the local file that this file object represents.
256      *
257      * @return the local file that this file object represents.
258      */
259     protected File getLocalFile() {
260         return file;
261     }
262 
263     /**
264      * Returns the URI of the file.
265      *
266      * @return The URI of the file.
267      */
268     @Override
269     public String toString() {
270         try {
271             // VFS-325: URI may contain percent-encoded values as part of file name, so decode
272             // those characters before returning
273             return UriParser.decode(getName().getURI());
274         } catch (final FileSystemException e) {
275             return getName().getURI();
276         }
277     }
278 }