com.anrisoftware.globalpom.exec.core.DefaultCommandExec.java Source code

Java tutorial

Introduction

Here is the source code for com.anrisoftware.globalpom.exec.core.DefaultCommandExec.java

Source

/*
 * Copyright 2014 Erwin Mller <erwin.mueller@deventm.org>
 *
 * This file is part of globalpomutils-exec.
 *
 * globalpomutils-exec is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * globalpomutils-exec 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 Lesser General Public License
 * along with globalpomutils-exec. If not, see <http://www.gnu.org/licenses/>.
 */
package com.anrisoftware.globalpom.exec.core;

import static com.anrisoftware.globalpom.exec.core.DefaultProcessModule.getCommandExecFactory;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Observer;
import java.util.concurrent.Future;

import javax.inject.Inject;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;

import com.anrisoftware.globalpom.exec.api.CommandExec;
import com.anrisoftware.globalpom.exec.api.CommandExecException;
import com.anrisoftware.globalpom.exec.api.CommandExecFactory;
import com.anrisoftware.globalpom.exec.api.CommandInput;
import com.anrisoftware.globalpom.exec.api.CommandLine;
import com.anrisoftware.globalpom.exec.api.CommandOutput;
import com.anrisoftware.globalpom.exec.api.ProcessTask;
import com.anrisoftware.globalpom.threads.api.ListenableFuture.Status;
import com.anrisoftware.globalpom.threads.api.Threads;

/**
 * Executes an external command.
 * 
 * @author Erwin Mueller, erwin.mueller@deventm.org
 * @since 1.11
 */
public final class DefaultCommandExec implements CommandExec {

    /**
     * @see CommandExecFactory#create()
     */
    public static CommandExec createCommandExec() {
        return getCommandExecFactory().create();
    }

    private final List<Observer> observers;

    @Inject
    private DefaultCommandExecLogger log;

    @Inject
    private DefaultProcessTaskFactory processTaskFactory;

    private Threads threads;

    private CommandOutput output;

    private CommandOutput error;

    private CommandInput input;

    private int[] exitCodes;

    private boolean destroyOnTimeout;

    DefaultCommandExec() {
        this.exitCodes = null;
        this.destroyOnTimeout = true;
        this.observers = new ArrayList<Observer>();
    }

    @Override
    public void setThreads(Threads threads) {
        this.threads = threads;
    }

    @Override
    public void setCommandOutput(CommandOutput output) {
        this.output = output;
    }

    @Override
    public void setCommandError(CommandOutput error) {
        this.error = error;
    }

    @Override
    public void setCommandInput(CommandInput input) {
        this.input = input;
    }

    @Override
    public void setExitCode(int... codes) {
        this.exitCodes = codes;
    }

    @Override
    public void setDestroyOnTimeout(boolean flag) {
        this.destroyOnTimeout = flag;
    }

    @Override
    public void setObserver(Observer... observer) {
        this.observers.addAll(Arrays.asList(observer));
    }

    @Override
    public Future<ProcessTask> exec(CommandLine commandLine, PropertyChangeListener... listeners)
            throws CommandExecException {
        try {
            ProcessTask task = createProcessTask(commandLine, observers);
            return threads.submit(task, setupListener(task, listeners));
        } catch (IOException e) {
            throw log.errorExecuteCommand(this, e, commandLine);
        }
    }

    private ProcessTask createProcessTask(CommandLine commandLine, List<Observer> observers) throws IOException {
        DefaultProcessTask task = processTaskFactory.create(commandLine);
        task.setThreads(threads);
        task.addObserver(observers.toArray(new Observer[] {}));
        if (output != null) {
            task.setCommandOutput(output.clone());
        }
        if (error != null) {
            task.setCommandError(error.clone());
        }
        if (input != null) {
            task.setCommandInput(input.clone());
        }
        task.setExitCodes(exitCodes);
        return task;
    }

    private PropertyChangeListener[] setupListener(ProcessTask task, PropertyChangeListener... l) {
        return destroyOnTimeout ? addTimeoutListener(task, l) : l;
    }

    private PropertyChangeListener[] addTimeoutListener(final ProcessTask task,
            PropertyChangeListener... listeners) {
        return ArrayUtils.add(listeners, new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                Status status = (Status) evt.getNewValue();
                if (status == Status.TIMEOUT) {
                    task.destroy();
                }
            }
        });
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this).toString();
    }
}