/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.components.script.execution; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.script.ScriptEngine; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import de.rcenvironment.components.script.common.ScriptComponentHistoryDataItem; import de.rcenvironment.components.script.common.registry.ScriptExecutor; import de.rcenvironment.core.component.api.ComponentException; import de.rcenvironment.core.component.execution.api.ComponentContext; import de.rcenvironment.core.component.execution.api.ConsoleRow; import de.rcenvironment.core.component.scripting.WorkflowConsoleForwardingWriter; import de.rcenvironment.core.datamodel.api.TypedDatum; import de.rcenvironment.core.datamodel.api.TypedDatumFactory; import de.rcenvironment.core.datamodel.api.TypedDatumService; import de.rcenvironment.core.scripting.ScriptDataTypeHelper; import de.rcenvironment.core.scripting.ScriptingService; import de.rcenvironment.core.utils.common.TempFileServiceAccess; import de.rcenvironment.core.utils.scripting.ScriptLanguage; /** * Implementation of {@link ScriptExecutor} to execute default script engines. * * @author Mark Geiger * @author Sascha Zur */ public abstract class DefaultScriptExecutor implements ScriptExecutor { protected static TypedDatumFactory typedDatumFactory; protected static ScriptingService scriptingService; protected static final String INPUT_STRING = " = \"%s\"\n"; protected static final String INPUT_NO_STRING = " = %s \n"; private static final Log LOGGER = LogFactory.getLog(DefaultScriptExecutor.class); protected ComponentContext componentContext; protected ScriptEngine scriptEngine; protected String wrappingScript; protected List<File> tempFiles = new LinkedList<File>(); protected File tempDir; protected ScriptComponentHistoryDataItem historyDataItem; protected Map<String, Object> stateMap; private Writer stdoutWriter; private Writer stderrWriter; /** * Resets the script component for being used in nested loops. */ @Override public void reset() { stateMap = new HashMap<String, Object>(); } @Override public boolean prepareExecutor(ComponentContext compCtx) throws ComponentException { this.componentContext = compCtx; try { tempDir = TempFileServiceAccess.getInstance().createManagedTempDir("scriptExecutor"); } catch (IOException e) { throw new ComponentException("Failed to create temporary directory needed to temporarely store input files/directories", e); } return true; } @Override public abstract void prepareNewRun(ScriptLanguage scriptLanguage, String userScript, ScriptComponentHistoryDataItem dataItem) throws ComponentException; @Override public void prepareOutputForRun() { final int buffer = 1024; StringWriter out = new StringWriter(buffer); StringWriter err = new StringWriter(buffer); stdoutWriter = new WorkflowConsoleForwardingWriter(out, componentContext.getLog(), ConsoleRow.Type.TOOL_OUT, null); stderrWriter = new WorkflowConsoleForwardingWriter(err, componentContext.getLog(), ConsoleRow.Type.TOOL_ERROR, null); scriptEngine.getContext().setWriter(stdoutWriter); scriptEngine.getContext().setErrorWriter(stderrWriter); } @Override public abstract void runScript() throws ComponentException; @Override public abstract void cancelScript(); public long getCurrentRunNumber() { return componentContext.getExecutionCount(); } @Override public abstract boolean postRun() throws ComponentException; protected void closeConsoleWriters() throws IOException { stderrWriter.flush(); stderrWriter.close(); stdoutWriter.flush(); stdoutWriter.close(); } protected TypedDatum getTypedDatum(Object value) { return ScriptDataTypeHelper.getTypedDatum(value, componentContext.getService(TypedDatumService.class).getFactory()); } @Override public void deleteTempFiles() { // delete all temporary created files try { TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(tempDir); } catch (IOException e) { LOGGER.error("Failed to delete temporary directory " + "(probably because a file were not properly closed in the Python script)", e); } } @Override public void setComponentContext(ComponentContext componentContext) { this.componentContext = componentContext; } @Override public void setScriptEngine(ScriptEngine scriptEngine) { this.scriptEngine = scriptEngine; } @Override public void setHistoryDataItem(ScriptComponentHistoryDataItem historyDataItem) { this.historyDataItem = historyDataItem; } @Override public void setStateMap(Map<String, Object> stateMap) { this.stateMap = stateMap; } @Override public void setStdoutWriter(Writer stdoutWriter) { this.stdoutWriter = stdoutWriter; } @Override public void setStderrWriter(Writer stderrWriter) { this.stderrWriter = stderrWriter; } @Override public void setWorkingPath(String path) {} }