
org.jppf.node.protocol.CommandLineTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jppf-common Show documentation
Show all versions of jppf-common Show documentation
JPPF, the open source grid computing solution
/*
* JPPF.
* Copyright (C) 2005-2015 JPPF Team.
* http://www.jppf.org
*
* 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.jppf.node.protocol;
import java.io.File;
import java.util.*;
import org.jppf.process.*;
import org.jppf.utils.collections.CollectionUtils;
/**
* Instances of this class encapsulate the execution of an external process, program or shell script.
* This task starts and external process using command line arguments, environment variables, and a list
* of input and/or output files to use or generated by the external process.
* This task also captures the standard and error output (i.e. equivalent to System.out and System.err) of the
* external process.
* @param the type of results returned by this task.
* @author Laurent Cohen
*/
public abstract class CommandLineTask extends AbstractTask implements ProcessWrapperEventListener
{
/**
* Explicit serialVersionUID.
*/
private static final long serialVersionUID = 1L;
/**
* The list of command-line arguments.
*/
private List commandList = new LinkedList<>();
/**
* The environment variables to set.
*/
private Map env = new HashMap<>();
/**
* The directory to start the command in.
*/
private String startDir = null;
/**
* Content of the standard output for the process.
*/
private StringBuilder standardOutput = new StringBuilder();
/**
* Content of the error output for the process.
*/
private StringBuilder errorOutput = new StringBuilder();
/**
* Determines whether the process output should be captured.
*/
private boolean captureOutput = false;
/**
* The exit code returned by the sub-process.
*/
private int exitCode = -1;
/**
* The process that is launched.
*/
private transient Process process = null;
/**
* Default constructor.
*/
public CommandLineTask()
{
}
/**
* Create an instance of this class and set the parameters of the external process or script to launch.
* @param commands the list of command-line arguments.
*/
public CommandLineTask(final String...commands)
{
this(null, null, commands);
}
/**
* Create an instance of this class and set the parameters of the external process or script to launch.
* @param env the environment variables to set.
* @param startDir the directory to start the command in.
* @param commands the list of command-line arguments.
*/
public CommandLineTask(final Map env, final String startDir, final String...commands)
{
if (commands != null)
{
for (String s: commands) commandList.add(s);
}
this.env = env;
this.startDir = startDir;
}
/**
* Run the external process or script.
* @return the exit code returned by the sub-process.
* @throws Exception if an error occurs.
*/
public int launchProcess() throws Exception
{
ProcessBuilder builder = new ProcessBuilder();
builder.command(commandList);
if (startDir != null) builder.directory(new File(startDir));
if (env != null)
{
Map map = builder.environment();
for (Map.Entry e: env.entrySet()) map.put(e.getKey(), e.getValue());
}
ProcessWrapper wrapper = new ProcessWrapper();
if (captureOutput) wrapper.addListener(this);
try
{
process = builder.start();
wrapper.setProcess(process);
exitCode = process.waitFor();
return exitCode;
}
finally
{
if (captureOutput) wrapper.removeListener(this);
}
}
/**
* Determines whether the process output is captured.
* @return true if the output is captured, false otherwise.
*/
public boolean isCaptureOutput()
{
return captureOutput;
}
/**
* Specifies whether the process output is captured.
* @param captureOutput true if the output is captured, false otherwise.
*/
public void setCaptureOutput(final boolean captureOutput)
{
this.captureOutput = captureOutput;
}
/**
* Get the content of the standard output for the process.
* @return the output as a string.
*/
public String getStandardOutput()
{
return standardOutput.toString();
}
/**
* Get the content of the error output for the process.
* @return the output as a string.
*/
public String getErrorOutput()
{
return errorOutput.toString();
}
/**
* Get the list of command-line arguments.
* @return a list of arguments as strings.
*/
public List getCommandList()
{
return commandList;
}
/**
* Set the list of command-line arguments.
* @param commandList a list of arguments as strings.
*/
public void setCommandList(final List commandList)
{
this.commandList = commandList;
}
/**
* Set the list of command-line arguments.
* @param commands a list of arguments as strings.
*/
public void setCommandList(final String...commands)
{
commandList = CollectionUtils.list(commands);
}
/**
* Get the environment variables to set.
* @return a map of variable names to their corresponding values.
*/
public Map getEnv()
{
return env;
}
/**
* Get the environment variables to set.
* @param env a map of variable names to their corresponding values.
*/
public void setEnv(final Map env)
{
this.env = env;
}
/**
* Get the directory to start the command in.
* @return the start directory as a string.
*/
public String getStartDir()
{
return startDir;
}
/**
* Set the directory to start the command in.
* @param startDir the start directory as a string.
*/
public void setStartDir(final String startDir)
{
this.startDir = startDir;
}
/**
* Notification that the process has written to its output stream.
* @param event encapsulates the output stream's content.
* @see org.jppf.process.ProcessWrapperEventListener#outputStreamAltered(org.jppf.process.ProcessWrapperEvent)
*/
@Override
public void outputStreamAltered(final ProcessWrapperEvent event)
{
standardOutput.append(event.getContent());
}
/**
* Notification that the process has written to its error stream.
* @param event encapsulate the error stream's content.
* @see org.jppf.process.ProcessWrapperEventListener#errorStreamAltered(org.jppf.process.ProcessWrapperEvent)
*/
@Override
public void errorStreamAltered(final ProcessWrapperEvent event)
{
errorOutput.append(event.getContent());
}
/**
* Get the exit code returned by the sub-process.
* @return the value of the exit code returned by the sub-process.
* A negative value indicates the process was never launched or never returned.
* @see java.lang.Process#waitFor()
*/
public int getExitCode()
{
return exitCode;
}
/**
* Get the process that is launched by this task.
* @return a {@link Process} instance.
*/
public Process getProcess()
{
return process;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy