com.adito.vfs.VFSRepository.java Source code

Java tutorial

Introduction

Here is the source code for com.adito.vfs.VFSRepository.java

Source

/* ========================================================================== *
 * Copyright (C) 2004-2005 Pier Fumagalli <http://www.betaversion.org/~pier/> *
 *                            All rights reserved.                            *
 * ========================================================================== *
 *                                                                            *
 * 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.                                                         *
 *                                                                            *
 * ========================================================================== *
 *                                                                            *
 *                                                                            */

/*
*  Adito
*
*  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2 of
*  the License, or (at your option) any later version.
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public
*  License along with this program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

package com.adito.vfs;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.VFS;
import org.apache.commons.vfs.impl.DefaultFileReplicator;
import org.apache.commons.vfs.impl.DefaultFileSystemManager;

import com.adito.boot.SystemProperties;
import com.adito.boot.Util;
import com.adito.core.BundleActionMessage;
import com.adito.policyframework.LaunchSession;
import com.adito.policyframework.LaunchSessionManager;
import com.adito.policyframework.NoPermissionException;
import com.adito.policyframework.PolicyException;
import com.adito.security.Constants;
import com.adito.security.PasswordCredentials;
import com.adito.security.SessionInfo;
import com.adito.vfs.utils.DAVCredentialsCache;
import com.adito.vfs.webdav.DAVAuthenticationRequiredException;
import com.adito.vfs.webdav.DAVBundleActionMessageException;
import com.adito.vfs.webdav.DAVException;
import com.adito.vfs.webdav.DAVListener;
import com.adito.vfs.webdav.DAVUtilities;

/**
 * <p>
 * A simple class representing a {@link File} based WebDAV repository.
 * </p>
 * 
 * @author <a href="http://www.betaversion.org/~pier/">Pier Fumagalli</a>
 */
public class VFSRepository {

    final static Log log = LogFactory.getLog(VFSRepository.class);

    final static String REPOSITORY_ATTR = "networkPlacesRepository";
    /**
     * <p>
     * The {@link Set} of all configured {@link DAVListener}s.
     * </p>
     */
    private Set<DAVListener> listeners = new HashSet<DAVListener>();

    /**
     * <p>
     * The {@link FileSystemManager} used to retrieve resources
     * </p>
     */
    private FileSystemManager fsManager;

    /**
     * <p>
     * The {@link VFSStore} implementations being managed by the repository
     * </p>
     */
    private Map<String, VFSStore> stores;

    /** <p>A cache of resources for the life of this transaction */
    //private Map resourceCache = new HashMap();

    private HttpSession session;

    /**
     * Constructor.
     *
     * @param session session
     * @throws DAVBundleActionMessageException on any error
     */
    public VFSRepository(HttpSession session) throws DAVBundleActionMessageException {

        this.session = session;
        try {
            fsManager = VFS.getManager();
            ((DefaultFileSystemManager) fsManager).setBaseFile(new File(SystemProperties.get("user.dir")));

        } catch (FileSystemException e1) {
            log.error(e1);
            throw new DAVBundleActionMessageException(
                    new BundleActionMessage("vfs", "vfs.fsManager.failed", e1.getMessage()));
        }

        try {
            stores = VFSProviderManager.getInstance().createStores(this);
        } catch (Exception e) {
            log.error(e);
            throw new DAVBundleActionMessageException(new BundleActionMessage("vfs", "vfs.store.creation.failed"));
        }
    }

    /**
     * Get the session the repository was created under.
     * 
     * @return session
     */
    public SessionInfo getSession() {
        return (SessionInfo) session.getAttribute(Constants.SESSION_INFO);
    }

    /**
     * Return the {@link VFSResource} for the path.
     * 
     * @param launchSession launch session
     * @param path an absolute or relative {@link String} identifying the
     *        resource.
     * @param requestCredentials request credentials
     * @return a <b>non-null</b> {@link VFSResource} instance.
     * @throws IOException
     * @throws DAVBundleActionMessageException
     * @throws NoPermissionException 
     * @throws PolicyException 
     */
    public VFSResource getResource(LaunchSession launchSession, String path,
            PasswordCredentials requestCredentials/*, DAVTransaction transaction*/)
            throws DAVBundleActionMessageException, IOException, PolicyException, NoPermissionException,
            DAVAuthenticationRequiredException {

        if (path == null) {
            log.error("Cannot list store root.");
            throw new DAVBundleActionMessageException(new BundleActionMessage("vfs", "vfs.store.root", path));
        }

        if (launchSession == null) {
            throw new IOException("Must have launch session.");
        }

        path = DAVUtilities.stripLeadingSlash(path);
        if (path.startsWith("fs")) {
            path = DAVUtilities.stripLeadingSlash(path.substring(2));
        }

        String storeName = path;
        VFSStore store;
        String mountName = null;
        VFSMount mount;

        // Extract the store
        int idx = path.indexOf('/');
        if (idx != -1) {
            storeName = storeName.substring(0, idx);
            path = path.substring(idx + 1);
        } else {
            path = "";
        }

        if (storeName.equals("")) {
            return getRepositoryResource();
        } else {
            store = (VFSStore) this.getStore(storeName);
            if (store == null) {
                log.error("No store named \"" + storeName + "\".");
                throw new DAVException(404, "No store named \"" + storeName + "\".");
            }
        }

        // Extract the mount
        mountName = path;
        idx = path.indexOf('/', 1);
        if (idx != -1) {
            mountName = mountName.substring(0, idx);
            path = path.substring(idx + 1);
        } else {
            path = "";
        }
        if (mountName.length() == 0) {
            return store.getStoreResource(/*transaction*/);
        }

        // Check the launch session is valid
        if (launchSession.isTracked())
            launchSession.checkAccessRights(null, getSession());

        //
        try {
            mount = store.getMountFromString(mountName, launchSession);
        } catch (DAVAuthenticationRequiredException dare) {
            throw dare;
        } catch (Exception e) {
            log.error("Failed to get mount.", e);
            mount = null;
        }

        if (mount == null || mount.equals("")) {
            log.error("No mount named \"" + mountName + "\" for store \"" + storeName + "\".");
            throw new DAVException(404, "No mount named \"" + mountName + "\" for store \"" + storeName + "\".");
        }

        path = DAVUtilities.stripTrailingSlash(path);

        return mount.getResource(path, requestCredentials);
    }

    /**
     * Add a new {@link DAVListener} to the list of instances notified by this
     * {@link VFSRepository}.
     * 
     * @param listener listener to add
     */
    public void addListener(DAVListener listener) {
        if (listener != null)
            this.listeners.add(listener);
    }

    /**
     * Remove a {@link DAVListener} from the list of instances notified by this
     * {@link VFSRepository}.
     * 
     * @param listener listener to remove
     */
    public void removeListener(DAVListener listener) {
        if (listener != null)
            this.listeners.remove(listener);
    }

    /**
     * Notify all configured {@link DAVListener}s of an event.
     * 
     * @param resource resource 
     * @param event  event code
     */
    public void notify(VFSResource resource, int event) {
        if (resource == null)
            throw new NullPointerException("Null resource");
        if (resource.getMount().getStore().getRepository() != this)
            throw new IllegalArgumentException("Invalid resource");

        Iterator iterator = this.listeners.iterator();
        while (iterator.hasNext())
            try {
                ((DAVListener) iterator.next()).notify(resource, event);
            } catch (RuntimeException exception) {
                // Swallow any RuntimeException thrown by listeners.
            }
    }

    /**
     * Get the <i>Commons VFS</i> {@link FileSystemManager} instance.
     * 
     * @return file system manager
     */
    public FileSystemManager getFileSystemManager() {
        return fsManager;
    }

    /**
     * Get a resource that represents the entire repository.
     * 
     * @return resource repository
     */
    public VFSResource getRepositoryResource() {
        try {
            return new RepositoryResource(new URI(""));
        } catch (Exception e) {
            // shouldn't happen
            return null;
        }
    }

    /**
     * Get the object that caches used credentials.
     * 
     * @return credentials cache
     */
    public DAVCredentialsCache getCredentialsCache() {
        // get the credentials cashe
        DAVCredentialsCache credentialsCashe = (DAVCredentialsCache) session.getAttribute("CredentialsCashe");
        // if there is not 1 make 1 then get the cashe
        if (credentialsCashe == null) {
            session.setAttribute("CredentialsCashe", new DAVCredentialsCache());
            credentialsCashe = (DAVCredentialsCache) session.getAttribute("CredentialsCashe");
        }
        return credentialsCashe;
    }

    /**
     * Create a {@link VFSRepository} repository for the given session. The 
     * repository will be placed in the users session and used for all VFS
     * operations.
     * 
     * @param session
     * @return VFS repository
     * @throws DAVBundleActionMessageException
     * @throws Exception
     */
    public static VFSRepository getRepository(HttpSession session)
            throws DAVBundleActionMessageException, Exception {
        VFSRepository repository = (VFSRepository) session.getAttribute(REPOSITORY_ATTR);
        if (repository == null) {
            repository = new VFSRepository(session);
            session.setAttribute(REPOSITORY_ATTR, repository);
            if (log.isInfoEnabled())
                log.info("Initialized repository");
        }
        return repository;
    }

    /**
     * Remove a {@link VFSRepository} repository from the given session. 
     * @param session
     */
    public static void removeRepository(SessionInfo session) {
        HttpSession httpSession = session.getHttpSession();
        if (httpSession != null) {
            httpSession.removeAttribute(REPOSITORY_ATTR);
            if (log.isInfoEnabled())
                log.info("Removed repository");
        }
    }

    /**
     * Get a store that will handle a given a scheme. 
     * 
     * @param scheme
     * @return store
     */
    public VFSStore getStore(String scheme) {
        for (Iterator i = stores.values().iterator(); i.hasNext();) {
            VFSStore s = (VFSStore) i.next();
            if (s.getProvider().willHandle(scheme)) {
                return s;
            }
        }
        return null;
    }

    class RepositoryResource extends AbstractVFSResource {

        RepositoryResource(URI relativeUri) {
            super(new LaunchSession(getSession()), relativeUri, true, "", null, VFSRepository.this);
        }

        public Iterator getChildren() {
            List<VFSResource> l = new ArrayList<VFSResource>();
            for (Iterator i = stores.values().iterator(); i.hasNext();) {
                l.add(((VFSStore) i.next()).getStoreResource());
            }
            return l.iterator();
        }

        public boolean isBrowsable() throws IOException {
            return false;
        }

    }
}