/*
 * Copyright 2002-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.vfs;

import java.net.URL;
import java.util.List;

/**
 * Represents a file, and is used to access the content and
 * structure of the file.
 * <p/>
 * <p>Files are arranged in a hierarchy.  Each hierachy forms a
 * <i>file system</i>.  A file system represents things like a local OS
 * file system, a windows share, an HTTP server, or the contents of a Zip file.
 * <p/>
 * <p>There are two types of files: <i>Folders</i>, which contain other files,
 * and <i>normal files</i>, which contain data, or <i>content</i>.  A folder may
 * not have any content, and a normal file cannot contain other files.
 * <p/>
 * <h4>File Naming</h4>
 * <p/>
 * <p>TODO - write this.
 * <p/>
 * <h4>Reading and Writing a File</h4>
 * <p/>
 * <p>Reading and writing a file, and all other operations on the file's
 * <i>content</i>, is done using the {@link FileContent} object returned
 * by {@link #getContent}.
 * <p/>
 * <h4>Creating and Deleting a File</h4>
 * <p/>
 * <p>A file is created using either {@link #createFolder}, {@link #createFile},
 * or by writing to the file using one of the {@link FileContent} methods.
 * <p/>
 * <p>A file is deleted using {@link #delete}.  Recursive deletion can be
 * done using {@link #delete(FileSelector)}.
 * <p/>
 * <h4>Finding Files</h4>
 * <p/>
 * <p>Other files in the <i>same</i> file system as this file can be found
 * using:
 * <ul>
 * <li>{@link #resolveFile} to find another file relative to this file.
 * <li>{@link #getChildren} and {@link #getChild} to find the children of this file.
 * <li>{@link #getParent} to find the folder containing this file.
 * <li>{@link #getFileSystem} to find another file in the same file system.
 * </ul>
 * <p/>
 * <p>To find files in another file system, use a {@link FileSystemManager}.
 *
 * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
 * @version $Revision$ $Date$
 * @see FileSystemManager
 * @see FileContent
 * @see FileName
 */
public interface FileObject
{
    /**
     * Returns the name of this file.
     */
    public FileName getName();

    /**
     * Returns a URL representing this file.
     */
    public URL getURL() throws FileSystemException;

    /**
     * Determines if this file exists.
     *
     * @return <code>true</code> if this file exists, <code>false</code> if not.
     * @throws FileSystemException On error determining if this file exists.
     */
    public boolean exists() throws FileSystemException;

    /**
     * Determines if this file is hidden.
     *
     * @return <code>true</code> if this file is hidden, <code>false</code> if not.
     * @throws FileSystemException On error determining if this file exists.
     */
    public boolean isHidden() throws FileSystemException;

    /**
     * Determines if this file can be read.
     *
     * @return <code>true</code> if this file is readable, <code>false</code> if not.
     * @throws FileSystemException On error determining if this file exists.
     */
    public boolean isReadable() throws FileSystemException;

    /**
     * Determines if this file can be written to.
     *
     * @return <code>true</code> if this file is writeable, <code>false</code> if not.
     * @throws FileSystemException On error determining if this file exists.
     */
    public boolean isWriteable() throws FileSystemException;

    /**
     * Returns this file's type.
     *
     * @return One of the {@link FileType} constants.  Never returns null.
     * @throws FileSystemException On error determining the file's type.
     */
    public FileType getType() throws FileSystemException;

    /**
     * Returns the folder that contains this file.
     *
     * @return The folder that contains this file.  Returns null if this file is
     *         the root of a file system.
     * @throws FileSystemException On error finding the file's parent.
     */
    public FileObject getParent() throws FileSystemException;

    /**
     * Returns the file system that contains this file.
     *
     * @return The file system.
     */
    public FileSystem getFileSystem();

    /**
     * Lists the children of this file.
     *
     * @return An array containing the children of this file.  The array is
     *         unordered.  If the file does not have any children, a zero-length
     *         array is returned.  This method never returns null.
     * @throws FileSystemException If this file does not exist, or is not a folder, or on error
     *                             listing this file's children.
     */
    public FileObject[] getChildren() throws FileSystemException;

    /**
     * Returns a child of this file.  Note that this method returns <code>null</code>
     * when the child does not exist.  This differs from
     * {@link #resolveFile( String, NameScope)} which never returns null.
     *
     * @param name The name of the child.
     * @return The child, or null if there is no such child.
     * @throws FileSystemException If this file does not exist, or is not a folder, or on error
     *                             determining this file's children.
     */
    public FileObject getChild(String name) throws FileSystemException;

    /**
     * Finds a file, relative to this file.  Refer to {@link NameScope}
     * for a description of how names are resolved in the different scopes.
     *
     * @param name The name to resolve.
     * @return The file.
     * @throws FileSystemException On error parsing the path, or on error finding the file.
     */
    public FileObject resolveFile(String name, NameScope scope)
        throws FileSystemException;

    /**
     * Finds a file, relative to this file.  Equivalent to calling
     * <code>resolveFile( path, NameScope.FILE_SYSTEM )</code>.
     *
     * @param path The path of the file to locate.  Can either be a relative
     *             path or an absolute path.
     * @return The file.
     * @throws FileSystemException On error parsing the path, or on error finding the file.
     */
    public FileObject resolveFile(String path) throws FileSystemException;

    /**
     * Finds the set of matching descendents of this file, in depthwise order.
     *
     * @param selector The selector to use to select matching files.
     * @return The matching files.  The files are returned in depthwise order
     *         (that is, a child appears in the list before its parent).
     */
    public FileObject[] findFiles(FileSelector selector) throws FileSystemException;

    /**
         * Finds the set of matching descendents of this file.
         *
         * @param selector  the selector used to determine if the file should be selected
         * @param depthwise controls the ordering in the list. e.g. deepest first
         * @param selected  container for selected files. list needs not to be empty.
         * @throws FileSystemException
         */
    public void findFiles(FileSelector selector,
                   boolean depthwise,
                   List selected) throws FileSystemException;

    /**
     * Deletes this file.  Does nothing if this file does not exist of if it is a
     * folder that has children.  Does not delete any descendents of this file,
     * use {@link #delete(FileSelector)} for that.
     *
     * @return true if this object has been deleted
     * @throws FileSystemException If this file is a non-empty folder, or if this file is read-only,
     *                             or on error deleteing this file.
     */
    public boolean delete() throws FileSystemException;

    /**
     * Deletes all descendents of this file that match a selector.  Does
     * nothing if this file does not exist.
     * <p/>
     * <p>This method is not transactional.  If it fails and throws an
     * exception, this file will potentially only be partially deleted.
     *
     * @param selector The selector to use to select which files to delete.
     * @return the number of deleted objects
     * @throws FileSystemException If this file or one of its descendents is read-only, or on error
     *                             deleting this file or one of its descendents.
     */
    public int delete(FileSelector selector) throws FileSystemException;

    /**
     * Creates this folder, if it does not exist.  Also creates any ancestor
     * folders which do not exist.  This method does nothing if the folder
     * already exists.
     *
     * @throws FileSystemException If the folder already exists with the wrong type, or the parent
     *                             folder is read-only, or on error creating this folder or one of
     *                             its ancestors.
     */
    public void createFolder() throws FileSystemException;

    /**
     * Creates this file, if it does not exist.  Also creates any ancestor
     * folders which do not exist.  This method does nothing if the file
     * already exists and is a file.
     *
     * @throws FileSystemException If the file already exists with the wrong type, or the parent
     *                             folder is read-only, or on error creating this file or one of
     *                             its ancestors.
     */
    public void createFile() throws FileSystemException;

    /**
     * Copies another file, and all its descendents, to this file.
     * <p/>
     * If this file does not exist, it is created.  Its parent folder is also
     * created, if necessary.  If this file does exist, it is deleted first.
     * <p/>
     * <p>This method is not transactional.  If it fails and throws an
     * exception, this file will potentially only be partially copied.
     *
     * @param srcFile  The source file to copy.
     * @param selector The selector to use to select which files to copy.
     * @throws FileSystemException If this file is read-only, or if the source file does not exist,
     *                             or on error copying the file.
     */
    public void copyFrom(FileObject srcFile, FileSelector selector)
        throws FileSystemException;

    /**
     * Move this file.
     * <p>If the destFile exists, it is deleted first</b> 
     *
     * @param destFile the New filename.
     * @throws FileSystemException If this file is read-only, or if the source file does not exist,
     *                             or on error copying the file.
     */
    public void moveTo(FileObject destFile)
        throws FileSystemException;

    /**
     * Queries the file if it is possible to rename it to newfile.
     *
     * @param newfile the new file(-name)
     * @return true it this is the case
     */
    public boolean canRenameTo(FileObject newfile);

    /**
     * Returns this file's content.  The {@link FileContent} returned by this
     * method can be used to read and write the content of the file.
     * <p/>
     * <p>This method can be called if the file does not exist, and
     * the returned {@link FileContent} can be used to create the file
     * by writing its content.
     *
     * @return This file's content.
     * @throws FileSystemException On error getting this file's content.
     */
    public FileContent getContent() throws FileSystemException;

    /**
     * Closes this file, and its content.  This method is a hint to the
     * implementation that it can release any resources asociated with
     * the file.
     * <p/>
     * <p>The file object can continue to be used after this method is called.
     *
     * @throws FileSystemException On error closing the file.
     * @see FileContent#close
     */
    public void close() throws FileSystemException;
}
