View Javadoc
1   /*
2    * Copyright (C) 2010-2014 Hamburg Sud and the contributors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.vfs2.provider.local;
17  
18  import java.io.File;
19  import java.io.FileInputStream;
20  import java.io.FileOutputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  
25  import org.apache.commons.vfs2.FileObject;
26  import org.apache.commons.vfs2.FileSystemException;
27  import org.apache.commons.vfs2.FileType;
28  import org.apache.commons.vfs2.RandomAccessContent;
29  import org.apache.commons.vfs2.provider.AbstractFileName;
30  import org.apache.commons.vfs2.provider.AbstractFileObject;
31  import org.apache.commons.vfs2.provider.UriParser;
32  import org.apache.commons.vfs2.util.FileObjectUtils;
33  import org.apache.commons.vfs2.util.RandomAccessMode;
34  
35  /** Copies VFS-2.0's {@link LocalFile} class and fixes a bug in the usage of {@link File#mkdirs()}. Unfortunately the LocalFile
36   * class has private members which cannot be properly initialized and accessed by inheriting form it, so we had to copy and adapt
37   * the source of the LocalFile class.
38   * @author Volker Bergmann */
39  public class AludraLocalFile extends AbstractFileObject implements FileObject {
40      private final String rootFile;
41  
42      private File file;
43  
44      /** Creates a non-root file. */
45      protected AludraLocalFile(final LocalFileSystem fileSystem, final String rootFile, final AbstractFileName name)
46              throws FileSystemException {
47          super(name, fileSystem);
48          this.rootFile = rootFile;
49      }
50  
51      /** Returns the local file that this file object represents. */
52      protected File getLocalFile() {
53          return file;
54      }
55  
56      /** Attaches this file object to its file resource. */
57      @Override
58      protected void doAttach() throws Exception {
59          if (file == null) {
60              // Remove the "file:///"
61              // LocalFileName localFileName = (LocalFileName) getName();
62              String fileName = rootFile + getName().getPathDecoded();
63              // fileName = UriParser.decode(fileName);
64              file = new File(fileName);
65          }
66      }
67  
68      /** Returns the file's type. */
69      @Override
70      protected FileType doGetType() throws Exception {
71          // JDK BUG: 6192331
72          // if (!file.exists())
73          if (!file.exists() && file.length() < 1) {
74              return FileType.IMAGINARY;
75          }
76  
77          if (file.isDirectory()) {
78              return FileType.FOLDER;
79          }
80  
81          // In doubt, treat an existing file as file
82          // if (file.isFile())
83          // {
84          return FileType.FILE;
85          // }
86  
87          // throw new FileSystemException("vfs.provider.local/get-type.error", file);
88      }
89  
90      /** Returns the children of the file. */
91      @Override
92      protected String[] doListChildren() throws Exception {
93          return UriParser.encode(file.list());
94      }
95  
96      /** Deletes this file, and all children. */
97      @Override
98      protected void doDelete() throws Exception {
99          if (!file.delete()) {
100             throw new FileSystemException("vfs.provider.local/delete-file.error", file);
101         }
102     }
103 
104     /** rename this file */
105     @Override
106     protected void doRename(final FileObject newfile) throws Exception {
107         AludraLocalFile newLocalFile = (AludraLocalFile) FileObjectUtils.getAbstractFileObject(newfile);
108 
109         if (!file.renameTo(newLocalFile.getLocalFile())) {
110             throw new FileSystemException("vfs.provider.local/rename-file.error", new String[] { file.toString(),
111                     newfile.toString() });
112         }
113     }
114 
115     /** Creates this folder. */
116     @Override
117     protected void doCreateFolder() throws Exception {
118         if (!file.mkdirs()) {
119             // Modification to the original VFS class: Instead of immediately throwing an exception,
120             // it is checked if the target folder really does not exist
121             if (!file.exists()) {
122                 throw new FileSystemException("vfs.provider.local/create-folder.error", file);
123             }
124         }
125     }
126 
127     /** Determines if this file can be written to. */
128     @Override
129     protected boolean doIsWriteable() throws FileSystemException {
130         return file.canWrite();
131     }
132 
133     /** Determines if this file is hidden. */
134     @Override
135     protected boolean doIsHidden() {
136         return file.isHidden();
137     }
138 
139     /** Determines if this file can be read. */
140     @Override
141     protected boolean doIsReadable() throws FileSystemException {
142         return file.canRead();
143     }
144 
145     /** Gets the last modified time of this file. */
146     @Override
147     protected long doGetLastModifiedTime() throws FileSystemException {
148         return file.lastModified();
149     }
150 
151     /** Sets the last modified time of this file.
152      * @since 2.0 */
153     @Override
154     protected boolean doSetLastModifiedTime(final long modtime) throws FileSystemException {
155         return file.setLastModified(modtime);
156     }
157 
158     /** Creates an input stream to read the content from. */
159     @Override
160     protected InputStream doGetInputStream() throws Exception {
161         return new FileInputStream(file);
162     }
163 
164     /** Creates an output stream to write the file content to. */
165     @Override
166     protected OutputStream doGetOutputStream(boolean bAppend) throws Exception {
167         return new FileOutputStream(file.getPath(), bAppend);
168     }
169 
170     /** Returns the size of the file content (in bytes). */
171     @Override
172     protected long doGetContentSize() throws Exception {
173         return file.length();
174     }
175 
176     @Override
177     protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
178         return new LocalFileRandomAccessContent(file, mode);
179     }
180 
181     @Override
182     protected boolean doIsSameFile(FileObject destFile) throws FileSystemException {
183         if (!FileObjectUtils.isInstanceOf(destFile, AludraLocalFile.class)) {
184             return false;
185         }
186 
187         AludraLocalFile destLocalFile = (AludraLocalFile) FileObjectUtils.getAbstractFileObject(destFile);
188         if (!exists() || !destLocalFile.exists()) {
189             return false;
190         }
191 
192         try {
193             return file.getCanonicalPath().equals(destLocalFile.file.getCanonicalPath());
194         }
195         catch (IOException e) {
196             throw new FileSystemException(e);
197         }
198 
199     }
200 }