Package org.apache.commons.vfs.impl

Source Code of org.apache.commons.vfs.impl.VirtualFileSystem

/*
* 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.impl;

import org.apache.commons.vfs.Capability;
import org.apache.commons.vfs.FileName;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemOptions;
import org.apache.commons.vfs.FileType;
import org.apache.commons.vfs.NameScope;
import org.apache.commons.vfs.provider.AbstractFileSystem;
import org.apache.commons.vfs.provider.DelegateFileObject;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* A logical file system, made up of set of junctions, or links, to files from
* other file systems.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
* @todo Handle nested junctions.
*/
public class VirtualFileSystem
    extends AbstractFileSystem
{
    private final Map junctions = new HashMap();

    public VirtualFileSystem(final FileName rootName, final FileSystemOptions fileSystemOptions)
    {
        super(rootName, null, fileSystemOptions);
    }

    /**
     * Adds the capabilities of this file system.
     */
    protected void addCapabilities(final Collection caps)
    {
        // TODO - this isn't really true
        caps.add(Capability.ATTRIBUTES);
        caps.add(Capability.CREATE);
        caps.add(Capability.DELETE);
        caps.add(Capability.GET_TYPE);
        caps.add(Capability.JUNCTIONS);
        caps.add(Capability.GET_LAST_MODIFIED);
        caps.add(Capability.SET_LAST_MODIFIED_FILE);
        caps.add(Capability.SET_LAST_MODIFIED_FOLDER);
        caps.add(Capability.LIST_CHILDREN);
        caps.add(Capability.READ_CONTENT);
        caps.add(Capability.SIGNING);
        caps.add(Capability.WRITE_CONTENT);
        caps.add(Capability.APPEND_CONTENT);
    }

    /**
     * Creates a file object.  This method is called only if the requested
     * file is not cached.
     */
    protected FileObject createFile(final FileName name)
        throws Exception
    {
        // Find the file that the name points to
        final FileName junctionPoint = getJunctionForFile(name);
        final FileObject file;
        if (junctionPoint != null)
        {
            // Resolve the real file
            final FileObject junctionFile = (FileObject) junctions.get(junctionPoint);
            final String relName = junctionPoint.getRelativeName(name);
            file = junctionFile.resolveFile(relName, NameScope.DESCENDENT_OR_SELF);
        }
        else
        {
            file = null;
        }

        // Return a wrapper around the file
        return new DelegateFileObject(name, this, file);
    }

    /**
     * Adds a junction to this file system.
     */
    public void addJunction(final String junctionPoint,
                            final FileObject targetFile)
        throws FileSystemException
    {
        final FileName junctionName = getFileSystemManager().resolveName(getRootName(), junctionPoint);

        // Check for nested junction - these are not supported yet
        if (getJunctionForFile(junctionName) != null)
        {
            throw new FileSystemException("vfs.impl/nested-junction.error", junctionName);
        }

        try
        {
            // Add to junction table
            junctions.put(junctionName, targetFile);

            // Attach to file
            final DelegateFileObject junctionFile = (DelegateFileObject) getFileFromCache(junctionName);
            if (junctionFile != null)
            {
                junctionFile.setFile(targetFile);
            }

            // Create ancestors of junction point
            FileName childName = junctionName;
            boolean done = false;
            for (FileName parentName = childName.getParent();
                 !done && parentName != null;
                 childName = parentName, parentName = parentName.getParent())
            {
                DelegateFileObject file = (DelegateFileObject) getFileFromCache(parentName);
                if (file == null)
                {
                    file = new DelegateFileObject(parentName, this, null);
                    putFileToCache(file);
                }
                else
                {
                    done = file.exists();
                }
               
                // As this is the parent of our junction it has to be a folder
                file.attachChild(childName, FileType.FOLDER);
            }

            // TODO - attach all cached children of the junction point to their real file
        }
        catch (final Exception e)
        {
            throw new FileSystemException("vfs.impl/create-junction.error", junctionName, e);
        }
    }

    /**
     * Removes a junction from this file system.
     */
    public void removeJunction(final String junctionPoint)
        throws FileSystemException
    {
        final FileName junctionName = getFileSystemManager().resolveName(getRootName(), junctionPoint);
        junctions.remove(junctionName);

        // TODO - remove from parents of junction point
        // TODO - detach all cached children of the junction point from their real file
    }

    /**
     * Locates the junction point for the junction containing the given file.
     */
    private FileName getJunctionForFile(final FileName name)
    {
        if (junctions.containsKey(name))
        {
            // The name points to the junction point directly
            return name;
        }

        // Find matching junction
        for (Iterator iterator = junctions.keySet().iterator(); iterator.hasNext();)
        {
            final FileName junctionPoint = (FileName) iterator.next();
            if (junctionPoint.isDescendent(name))
            {
                return junctionPoint;
            }
        }

        // None
        return null;
    }
}
TOP

Related Classes of org.apache.commons.vfs.impl.VirtualFileSystem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.