1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski package helper; 24*b1cdbd2cSJim Jagielski 25*b1cdbd2cSJim Jagielski import java.io.BufferedReader; 26*b1cdbd2cSJim Jagielski import java.io.InputStream; 27*b1cdbd2cSJim Jagielski import java.io.File; 28*b1cdbd2cSJim Jagielski import java.io.PrintWriter; 29*b1cdbd2cSJim Jagielski import java.io.PrintStream; 30*b1cdbd2cSJim Jagielski import java.io.LineNumberReader; 31*b1cdbd2cSJim Jagielski import java.io.InputStreamReader; 32*b1cdbd2cSJim Jagielski import java.io.OutputStreamWriter; 33*b1cdbd2cSJim Jagielski import java.io.Writer; 34*b1cdbd2cSJim Jagielski import java.util.Calendar; 35*b1cdbd2cSJim Jagielski import java.util.Date; 36*b1cdbd2cSJim Jagielski import java.util.GregorianCalendar; 37*b1cdbd2cSJim Jagielski import lib.TestParameters; 38*b1cdbd2cSJim Jagielski import share.LogWriter; 39*b1cdbd2cSJim Jagielski import util.PropertyName; 40*b1cdbd2cSJim Jagielski import util.utils; 41*b1cdbd2cSJim Jagielski 42*b1cdbd2cSJim Jagielski /** 43*b1cdbd2cSJim Jagielski * Class collect information from input stream in 44*b1cdbd2cSJim Jagielski * background (sparate thread) and outputs it to 45*b1cdbd2cSJim Jagielski * some log stream. I helps to avoid buffer overflow 46*b1cdbd2cSJim Jagielski * when output stream has small buffer size (e.g. 47*b1cdbd2cSJim Jagielski * in case when handling stdout from external 48*b1cdbd2cSJim Jagielski * <code>Process</code>) 49*b1cdbd2cSJim Jagielski * 50*b1cdbd2cSJim Jagielski * This class is currently used by ProcesHandler 51*b1cdbd2cSJim Jagielski * internally only. 52*b1cdbd2cSJim Jagielski */ 53*b1cdbd2cSJim Jagielski class Pump extends Thread 54*b1cdbd2cSJim Jagielski { 55*b1cdbd2cSJim Jagielski 56*b1cdbd2cSJim Jagielski private LineNumberReader reader; 57*b1cdbd2cSJim Jagielski private String pref; 58*b1cdbd2cSJim Jagielski private StringBuffer buf = new StringBuffer(256); 59*b1cdbd2cSJim Jagielski private PrintWriter log; 60*b1cdbd2cSJim Jagielski private boolean bOutput; 61*b1cdbd2cSJim Jagielski 62*b1cdbd2cSJim Jagielski /** 63*b1cdbd2cSJim Jagielski * Creates Pump for specified <code>InputStream</code>. 64*b1cdbd2cSJim Jagielski * This Pump also synchronously output text read to 65*b1cdbd2cSJim Jagielski * log by prefixed lines. Constructor immediately 66*b1cdbd2cSJim Jagielski * starts reading in a separate thread. 67*b1cdbd2cSJim Jagielski * 68*b1cdbd2cSJim Jagielski * @param is Stream which requires permanent reading. 69*b1cdbd2cSJim Jagielski * @param log Writer where prefixed text lines to be output 70*b1cdbd2cSJim Jagielski * @param outPrefix A prefix which is printed at the 71*b1cdbd2cSJim Jagielski * beginning of each output line. 72*b1cdbd2cSJim Jagielski */ Pump(InputStream is, PrintWriter log, String outPrefix, boolean _bOutput)73*b1cdbd2cSJim Jagielski public Pump(InputStream is, PrintWriter log, String outPrefix, boolean _bOutput) 74*b1cdbd2cSJim Jagielski { 75*b1cdbd2cSJim Jagielski this.pref = (outPrefix == null) ? "" : outPrefix; 76*b1cdbd2cSJim Jagielski reader = new LineNumberReader(new InputStreamReader(is)); 77*b1cdbd2cSJim Jagielski this.log = log; 78*b1cdbd2cSJim Jagielski this.bOutput = _bOutput; 79*b1cdbd2cSJim Jagielski start(); 80*b1cdbd2cSJim Jagielski } 81*b1cdbd2cSJim Jagielski run()82*b1cdbd2cSJim Jagielski public void run() 83*b1cdbd2cSJim Jagielski { 84*b1cdbd2cSJim Jagielski try 85*b1cdbd2cSJim Jagielski { 86*b1cdbd2cSJim Jagielski String line = reader.readLine(); 87*b1cdbd2cSJim Jagielski while (line != null) 88*b1cdbd2cSJim Jagielski { 89*b1cdbd2cSJim Jagielski if (bOutput) 90*b1cdbd2cSJim Jagielski { 91*b1cdbd2cSJim Jagielski log.println(pref + line); 92*b1cdbd2cSJim Jagielski log.flush(); 93*b1cdbd2cSJim Jagielski } 94*b1cdbd2cSJim Jagielski buf.append(line).append('\n'); 95*b1cdbd2cSJim Jagielski line = reader.readLine(); 96*b1cdbd2cSJim Jagielski } 97*b1cdbd2cSJim Jagielski } 98*b1cdbd2cSJim Jagielski catch (java.io.IOException e) 99*b1cdbd2cSJim Jagielski { 100*b1cdbd2cSJim Jagielski log.println(pref + "Exception occured: " + e); 101*b1cdbd2cSJim Jagielski } 102*b1cdbd2cSJim Jagielski } 103*b1cdbd2cSJim Jagielski 104*b1cdbd2cSJim Jagielski /** 105*b1cdbd2cSJim Jagielski * Returns the text collected from input stream. 106*b1cdbd2cSJim Jagielski */ getStringBuffer()107*b1cdbd2cSJim Jagielski public String getStringBuffer() 108*b1cdbd2cSJim Jagielski { 109*b1cdbd2cSJim Jagielski return buf.toString(); 110*b1cdbd2cSJim Jagielski } 111*b1cdbd2cSJim Jagielski } 112*b1cdbd2cSJim Jagielski 113*b1cdbd2cSJim Jagielski /** 114*b1cdbd2cSJim Jagielski * Class provides convenient way for running external program 115*b1cdbd2cSJim Jagielski * handle its standard streams, control execution and check results. 116*b1cdbd2cSJim Jagielski * Instance of this class must be created only for a single 117*b1cdbd2cSJim Jagielski * execution. If you need to execute the same command again you 118*b1cdbd2cSJim Jagielski * should create a new instance for this. 119*b1cdbd2cSJim Jagielski */ 120*b1cdbd2cSJim Jagielski public class ProcessHandler 121*b1cdbd2cSJim Jagielski { 122*b1cdbd2cSJim Jagielski 123*b1cdbd2cSJim Jagielski private String cmdLine; 124*b1cdbd2cSJim Jagielski private String[] cmdLineArray; 125*b1cdbd2cSJim Jagielski private String[] envVars = null; 126*b1cdbd2cSJim Jagielski private File workDir = null; 127*b1cdbd2cSJim Jagielski private PrintWriter log; 128*b1cdbd2cSJim Jagielski private int exitValue = -1; 129*b1cdbd2cSJim Jagielski private boolean isFinished = false; 130*b1cdbd2cSJim Jagielski private boolean isStarted = false; 131*b1cdbd2cSJim Jagielski private boolean mbTimedOut = false; 132*b1cdbd2cSJim Jagielski private long mTimeOut = 0; 133*b1cdbd2cSJim Jagielski private String stdInBuff = ""; 134*b1cdbd2cSJim Jagielski private Pump stdout = null; 135*b1cdbd2cSJim Jagielski private Pump stderr = null; 136*b1cdbd2cSJim Jagielski private PrintStream stdIn = null; 137*b1cdbd2cSJim Jagielski private Process m_aProcess = null; 138*b1cdbd2cSJim Jagielski private TestParameters param = null; 139*b1cdbd2cSJim Jagielski private boolean debug = false; 140*b1cdbd2cSJim Jagielski private boolean bUseOutput = true; 141*b1cdbd2cSJim Jagielski 142*b1cdbd2cSJim Jagielski private int m_nProcessTimeout = 0; 143*b1cdbd2cSJim Jagielski private String m_sProcessKiller; 144*b1cdbd2cSJim Jagielski private ProcessWatcher m_aWatcher; 145*b1cdbd2cSJim Jagielski 146*b1cdbd2cSJim Jagielski /** 147*b1cdbd2cSJim Jagielski * Creates instance with specified external command. 148*b1cdbd2cSJim Jagielski * Debug info and output 149*b1cdbd2cSJim Jagielski * of external command is printed to stdout. 150*b1cdbd2cSJim Jagielski * @param cmdLine 151*b1cdbd2cSJim Jagielski */ ProcessHandler(String cmdLine)152*b1cdbd2cSJim Jagielski public ProcessHandler(String cmdLine) 153*b1cdbd2cSJim Jagielski { 154*b1cdbd2cSJim Jagielski this(cmdLine, null, null, null, 0); 155*b1cdbd2cSJim Jagielski } 156*b1cdbd2cSJim Jagielski 157*b1cdbd2cSJim Jagielski /** 158*b1cdbd2cSJim Jagielski * Creates instance with specified external command 159*b1cdbd2cSJim Jagielski * including parameters as an array. 160*b1cdbd2cSJim Jagielski * Debug info and output 161*b1cdbd2cSJim Jagielski * of external command is printed to stdout. 162*b1cdbd2cSJim Jagielski * @param cmdLines 163*b1cdbd2cSJim Jagielski */ ProcessHandler(String[] cmdLines)164*b1cdbd2cSJim Jagielski public ProcessHandler(String[] cmdLines) 165*b1cdbd2cSJim Jagielski { 166*b1cdbd2cSJim Jagielski this(null, null, null, null, 0); 167*b1cdbd2cSJim Jagielski cmdLineArray = cmdLines; 168*b1cdbd2cSJim Jagielski } 169*b1cdbd2cSJim Jagielski 170*b1cdbd2cSJim Jagielski /** 171*b1cdbd2cSJim Jagielski * Creates instance with specified external command 172*b1cdbd2cSJim Jagielski * including parameters as an array, with environment 173*b1cdbd2cSJim Jagielski * variables. 174*b1cdbd2cSJim Jagielski * Debug info and output 175*b1cdbd2cSJim Jagielski * of external command is printed to stdout. 176*b1cdbd2cSJim Jagielski * @param cmdLines 177*b1cdbd2cSJim Jagielski * @param envVars 178*b1cdbd2cSJim Jagielski * @see java.lang.Runtime exec(String[], String[]) 179*b1cdbd2cSJim Jagielski */ ProcessHandler(String[] cmdLines, String[] envVars)180*b1cdbd2cSJim Jagielski public ProcessHandler(String[] cmdLines, String[] envVars) 181*b1cdbd2cSJim Jagielski { 182*b1cdbd2cSJim Jagielski this(null, null, null, envVars, 0); 183*b1cdbd2cSJim Jagielski cmdLineArray = cmdLines; 184*b1cdbd2cSJim Jagielski } 185*b1cdbd2cSJim Jagielski 186*b1cdbd2cSJim Jagielski /** 187*b1cdbd2cSJim Jagielski * Creates instance with specified external command 188*b1cdbd2cSJim Jagielski * including parameters as an array, with environment 189*b1cdbd2cSJim Jagielski * variables. The command will be started in workDir. 190*b1cdbd2cSJim Jagielski * Debug info and output 191*b1cdbd2cSJim Jagielski * of external command is printed to stdout. 192*b1cdbd2cSJim Jagielski * @param cmdLines 193*b1cdbd2cSJim Jagielski * @param workDir 194*b1cdbd2cSJim Jagielski */ ProcessHandler(String[] cmdLines, File workDir)195*b1cdbd2cSJim Jagielski public ProcessHandler(String[] cmdLines, File workDir) 196*b1cdbd2cSJim Jagielski { 197*b1cdbd2cSJim Jagielski this(null, null, workDir, null, 0); 198*b1cdbd2cSJim Jagielski cmdLineArray = cmdLines; 199*b1cdbd2cSJim Jagielski 200*b1cdbd2cSJim Jagielski } 201*b1cdbd2cSJim Jagielski 202*b1cdbd2cSJim Jagielski /** 203*b1cdbd2cSJim Jagielski * Creates instance with specified external command and 204*b1cdbd2cSJim Jagielski * log stream where debug info and output 205*b1cdbd2cSJim Jagielski * of external command is printed out. The command will be started in workDir. 206*b1cdbd2cSJim Jagielski * @param cmdLines 207*b1cdbd2cSJim Jagielski * @param log 208*b1cdbd2cSJim Jagielski * @param workDir 209*b1cdbd2cSJim Jagielski */ ProcessHandler(String[] cmdLines, PrintWriter log, File workDir)210*b1cdbd2cSJim Jagielski public ProcessHandler(String[] cmdLines, PrintWriter log, File workDir) 211*b1cdbd2cSJim Jagielski { 212*b1cdbd2cSJim Jagielski this(null, log, workDir, null, 0); 213*b1cdbd2cSJim Jagielski cmdLineArray = cmdLines; 214*b1cdbd2cSJim Jagielski } 215*b1cdbd2cSJim Jagielski 216*b1cdbd2cSJim Jagielski /** 217*b1cdbd2cSJim Jagielski * Creates instance with specified external command and 218*b1cdbd2cSJim Jagielski * log stream where debug info and output 219*b1cdbd2cSJim Jagielski * of external command is printed out. 220*b1cdbd2cSJim Jagielski * @param cmdLine 221*b1cdbd2cSJim Jagielski * @param log 222*b1cdbd2cSJim Jagielski */ ProcessHandler(String cmdLine, PrintWriter log)223*b1cdbd2cSJim Jagielski public ProcessHandler(String cmdLine, PrintWriter log) 224*b1cdbd2cSJim Jagielski { 225*b1cdbd2cSJim Jagielski this(cmdLine, log, null, null, 0); 226*b1cdbd2cSJim Jagielski } 227*b1cdbd2cSJim Jagielski 228*b1cdbd2cSJim Jagielski /** 229*b1cdbd2cSJim Jagielski * Creates instance with specified external command and set the time out for the command. 230*b1cdbd2cSJim Jagielski * @param cmdLine 231*b1cdbd2cSJim Jagielski * @param timeOut 232*b1cdbd2cSJim Jagielski */ ProcessHandler(String cmdLine, int timeOut)233*b1cdbd2cSJim Jagielski public ProcessHandler(String cmdLine, int timeOut) 234*b1cdbd2cSJim Jagielski { 235*b1cdbd2cSJim Jagielski this(cmdLine, null, null, null, timeOut); 236*b1cdbd2cSJim Jagielski } 237*b1cdbd2cSJim Jagielski 238*b1cdbd2cSJim Jagielski /** 239*b1cdbd2cSJim Jagielski * Creates instance with specified external command which 240*b1cdbd2cSJim Jagielski * will be executed in the some work directory. 241*b1cdbd2cSJim Jagielski * Debug info and output 242*b1cdbd2cSJim Jagielski * of external commandis printed to stdout. 243*b1cdbd2cSJim Jagielski * @param cmdLine 244*b1cdbd2cSJim Jagielski * @param workDir 245*b1cdbd2cSJim Jagielski */ ProcessHandler(String cmdLine, File workDir)246*b1cdbd2cSJim Jagielski public ProcessHandler(String cmdLine, File workDir) 247*b1cdbd2cSJim Jagielski { 248*b1cdbd2cSJim Jagielski this(cmdLine, null, workDir, null, 0); 249*b1cdbd2cSJim Jagielski } 250*b1cdbd2cSJim Jagielski 251*b1cdbd2cSJim Jagielski /** 252*b1cdbd2cSJim Jagielski * Creates instance with specified external command which 253*b1cdbd2cSJim Jagielski * will be executed in the some work directory. 254*b1cdbd2cSJim Jagielski * Debug info and output printed in log stream. 255*b1cdbd2cSJim Jagielski * @param cmdLine 256*b1cdbd2cSJim Jagielski * @param log 257*b1cdbd2cSJim Jagielski * @param workDir 258*b1cdbd2cSJim Jagielski */ ProcessHandler(String cmdLine, PrintWriter log, File workDir)259*b1cdbd2cSJim Jagielski public ProcessHandler(String cmdLine, PrintWriter log, File workDir) 260*b1cdbd2cSJim Jagielski { 261*b1cdbd2cSJim Jagielski this(cmdLine, log, workDir, null, 0); 262*b1cdbd2cSJim Jagielski } 263*b1cdbd2cSJim Jagielski 264*b1cdbd2cSJim Jagielski /** 265*b1cdbd2cSJim Jagielski * Creates instance with specified external command which 266*b1cdbd2cSJim Jagielski * will be executed in the some work directory and 267*b1cdbd2cSJim Jagielski * log stream where debug info and output 268*b1cdbd2cSJim Jagielski * of external command is printed . 269*b1cdbd2cSJim Jagielski * The specified environment variables are set for the new process. 270*b1cdbd2cSJim Jagielski * If log stream is null, logging is printed to stdout. 271*b1cdbd2cSJim Jagielski * @param cmdLine 272*b1cdbd2cSJim Jagielski * @param log 273*b1cdbd2cSJim Jagielski * @param workDir 274*b1cdbd2cSJim Jagielski * @param envVars 275*b1cdbd2cSJim Jagielski */ ProcessHandler(String cmdLine, PrintWriter log, File workDir, String[] envVars)276*b1cdbd2cSJim Jagielski public ProcessHandler(String cmdLine, PrintWriter log, File workDir, String[] envVars) 277*b1cdbd2cSJim Jagielski { 278*b1cdbd2cSJim Jagielski this(cmdLine, log, workDir, envVars, 0); 279*b1cdbd2cSJim Jagielski } 280*b1cdbd2cSJim Jagielski 281*b1cdbd2cSJim Jagielski /** 282*b1cdbd2cSJim Jagielski * Creates instance with specified external command which 283*b1cdbd2cSJim Jagielski * will be executed in the some work directory and 284*b1cdbd2cSJim Jagielski * 285*b1cdbd2cSJim Jagielski * @param cmdLine the command to be executed 286*b1cdbd2cSJim Jagielski * @param log log stream where debug info and output 287*b1cdbd2cSJim Jagielski * of external command is printed . 288*b1cdbd2cSJim Jagielski * @param workDir The working directory of the new process 289*b1cdbd2cSJim Jagielski * @param envVars The specified environment variables are 290*b1cdbd2cSJim Jagielski * set for the new process. 291*b1cdbd2cSJim Jagielski * If log stream is null, logging is printed to stdout. 292*b1cdbd2cSJim Jagielski * @param timeOut When started sychronisly, the maximum time the 293*b1cdbd2cSJim Jagielski * process will live. When the process being destroyed 294*b1cdbd2cSJim Jagielski * a log will be written out. It can be asked on 295*b1cdbd2cSJim Jagielski * <code>isTimedOut()</code> if it has been terminated. 296*b1cdbd2cSJim Jagielski * 297*b1cdbd2cSJim Jagielski * timeOut > 0 298*b1cdbd2cSJim Jagielski * Waits specified time in miliSeconds for 299*b1cdbd2cSJim Jagielski * process to exit and return its status. 300*b1cdbd2cSJim Jagielski * 301*b1cdbd2cSJim Jagielski * timeOut = 0 302*b1cdbd2cSJim Jagielski * Waits for the process to end regulary 303*b1cdbd2cSJim Jagielski * 304*b1cdbd2cSJim Jagielski * timeOut < 0 305*b1cdbd2cSJim Jagielski * Kills the process immediately 306*b1cdbd2cSJim Jagielski * 307*b1cdbd2cSJim Jagielski * 308*b1cdbd2cSJim Jagielski */ ProcessHandler(String cmdLine, PrintWriter log, File workDir, String[] envVars, long timeOut)309*b1cdbd2cSJim Jagielski public ProcessHandler(String cmdLine, PrintWriter log, File workDir, String[] envVars, long timeOut) 310*b1cdbd2cSJim Jagielski { 311*b1cdbd2cSJim Jagielski this.cmdLine = cmdLine; 312*b1cdbd2cSJim Jagielski this.workDir = workDir; 313*b1cdbd2cSJim Jagielski this.log = log; 314*b1cdbd2cSJim Jagielski this.cmdLine = cmdLine; 315*b1cdbd2cSJim Jagielski this.envVars = envVars; 316*b1cdbd2cSJim Jagielski if (log == null) 317*b1cdbd2cSJim Jagielski { 318*b1cdbd2cSJim Jagielski this.log = new PrintWriter(new OutputStreamWriter(System.out)); 319*b1cdbd2cSJim Jagielski } 320*b1cdbd2cSJim Jagielski else 321*b1cdbd2cSJim Jagielski { 322*b1cdbd2cSJim Jagielski this.log = log; 323*b1cdbd2cSJim Jagielski } 324*b1cdbd2cSJim Jagielski this.mTimeOut = timeOut; 325*b1cdbd2cSJim Jagielski } 326*b1cdbd2cSJim Jagielski 327*b1cdbd2cSJim Jagielski /** 328*b1cdbd2cSJim Jagielski * Creates instance with specified external command which 329*b1cdbd2cSJim Jagielski * will be executed in the some work directory and 330*b1cdbd2cSJim Jagielski * log stream where debug info and output of external command is printed. 331*b1cdbd2cSJim Jagielski * If log stream is null, logging is printed to stdout. 332*b1cdbd2cSJim Jagielski * From the <CODE>TestParameters</CODE> the <CODE>OfficeWachter</CODE> get a ping. 333*b1cdbd2cSJim Jagielski * @param commands 334*b1cdbd2cSJim Jagielski * @param log 335*b1cdbd2cSJim Jagielski * @param workDir 336*b1cdbd2cSJim Jagielski * @param shortWait If this parameter is ture the <CODE>mTimeOut</CODE> is set to 5000 ms, else it is set to 337*b1cdbd2cSJim Jagielski * half of time out from parameter timeout. 338*b1cdbd2cSJim Jagielski * @param param the TestParameters 339*b1cdbd2cSJim Jagielski * @see lib.TestParameters 340*b1cdbd2cSJim Jagielski * @see helper.OfficeWatcher 341*b1cdbd2cSJim Jagielski */ ProcessHandler(String[] commands, PrintWriter log, File workDir, int shortWait, TestParameters param)342*b1cdbd2cSJim Jagielski public ProcessHandler(String[] commands, PrintWriter log, File workDir, int shortWait, TestParameters param) 343*b1cdbd2cSJim Jagielski { 344*b1cdbd2cSJim Jagielski this(null, log, workDir, null, 0); 345*b1cdbd2cSJim Jagielski this.cmdLineArray = commands; 346*b1cdbd2cSJim Jagielski this.param = param; 347*b1cdbd2cSJim Jagielski if (shortWait != 0) 348*b1cdbd2cSJim Jagielski { 349*b1cdbd2cSJim Jagielski this.mTimeOut = shortWait; 350*b1cdbd2cSJim Jagielski } 351*b1cdbd2cSJim Jagielski else 352*b1cdbd2cSJim Jagielski { 353*b1cdbd2cSJim Jagielski this.mTimeOut = (long) (param.getInt(PropertyName.TIME_OUT) / 1.3); 354*b1cdbd2cSJim Jagielski } 355*b1cdbd2cSJim Jagielski debug = param.getBool(PropertyName.DEBUG_IS_ACTIVE); 356*b1cdbd2cSJim Jagielski 357*b1cdbd2cSJim Jagielski } 358*b1cdbd2cSJim Jagielski 359*b1cdbd2cSJim Jagielski /** 360*b1cdbd2cSJim Jagielski * If not equal 0, the time to maximal wait. 361*b1cdbd2cSJim Jagielski * @param _n 362*b1cdbd2cSJim Jagielski */ setProcessTimeout(int _n)363*b1cdbd2cSJim Jagielski public void setProcessTimeout(int _n) 364*b1cdbd2cSJim Jagielski { 365*b1cdbd2cSJim Jagielski m_nProcessTimeout = _n; 366*b1cdbd2cSJim Jagielski } 367*b1cdbd2cSJim Jagielski 368*b1cdbd2cSJim Jagielski /** 369*b1cdbd2cSJim Jagielski * This command will call after ProcessTimeout is arrived. 370*b1cdbd2cSJim Jagielski * @param _s 371*b1cdbd2cSJim Jagielski */ setProcessKiller(String _s)372*b1cdbd2cSJim Jagielski public void setProcessKiller(String _s) 373*b1cdbd2cSJim Jagielski { 374*b1cdbd2cSJim Jagielski m_sProcessKiller = _s; 375*b1cdbd2cSJim Jagielski } 376*b1cdbd2cSJim Jagielski 377*b1cdbd2cSJim Jagielski /** 378*b1cdbd2cSJim Jagielski * This method do an asynchronous execution of the commands. To avoid a interruption on long running processes 379*b1cdbd2cSJim Jagielski * caused by <CODE>OfficeWatcher</CODE>, the OfficeWatcher get frequently a ping. 380*b1cdbd2cSJim Jagielski * @see helper.OfficeWatcher 381*b1cdbd2cSJim Jagielski */ runCommand()382*b1cdbd2cSJim Jagielski public void runCommand() 383*b1cdbd2cSJim Jagielski { 384*b1cdbd2cSJim Jagielski 385*b1cdbd2cSJim Jagielski boolean changedText = true; 386*b1cdbd2cSJim Jagielski int count = 0; 387*b1cdbd2cSJim Jagielski String memText = ""; 388*b1cdbd2cSJim Jagielski 389*b1cdbd2cSJim Jagielski this.executeAsynchronously(); 390*b1cdbd2cSJim Jagielski 391*b1cdbd2cSJim Jagielski OfficeWatcher ow = null; 392*b1cdbd2cSJim Jagielski if (param != null) 393*b1cdbd2cSJim Jagielski { 394*b1cdbd2cSJim Jagielski ow = (OfficeWatcher) param.get(PropertyName.OFFICE_WATCHER); 395*b1cdbd2cSJim Jagielski } 396*b1cdbd2cSJim Jagielski if (ow != null) 397*b1cdbd2cSJim Jagielski { 398*b1cdbd2cSJim Jagielski ow.ping(); 399*b1cdbd2cSJim Jagielski } 400*b1cdbd2cSJim Jagielski 401*b1cdbd2cSJim Jagielski int hangcheck = 10; 402*b1cdbd2cSJim Jagielski while (!this.isFinished() && changedText) 403*b1cdbd2cSJim Jagielski { 404*b1cdbd2cSJim Jagielski count++; 405*b1cdbd2cSJim Jagielski // dbg("runCommand: waiting " + mTimeOut / 1000 + " seconds while command execution is ongoing... " + count); 406*b1cdbd2cSJim Jagielski // shortWait(mTimeOut); 407*b1cdbd2cSJim Jagielski // shortWait(2000); // wait 2 seconds. 408*b1cdbd2cSJim Jagielski //waitFor(mTimeOut); 409*b1cdbd2cSJim Jagielski waitFor(2000, false); // wait but don't kill 410*b1cdbd2cSJim Jagielski 411*b1cdbd2cSJim Jagielski if (ow != null) 412*b1cdbd2cSJim Jagielski { 413*b1cdbd2cSJim Jagielski ow.ping(); 414*b1cdbd2cSJim Jagielski } 415*b1cdbd2cSJim Jagielski // check for changes in the output stream. If there are no changes, the process maybe hangs 416*b1cdbd2cSJim Jagielski if (!this.isFinished()) 417*b1cdbd2cSJim Jagielski { 418*b1cdbd2cSJim Jagielski hangcheck--; 419*b1cdbd2cSJim Jagielski if (hangcheck < 0) 420*b1cdbd2cSJim Jagielski { 421*b1cdbd2cSJim Jagielski String sOutputText = getOutputText(); 422*b1cdbd2cSJim Jagielski if (sOutputText.length() == memText.length()) 423*b1cdbd2cSJim Jagielski { 424*b1cdbd2cSJim Jagielski changedText = false; 425*b1cdbd2cSJim Jagielski // dbg("runCommand Could not detect changes in output stream!!!"); 426*b1cdbd2cSJim Jagielski } 427*b1cdbd2cSJim Jagielski hangcheck = 10; 428*b1cdbd2cSJim Jagielski memText = this.getOutputText(); 429*b1cdbd2cSJim Jagielski } 430*b1cdbd2cSJim Jagielski } 431*b1cdbd2cSJim Jagielski } 432*b1cdbd2cSJim Jagielski 433*b1cdbd2cSJim Jagielski if (!this.isFinished()) 434*b1cdbd2cSJim Jagielski { 435*b1cdbd2cSJim Jagielski dbg("runCommand Process ist not finished but there are no changes in output stream."); 436*b1cdbd2cSJim Jagielski this.kill(); 437*b1cdbd2cSJim Jagielski } 438*b1cdbd2cSJim Jagielski } 439*b1cdbd2cSJim Jagielski isTimedOut()440*b1cdbd2cSJim Jagielski public boolean isTimedOut() 441*b1cdbd2cSJim Jagielski { 442*b1cdbd2cSJim Jagielski return mbTimedOut; 443*b1cdbd2cSJim Jagielski } 444*b1cdbd2cSJim Jagielski setTimedOut(boolean bTimedOut)445*b1cdbd2cSJim Jagielski private void setTimedOut(boolean bTimedOut) 446*b1cdbd2cSJim Jagielski { 447*b1cdbd2cSJim Jagielski mbTimedOut = bTimedOut; 448*b1cdbd2cSJim Jagielski } 449*b1cdbd2cSJim Jagielski 450*b1cdbd2cSJim Jagielski /** 451*b1cdbd2cSJim Jagielski * Executes the command and returns only when the process 452*b1cdbd2cSJim Jagielski * exits. 453*b1cdbd2cSJim Jagielski * 454*b1cdbd2cSJim Jagielski * @return <code>true</code> if process was successfully 455*b1cdbd2cSJim Jagielski * started and correcly exits (exit code doesn't affect 456*b1cdbd2cSJim Jagielski * to this result). 457*b1cdbd2cSJim Jagielski */ executeSynchronously()458*b1cdbd2cSJim Jagielski public boolean executeSynchronously() 459*b1cdbd2cSJim Jagielski { 460*b1cdbd2cSJim Jagielski execute(); 461*b1cdbd2cSJim Jagielski return waitFor(mTimeOut); 462*b1cdbd2cSJim Jagielski } 463*b1cdbd2cSJim Jagielski 464*b1cdbd2cSJim Jagielski /** 465*b1cdbd2cSJim Jagielski * Executes the command immediately returns. The process 466*b1cdbd2cSJim Jagielski * remains in running state. Control of its state should 467*b1cdbd2cSJim Jagielski * be made by <code>waitFor</code> methods. 468*b1cdbd2cSJim Jagielski * 469*b1cdbd2cSJim Jagielski * @return <code>true</code> if process was successfully 470*b1cdbd2cSJim Jagielski * started. 471*b1cdbd2cSJim Jagielski */ executeAsynchronously()472*b1cdbd2cSJim Jagielski public boolean executeAsynchronously() 473*b1cdbd2cSJim Jagielski { 474*b1cdbd2cSJim Jagielski execute(); 475*b1cdbd2cSJim Jagielski return isStarted(); 476*b1cdbd2cSJim Jagielski } 477*b1cdbd2cSJim Jagielski kill()478*b1cdbd2cSJim Jagielski public synchronized void kill() 479*b1cdbd2cSJim Jagielski { 480*b1cdbd2cSJim Jagielski if (!isStarted()) 481*b1cdbd2cSJim Jagielski { 482*b1cdbd2cSJim Jagielski return; 483*b1cdbd2cSJim Jagielski } 484*b1cdbd2cSJim Jagielski boolean exit = false; 485*b1cdbd2cSJim Jagielski int counter = 1; 486*b1cdbd2cSJim Jagielski while (counter < 3 && !exit) 487*b1cdbd2cSJim Jagielski { 488*b1cdbd2cSJim Jagielski m_aProcess.destroy(); 489*b1cdbd2cSJim Jagielski 490*b1cdbd2cSJim Jagielski try 491*b1cdbd2cSJim Jagielski { 492*b1cdbd2cSJim Jagielski Thread.sleep(1000 * counter); // 5000 493*b1cdbd2cSJim Jagielski } 494*b1cdbd2cSJim Jagielski catch (java.lang.InterruptedException e) 495*b1cdbd2cSJim Jagielski { 496*b1cdbd2cSJim Jagielski } 497*b1cdbd2cSJim Jagielski try 498*b1cdbd2cSJim Jagielski { 499*b1cdbd2cSJim Jagielski final int exit_Value = m_aProcess.exitValue(); 500*b1cdbd2cSJim Jagielski if (exit_Value < 1) 501*b1cdbd2cSJim Jagielski { 502*b1cdbd2cSJim Jagielski exit = true; 503*b1cdbd2cSJim Jagielski } 504*b1cdbd2cSJim Jagielski else 505*b1cdbd2cSJim Jagielski { 506*b1cdbd2cSJim Jagielski counter++; 507*b1cdbd2cSJim Jagielski } 508*b1cdbd2cSJim Jagielski dbg("kill: process closed with exit code " + exit_Value); 509*b1cdbd2cSJim Jagielski } 510*b1cdbd2cSJim Jagielski catch (java.lang.IllegalThreadStateException e) 511*b1cdbd2cSJim Jagielski { 512*b1cdbd2cSJim Jagielski if (counter < 3) 513*b1cdbd2cSJim Jagielski { 514*b1cdbd2cSJim Jagielski dbg("kill: Couldn't close process after " + counter + " attempts, trying again"); 515*b1cdbd2cSJim Jagielski } 516*b1cdbd2cSJim Jagielski counter++; 517*b1cdbd2cSJim Jagielski } 518*b1cdbd2cSJim Jagielski } 519*b1cdbd2cSJim Jagielski isStarted = false; 520*b1cdbd2cSJim Jagielski } 521*b1cdbd2cSJim Jagielski 522*b1cdbd2cSJim Jagielski /** 523*b1cdbd2cSJim Jagielski * Returns the time in seconds since 1st January 1970 524*b1cdbd2cSJim Jagielski * @return 525*b1cdbd2cSJim Jagielski */ getSystemTime()526*b1cdbd2cSJim Jagielski public static long getSystemTime() 527*b1cdbd2cSJim Jagielski { 528*b1cdbd2cSJim Jagielski // Calendar cal = new GregorianCalendar(); 529*b1cdbd2cSJim Jagielski // final long nTime = cal.getTimeInMillis(); 530*b1cdbd2cSJim Jagielski final long nTime = System.currentTimeMillis(); 531*b1cdbd2cSJim Jagielski return nTime; 532*b1cdbd2cSJim Jagielski } 533*b1cdbd2cSJim Jagielski private long m_nExactStartTimeInMillisec; 534*b1cdbd2cSJim Jagielski initialExactStartTime()535*b1cdbd2cSJim Jagielski private void initialExactStartTime() 536*b1cdbd2cSJim Jagielski { 537*b1cdbd2cSJim Jagielski m_nExactStartTimeInMillisec = getSystemTime(); 538*b1cdbd2cSJim Jagielski } 539*b1cdbd2cSJim Jagielski getProcessStartTime()540*b1cdbd2cSJim Jagielski public long getProcessStartTime() 541*b1cdbd2cSJim Jagielski { 542*b1cdbd2cSJim Jagielski return m_nExactStartTimeInMillisec; 543*b1cdbd2cSJim Jagielski } 544*b1cdbd2cSJim Jagielski showEnvVars()545*b1cdbd2cSJim Jagielski private void showEnvVars() 546*b1cdbd2cSJim Jagielski { 547*b1cdbd2cSJim Jagielski if (envVars != null) 548*b1cdbd2cSJim Jagielski { 549*b1cdbd2cSJim Jagielski for (int i = 0; i < envVars.length; i++) 550*b1cdbd2cSJim Jagielski { 551*b1cdbd2cSJim Jagielski log.println("env: " + envVars[i]); 552*b1cdbd2cSJim Jagielski } 553*b1cdbd2cSJim Jagielski } 554*b1cdbd2cSJim Jagielski else 555*b1cdbd2cSJim Jagielski { 556*b1cdbd2cSJim Jagielski log.println("env: null"); 557*b1cdbd2cSJim Jagielski } 558*b1cdbd2cSJim Jagielski } 559*b1cdbd2cSJim Jagielski execute()560*b1cdbd2cSJim Jagielski protected void execute() 561*b1cdbd2cSJim Jagielski { 562*b1cdbd2cSJim Jagielski if (isStarted()) 563*b1cdbd2cSJim Jagielski { 564*b1cdbd2cSJim Jagielski throw new RuntimeException( 565*b1cdbd2cSJim Jagielski "The process handler has already been executed."); 566*b1cdbd2cSJim Jagielski } 567*b1cdbd2cSJim Jagielski final Runtime runtime = Runtime.getRuntime(); 568*b1cdbd2cSJim Jagielski try 569*b1cdbd2cSJim Jagielski { 570*b1cdbd2cSJim Jagielski if (cmdLine == null) 571*b1cdbd2cSJim Jagielski { 572*b1cdbd2cSJim Jagielski log.println(utils.getDateTime() + "execute: Starting command from array: "); 573*b1cdbd2cSJim Jagielski for (int i = 0; i < cmdLineArray.length; i++) 574*b1cdbd2cSJim Jagielski { 575*b1cdbd2cSJim Jagielski log.println(cmdLineArray[i]); 576*b1cdbd2cSJim Jagielski // log.print(" "); 577*b1cdbd2cSJim Jagielski } 578*b1cdbd2cSJim Jagielski showEnvVars(); 579*b1cdbd2cSJim Jagielski log.println(""); 580*b1cdbd2cSJim Jagielski initialExactStartTime(); 581*b1cdbd2cSJim Jagielski initializeProcessKiller(); 582*b1cdbd2cSJim Jagielski m_aProcess = runtime.exec(cmdLineArray, envVars); 583*b1cdbd2cSJim Jagielski } 584*b1cdbd2cSJim Jagielski else 585*b1cdbd2cSJim Jagielski { 586*b1cdbd2cSJim Jagielski if (workDir != null) 587*b1cdbd2cSJim Jagielski { 588*b1cdbd2cSJim Jagielski log.println(utils.getDateTime() + "execute: Starting command: "); 589*b1cdbd2cSJim Jagielski log.println(cmdLine + " path=" + workDir.getAbsolutePath()); 590*b1cdbd2cSJim Jagielski showEnvVars(); 591*b1cdbd2cSJim Jagielski m_aProcess = runtime.exec(cmdLine, envVars, workDir); 592*b1cdbd2cSJim Jagielski } 593*b1cdbd2cSJim Jagielski else 594*b1cdbd2cSJim Jagielski { 595*b1cdbd2cSJim Jagielski log.println(utils.getDateTime() + "execute: Starting command: "); 596*b1cdbd2cSJim Jagielski log.println(cmdLine); 597*b1cdbd2cSJim Jagielski showEnvVars(); 598*b1cdbd2cSJim Jagielski m_aProcess = runtime.exec(cmdLine, envVars); 599*b1cdbd2cSJim Jagielski } 600*b1cdbd2cSJim Jagielski } 601*b1cdbd2cSJim Jagielski isStarted = true; 602*b1cdbd2cSJim Jagielski } 603*b1cdbd2cSJim Jagielski catch (java.io.IOException e) 604*b1cdbd2cSJim Jagielski { 605*b1cdbd2cSJim Jagielski if (cmdLine == null) 606*b1cdbd2cSJim Jagielski { 607*b1cdbd2cSJim Jagielski log.println(utils.getDateTime() + "execute: The command array can't be started: " + e); 608*b1cdbd2cSJim Jagielski } 609*b1cdbd2cSJim Jagielski else 610*b1cdbd2cSJim Jagielski { 611*b1cdbd2cSJim Jagielski log.println(utils.getDateTime() + "execute: The command " + cmdLine + " can't be started: " + e); 612*b1cdbd2cSJim Jagielski } 613*b1cdbd2cSJim Jagielski return; 614*b1cdbd2cSJim Jagielski } 615*b1cdbd2cSJim Jagielski dbg("execute: pump io-streams"); 616*b1cdbd2cSJim Jagielski stdout = new Pump(m_aProcess.getInputStream(), log, "out > ", bUseOutput); 617*b1cdbd2cSJim Jagielski stderr = new Pump(m_aProcess.getErrorStream(), log, "err > ", bUseOutput); 618*b1cdbd2cSJim Jagielski stdIn = new PrintStream(m_aProcess.getOutputStream()); 619*b1cdbd2cSJim Jagielski 620*b1cdbd2cSJim Jagielski // int nExitValue = m_aProcess.exitValue(); 621*b1cdbd2cSJim Jagielski // int dummy = 0; 622*b1cdbd2cSJim Jagielski 623*b1cdbd2cSJim Jagielski dbg("execute: flush io-streams"); 624*b1cdbd2cSJim Jagielski 625*b1cdbd2cSJim Jagielski flushInput(); 626*b1cdbd2cSJim Jagielski } 627*b1cdbd2cSJim Jagielski 628*b1cdbd2cSJim Jagielski /** 629*b1cdbd2cSJim Jagielski * This method is useful when the process was executed 630*b1cdbd2cSJim Jagielski * asynchronously. Waits for process to exit and return 631*b1cdbd2cSJim Jagielski * its result. 632*b1cdbd2cSJim Jagielski * 633*b1cdbd2cSJim Jagielski * @return <code>true</code> if process correctly exited 634*b1cdbd2cSJim Jagielski * (exit code doesn't affect to this result). 635*b1cdbd2cSJim Jagielski */ waitFor()636*b1cdbd2cSJim Jagielski public boolean waitFor() 637*b1cdbd2cSJim Jagielski { 638*b1cdbd2cSJim Jagielski return waitFor(0); 639*b1cdbd2cSJim Jagielski } 640*b1cdbd2cSJim Jagielski 641*b1cdbd2cSJim Jagielski /** 642*b1cdbd2cSJim Jagielski * This method is useful when the process was executed 643*b1cdbd2cSJim Jagielski * asynchronously. Waits during specified time for process 644*b1cdbd2cSJim Jagielski * to exit and return its status. 645*b1cdbd2cSJim Jagielski * 646*b1cdbd2cSJim Jagielski * @param timeout > 0 647*b1cdbd2cSJim Jagielski * Waits specified time in miliSeconds for 648*b1cdbd2cSJim Jagielski * process to exit and return its status. 649*b1cdbd2cSJim Jagielski * 650*b1cdbd2cSJim Jagielski * = 0 651*b1cdbd2cSJim Jagielski * Waits for the process to end regulary 652*b1cdbd2cSJim Jagielski * 653*b1cdbd2cSJim Jagielski * < 0 654*b1cdbd2cSJim Jagielski * Kills the process immediately 655*b1cdbd2cSJim Jagielski * 656*b1cdbd2cSJim Jagielski * @return <code>true</code> if process correctly exited 657*b1cdbd2cSJim Jagielski * (exit code doesn't affect to this result). 658*b1cdbd2cSJim Jagielski */ waitFor(long timeout)659*b1cdbd2cSJim Jagielski public boolean waitFor(long timeout) 660*b1cdbd2cSJim Jagielski { 661*b1cdbd2cSJim Jagielski return waitFor(timeout, true); 662*b1cdbd2cSJim Jagielski } 663*b1cdbd2cSJim Jagielski waitFor(long timeout, boolean bKillProcessAfterTimeout)664*b1cdbd2cSJim Jagielski private boolean waitFor(long timeout, boolean bKillProcessAfterTimeout) 665*b1cdbd2cSJim Jagielski { 666*b1cdbd2cSJim Jagielski if (isFinished()) 667*b1cdbd2cSJim Jagielski { 668*b1cdbd2cSJim Jagielski return true; 669*b1cdbd2cSJim Jagielski } 670*b1cdbd2cSJim Jagielski if (!isStarted()) 671*b1cdbd2cSJim Jagielski { 672*b1cdbd2cSJim Jagielski return false; 673*b1cdbd2cSJim Jagielski } 674*b1cdbd2cSJim Jagielski 675*b1cdbd2cSJim Jagielski if (timeout == 0) 676*b1cdbd2cSJim Jagielski { 677*b1cdbd2cSJim Jagielski try 678*b1cdbd2cSJim Jagielski { 679*b1cdbd2cSJim Jagielski m_aProcess.waitFor(); 680*b1cdbd2cSJim Jagielski } 681*b1cdbd2cSJim Jagielski catch (InterruptedException e) 682*b1cdbd2cSJim Jagielski { 683*b1cdbd2cSJim Jagielski log.println("The process was interrupted: " + e); 684*b1cdbd2cSJim Jagielski } 685*b1cdbd2cSJim Jagielski isFinished = true; 686*b1cdbd2cSJim Jagielski try 687*b1cdbd2cSJim Jagielski { 688*b1cdbd2cSJim Jagielski exitValue = m_aProcess.exitValue(); 689*b1cdbd2cSJim Jagielski } 690*b1cdbd2cSJim Jagielski catch (IllegalThreadStateException e) 691*b1cdbd2cSJim Jagielski { 692*b1cdbd2cSJim Jagielski } 693*b1cdbd2cSJim Jagielski } 694*b1cdbd2cSJim Jagielski else 695*b1cdbd2cSJim Jagielski { 696*b1cdbd2cSJim Jagielski try 697*b1cdbd2cSJim Jagielski { 698*b1cdbd2cSJim Jagielski while (!isFinished && timeout > 0) 699*b1cdbd2cSJim Jagielski { 700*b1cdbd2cSJim Jagielski isFinished = true; 701*b1cdbd2cSJim Jagielski Thread.sleep(1000); 702*b1cdbd2cSJim Jagielski timeout -= 1000; 703*b1cdbd2cSJim Jagielski try 704*b1cdbd2cSJim Jagielski { 705*b1cdbd2cSJim Jagielski exitValue = m_aProcess.exitValue(); // throws exception if not finished 706*b1cdbd2cSJim Jagielski } 707*b1cdbd2cSJim Jagielski catch (IllegalThreadStateException e) 708*b1cdbd2cSJim Jagielski { 709*b1cdbd2cSJim Jagielski isFinished = false; 710*b1cdbd2cSJim Jagielski } 711*b1cdbd2cSJim Jagielski } 712*b1cdbd2cSJim Jagielski if (timeout < 0) 713*b1cdbd2cSJim Jagielski { 714*b1cdbd2cSJim Jagielski setTimedOut(true); 715*b1cdbd2cSJim Jagielski log.println("The process has timed out!"); 716*b1cdbd2cSJim Jagielski } 717*b1cdbd2cSJim Jagielski } 718*b1cdbd2cSJim Jagielski catch (InterruptedException ex) 719*b1cdbd2cSJim Jagielski { 720*b1cdbd2cSJim Jagielski log.println("The process was interrupted: " + ex); 721*b1cdbd2cSJim Jagielski } 722*b1cdbd2cSJim Jagielski } 723*b1cdbd2cSJim Jagielski 724*b1cdbd2cSJim Jagielski if (bKillProcessAfterTimeout == true) 725*b1cdbd2cSJim Jagielski { 726*b1cdbd2cSJim Jagielski if (!isFinished) 727*b1cdbd2cSJim Jagielski { 728*b1cdbd2cSJim Jagielski log.println("Going to destroy the process!!"); 729*b1cdbd2cSJim Jagielski m_aProcess.destroy(); 730*b1cdbd2cSJim Jagielski log.println("Process has been destroyed!"); 731*b1cdbd2cSJim Jagielski } 732*b1cdbd2cSJim Jagielski } 733*b1cdbd2cSJim Jagielski // Removed as hung up in SDK test 'PathSettings' 734*b1cdbd2cSJim Jagielski // try { 735*b1cdbd2cSJim Jagielski // stdout.join(); 736*b1cdbd2cSJim Jagielski // stderr.join(); 737*b1cdbd2cSJim Jagielski // } catch (InterruptedException e) {} 738*b1cdbd2cSJim Jagielski 739*b1cdbd2cSJim Jagielski return isFinished(); 740*b1cdbd2cSJim Jagielski } 741*b1cdbd2cSJim Jagielski flushInput()742*b1cdbd2cSJim Jagielski protected void flushInput() 743*b1cdbd2cSJim Jagielski { 744*b1cdbd2cSJim Jagielski if (stdIn == null) 745*b1cdbd2cSJim Jagielski { 746*b1cdbd2cSJim Jagielski return; 747*b1cdbd2cSJim Jagielski } 748*b1cdbd2cSJim Jagielski 749*b1cdbd2cSJim Jagielski synchronized(stdInBuff) 750*b1cdbd2cSJim Jagielski { 751*b1cdbd2cSJim Jagielski stdIn.print(stdInBuff); 752*b1cdbd2cSJim Jagielski stdIn.flush(); 753*b1cdbd2cSJim Jagielski stdInBuff = ""; 754*b1cdbd2cSJim Jagielski } 755*b1cdbd2cSJim Jagielski } 756*b1cdbd2cSJim Jagielski 757*b1cdbd2cSJim Jagielski /** 758*b1cdbd2cSJim Jagielski * Returns the text output by external command to stdout. 759*b1cdbd2cSJim Jagielski * @return the text output by external command to stdout 760*b1cdbd2cSJim Jagielski */ getOutputText()761*b1cdbd2cSJim Jagielski public String getOutputText() 762*b1cdbd2cSJim Jagielski { 763*b1cdbd2cSJim Jagielski if (stdout == null) 764*b1cdbd2cSJim Jagielski { 765*b1cdbd2cSJim Jagielski return ""; 766*b1cdbd2cSJim Jagielski } 767*b1cdbd2cSJim Jagielski else 768*b1cdbd2cSJim Jagielski { 769*b1cdbd2cSJim Jagielski return stdout.getStringBuffer(); 770*b1cdbd2cSJim Jagielski } 771*b1cdbd2cSJim Jagielski } 772*b1cdbd2cSJim Jagielski 773*b1cdbd2cSJim Jagielski /** 774*b1cdbd2cSJim Jagielski * Returns the text output by external command to stderr. 775*b1cdbd2cSJim Jagielski * @return the text output by external command to stderr 776*b1cdbd2cSJim Jagielski */ getErrorText()777*b1cdbd2cSJim Jagielski public String getErrorText() 778*b1cdbd2cSJim Jagielski { 779*b1cdbd2cSJim Jagielski if (stderr == null) 780*b1cdbd2cSJim Jagielski { 781*b1cdbd2cSJim Jagielski return ""; 782*b1cdbd2cSJim Jagielski } 783*b1cdbd2cSJim Jagielski else 784*b1cdbd2cSJim Jagielski { 785*b1cdbd2cSJim Jagielski return stderr.getStringBuffer(); 786*b1cdbd2cSJim Jagielski } 787*b1cdbd2cSJim Jagielski } 788*b1cdbd2cSJim Jagielski 789*b1cdbd2cSJim Jagielski /** 790*b1cdbd2cSJim Jagielski * Prints the string specified to sdtin of external 791*b1cdbd2cSJim Jagielski * command. '\n' is not added so if you need you 792*b1cdbd2cSJim Jagielski * should terminate the string with '\n'. <p> 793*b1cdbd2cSJim Jagielski * 794*b1cdbd2cSJim Jagielski * The method can also be called before the command 795*b1cdbd2cSJim Jagielski * starts its execution. Then the text is buffered 796*b1cdbd2cSJim Jagielski * and transfered to command when it will be started. 797*b1cdbd2cSJim Jagielski * @param str 798*b1cdbd2cSJim Jagielski */ printInputText(String str)799*b1cdbd2cSJim Jagielski public void printInputText(String str) 800*b1cdbd2cSJim Jagielski { 801*b1cdbd2cSJim Jagielski stdInBuff += str; 802*b1cdbd2cSJim Jagielski flushInput(); 803*b1cdbd2cSJim Jagielski } 804*b1cdbd2cSJim Jagielski 805*b1cdbd2cSJim Jagielski /** 806*b1cdbd2cSJim Jagielski * Returns information about was the command started or 807*b1cdbd2cSJim Jagielski * not. 808*b1cdbd2cSJim Jagielski * 809*b1cdbd2cSJim Jagielski * @return <code>true</code> if the external command was 810*b1cdbd2cSJim Jagielski * found and successfully started. 811*b1cdbd2cSJim Jagielski */ isStarted()812*b1cdbd2cSJim Jagielski public boolean isStarted() 813*b1cdbd2cSJim Jagielski { 814*b1cdbd2cSJim Jagielski return isStarted; 815*b1cdbd2cSJim Jagielski } 816*b1cdbd2cSJim Jagielski 817*b1cdbd2cSJim Jagielski /** 818*b1cdbd2cSJim Jagielski * Returns the information about the final state of command 819*b1cdbd2cSJim Jagielski * execution. 820*b1cdbd2cSJim Jagielski * 821*b1cdbd2cSJim Jagielski * @return <code>true</code> if the command correctly starts, 822*b1cdbd2cSJim Jagielski * exits and was not interrupted due to timeout. 823*b1cdbd2cSJim Jagielski */ isFinished()824*b1cdbd2cSJim Jagielski public boolean isFinished() 825*b1cdbd2cSJim Jagielski { 826*b1cdbd2cSJim Jagielski return isFinished; 827*b1cdbd2cSJim Jagielski } 828*b1cdbd2cSJim Jagielski 829*b1cdbd2cSJim Jagielski /** 830*b1cdbd2cSJim Jagielski * Returns exit code of the external command. 831*b1cdbd2cSJim Jagielski * 832*b1cdbd2cSJim Jagielski * @return exit code of command if it was finished, 833*b1cdbd2cSJim Jagielski * -1 if not. 834*b1cdbd2cSJim Jagielski */ getExitCode()835*b1cdbd2cSJim Jagielski public int getExitCode() 836*b1cdbd2cSJim Jagielski { 837*b1cdbd2cSJim Jagielski try 838*b1cdbd2cSJim Jagielski { 839*b1cdbd2cSJim Jagielski exitValue = m_aProcess.exitValue(); 840*b1cdbd2cSJim Jagielski } 841*b1cdbd2cSJim Jagielski catch (Exception e) 842*b1cdbd2cSJim Jagielski { 843*b1cdbd2cSJim Jagielski //System.out.println("No ExitValue available"); 844*b1cdbd2cSJim Jagielski } 845*b1cdbd2cSJim Jagielski 846*b1cdbd2cSJim Jagielski return exitValue; 847*b1cdbd2cSJim Jagielski } 848*b1cdbd2cSJim Jagielski 849*b1cdbd2cSJim Jagielski /** Causes the thread to sleep some time. 850*b1cdbd2cSJim Jagielski * @param milliseconds 851*b1cdbd2cSJim Jagielski */ shortWait(long milliseconds)852*b1cdbd2cSJim Jagielski public static void shortWait(long milliseconds) 853*b1cdbd2cSJim Jagielski { 854*b1cdbd2cSJim Jagielski try 855*b1cdbd2cSJim Jagielski { 856*b1cdbd2cSJim Jagielski Thread.sleep(milliseconds); 857*b1cdbd2cSJim Jagielski } 858*b1cdbd2cSJim Jagielski catch (InterruptedException e) 859*b1cdbd2cSJim Jagielski { 860*b1cdbd2cSJim Jagielski System.out.println("While waiting :" + e); 861*b1cdbd2cSJim Jagielski } 862*b1cdbd2cSJim Jagielski } 863*b1cdbd2cSJim Jagielski dbg(String message)864*b1cdbd2cSJim Jagielski private void dbg(String message) 865*b1cdbd2cSJim Jagielski { 866*b1cdbd2cSJim Jagielski if (debug) 867*b1cdbd2cSJim Jagielski { 868*b1cdbd2cSJim Jagielski log.println(utils.getDateTime() + "PH." + message); 869*b1cdbd2cSJim Jagielski } 870*b1cdbd2cSJim Jagielski } 871*b1cdbd2cSJim Jagielski noOutput()872*b1cdbd2cSJim Jagielski public void noOutput() 873*b1cdbd2cSJim Jagielski { 874*b1cdbd2cSJim Jagielski bUseOutput = false; 875*b1cdbd2cSJim Jagielski } 876*b1cdbd2cSJim Jagielski // ------------------------------------------------------------------------- 877*b1cdbd2cSJim Jagielski class ProcessWatcher extends Thread 878*b1cdbd2cSJim Jagielski { 879*b1cdbd2cSJim Jagielski 880*b1cdbd2cSJim Jagielski private int m_nTimeoutInSec; 881*b1cdbd2cSJim Jagielski private String m_sProcessToStart; 882*b1cdbd2cSJim Jagielski private boolean m_bInterrupt; 883*b1cdbd2cSJim Jagielski ProcessWatcher(int _nTimeOut, String _sProcess)884*b1cdbd2cSJim Jagielski public ProcessWatcher(int _nTimeOut, String _sProcess) 885*b1cdbd2cSJim Jagielski { 886*b1cdbd2cSJim Jagielski m_nTimeoutInSec = _nTimeOut; 887*b1cdbd2cSJim Jagielski m_sProcessToStart = _sProcess; 888*b1cdbd2cSJim Jagielski m_bInterrupt = false; 889*b1cdbd2cSJim Jagielski } 890*b1cdbd2cSJim Jagielski 891*b1cdbd2cSJim Jagielski /** 892*b1cdbd2cSJim Jagielski * returns true, if the thread should hold on 893*b1cdbd2cSJim Jagielski * @return 894*b1cdbd2cSJim Jagielski */ isInHoldOn()895*b1cdbd2cSJim Jagielski public synchronized boolean isInHoldOn() 896*b1cdbd2cSJim Jagielski { 897*b1cdbd2cSJim Jagielski return m_bInterrupt; 898*b1cdbd2cSJim Jagielski } 899*b1cdbd2cSJim Jagielski /** 900*b1cdbd2cSJim Jagielski * Marks the thread to hold on, next time 901*b1cdbd2cSJim Jagielski * STUPID: The thread must poll this flag itself. 902*b1cdbd2cSJim Jagielski * 903*b1cdbd2cSJim Jagielski * Reason: interrupt() seems not to work as expected. 904*b1cdbd2cSJim Jagielski */ holdOn()905*b1cdbd2cSJim Jagielski public synchronized void holdOn() 906*b1cdbd2cSJim Jagielski { 907*b1cdbd2cSJim Jagielski m_bInterrupt = true; 908*b1cdbd2cSJim Jagielski interrupt(); 909*b1cdbd2cSJim Jagielski } 910*b1cdbd2cSJim Jagielski run()911*b1cdbd2cSJim Jagielski public void run() 912*b1cdbd2cSJim Jagielski { 913*b1cdbd2cSJim Jagielski while (m_nTimeoutInSec > 0) 914*b1cdbd2cSJim Jagielski { 915*b1cdbd2cSJim Jagielski m_nTimeoutInSec--; 916*b1cdbd2cSJim Jagielski try 917*b1cdbd2cSJim Jagielski { 918*b1cdbd2cSJim Jagielski sleep(1000); 919*b1cdbd2cSJim Jagielski } 920*b1cdbd2cSJim Jagielski catch(java.lang.InterruptedException e) 921*b1cdbd2cSJim Jagielski { 922*b1cdbd2cSJim Jagielski // interrupt flag is set back to 'not interrupted' :-( 923*b1cdbd2cSJim Jagielski } 924*b1cdbd2cSJim Jagielski if (isInHoldOn()) 925*b1cdbd2cSJim Jagielski { 926*b1cdbd2cSJim Jagielski break; 927*b1cdbd2cSJim Jagielski } 928*b1cdbd2cSJim Jagielski } 929*b1cdbd2cSJim Jagielski if (m_nTimeoutInSec <= 0 && !isInHoldOn()) // not zero, so we are interrupted. 930*b1cdbd2cSJim Jagielski { 931*b1cdbd2cSJim Jagielski system(m_sProcessToStart); 932*b1cdbd2cSJim Jagielski } 933*b1cdbd2cSJim Jagielski } 934*b1cdbd2cSJim Jagielski 935*b1cdbd2cSJim Jagielski /** 936*b1cdbd2cSJim Jagielski * Start an external Process 937*b1cdbd2cSJim Jagielski * @param _sProcess 938*b1cdbd2cSJim Jagielski */ system(String _sProcess)939*b1cdbd2cSJim Jagielski private void system(String _sProcess) 940*b1cdbd2cSJim Jagielski { 941*b1cdbd2cSJim Jagielski if (_sProcess == null) 942*b1cdbd2cSJim Jagielski { 943*b1cdbd2cSJim Jagielski return; 944*b1cdbd2cSJim Jagielski } 945*b1cdbd2cSJim Jagielski 946*b1cdbd2cSJim Jagielski try 947*b1cdbd2cSJim Jagielski { 948*b1cdbd2cSJim Jagielski 949*b1cdbd2cSJim Jagielski // run a _sProcess command 950*b1cdbd2cSJim Jagielski // using the Runtime exec method: 951*b1cdbd2cSJim Jagielski Process p = Runtime.getRuntime().exec(_sProcess); 952*b1cdbd2cSJim Jagielski 953*b1cdbd2cSJim Jagielski BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); 954*b1cdbd2cSJim Jagielski 955*b1cdbd2cSJim Jagielski BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 956*b1cdbd2cSJim Jagielski 957*b1cdbd2cSJim Jagielski // read the output from the command 958*b1cdbd2cSJim Jagielski String s; 959*b1cdbd2cSJim Jagielski while ((s = stdInput.readLine()) != null) 960*b1cdbd2cSJim Jagielski { 961*b1cdbd2cSJim Jagielski System.out.println("out:" + s); 962*b1cdbd2cSJim Jagielski } 963*b1cdbd2cSJim Jagielski 964*b1cdbd2cSJim Jagielski // read any errors from the attempted command 965*b1cdbd2cSJim Jagielski while ((s = stdError.readLine()) != null) 966*b1cdbd2cSJim Jagielski { 967*b1cdbd2cSJim Jagielski System.out.println("err:" + s); 968*b1cdbd2cSJim Jagielski } 969*b1cdbd2cSJim Jagielski 970*b1cdbd2cSJim Jagielski } 971*b1cdbd2cSJim Jagielski catch (java.io.IOException e) 972*b1cdbd2cSJim Jagielski { 973*b1cdbd2cSJim Jagielski System.out.println("exception caught: "); 974*b1cdbd2cSJim Jagielski e.printStackTrace(); 975*b1cdbd2cSJim Jagielski } 976*b1cdbd2cSJim Jagielski 977*b1cdbd2cSJim Jagielski } 978*b1cdbd2cSJim Jagielski } 979*b1cdbd2cSJim Jagielski 980*b1cdbd2cSJim Jagielski /** 981*b1cdbd2cSJim Jagielski * If the timeout only given by setProcessTimeout(int seconds) function is != 0, 982*b1cdbd2cSJim Jagielski * a extra thread is created and after time has run out, the ProcessKiller string 983*b1cdbd2cSJim Jagielski * given by function setProcessKiller(string) will execute. 984*b1cdbd2cSJim Jagielski * So it is possible to kill a running office after a given time of seconds. 985*b1cdbd2cSJim Jagielski */ initializeProcessKiller()986*b1cdbd2cSJim Jagielski private void initializeProcessKiller() 987*b1cdbd2cSJim Jagielski { 988*b1cdbd2cSJim Jagielski if (m_nProcessTimeout != 0) 989*b1cdbd2cSJim Jagielski { 990*b1cdbd2cSJim Jagielski m_aWatcher = new ProcessWatcher(m_nProcessTimeout, m_sProcessKiller); 991*b1cdbd2cSJim Jagielski m_aWatcher.start(); 992*b1cdbd2cSJim Jagielski } 993*b1cdbd2cSJim Jagielski } 994*b1cdbd2cSJim Jagielski 995*b1cdbd2cSJim Jagielski /** 996*b1cdbd2cSJim Jagielski * to stop the extra thread, before he will kill a running office. This will stop the thread. 997*b1cdbd2cSJim Jagielski */ stopWatcher()998*b1cdbd2cSJim Jagielski public void stopWatcher() 999*b1cdbd2cSJim Jagielski { 1000*b1cdbd2cSJim Jagielski if (m_aWatcher != null) 1001*b1cdbd2cSJim Jagielski { 1002*b1cdbd2cSJim Jagielski m_aWatcher.holdOn(); 1003*b1cdbd2cSJim Jagielski shortWait(5000); 1004*b1cdbd2cSJim Jagielski } 1005*b1cdbd2cSJim Jagielski } 1006*b1cdbd2cSJim Jagielski } 1007