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
031    /**
032     * Constructs a new instance for subclasses.
033     */
034    public AbstractOriginatingFileProvider() {
035    }
036
037    /**
038     * Creates a {@link FileSystem}. If the returned FileSystem implements {@link VfsComponent}, it will be initialized.
039     *
040     * @param rootFileName The name of the root file of the file system to create.
041     * @param fileSystemOptions The FileSystem options.
042     * @return The FileSystem, never null.
043     * @throws FileSystemException if an error occurs.
044     */
045    protected abstract FileSystem doCreateFileSystem(FileName rootFileName, FileSystemOptions fileSystemOptions) throws FileSystemException;
046
047    /**
048     * Locates a file from its parsed URI.
049     *
050     * @param fileName The file name.
051     * @param fileSystemOptions FileSystem options.
052     * @return A FileObject associated with the file, never null.
053     * @throws FileSystemException if an error occurs.
054     */
055    protected FileObject findFile(final FileName fileName, final FileSystemOptions fileSystemOptions)
056            throws FileSystemException {
057        // Check in the cache for the file system
058        final FileName rootName = getContext().getFileSystemManager().resolveName(fileName, FileName.ROOT_PATH);
059        // Locate the file
060        return getFileSystem(rootName, fileSystemOptions).resolveFile(fileName);
061    }
062
063    /**
064     * Locates a file object, by absolute URI.
065     *
066     * @param baseFileObject The base file object.
067     * @param uri The URI of the file to locate
068     * @param fileSystemOptions The FileSystem options.
069     * @return The located FileObject
070     * @throws FileSystemException if an error occurs.
071     */
072    @Override
073    public FileObject findFile(final FileObject baseFileObject, final String uri, final FileSystemOptions fileSystemOptions)
074            throws FileSystemException {
075        // Parse the URI
076        final FileName name;
077        try {
078            name = parseUri(baseFileObject != null ? baseFileObject.getName() : null, uri);
079        } catch (final FileSystemException exc) {
080            throw new FileSystemException("vfs.provider/invalid-absolute-uri.error", uri, exc);
081        }
082        // Locate the file
083        return findFile(name, fileSystemOptions);
084    }
085
086    /**
087     * Returns the FileSystem associated with the specified root.
088     *
089     * @param rootFileName The root path.
090     * @param fileSystemOptions The FileSystem options.
091     * @return The FileSystem, never null.
092     * @throws FileSystemException if an error occurs.
093     * @since 2.0
094     */
095    protected synchronized FileSystem getFileSystem(final FileName rootFileName, final FileSystemOptions fileSystemOptions)
096            throws FileSystemException {
097        FileSystem fs = findFileSystem(rootFileName, fileSystemOptions);
098        if (fs == null) {
099            // Need to create the file system, and cache it
100            fs = doCreateFileSystem(rootFileName, fileSystemOptions);
101            addFileSystem(rootFileName, fs);
102        }
103        return fs;
104    }
105}