/*
* Lokomo OneCMDB - An Open Source Software for Configuration
* Management of Datacenter Resources
*
* Copyright (C) 2006 Lokomo Systems AB
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via
* paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33
* Danderyd, Sweden.
*
*/
package org.onecmdb.ui.gwt.desktop.server.command.exec;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.onecmdb.ui.gwt.desktop.client.service.content.ContentServiceFactory;
import org.onecmdb.ui.gwt.desktop.server.service.model.ConfigurationFactory;
public class JavaExec {
Log log = LogFactory.getLog(this.getClass());
String shells = "AUTO:,BASH:/bin/bash,PERL:/usr/bin/perl,CMD:CMD /C,ACTIVEPERL:/usr/local/ActivePerl-5.6/bin/perl";
private File startDir;
private String program;
private HashMap<String, String> params;
private Process process;
private StreamHandler streamHandler;
private Properties shellMap = new Properties();
private MDRExecThread control;
public JavaExec(MDRExecThread execThread) {
this.control = execThread;
// Set default shell map.
shellMap.put(".bat", "CMD /C");
shellMap.put(".sh", "/bin/bash");
shellMap.put(".pl", "/usr/bin/perl");
}
public Properties getShellMap() {
return shellMap;
}
public void setShellMap(Properties shellMap) {
this.shellMap = shellMap;
}
public void setStreamHandler(StreamHandler streamHandler) {
this.streamHandler = streamHandler;
}
public void setStartDir(String dir) {
this.startDir = new File(dir);
}
public void setProgramPath(String prg) {
this.program = prg;
}
public void setProgramArgs(HashMap<String, String> params) {
this.params = params;
}
/**
*
* Start the handled program
* @param unpackdir Directory containing the files in the Job Definition
* @throws IOException
*/
public ExecResult doExec() {
ExecResult result = new ExecResult();
String program = reolveProgram();
List<String> shellArgs = resolveShell(program);
List<String> params = reloveParams();
List<String> cmdList = new ArrayList<String>();
cmdList.addAll(shellArgs);
cmdList.add(program);
cmdList.addAll(params);
liveLog("CMD-LIST : " + cmdList.toString());
log.info("Startup Directory:" + startDir);
for (int i = 0; i < cmdList.size(); i++) {
log.info("$" + i + ": " + cmdList.get(i));
}
// Do some checks.
if (!startDir.isDirectory()) {
result.setRc(ExecResult.ERROR_NO_STARTUP_DIR);
result.setMessage("Starup directory `" + startDir + "' not accessible.");
return(result);
}
File f = new File(program);
if (!f.exists()) {
result.setRc(ExecResult.ERROR_NO_PROGRAM);
result.setMessage("Program `" + program + "' is not found.");
return(result);
}
if (f.isDirectory()) {
result.setRc(ExecResult.ERROR_NO_PROGRAM);
result.setMessage("Program `" + program + "' is a directory.");
return(result);
}
try {
// let us start it now...
Runtime runtime = Runtime.getRuntime();
this.process = runtime.exec( cmdList.toArray(new String[0]), null, startDir );
// handle the streams
if (this.streamHandler != null) {
streamHandler.setStdin(new OutputStreamWriter(this.process.getOutputStream()));
streamHandler.setStdout(new BufferedReader(new InputStreamReader(this.process.getInputStream())));
streamHandler.setStderr(new BufferedReader(new InputStreamReader(this.process.getErrorStream())));
}
// according to the contract for `doExec' we should wait until the
// the process has finished.
int rc = this.process.waitFor();
result.setRc(rc);
this.process = null;
} catch (InterruptedException e) {
log.info("Execution interrupted. " + e.getMessage());
result.setRc(ExecResult.ERROR_INTERRUPTED);
result.setMessage("Execution interrupted. " + e.getMessage());
} catch (Throwable e) {
log.error("Failed to compleate execution. " + e.getMessage(), e);
result.setRc(ExecResult.ERROR_EXCEPTION);
result.setMessage("Execution <" + program + "> failed. Reason " + e.getMessage());
}
return result;
}
private void liveLog(String msg) {
if (this.control != null) {
this.control.log(msg);
}
}
private List<String> reloveParams() {
List<String> args = new ArrayList<String>();
if (this.params == null) {
return(args);
}
for (String arg : params.keySet()) {
String value = params.get(arg);
if (value == null) {
continue;
}
value = value.trim();
// Handling space....
value = value.replace(' ', '_');
if (isUNIX()) {
args.add("--" + arg);
args.add(value);
} else {
args.add("/" + arg + ":" + value);
}
}
return(args);
}
private List<String> resolveShell(String program) {
File f = new File(program);
String ext = "";
int index = program.lastIndexOf(".");
if (index > 0) {
ext = program.substring(index);
}
String shell = shellMap.getProperty(ext);
liveLog("Shell for " + ext + " resolved to '" + shell + "'");
if (shell == null) {
return(new ArrayList<String>());
}
String args[] = shell.split(" ");
List<String> shellArgs = Arrays.asList(args);
return(shellArgs);
}
private String reolveProgram() {
File f = new File(program);
if (!f.exists()) {
String ext = "";
// Check type of OS, eq UNIX or Windows -->.bat or .sh
if (isUNIX()) {
ext = ".sh";
} else {
ext =".bat";
}
f = new File(program + ext);
}
return(f.getPath());
}
public boolean isUNIX() {
String sep = System.getProperty("file.separator");
return(sep.equals("/"));
}
/* (non-Javadoc)
* @see com.lokomo.executor.Job#halt()
*/
protected void halt() {
if (this.process != null) {
this.process.destroy();
}
}
}