/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.impl.wsdl.actions.iface.tools.support; import com.eviware.soapui.model.ModelItem; import com.eviware.soapui.support.UISupport; import java.io.InputStream; /** * ToolRunner for running command-line processes * * @author ole.matzura */ public class ProcessToolRunner implements ToolRunner { private final ProcessBuilder[] builders; private boolean running; private Process process; private RunnerContext context; private final String name; private final ModelItem modelItem; private boolean canCancel = true; private boolean showLog = true; private ArgumentBuilder args; public ProcessToolRunner(ProcessBuilder builder, String name, ModelItem modelItem, ArgumentBuilder args) { this(new ProcessBuilder[]{builder}, name, modelItem, args); } public ProcessToolRunner(ProcessBuilder[] builders, String name, ModelItem modelItem, ArgumentBuilder args) { this.builders = builders; this.name = name; this.modelItem = modelItem; this.args = args; } public ProcessToolRunner(ProcessBuilder[] processBuilders, String s, ModelItem modelItem) { this(processBuilders, s, modelItem, null); } public ProcessToolRunner(ProcessBuilder builder, String s, ModelItem modelItem) { this(builder, s, modelItem, null); } public ProcessBuilder[] getBuilders() { return builders; } public Process getProcess() { return process; } public boolean isRunning() { return running; } public void cancel() { getProcess().destroy(); try { getProcess().waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } running = false; } public void run() { try { int exitCode = -1; beforeRun(context); for (int c = 0; c < builders.length; c++) { beforeProcess(builders[c], context); logRunInfo(builders[c]); process = builders[c].start(); if (c == 0) { context.setStatus(RunnerContext.RunnerStatus.RUNNING); } running = true; InputStream in = process.getInputStream(); InputStream err = process.getErrorStream(); exitCode = -1; while (exitCode == -1 && running) { try { exitCode = process.exitValue(); break; } catch (IllegalThreadStateException e) { } finally { while (in.available() > 0) { byte[] data = new byte[in.available()]; in.read(data); context.log(new String(data)); } while (err.available() > 0) { byte[] data = new byte[err.available()]; err.read(data); context.logError(new String(data)); } } Thread.sleep(25); } afterProcess(process, context); } context.setStatus(RunnerContext.RunnerStatus.FINISHED); if (running) { running = false; afterRun(exitCode, context); } } catch (Exception ex) { context.setStatus(RunnerContext.RunnerStatus.ERROR); UISupport.showErrorMessage(ex); running = false; afterRun(-1, context); } finally { context.disposeContext(); } } protected void beforeRun(RunnerContext context) { } protected void beforeProcess(ProcessBuilder processBuilder, RunnerContext context) { } protected void afterProcess(Process process2, RunnerContext context) { } protected void afterRun(int exitCode, RunnerContext context) { if (exitCode == 0) { UISupport.showInfoMessage("Execution finished successfully", context.getTitle()); } else { UISupport.showInfoMessage("Execution finished with errorCode " + exitCode + ",\r\nplease check log for error messages", context.getTitle()); } } private void logRunInfo(ProcessBuilder builder) { context.log("directory: " + builder.directory().getAbsolutePath() + "\r\n"); context.log("command: " + (args == null ? builder.command() : args) + "\r\n"); } public void setContext(RunnerContext context) { this.context = context; } public ModelItem getModelItem() { return modelItem; } public String getName() { return name; } public boolean canCancel() { return canCancel; } public boolean showLog() { return showLog; } public void setCanCancel(boolean canCancel) { this.canCancel = canCancel; } public void setShowLog(boolean showLog) { this.showLog = showLog; } public String getDescription() { return null; } }