<!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You 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.
-->
<document>
    <properties>
        <title>Using The API</title>
        <author email="adammurdoch@apache.org">Adam Murdoch</author>
    </properties>

    <body>
        <section name="Using The API">
            <p>
                The
                <a href="apidocs/org/apache/commons/vfs/FileSystemManager.html">FileSystemManager</a>
                interface provides access to Commons VFS.  Using this interface
                you can locate files and create file systems.
                There are a
                <a href="#Configuring Commons VFS">number of ways</a>
                to obtain a
                <code>FileSystemManager</code> instance.
                The simplest is to use the static
                <a href="apidocs/org/apache/commons/vfs/VFS.html#getManager()">VFS.getManager()</a>
                method, which returns the default Commons VFS implementation.
            </p>

            <p>
                Once you have a
                <code>FileSystemManager</code>, you can use its
                <code>resolveFile()</code> methods to locate a file by name.
                For example:
            </p>

            <source><![CDATA[
FileSystemManager fsManager = VFS.getManager();
FileObject jarFile = fsManager.resolveFile( "jar:lib/aJarFile.jar" );
                ]]></source>

            <p>
                Each file is represented by a
                <a href="apidocs/org/apache/commons/vfs/FileObject.html">FileObject</a>
                instance.  Using this interface you can create or delete the
                file, list its children, read or write its content, and so on.
                For example:
            </p>

            <source><![CDATA[
// Locate the Jar file
FileSystemManager fsManager = VFS.getManager();
FileObject jarFile = fsManager.resolveFile( "jar:lib/aJarFile.jar" );

// List the children of the Jar file
FileObject[] children = jarFile.getChildren();
System.out.println( "Children of " + jarFile.getName().getURI() );
for ( int i = 0; i < children.length; i++ )
{
    System.out.println( children[ i ].getName().getBaseName() );
}
                ]]></source>

			<p>
				In some cases you might want to explicitely free resources allocated by the filesystem.
				You can do this by calling
				<a href="apidocs/org/apache/commons/vfs/FileSystemManager.html#closeFileSystem">VFS.getManager().closeFileSystem(fs)</a>.
				If you use VFS as singleton (as described above) you should take care that this will close the filesystem for
				all threads.<br />
				In other words, do not close any globally used filesystem like the one for local files.  
			</p>

			<p>
                See the
                <a href="apidocs/org/apache/commons/vfs/FileObject.html">FileObject</a>
                Javadocs for more detail.
            </p>

            <subsection name="Cache">
                <p>
                    Commons VFS uses a <a href="apidocs/org/apache/commons/vfs/cache/SoftRefFilesCache.html">SoftRefFilesCache</a> to release memory if a file is no longer used by the application.
                </p>
                <p>
                    This cache will return the same instance for a file as long as it is "strongly reachable" e.g. you
                    hold a reference to this object. If the FileObject is no longer reachable, and the jvm needs some memory,
                    it will be released.
                </p>
				<p>
					There is also a internal cache of each file object avoid the need to access the network layer. Now its possible
					to configure this behviour through the use of <a href="apidocs/org/apache/commons/vfs/CacheStrategy.html">CacheStrategy</a>.
					<br />
					Do this on the DefaultFileSystemManager. For example:
					<code>
						((DefaultFileSystemManager) VFS.getManager()).setCacheStrategy(CacheStrategy.ON_CALL)
					</code>
				</p>
			</subsection>

			<subsection name="User Authentication">
				<p>
					You can put the credentials into the url, but the drawback here is, that it is
                    easily possible to get access to the password.
				</p>
				<p>
					To solve you can use the
                    <a href="apidocs/org/apache/commons/vfs/UserAuthenticator.html">UserAuthenticator</a>
				</p>
				<p>
					For example:
					<code>
						StaticUserAuthenticator auth = new StaticUserAuthenticator("username", "password", null);
						FileSystemOptions opts = new FileSystemOptions();
						DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, auth);

						FileObject fo = VFS.getManager().resolveFile("smb://host/anyshare/dir", opts);
					</code>
				</p>
				<p>
					Internally the UserAuthenticator uses char arrays which will be zeroed before it is
                    freed for garbage collection.Unhappily none of the current libraries use char
                    arrays and so VFS has to create a string. Thus, the main advantage
					of this solution - security - is lost, but hey, thats not VFS fault ;-)
				</p>
				<p>
					VFS calls <code>UserAuthenticator.requestAuthentication</code> each time it
                    requires credentials, it depends on the filesystem implementation how often
                    this might be. For example, with FTP this is on every connection, in SMB/JCIFS
					this is for EVERY OBJECT. It is up to you how long you will cache credentials
                    of if you would like to provide a "save credentials" checkbox.
				</p>
			</subsection>

			<subsection name="Examples">
                <p>
                    For an example of using the API, take a look at the classes
                    in the
                    <a href="apidocs/org/apache/commons/vfs/example/package-summary.html">example</a>
                    package.
                </p>
            </subsection>

        </section>

        <section name="Configuring Commons VFS">
            <p>
                Commons VFS is represented using the
                <a href="apidocs/org/apache/commons/vfs/FileSystemManager.html">FileSystemManager</a>
                interface.  There are a number of ways to create and configure a
                <code>FileSystemManager</code> instance.
            </p>
            <p>
                The simplest method is to use the static
                <a href="apidocs/org/apache/commons/vfs/VFS.html#getManager()">VFS.getManager()</a>
                method, which returns the default Commons VFS implementation.
            </p>
            <p>
                This method will also automatically scan the classpath for a /META-INF/vfs-providers.xml file
                (also in jar files).
                If such a file is found Commons VFS uses it in <u>addition</u> to the default providers.xml.
                This allows you to start using a new filesystem by simply drop its implementation into the classpath.
                The configuration file format is described below.<br />
                <b>Notice:</b> Currently it is not allowed to override a already configured filesystem. Commons VFS throws
                an exception if there is already a filesystem for a scheme.
            </p>

            <p>
                To configure Commons VFS programatically, you can create an
                instance of
                <a href="apidocs/org/apache/commons/vfs/impl/DefaultFileSystemManager.html">DefaultFileSystemManager</a>
                and configure it manually.  The default constructor
                <code>DefaultFileSystemManager</code> creates a manager that
                is completely empty.  You will have to add file providers to it
                to make it do anything useful.
            </p>
            <p>
                Here are the steps for using
                <code>DefaultFileSystemManager</code>:
            </p>
            <ol>
                <li>Create a new instance.</li>
                <li>
                    Set the logger for the manager and all its components,
                    using
                    <code>setLogger()</code>.  This step is
                    optional, and if skipped, the manager will use the default
                    logger provided by Commons Logging.
                </li>
                <li>
                    Add file providers, using
                    <code>addProvider()</code>.
                </li>
                <li>
                    Set the default provider, using
                    <code>setDefaultProvider()</code>.  This step is optional.
                    See
                    <a href="apidocs/org/apache/commons/vfs/provider/url/UrlFileProvider.html">UrlFileProvider</a>
                    for a useful default provider.
                </li>
                <li>
                    Set the file replicator, using
                    <code>setReplicator()</code>.
                    This step is optional.
                </li>
                <li>
                    Set the temporary file store, using
                    <code>setTemporaryFileStore()</code>.
                    This step is optional.
                </li>
                <li>
                    Set the base file using
                    <code>setBaseFile()</code>.  The
                    base file is used to resolve relative URI passed to
                    <code>resolveFile()</code>.  This step is optional.
                </li>
                <li>
                    Initialise the manager using
                    <code>init()</code>.
                </li>
            </ol>
            <p>
                You should make sure that you call
                <code>close()</code> on the
                manager when you are finished with it.
            </p>

            <p>
                The third method for configuring Commons VFS, is to configure
                it from a file.  Create an instance of
                <a href="apidocs/org/apache/commons/vfs/impl/StandardFileSystemManager.html">StandardFileSystemManager</a>,
                and use its
                <code>setConfiguration()</code> method to set the
                location of the configuration file to use.  The configuration
                file format is described below.
            </p>

            <p>
                <code>StandardFileSystemManager</code> is a subclass of
                <code>DefaultFileSystemManager</code>, so you can also
                configure it programmatically, as described above.
            </p>
            <subsection name="Configuration File">
                <p>
                    The configuration file is an XML file.  The root element
                    of the configuration file should be a
                    <code>&lt;providers&gt;</code> element.
                    The
                    <code>&lt;providers&gt;</code> element may contain:
                </p>
                <ul>
                    <li>Zero or more
                        <code>&lt;provider&gt;</code> elements.
                    </li>
                    <li>An optional
                        <code>&lt;default-provider&gt;</code> element.
                    </li>
                    <li>Zero or more
                        <code>&lt;extension-map&gt;</code> elements.
                    </li>
                    <li>Zero or more
                        <code>&lt;mime-type-map&gt;</code> elements.
                    </li>
                </ul>

                <p>
                    <b>
                        <code>&lt;provider&gt;</code>
                    </b>
                </p>
                <p>
                    The
                    <code>&lt;provider&gt;</code> element defines a file
                    provider.   It must have a
                    <code>class-name</code> attribute,
                    which specifies the fully-qualified name of the provider
                    class.  The provider class must be public, and must have a
                    public constructor with an FileSystemManager argument which
                    allows the systems to pass the used filesystem manager.
                </p>
                <p>
                    The
                    <code>&lt;provider&gt;</code> element may contain
                    zero or more
                    <code>&lt;scheme&gt;</code> elements,
                    and zero or more
                    <code>&lt;if-available&gt;</code> elements.
                </p>
                <p>
                    The
                    <code>&lt;scheme&gt;</code> element defines a URI scheme
                    that the provider will handle.  It must have a
                    <code>name</code> attribute, which specifies the URI scheme.
                </p>
                <p>
                    The
                    <code>&lt;if-available&gt;</code> elements is used to
                    disable the provider if certain classes are not present in
                    the class-path.
                    It must have a
                    <code>class-name</code> attribute, which
                    specifies the fully qualified name of a class to test for.
                    If the class cannot be found, the provider is not registered.
                </p>

                <p>
                    <b>
                        <code>&lt;default-provider&gt;</code>
                    </b>
                </p>
                <p>
                    The
                    <code>&lt;default-provider&gt;</code> element defines
                    the default provider.  It has the same format as the
                    <code>&lt;provider&gt;</code> element.
                </p>

                <p>
                    <b>
                        <code>&lt;extension-map&gt;</code>
                    </b>
                </p>
                <p>
                    The
                    <code>&lt;extension-map&gt;</code> element defines
                    a mapping from a file's extension to the provider that
                    should handle files with that extension.
                    It must have an
                    <code>extension</code> attribute, which
                    specifies the extension, and a
                    <code>scheme</code> attribute,
                    which specifies the URI scheme of the provider.
                </p>

                <p>
                    <b>
                        <code>&lt;mime-type-map&gt;</code>
                    </b>
                </p>
                <p>
                    The
                    <code>&lt;mime-type-map&gt;</code> element defines
                    a mapping from a file's MIME type to the provider that
                    should handle files with that MIME type.
                    It must have an
                    <code>mime-type</code> attribute, which
                    specifies the MIME type, and a
                    <code>scheme</code> attribute,
                    which specified the URI scheme of the provider.
                </p>

                <p>
                    Below is an example configuration file:
                </p>
                <source><![CDATA[
<providers>
    <provider class-name="org.apache.commons.vfs.provider.zip.ZipFileProvider">
        <scheme name="zip"/>
    </provider>
    <extension-map extension="zip" scheme="zip"/>
    <mime-type-map mime-type="application/zip" scheme="zip"/>
    <provider class-name="org.apache.commons.vfs.provider.ftp.FtpFileProvider">
        <scheme name="ftp"/>
        <if-available class-name="org.apache.commons.net.ftp.FTPFile"/>
    </provider>
    <default-provider class-name="org.apache.commons.vfs.provider.url.UrlFileProvider"/>
</providers>
                    ]]></source>
            </subsection>
        </section>
    </body>
</document>