001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2;
018
019import java.io.Closeable;
020import java.net.URL;
021import java.util.Arrays;
022import java.util.Collections;
023import java.util.List;
024
025import org.apache.commons.vfs2.operations.FileOperations;
026
027/**
028 * Represents a file, and is used to access the content and
029 * structure of the file.
030 * <p/>
031 * <p>Files are arranged in a hierarchy.  Each hierarchy forms a
032 * <i>file system</i>.  A file system represents things like a local OS
033 * file system, a windows share, an HTTP server, or the contents of a Zip file.
034 * <p/>
035 * <p>There are two types of files: <i>Folders</i>, which contain other files,
036 * and <i>normal files</i>, which contain data, or <i>content</i>.  A folder may
037 * not have any content, and a normal file cannot contain other files.
038 * <p/>
039 * <h4>File Naming</h4>
040 * <p/>
041 * <p>TODO - write this.
042 * <p/>
043 * <h4>Reading and Writing a File</h4>
044 * <p/>
045 * <p>Reading and writing a file, and all other operations on the file's
046 * <i>content</i>, is done using the {@link FileContent} object returned
047 * by {@link #getContent}.
048 * <p/>
049 * <h4>Creating and Deleting a File</h4>
050 * <p/>
051 * <p>A file is created using either {@link #createFolder}, {@link #createFile},
052 * or by writing to the file using one of the {@link FileContent} methods.
053 * <p/>
054 * <p>A file is deleted using {@link #delete}.  Recursive deletion can be
055 * done using {@link #delete(FileSelector)}.
056 * <p/>
057 * <h4>Finding Files</h4>
058 * <p/>
059 * <p>Other files in the <i>same</i> file system as this file can be found
060 * using:
061 * <ul>
062 * <li>{@link #findFiles} to find a set of matching descendants in in the same file system.
063 * <li>{@link #getChildren} and {@link #getChild} to find the children of this file.
064 * <li>{@link #getParent} to find the folder containing this file.
065 * <li>{@link #getFileSystem} to find another file in the same file system.
066 * <li>{@link #resolveFile} to find another file relative to this file.
067 * </ul>
068 * <p/>
069 * <p>To find files in another file system, use a {@link FileSystemManager}.
070 * <h4>Iterating Files</h4>
071 *<p>You can iterate over a FileObject using the Java "foreach" statement, which provides all descendants of a File
072 * Object.</p>
073 *
074 * <h4>Sorting Files</h4>
075 *<p>Files may be sorted using {@link Arrays#sort(Object[])} and {@link Collections#sort(List)}.</p>
076 *
077 * @see FileSystemManager
078 * @see FileContent
079 * @see FileName
080 */
081public interface FileObject extends Comparable<FileObject>, Iterable<FileObject>, Closeable
082{
083    /**
084     * Queries the file if it is possible to rename it to newfile.
085     *
086     * @param newfile the new file(-name)
087     * @return true it this is the case
088     */
089    boolean canRenameTo(FileObject newfile);
090
091    /**
092     * Closes this file, and its content.  This method is a hint to the
093     * implementation that it can release any resources associated with
094     * the file.
095     * <p>
096     * The file object can continue to be used after this method is called.
097     * </p>
098     *
099     * @throws FileSystemException On error closing the file.
100     * @see FileContent#close
101     */
102    @Override
103    void close() throws FileSystemException;
104
105    /**
106     * Copies another file, and all its descendants, to this file.
107     * <p>
108     * If this file does not exist, it is created.  Its parent folder is also
109     * created, if necessary.  If this file does exist, it is deleted first.
110     * </p>
111     * <p>
112     * This method is not transactional.  If it fails and throws an
113     * exception, this file will potentially only be partially copied.
114     * </p>
115     *
116     * @param srcFile  The source file to copy.
117     * @param selector The selector to use to select which files to copy.
118     * @throws FileSystemException If this file is read-only, or if the source file does not exist,
119     *                             or on error copying the file.
120     */
121    void copyFrom(FileObject srcFile, FileSelector selector)
122        throws FileSystemException;
123
124    /**
125     * Creates this file, if it does not exist.  Also creates any ancestor
126     * folders which do not exist.  This method does nothing if the file
127     * already exists and is a file.
128     *
129     * @throws FileSystemException If the file already exists with the wrong type, or the parent
130     *                             folder is read-only, or on error creating this file or one of
131     *                             its ancestors.
132     */
133    void createFile() throws FileSystemException;
134
135    /**
136     * Creates this folder, if it does not exist.  Also creates any ancestor
137     * folders which do not exist.  This method does nothing if the folder
138     * already exists.
139     *
140     * @throws FileSystemException If the folder already exists with the wrong type, or the parent
141     *                             folder is read-only, or on error creating this folder or one of
142     *                             its ancestors.
143     */
144    void createFolder() throws FileSystemException;
145
146    /**
147     * Deletes this file.  Does nothing if this file does not exist of if it is a
148     * folder that has children.  Does not delete any descendants of this file,
149     * use {@link #delete(FileSelector)} or {@link #deleteAll()} for that.
150     *
151     * @return true if this object has been deleted
152     * @throws FileSystemException If this file is a non-empty folder, or if this file is read-only,
153     *                             or on error deleteing this file.
154     */
155    boolean delete() throws FileSystemException;
156
157    /**
158     * Deletes all descendants of this file that match a selector.  Does
159     * nothing if this file does not exist.
160     *
161     * <p>This method is not transactional.  If it fails and throws an
162     * exception, this file will potentially only be partially deleted.
163     * </p>
164     *
165     * @param selector The selector to use to select which files to delete.
166     * @return the number of deleted objects
167     * @throws FileSystemException If this file or one of its descendants is read-only, or on error
168     *                             deleting this file or one of its descendants.
169     */
170    int delete(FileSelector selector) throws FileSystemException;
171
172    /**
173     * Deletes this file and all children.
174     *
175     * @return the number of deleted files.
176     * @throws FileSystemException if an error occurs.
177     * @see #delete(FileSelector)
178     * @see Selectors#SELECT_ALL
179     */
180    int deleteAll() throws FileSystemException;
181
182    /**
183     * Determines if this file exists.
184     *
185     * @return {@code true} if this file exists, {@code false} if not.
186     * @throws FileSystemException On error determining if this file exists.
187     */
188    boolean exists() throws FileSystemException;
189
190    /**
191     * Finds the set of matching descendants of this file, in depthwise order.
192     *
193     * @param selector The selector to use to select matching files.
194     * @return The matching files.  The files are returned in depthwise order
195     *         (that is, a child appears in the list before its parent).
196     * @throws FileSystemException if an error occurs.
197     */
198    FileObject[] findFiles(FileSelector selector) throws FileSystemException;
199
200    /**
201      * Finds the set of matching descendants of this file.
202      *
203      * @param selector  the selector used to determine if the file should be selected
204      * @param depthwise controls the ordering in the list. e.g. deepest first
205      * @param selected  container for selected files. list needs not to be empty.
206      * @throws FileSystemException if an error occurs.
207      */
208    void findFiles(FileSelector selector, boolean depthwise, List<FileObject> selected) throws FileSystemException;
209
210    /**
211     * Returns a child of this file.  Note that this method returns {@code null}
212     * when the child does not exist.  This differs from
213     * {@link #resolveFile(String, NameScope)} which never returns null.
214     *
215     * @param name The name of the child.
216     * @return The child, or null if there is no such child.
217     * @throws FileSystemException If this file does not exist, or is not a folder, or on error
218     *                             determining this file's children.
219     */
220    FileObject getChild(String name) throws FileSystemException;
221
222    /**
223     * Lists the children of this file.
224     *
225     * @return An array containing the children of this file.  The array is
226     *         unordered.  If the file does not have any children, a zero-length
227     *         array is returned.  This method never returns null.
228     * @throws FileSystemException If this file does not exist, or is not a folder, or on error
229     *                             listing this file's children.
230     */
231    FileObject[] getChildren() throws FileSystemException;
232
233    /**
234     * Returns this file's content.  The {@link FileContent} returned by this
235     * method can be used to read and write the content of the file.
236     *
237     * <p>This method can be called if the file does not exist, and
238     * the returned {@link FileContent} can be used to create the file
239     * by writing its content.
240     * </p>
241     *
242     * @return This file's content.
243     * @throws FileSystemException On error getting this file's content.
244     */
245    FileContent getContent() throws FileSystemException;
246
247    /**
248     * @return FileOperations interface that provides access to the operations API.
249     * @throws FileSystemException if an error occurs.
250     */
251    FileOperations getFileOperations() throws FileSystemException;
252
253    /**
254     * Returns the file system that contains this file.
255     *
256     * @return The file system.
257     */
258    FileSystem getFileSystem();
259
260    /**
261     * Returns the name of this file.
262     *
263     * @return the FileName.
264     */
265    FileName getName();
266
267    /**
268     * Returns the folder that contains this file.
269     *
270     * @return The folder that contains this file.  Returns null if this file is
271     *         the root of a file system.
272     * @throws FileSystemException On error finding the file's parent.
273     */
274    FileObject getParent() throws FileSystemException;
275
276    /**
277     * Returns the receiver as a URI String for public display, like, without a
278     * password.
279     * 
280     * @return A URI String without a password, never {@code null}.
281     */
282    String getPublicURIString();
283
284    /**
285     * Returns this file's type.
286     *
287     * @return One of the {@link FileType} constants.  Never returns null.
288     * @throws FileSystemException On error determining the file's type.
289     */
290    FileType getType() throws FileSystemException;
291
292    /**
293     * Returns a URL representing this file.
294     *
295     * @return the URL for the file.
296     * @throws FileSystemException if an error occurs.
297     */
298    URL getURL() throws FileSystemException;
299
300    /**
301     * Checks if the fileObject is attached.
302     *
303     * @return true if the FileObject is attached.
304     */
305    boolean isAttached();
306
307    /**
308     * Checks if someone reads/write to this file.
309     *
310     * @return true if the file content is open.
311     */
312    boolean isContentOpen();
313
314    /**
315     * Determines if this file is executable.
316     *
317     * @return {@code true} if this file is executable, {@code false} if not.
318     * @throws FileSystemException On error determining if this file exists.
319     */
320    boolean isExecutable() throws FileSystemException;
321
322    /**
323     * Checks if this file is a regular file.
324     *
325     * @return true if this file is a regular file.
326     * @throws FileSystemException if an error occurs.
327     * @see #getType()
328     * @see FileType#FILE
329     * @since 2.1
330     */
331    boolean isFile() throws FileSystemException;
332
333    /**
334     * Checks if this file is a folder.
335     *
336     * @return true if this file is a folder.
337     * @throws FileSystemException if an error occurs.
338     * @see #getType()
339     * @see FileType#FOLDER
340     * @since 2.1
341     */
342    boolean isFolder() throws FileSystemException;
343
344    /**
345     * Determines if this file is hidden.
346     *
347     * @return {@code true} if this file is hidden, {@code false} if not.
348     * @throws FileSystemException On error determining if this file exists.
349     */
350    boolean isHidden() throws FileSystemException;
351
352    /**
353     * Determines if this file can be read.
354     *
355     * @return {@code true} if this file is readable, {@code false} if not.
356     * @throws FileSystemException On error determining if this file exists.
357     */
358    boolean isReadable() throws FileSystemException;
359
360    /**
361     * Determines if this file can be written to.
362     *
363     * @return {@code true} if this file is writeable, {@code false} if not.
364     * @throws FileSystemException On error determining if this file exists.
365     */
366    boolean isWriteable() throws FileSystemException;
367
368    /**
369     * Move this file.
370     *
371     * <p>
372     * If the destFile exists, it is deleted first.
373     * </p>
374     *
375     * @param destFile the New filename.
376     * @throws FileSystemException If this file is read-only, or if the source file does not exist,
377     *                             or on error copying the file.
378     */
379    void moveTo(FileObject destFile)
380        throws FileSystemException;
381
382    /**
383     * This will prepare the fileObject to get resynchronized with the underlying file system if required.
384     *
385     * @throws FileSystemException if an error occurs.
386     */
387    void refresh() throws FileSystemException;
388
389    /**
390     * Finds a file, relative to this file.  Equivalent to calling
391     * {@code resolveFile( path, NameScope.FILE_SYSTEM )}.
392     *
393     * @param path The path of the file to locate.  Can either be a relative
394     *             path or an absolute path.
395     * @return The file.
396     * @throws FileSystemException On error parsing the path, or on error finding the file.
397     */
398    FileObject resolveFile(String path) throws FileSystemException;
399
400    /**
401     * Finds a file relative to this file.
402     *
403     * Refer to {@link NameScope} for a description of how names are resolved in the different scopes.
404     *
405     * @param name The name to resolve.
406     * @param scope the NameScope for the file.
407     * @return The file.
408     * @throws FileSystemException On error parsing the path, or on error finding the file.
409     */
410    FileObject resolveFile(String name, NameScope scope)
411        throws FileSystemException;
412
413    /**
414     * Sets the owner's (or everybody's) write permission.
415     *
416     * @param executable
417     *            True to allow read access, false to disallow.
418     * @param ownerOnly
419     *            If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
420     * @return true if the operation succeeded.
421     * @throws FileSystemException
422     *             On error determining if this file exists.
423     * @since 2.1
424     */
425    boolean setExecutable(boolean executable, boolean ownerOnly) throws FileSystemException;
426
427
428    /**
429     * Sets the owner's (or everybody's) read permission.
430     *
431     * @param readable
432     *            True to allow read access, false to disallow
433     * @param ownerOnly
434     *            If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
435     * @return true if the operation succeeded
436     * @throws FileSystemException
437     *             On error determining if this file exists.
438     * @since 2.1
439     */
440    boolean setReadable(boolean readable, boolean ownerOnly) throws FileSystemException;
441
442    /**
443     * Sets the owner's (or everybody's) write permission.
444     *
445     * @param writable
446     *            True to allow read access, false to disallow
447     * @param ownerOnly
448     *            If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
449     * @return true if the operation succeeded
450     * @throws FileSystemException
451     *             On error determining if this file exists.
452     * @since 2.1
453     */
454    boolean setWritable(boolean writable, boolean ownerOnly) throws FileSystemException;
455}