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.provider;
018
019import org.apache.commons.vfs2.FileName;
020import org.apache.commons.vfs2.FileObject;
021import org.apache.commons.vfs2.FileSystem;
022import org.apache.commons.vfs2.FileSystemException;
023import org.apache.commons.vfs2.FileSystemOptions;
024
025/**
026 * A {@link FileProvider} that handles physical files, such as the files in a local fs, or on an FTP server. An
027 * originating file system cannot be layered on top of another file system.
028 */
029public abstract class AbstractOriginatingFileProvider extends AbstractFileProvider {
030    public AbstractOriginatingFileProvider() {
031        super();
032    }
033
034    /**
035     * Locates a file object, by absolute URI.
036     *
037     * @param baseFile The base file object.
038     * @param uri The URI of the file to locate
039     * @param fileSystemOptions The FileSystem options.
040     * @return The located FileObject
041     * @throws FileSystemException if an error occurs.
042     */
043    @Override
044    public FileObject findFile(final FileObject baseFile, final String uri, final FileSystemOptions fileSystemOptions)
045            throws FileSystemException {
046        // Parse the URI
047        final FileName name;
048        try {
049            name = parseUri(baseFile != null ? baseFile.getName() : null, uri);
050        } catch (final FileSystemException exc) {
051            throw new FileSystemException("vfs.provider/invalid-absolute-uri.error", uri, exc);
052        }
053
054        // Locate the file
055        return findFile(name, fileSystemOptions);
056    }
057
058    /**
059     * Locates a file from its parsed URI.
060     *
061     * @param name The file name.
062     * @param fileSystemOptions FileSystem options.
063     * @return A FileObject associated with the file.
064     * @throws FileSystemException if an error occurs.
065     */
066    protected FileObject findFile(final FileName name, final FileSystemOptions fileSystemOptions)
067            throws FileSystemException {
068        // Check in the cache for the file system
069        final FileName rootName = getContext().getFileSystemManager().resolveName(name, FileName.ROOT_PATH);
070
071        final FileSystem fs = getFileSystem(rootName, fileSystemOptions);
072
073        // Locate the file
074        // return fs.resolveFile(name.getPath());
075        return fs.resolveFile(name);
076    }
077
078    /**
079     * Returns the FileSystem associated with the specified root.
080     *
081     * @param rootName The root path.
082     * @param fileSystemOptions The FileSystem options.
083     * @return The FileSystem.
084     * @throws FileSystemException if an error occurs.
085     * @since 2.0
086     */
087    protected synchronized FileSystem getFileSystem(final FileName rootName, final FileSystemOptions fileSystemOptions)
088            throws FileSystemException {
089        FileSystem fs = findFileSystem(rootName, fileSystemOptions);
090        if (fs == null) {
091            // Need to create the file system, and cache it
092            fs = doCreateFileSystem(rootName, fileSystemOptions);
093            addFileSystem(rootName, fs);
094        }
095        return fs;
096    }
097
098    /**
099     * Creates a {@link FileSystem}. If the returned FileSystem implements {@link VfsComponent}, it will be initialised.
100     *
101     * @param rootName The name of the root file of the file system to create.
102     * @param fileSystemOptions The FileSystem options.
103     * @return The FileSystem.
104     * @throws FileSystemException if an error occurs.
105     */
106    protected abstract FileSystem doCreateFileSystem(final FileName rootName, final FileSystemOptions fileSystemOptions)
107            throws FileSystemException;
108}