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.FileOutputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  
26  import org.apache.commons.vfs2.FileObject;
27  import org.apache.commons.vfs2.FileSystemException;
28  import org.apache.commons.vfs2.FileType;
29  import org.apache.commons.vfs2.RandomAccessContent;
30  import org.apache.commons.vfs2.provider.AbstractFileName;
31  import org.apache.commons.vfs2.provider.AbstractFileObject;
32  import org.apache.commons.vfs2.provider.UriParser;
33  import org.apache.commons.vfs2.util.FileObjectUtils;
34  import org.apache.commons.vfs2.util.RandomAccessMode;
35  
36  /**
37   * A file object implementation which uses direct file access.
38   */
39  public class LocalFile extends AbstractFileObject<LocalFileSystem>
40  {
41      private final String rootFile;
42  
43      private File file;
44  
45      /**
46       * Creates a non-root file.
47       *
48       * @param fileSystem the file system this file belongs to.
49       * @param rootFile the root file for the file system.
50       * @param name the file name on this file system.
51       * @throws FileSystemException if an error occurs.
52       */
53      protected LocalFile(final LocalFileSystem fileSystem,
54                          final String rootFile,
55                          final AbstractFileName name) throws FileSystemException
56      {
57          super(name, fileSystem);
58          this.rootFile = rootFile;
59      }
60  
61      /**
62       * Returns the local file that this file object represents.
63       *
64       * @return the local file that this file object represents.
65       */
66      protected File getLocalFile()
67      {
68          return file;
69      }
70  
71      /**
72       * Attaches this file object to its file resource.
73       */
74      @Override
75      protected void doAttach() throws Exception
76      {
77          if (file == null)
78          {
79              // Remove the "file:///"
80              // LocalFileName localFileName = (LocalFileName) getName();
81              final String fileName = rootFile + getName().getPathDecoded();
82              // fileName = UriParser.decode(fileName);
83              file = new File(fileName);
84          }
85      }
86  
87      /**
88       * Returns the file's type.
89       */
90      @Override
91      protected FileType doGetType() throws Exception
92      {
93          // JDK BUG: 6192331
94          // if (!file.exists())
95          if (!file.exists() && file.length() < 1)
96          {
97              return FileType.IMAGINARY;
98          }
99  
100         if (file.isDirectory())
101         {
102             return FileType.FOLDER;
103         }
104 
105         // In doubt, treat an existing file as file
106         // if (file.isFile())
107         // {
108             return FileType.FILE;
109         // }
110 
111         // throw new FileSystemException("vfs.provider.local/get-type.error", file);
112     }
113 
114     /**
115      * Returns the children of the file.
116      */
117     @Override
118     protected String[] doListChildren() throws Exception
119     {
120         return UriParser.encode(file.list());
121     }
122 
123     /**
124      * Deletes this file, and all children.
125      */
126     @Override
127     protected void doDelete() throws Exception
128     {
129         if (!file.delete())
130         {
131             throw new FileSystemException("vfs.provider.local/delete-file.error", file);
132         }
133     }
134 
135     /**
136      * rename this file
137      */
138     @Override
139     protected void doRename(final FileObject newFile) throws Exception
140     {
141         final LocalFile newLocalFile = (LocalFile) FileObjectUtils.getAbstractFileObject(newFile);
142 
143         if (!file.renameTo(newLocalFile.getLocalFile()))
144         {
145             throw new FileSystemException("vfs.provider.local/rename-file.error",
146                 file.toString(), newFile.toString());
147         }
148     }
149 
150     /**
151      * Creates this folder.
152      */
153     @Override
154     protected void doCreateFolder() throws Exception
155     {
156         if (!file.mkdirs())
157         {
158             throw new FileSystemException("vfs.provider.local/create-folder.error", file);
159         }
160     }
161 
162     /**
163      * Determines if this file can be written to.
164      */
165     @Override
166     protected boolean doIsWriteable() throws FileSystemException
167     {
168         return file.canWrite();
169     }
170 
171     @Override
172     protected boolean doSetWritable(final boolean writable, final boolean ownerOnly) throws Exception
173     {
174         return file.setWritable(writable, ownerOnly);
175     }
176 
177     /**
178      * Determines if this file is hidden.
179      */
180     @Override
181     protected boolean doIsExecutable()
182     {
183         return file.canExecute();
184     }
185 
186     /**
187      * Determines if this file is hidden.
188      */
189     @Override
190     protected boolean doIsHidden()
191     {
192         return file.isHidden();
193     }
194 
195     /**
196      * Determines if this file can be read.
197      */
198     @Override
199     protected boolean doIsReadable() throws FileSystemException
200     {
201         return file.canRead();
202     }
203 
204     @Override
205     protected boolean doSetReadable(final boolean readable, final boolean ownerOnly) throws Exception
206     {
207         return file.setReadable(readable, ownerOnly);
208     }
209 
210     @Override
211     protected boolean doSetExecutable(final boolean executable, final boolean ownerOnly) throws Exception
212     {
213         return file.setExecutable(executable, ownerOnly);
214     }
215 
216     /**
217      * Gets the last modified time of this file.
218      */
219     @Override
220     protected long doGetLastModifiedTime() throws FileSystemException
221     {
222         return file.lastModified();
223     }
224 
225     /**
226      * Sets the last modified time of this file.
227      * @since 2.0
228      */
229     @Override
230     protected boolean doSetLastModifiedTime(final long modtime) throws FileSystemException
231     {
232         return file.setLastModified(modtime);
233     }
234 
235     /**
236      * Creates an input stream to read the content from.
237      */
238     @Override
239     protected InputStream doGetInputStream() throws Exception
240     {
241         return new FileInputStream(file);
242     }
243 
244     /**
245      * Creates an output stream to write the file content to.
246      */
247     @Override
248     protected OutputStream doGetOutputStream(final boolean bAppend)
249         throws Exception
250     {
251         return new FileOutputStream(file.getPath(), bAppend);
252     }
253 
254     /**
255      * Returns the size of the file content (in bytes).
256      */
257     @Override
258     protected long doGetContentSize() throws Exception
259     {
260         return file.length();
261     }
262 
263     @Override
264     protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception
265     {
266         return new LocalFileRandomAccessContent(file, mode);
267     }
268 
269     @Override
270     protected boolean doIsSameFile(final FileObject destFile) throws FileSystemException
271     {
272         if (!FileObjectUtils.isInstanceOf(destFile, LocalFile.class))
273         {
274             return false;
275         }
276 
277         final LocalFile destLocalFile = (LocalFile) FileObjectUtils.getAbstractFileObject(destFile);
278         if (!exists() || !destLocalFile.exists())
279         {
280             return false;
281         }
282 
283         try
284         {
285             return file.getCanonicalPath().equals(destLocalFile.file.getCanonicalPath());
286         }
287         catch (final IOException e)
288         {
289             throw new FileSystemException(e);
290         }
291     }
292 
293     /**
294      * Returns the URI of the file.
295      * @return The URI of the file.
296      */
297     @Override
298     public String toString()
299     {
300         try
301         {
302             // VFS-325: URI may contain percent-encoded values as part of filename, so decode
303             // those characters before returning
304             return UriParser.decode(getName().getURI());
305         }
306         catch (final FileSystemException e)
307         {
308             return getName().getURI();
309         }
310     }
311 }