/* * Created on May 4, 2006 */ package com.openedit.util; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Element; import org.openedit.util.FinalizedProcess; import org.openedit.util.FinalizedProcessBuilder; import org.openedit.xml.XmlArchive; import org.openedit.xml.XmlFile; import com.openedit.OpenEditException; public class Exec { private static final Log log = LogFactory.getLog(Exec.class); protected long fieldTimeLimit = 3600000L; //1h max, make video conversions be longer protected String fieldXmlCommandsFilename; protected HashMap<String, ExecCommand> fieldCachedCommands; protected XmlArchive fieldXmlArchive; protected File fieldRoot; protected OutputFiller fieldFiller; protected Boolean fieldOnWindows; protected ExecutorManager fieldExecutorManager; public ExecutorManager getExecutorManager() { if (fieldExecutorManager == null) { fieldExecutorManager = new ExecutorManager(); } return fieldExecutorManager; } public void setExecutorManager(ExecutorManager inExecutorManager) { fieldExecutorManager = inExecutorManager; } public OutputFiller getFiller() { if (fieldFiller == null) { fieldFiller = new OutputFiller(); } return fieldFiller; } public Exec() { fieldCachedCommands = new HashMap<String, ExecCommand>(); } public long getTimeLimit() { return fieldTimeLimit; } public void setTimeLimit(long inTimelimit) { fieldTimeLimit = inTimelimit; } /** * @deprecated Use a command key * @param inArgs * @return */ public ExecResult runExec(List<String> inArgs) { return runExec(inArgs, null, false); } /** * @deprecated Use a command key */ public ExecResult runExec(List<String> inArgs, boolean inSaveOutput) { return runExec(inArgs, null, inSaveOutput); } public ExecResult runExec(String inCommandKey, List<String> inArgs) { return runExec(inCommandKey, inArgs, getTimeLimit()); } public ExecResult runExec(String inCommandKey, List<String> inArgs, long inTimeout) { return runExec(inCommandKey, inArgs, false, null, inTimeout); } public ExecResult runExec(String inCommandKey, List<String> inArgs, File inRootFolder) { return runExec(inCommandKey, inArgs, false, inRootFolder, getTimeLimit()); } public ExecResult runExec(String inCommandKey, List<String> inArgs, boolean inSaveOutput) { return runExec(inCommandKey, inArgs, inSaveOutput, getTimeLimit()); } public ExecResult runExec(String inCommandKey, List<String> inArgs, boolean inSaveOutput, long inTimeout) { return runExec(inCommandKey, inArgs, inSaveOutput, null, inTimeout); } public ExecResult runExec(String inCommandKey, List<String> inArgs, boolean inSaveOutput, File inRootFolder, long inTimeout) { ArrayList<String> command = new ArrayList<String>(); //check for cached version ExecCommand cachedCommand = (ExecCommand) fieldCachedCommands.get(inCommandKey); if (cachedCommand == null) { cachedCommand = lookUpCommand(inCommandKey); } command.add(cachedCommand.inCommand); if (inArgs != null && inArgs.size() > 0) { command.addAll(command.size(), inArgs); } if (inRootFolder == null) { return runExec(command, cachedCommand.inStartDir, inSaveOutput, inTimeout); } else { return runExec(command, inRootFolder, inSaveOutput, inTimeout); } } public ExecResult runExec(List<String> com, File inRunFrom, boolean inSaveOutput) throws OpenEditException { return runExec(com, inRunFrom, inSaveOutput, getTimeLimit()); } public ExecResult runExec(List<String> com, File inRunFrom, boolean inSaveOutput, long inTimeout) throws OpenEditException { if( inTimeout == -1) { inTimeout = getTimeLimit(); } log.info("Running: " + com); FinalizedProcessBuilder pb = new FinalizedProcessBuilder(com).keepProcess(false).logInputtStream(inSaveOutput); if(isOnWindows()) { pb.environment().put("HOME", inRunFrom.getAbsolutePath()); } ExecResult result = new ExecResult(); try { FinalizedProcess process = pb.start(getExecutorManager()); try { int returnVal = process.waitFor(inTimeout); if (inSaveOutput) { result.setStandardOut(process.getStandardOutputs()); } if (returnVal == 0) { result.setRunOk(true); } result.setReturnValue(returnVal); } finally { //Stream should be read in fully then it returns the code process.close(); } } catch (Exception ex) { log.error(ex); result.setRunOk(false); result.setReturnValue(1); //0 is success 1 is error } return result; } public String getXmlCommandsFilename() { return fieldXmlCommandsFilename; } public void setXmlCommandsFilename(String xmlCommands) { fieldXmlCommandsFilename = xmlCommands; } public XmlArchive getXmlArchive() { return fieldXmlArchive; } public void setXmlArchive(XmlArchive xmlArchive) { fieldXmlArchive = xmlArchive; } public File getRoot() { return fieldRoot; } public void setRoot(File root) { fieldRoot = root; } public String makeAbsolute(String inCommandBase) { if (inCommandBase.startsWith("./")) { inCommandBase = new File(getRoot(), inCommandBase.substring(2)).getAbsolutePath(); } if (!inCommandBase.endsWith("/")) { inCommandBase += "/"; } return inCommandBase; } public Boolean isOnWindows() { if (fieldOnWindows == null) { if (System.getProperty("os.name").toUpperCase().contains("WINDOWS")) { fieldOnWindows = Boolean.TRUE; } else { fieldOnWindows = Boolean.FALSE; } } return fieldOnWindows; } public void setIsOnWindows(boolean inBoolean) { fieldOnWindows = inBoolean; } protected ExecCommand lookUpCommand(String inCommandKey) { ExecCommand cachedCommand = null; //we need to search the xml file XmlFile file = fieldXmlArchive.getXml(fieldXmlCommandsFilename, "commandmaps"); if (file != null) { String os = System.getProperty("os.name").toUpperCase(); Iterator<Element> iter = (Iterator) file.getElements("commandmap"); while (iter.hasNext()) { // check for correct os Element map = (Element) iter.next(); String mapOs = map.attributeValue("os"); if (mapOs != null && os.contains(mapOs)) { cachedCommand = new ExecCommand(); String commandBase = map.elementText("commandbase"); if (commandBase != null) { commandBase = commandBase.replace('\\', '/'); //Make sure all commands are in Linux notation for now if (commandBase.startsWith("./") || commandBase.startsWith("../")) { String root = getRoot().getAbsolutePath(); root = root.replace('\\', '/'); if (root.endsWith("/")) { root = root.substring(0, root.length() - 1); } commandBase = PathUtilities.buildRelative(commandBase, root); } //commandBase = commandBase.replace('\\', '/'); //Make sure all commands are in Linux notation for now } else { commandBase = getRoot().getAbsolutePath(); } String commandText = map.elementText(inCommandKey); if (commandText == null) //Did not exists { cachedCommand.inCommand = inCommandKey; cachedCommand.inStartDir = new File(commandBase); } else { if (commandText.startsWith("./") || commandText.startsWith(".\\") || commandText.startsWith("../") || commandText.startsWith("..\\")) { commandText = commandText.replace('\\', '/'); //Make sure all commands are in Linux notation for now String commandline = PathUtilities.buildRelative(commandText, commandBase); File commandfile = new File(commandline); cachedCommand.inStartDir = commandfile.getParentFile(); cachedCommand.inCommand = commandfile.getAbsolutePath(); } else { cachedCommand.inStartDir = new File(commandBase); //TODO: Use the command for the parent dir? cachedCommand.inCommand = commandText; } } fieldCachedCommands.put(inCommandKey, cachedCommand); break; } } } //there was no trace of the command in the xml file so we will just execute //from the system path if (cachedCommand == null) { cachedCommand = new ExecCommand(); cachedCommand.inCommand = inCommandKey; fieldCachedCommands.put(inCommandKey, cachedCommand); } return cachedCommand; } class ExecCommand { protected String inCommand; protected File inStartDir; } }