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