org.objectweb.proactive.extensions.dataspaces.vfs.adapter.VFSFileObjectAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.objectweb.proactive.extensions.dataspaces.vfs.adapter.VFSFileObjectAdapter.java

Source

/*
 * ################################################################
 *
 * ProActive Parallel Suite(TM): The Java(TM) library for
 *    Parallel, Distributed, Multi-Core Computing for
 *    Enterprise Grids & Clouds
 *
 * Copyright (C) 1997-2012 INRIA/University of
 *                 Nice-Sophia Antipolis/ActiveEon
 * Contact: proactive@ow2.org or contact@activeeon.com
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation; version 3 of
 * the License.
 *
 * This library 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
 * Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * If needed, contact us to obtain a release under GPL Version 2 or 3
 * or a different license than the AGPL.
 *
 *  Initial developer(s):               The ProActive Team
 *                        http://proactive.inria.fr/team_members.htm
 *  Contributor(s):
 *
 * ################################################################
 * $$PROACTIVE_INITIAL_DEV$$
 */
package org.objectweb.proactive.extensions.dataspaces.vfs.adapter;

import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;

import org.apache.commons.vfs.FileName;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.NameScope;
import org.apache.commons.vfs.Selectors;
import org.apache.log4j.Logger;
import org.objectweb.proactive.core.ProActiveRuntimeException;
import org.objectweb.proactive.core.util.log.Loggers;
import org.objectweb.proactive.core.util.log.ProActiveLogger;
import org.objectweb.proactive.extensions.dataspaces.api.Capability;
import org.objectweb.proactive.extensions.dataspaces.api.DataSpacesFileObject;
import org.objectweb.proactive.extensions.dataspaces.api.FileContent;
import org.objectweb.proactive.extensions.dataspaces.api.FileSelector;
import org.objectweb.proactive.extensions.dataspaces.api.FileType;
import org.objectweb.proactive.extensions.dataspaces.core.DataSpacesURI;
import org.objectweb.proactive.extensions.dataspaces.exceptions.FileSystemException;
import org.objectweb.proactive.extensions.dataspaces.exceptions.SpaceNotFoundException;
import org.objectweb.proactive.extensions.dataspaces.vfs.VFSSpacesMountManagerImpl;
import org.objectweb.proactive.extensions.vfsprovider.util.URIHelper;

/**
 * VFS {@link FileObject} adapter to {@link DataSpacesFileObject} interface, adding getURI
 * functionality.
 * <p>
 * Adapted FileObject should provide any access limitation as required by Data Spaces specification.
 */
public class VFSFileObjectAdapter implements DataSpacesFileObject {
    private final static Logger logger = ProActiveLogger.getLogger(Loggers.DATASPACES);

    /**
     * Apache VFS FileObject handle
     */
    private FileObject currentFileObject;

    /**
     * Virtual Data Space URI
     */
    private final DataSpacesURI dataSpaceURI;

    /**
     * List of urls of the available roots (can be switched to any of them)
     */
    private final LinkedHashSet<String> rootFOUriSet;

    /**
     * url of the root of the current FileObject
     */
    private String currentRootFOUri;

    /**
     * Apache VFS object describing the file
     */
    private FileName dataSpaceVFSFileName;

    private final VFSSpacesMountManagerImpl manager;

    private final String ownerActiveObjectId;

    public VFSFileObjectAdapter(FileObject adaptee, DataSpacesURI dataSpaceURI, FileName dataSpaceVFSFileName,
            ArrayList<String> spaceRoots, String currentRoot) throws FileSystemException {
        this(adaptee, dataSpaceURI, dataSpaceVFSFileName, spaceRoots, currentRoot, null, null);
    }

    public VFSFileObjectAdapter(FileObject adaptee, DataSpacesURI dataSpaceURI, FileName dataSpaceVFSFileName,
            ArrayList<String> spaceRoots, String currentRoot, VFSSpacesMountManagerImpl manager)
            throws FileSystemException {
        this(adaptee, dataSpaceURI, dataSpaceVFSFileName, spaceRoots, currentRoot, manager, null);
    }

    /**
     * @param adaptee
     *            file object that is going to be represented as DataSpacesFileObject; cannot be
     *            <code>null</code>
     * @param dataSpaceURI
     *            Data Spaces virtual URI of this file object's space; must have space part fully defined
     *            and only this part; cannot be <code>null</code>
     * @param dataSpaceVFSFileName
     *            VFS file name of the space root FileObject; cannot be <code>null</code>
     * @throws FileSystemException
     *             when data space file name does not match adaptee's name
     */
    public VFSFileObjectAdapter(FileObject adaptee, DataSpacesURI dataSpaceURI, FileName dataSpaceVFSFileName,
            ArrayList<String> spaceRoots, String currentRoot, VFSSpacesMountManagerImpl manager,
            String ownerActiveObjectId) throws FileSystemException {
        this.dataSpaceURI = dataSpaceURI;
        this.dataSpaceVFSFileName = dataSpaceVFSFileName;
        this.currentFileObject = adaptee;
        this.rootFOUriSet = new LinkedHashSet<String>(spaceRoots);
        this.manager = manager;
        this.ownerActiveObjectId = ownerActiveObjectId;
        this.currentRootFOUri = currentRoot;
        checkFileNamesConsistencyOrWound();
    }

    private VFSFileObjectAdapter(FileObject adaptee, VFSFileObjectAdapter fileObjectAdapter)
            throws FileSystemException {
        this(adaptee, fileObjectAdapter.dataSpaceURI, fileObjectAdapter.dataSpaceVFSFileName,
                new ArrayList<String>(fileObjectAdapter.rootFOUriSet), fileObjectAdapter.currentRootFOUri,
                fileObjectAdapter.manager, fileObjectAdapter.ownerActiveObjectId);
    }

    public void close() throws FileSystemException {
        try {
            currentFileObject.close();
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public void copyFrom(DataSpacesFileObject srcFile, FileSelector selector) throws FileSystemException {
        final FileObject srcAdaptee = getVFSAdapteeOrWound(srcFile);
        final org.apache.commons.vfs.FileSelector vfsSelector = buildFVSSelector(selector);

        try {
            currentFileObject.copyFrom(srcAdaptee, vfsSelector);
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public void createFile() throws FileSystemException {
        try {
            currentFileObject.createFile();
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public void createFolder() throws FileSystemException {
        try {
            currentFileObject.createFolder();
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public boolean delete() throws FileSystemException {
        try {
            return currentFileObject.delete();
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public int delete(FileSelector selector) throws FileSystemException {
        final org.apache.commons.vfs.FileSelector vfsSelector = buildFVSSelector(selector);

        try {
            return currentFileObject.delete(vfsSelector);
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public boolean exists() throws FileSystemException {
        try {
            return currentFileObject.exists();
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public List<DataSpacesFileObject> findFiles(FileSelector selector) throws FileSystemException {
        final org.apache.commons.vfs.FileSelector vfsSelector = buildFVSSelector(selector);
        final List<DataSpacesFileObject> result = new ArrayList<DataSpacesFileObject>();

        try {
            final FileObject[] vfsResult = currentFileObject.findFiles(vfsSelector);

            adaptVFSResult(vfsResult, result);
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
        return result;
    }

    public void findFiles(FileSelector selector, boolean depthwise, List<DataSpacesFileObject> selected)
            throws FileSystemException {

        final org.apache.commons.vfs.FileSelector vfsSelector = buildFVSSelector(selector);

        try {
            final List<FileObject> vfsResult = new ArrayList<FileObject>();
            currentFileObject.findFiles(vfsSelector, depthwise, vfsResult);

            adaptVFSResult(vfsResult, selected);
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public DataSpacesFileObject getChild(String name) throws FileSystemException {
        try {
            return adaptVFSResult(currentFileObject.getChild(name));
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public List<DataSpacesFileObject> getChildren() throws FileSystemException {
        List<DataSpacesFileObject> adapted = new ArrayList<DataSpacesFileObject>();

        try {
            adaptVFSResult(currentFileObject.getChildren(), adapted);
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
        return adapted;
    }

    public FileContent getContent() throws FileSystemException {

        try {
            return new VFSContentAdapter(currentFileObject.getContent(), this);
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public DataSpacesFileObject getParent() throws FileSystemException {
        final FileObject vfsParent;
        try {
            vfsParent = currentFileObject.getParent();
        } catch (Exception e) {
            throw new FileSystemException(e);
        }

        if (vfsParent == null)
            throw new FileSystemException("Operation cannot be performed due to file system limitations");
        return adaptVFSResult(vfsParent);
    }

    public FileType getType() throws FileSystemException {
        try {
            return adaptVFSResult(currentFileObject.getType());
        } catch (Exception e) {
            throw new FileSystemException(e);
        }
    }

    public FileObject getFileObject() {
        return currentFileObject;
    }

    public boolean isContentOpen() {
        return currentFileObject.isContentOpen();
    }

    public boolean isHidden() throws FileSystemException {
        try {
            return currentFileObject.isHidden();
        } catch (org.apache.commons.vfs.FileSystemException e) {
            throw new FileSystemException(e);
        }
    }

    public boolean isReadable() throws FileSystemException {
        try {
            return currentFileObject.isReadable();
        } catch (org.apache.commons.vfs.FileSystemException e) {
            throw new FileSystemException(e);
        }
    }

    public boolean isWritable() throws FileSystemException {
        try {
            return currentFileObject.isWriteable();
        } catch (org.apache.commons.vfs.FileSystemException e) {
            throw new FileSystemException(e);
        }
    }

    public void moveTo(DataSpacesFileObject destFile) throws FileSystemException {
        final FileObject destAdaptee = getVFSAdapteeOrWound(destFile);

        try {
            currentFileObject.moveTo(destAdaptee);
        } catch (org.apache.commons.vfs.FileSystemException e) {
            throw new FileSystemException(e);
        }
    }

    public void refresh() throws FileSystemException {
        try {
            currentFileObject.refresh();
        } catch (org.apache.commons.vfs.FileSystemException e) {
            throw new FileSystemException(e);
        }
    }

    public DataSpacesFileObject resolveFile(String path) throws FileSystemException {
        if (path.startsWith("/"))
            throw new FileSystemException("Cannot resolve an absolute path");
        try {
            return adaptVFSResult(currentFileObject.resolveFile(path));
        } catch (org.apache.commons.vfs.FileSystemException e) {
            throw new FileSystemException(e);
        }
    }

    public FileObject getAdaptee() {
        return currentFileObject;
    }

    public boolean hasSpaceCapability(Capability capability) {
        final org.apache.commons.vfs.Capability vfsCapability = buildVFSCapability(capability);
        final org.apache.commons.vfs.FileSystem vfsFileSystem = currentFileObject.getFileSystem();

        return vfsFileSystem.hasCapability(vfsCapability);
    }

    /**
     * @param array
     *            may be null
     * @param adapted
     *            may be null only if <code>array</code> is
     * @throws FileSystemException
     *
     */
    private <T extends Collection<DataSpacesFileObject>> void adaptVFSResult(FileObject[] array, T adapted)
            throws FileSystemException {
        if (array == null)
            return;
        for (int i = 0; i < array.length; i++) {
            adapted.add(new VFSFileObjectAdapter(array[i], this));
        }
    }

    /**
     * @param vfsResult
     *            cannot be null
     * @param adapted
     *            cannot be null
     * @throws FileSystemException
     */
    private <T extends Collection<DataSpacesFileObject>, E extends Collection<FileObject>> void adaptVFSResult(
            E vfsResult, T adapted) throws FileSystemException {

        for (FileObject fo : vfsResult) {
            adapted.add(new VFSFileObjectAdapter(fo, this));
        }
    }

    /**
     * @param vfsFileObject
     *            may be null
     * @throws FileSystemException
     */
    private VFSFileObjectAdapter adaptVFSResult(final FileObject vfsFileObject) throws FileSystemException {
        return vfsFileObject == null ? null : new VFSFileObjectAdapter(vfsFileObject, this);
    }

    private static FileType adaptVFSResult(org.apache.commons.vfs.FileType vfsResult) {
        if (vfsResult == org.apache.commons.vfs.FileType.FILE)
            return FileType.FILE;

        if (vfsResult == org.apache.commons.vfs.FileType.FOLDER)
            return FileType.FOLDER;

        if (vfsResult == org.apache.commons.vfs.FileType.IMAGINARY)
            return FileType.ABSTRACT;

        return null;
    }

    /**
     * @param selector
     *            may be null
     */
    private static org.apache.commons.vfs.FileSelector buildFVSSelector(FileSelector selector) {
        switch (selector) {
        case EXCLUDE_SELF:
            return Selectors.EXCLUDE_SELF;
        case SELECT_ALL:
            return Selectors.SELECT_ALL;
        case SELECT_FILES:
            return Selectors.SELECT_FILES;
        case SELECT_FOLDERS:
            return Selectors.SELECT_FOLDERS;
        case SELECT_CHILDREN:
            return Selectors.SELECT_CHILDREN;
        case SELECT_SELF:
            return Selectors.SELECT_SELF;
        case SELECT_SELF_AND_CHILDREN:
            return Selectors.SELECT_SELF_AND_CHILDREN;
        default:
            return null;
        }
    }

    /**
     * @param capability
     *            may be null
     */
    private static org.apache.commons.vfs.Capability buildVFSCapability(Capability capability) {
        switch (capability) {
        case APPEND_CONTENT:
            return org.apache.commons.vfs.Capability.APPEND_CONTENT;
        case ATTRIBUTES:
            return org.apache.commons.vfs.Capability.ATTRIBUTES;
        case COMPRESS:
            return org.apache.commons.vfs.Capability.COMPRESS;
        case CREATE:
            return org.apache.commons.vfs.Capability.CREATE;
        case DELETE:
            return org.apache.commons.vfs.Capability.DELETE;
        case DIRECTORY_READ_CONTENT:
            return org.apache.commons.vfs.Capability.DIRECTORY_READ_CONTENT;
        case FS_ATTRIBUTES:
            return org.apache.commons.vfs.Capability.FS_ATTRIBUTES;
        case GET_LAST_MODIFIED:
            return org.apache.commons.vfs.Capability.GET_LAST_MODIFIED;
        case GET_TYPE:
            return org.apache.commons.vfs.Capability.GET_TYPE;
        case LAST_MODIFIED:
            return org.apache.commons.vfs.Capability.LAST_MODIFIED;
        case LIST_CHILDREN:
            return org.apache.commons.vfs.Capability.LIST_CHILDREN;
        case MANIFEST_ATTRIBUTES:
            return org.apache.commons.vfs.Capability.MANIFEST_ATTRIBUTES;
        case RANDOM_ACCESS_READ:
            return org.apache.commons.vfs.Capability.RANDOM_ACCESS_READ;
        case RANDOM_ACCESS_WRITE:
            return org.apache.commons.vfs.Capability.RANDOM_ACCESS_WRITE;
        case READ_CONTENT:
            return org.apache.commons.vfs.Capability.READ_CONTENT;
        case RENAME:
            return org.apache.commons.vfs.Capability.RENAME;
        case SET_LAST_MODIFIED_FILE:
            return org.apache.commons.vfs.Capability.SET_LAST_MODIFIED_FILE;
        case SET_LAST_MODIFIED_FOLDER:
            return org.apache.commons.vfs.Capability.SET_LAST_MODIFIED_FOLDER;
        case SIGNING:
            return org.apache.commons.vfs.Capability.SIGNING;
        case URI:
            return org.apache.commons.vfs.Capability.URI;
        case VIRTUAL:
            return org.apache.commons.vfs.Capability.VIRTUAL;
        case WRITE_CONTENT:
            return org.apache.commons.vfs.Capability.WRITE_CONTENT;
        default:
            return null;
        }
    }

    private void checkFileNamesConsistencyOrWound() throws FileSystemException {
        final FileName adapteeName = currentFileObject.getName();

        if (!dataSpaceVFSFileName.isDescendent(adapteeName, NameScope.DESCENDENT_OR_SELF))
            throw new FileSystemException("Specified data space file name does not match adaptee's name");
    }

    private FileObject getVFSAdapteeOrWound(DataSpacesFileObject file) throws FileSystemException {

        if (file instanceof VFSFileObjectAdapter) {
            return ((VFSFileObjectAdapter) file).getAdaptee();
        }
        throw new FileSystemException("Operation unsupported: destination file system unknown");
    }

    private String computeRelativePath() {
        String relativePath = null;
        try {
            relativePath = dataSpaceVFSFileName.getRelativeName(currentFileObject.getName());
        } catch (org.apache.commons.vfs.FileSystemException e) {
            ProActiveLogger.logImpossibleException(logger, e);
            throw new ProActiveRuntimeException(e);
        }
        if (".".equals(relativePath)) {
            relativePath = null;
        }
        return relativePath;
    }

    public String getVirtualURI() {
        String relativePath = computeRelativePath();

        return dataSpaceURI.withRelativeToSpace(relativePath).toString();
    }

    public String getRealURI() {
        try {
            URL url = currentFileObject.getURL();
            return URIHelper.convertToEncodedURIString(url.toString());
        } catch (org.apache.commons.vfs.FileSystemException e) {
            //null of unknown
            return null;
        }
    }

    public List<String> getAllRealURIs() {
        String relativePath = computeRelativePath();
        ArrayList<String> answer = new ArrayList<String>();
        for (String root : rootFOUriSet) {
            if ((relativePath != null) && !(relativePath.equals("."))) {
                answer.add(URIHelper.convertToEncodedURIString(root + relativePath));
            } else {
                answer.add(URIHelper.convertToEncodedURIString(root));
            }
        }
        return answer;
    }

    @Override
    public String getSpaceRootURI() {
        return URIHelper.convertToEncodedURIString(currentRootFOUri);
    }

    @Override
    public DataSpacesFileObject ensureExistingOrSwitch() throws FileSystemException, SpaceNotFoundException {
        if (this.exists()) {
            return this;
        }
        logger.debug(getRealURI() + " does not exist");
        for (String newUri : rootFOUriSet) {
            if (!newUri.equals(currentRootFOUri)) {
                DataSpacesFileObject newdsfo = switchToSpaceRoot(newUri);
                if (newdsfo.exists()) {
                    return newdsfo;
                }
                logger.debug(newdsfo.getRealURI() + " does not exist");
            }
        }

        return null;
    }

    public List<String> getAllSpaceRootURIs() {
        ArrayList<String> answer = new ArrayList<String>(rootFOUriSet.size());
        for (String uri : rootFOUriSet) {
            answer.add(URIHelper.convertToEncodedURIString(uri));
        }
        return answer;
    }

    public DataSpacesFileObject switchToSpaceRoot(String spaceRootUri)
            throws FileSystemException, SpaceNotFoundException {
        if (!rootFOUriSet.contains(spaceRootUri)) {
            throw new IllegalArgumentException(spaceRootUri + " is not accessible by DFO " + getVirtualURI());
        }
        if (manager == null) {
            throw new UnsupportedOperationException("Mount Manager is not initialized.");
        }
        String relativePath = computeRelativePath();
        DataSpacesFileObject newDsfo = manager.resolveFile(dataSpaceURI.withRelativeToSpace(relativePath),
                ownerActiveObjectId, spaceRootUri);
        logger.debug("switched to " + newDsfo.getRealURI());
        return newDsfo;
    }

    @Override
    public boolean equals(Object candidate) {

        if (!(candidate instanceof DataSpacesFileObject))
            return false;

        final DataSpacesFileObject file = (DataSpacesFileObject) candidate;
        return this.getVirtualURI().equals(file.getVirtualURI());
    }
}