sf.net.experimaestro.connectors.SingleHostConnector.java Source code

Java tutorial

Introduction

Here is the source code for sf.net.experimaestro.connectors.SingleHostConnector.java

Source

/*
 * This file is part of experimaestro.
 * Copyright (c) 2012 B. Piwowarski <benjamin@bpiwowar.net>
 *
 * experimaestro 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 3 of the License, or
 * (at your option) any later version.
 *
 * experimaestro 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 experimaestro.  If not, see <http://www.gnu.org/licenses/>.
 */

package sf.net.experimaestro.connectors;

import com.sleepycat.persist.model.Persistent;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystem;
import org.apache.commons.vfs2.FileSystemException;
import sf.net.experimaestro.exceptions.LockException;
import sf.net.experimaestro.exceptions.XPMRuntimeException;
import sf.net.experimaestro.locks.Lock;

import static java.lang.String.format;

/**
 * A connector that corresponds to a single host.
 * <p/>
 * Descendant of this class of connector provide access to a file system and to a process launcher.
 *
 * @author B. Piwowarski <benjamin@bpiwowar.net>
 */
@Persistent
abstract public class SingleHostConnector extends Connector implements Launcher {
    static private final char[] chars = new String("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
            .toCharArray();
    /**
     * Underlying filesystem
     */
    transient private FileSystem filesystem;

    public SingleHostConnector(String id) {
        super(id);
    }

    protected SingleHostConnector() {
    }

    @Override
    public SingleHostConnector getConnector(ComputationalRequirements requirements) {
        // By default, returns ourselves - TODO: check the requirements
        return this;
    }

    @Override
    public SingleHostConnector getMainConnector() {
        // By default, the main connector is ourselves
        return this;
    }

    /**
     * Get the underlying filesystem
     */
    protected abstract FileSystem doGetFileSystem() throws FileSystemException;

    /**
     * Get the underlying file system
     *
     * @return
     * @throws FileSystemException
     */
    public FileSystem getFileSystem() throws FileSystemException {
        if (filesystem == null)
            return filesystem = doGetFileSystem();
        return filesystem;
    }

    /**
     * Resolve the file name
     *
     * @param path The path to the file
     * @return A file object
     * @throws FileSystemException
     */
    public FileObject resolveFile(String path) throws FileSystemException {
        return getFileSystem().resolveFile(path);
    }

    /**
     * Resolve a FileObject to a local path
     * <p/>
     * Throws an exception when the file name cannot be resolved, i.e. when
     * the file object is not
     */
    public String resolve(FileObject file) throws FileSystemException {
        if (!contains(file.getFileSystem())) {
            throw new FileSystemException(format("Cannot resolve file %s within filesystem %s", file, this));
        }

        return file.getName().getPath();
    }

    /**
     * Returns true if the filesystem matches
     */
    protected abstract boolean contains(FileSystem fileSystem) throws FileSystemException;

    public String resolve(String path) throws FileSystemException {
        return resolve(resolveFile(path));
    }

    /**
     * Returns a process builder
     */
    public abstract AbstractProcessBuilder processBuilder();

    /**
     * Lock a file
     */
    public abstract Lock createLockFile(String path, boolean wait) throws LockException;

    /**
     * Returns the hostname
     */
    public abstract String getHostName();

    @Override
    public AbstractProcessBuilder processBuilder(SingleHostConnector connector) {
        if (connector != this)
            throw new XPMRuntimeException("");

        return this.processBuilder();
    }

    public FileObject getTemporaryFile(String prefix, String suffix) throws FileSystemException {
        FileObject tmpdir = getTemporaryDirectory();

        final int MAX_ATTEMPTS = 1000;

        for (int attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
            FileObject child = tmpdir.resolveFile(prefix + RandomStringUtils.random(10, chars) + suffix);
            if (!child.exists()) {
                try {
                    child.createFile();
                } catch (Throwable t) {
                }
                return child;
            }
        }
        throw new FileSystemException(
                format("Could not find a proper temporary file name after %d attempts", MAX_ATTEMPTS));
    }

    protected abstract FileObject getTemporaryDirectory() throws FileSystemException;
}