Path: blob/master/test/functional/cmdline_options_tester/src/CommandExecuter.java
6004 views
/*******************************************************************************1* Copyright (c) 2004, 2018 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122import java.io.*;23import java.util.Iterator;24import java.util.Vector;2526class CommandExecuter implements Runnable, Command {27private String _command;28private String _background;29private String _variableStdout;30private String _variableStderr;31private String _return;32private Vector _args;3334CommandExecuter( String cmd, String background, String var1, String var2, String ret) {35_command = cmd;36_background = background;37_variableStdout = var1;38_variableStderr = var2;39_return = ret;40_args = new Vector();41}4243public void executeSelf() {44String bg = TestSuite.evaluateVariables( _background );45if (bg != null && bg.equalsIgnoreCase("yes")) {46new Thread( this ).start();47} else {48this.run();49}50}5152public void run() {53/**54* Set up a built-in variable "Q" to represent a double-quotes(").55* The command comes with $Q$ initially set up by tester to quote the classpath with white spaces.56* $Q$ in the command string will be replaced with a double-quotes(") by the parser of57* test framework before passing it over to Tokenizer for further processing.58* @see Tokenizer59*/60TestSuite.putVariable("Q", "\"");61StringBuffer buf1 = new StringBuffer();62StringBuffer buf2 = new StringBuffer();63String command = TestSuite.evaluateVariables( _command );64System.out.println( "Executing command: " + command );65try {66/**67* According to the test framework, a command string is passed over to exec(String command,...) of Runtime for test execution.68* However, the method is unable to recognize a command string if white spaces occur in the classpath of the command string.69* To solve the issue, exec(String command,...) is replaced with exec(String[] cmdarray,...), in which case it requires that70* a command string be replaced with a command array with all arguments split up in the array.71* Meanwhile, a path of .jar file with white spaces should be treated as a single argument in the command array.72* Thus, a new class called Tokenizer is created to address the issue of classpath when splitting up a command string.73* NOTE: The reason why StreamTokenizer was discarded is that it wrongly interpreted escape characters (e.g. \b, \n, \t)74* in the classpath into a single character rather than two characters.75* @see Tokenizer76*/77String[] cmdArray = Tokenizer.tokenize(command);78Process proc;79if (_args.isEmpty()) {80proc = Runtime.getRuntime().exec(81cmdArray,82null,83new File( System.getProperty("user.dir") ) );84} else {85String[] args = new String[cmdArray.length + _args.size()];86System.arraycopy(cmdArray, 0, args, 0, cmdArray.length);8788for (int i = 0; i < _args.size(); i++) {89String arg = (String) _args.get(i);90args[cmdArray.length + i] = TestSuite.evaluateVariables(arg);91}92proc = Runtime.getRuntime().exec(93args,94null,95new File( System.getProperty("user.dir") ) );96}97// need to read from input/error streams as noted in98// http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html99CaptureThread ct = new CaptureThread( proc.getInputStream(), (null == _variableStdout) ? null : buf1);100ct.start();101CaptureThread ce = new CaptureThread( proc.getErrorStream(), (null == _variableStderr) ? null : buf2);102ce.start();103ct.join();104ce.join();105int retcode = proc.waitFor();106if (_return != null) {107//System.out.println( '"' + command + "\" returned code: " + retcode );108TestSuite.putVariable( _return, Integer.toString( retcode ) );109}110} catch (Exception e) {111System.out.println("Error while executing command");112e.printStackTrace();113}114if (null != _variableStdout) {115String value = buf1.toString();116//System.out.println( "Captured output from \"" + command + "\": " + value );117TestSuite.putVariable(_variableStdout, value );118}119if (null != _variableStderr) {120String value = buf2.toString();121//System.out.println( "Captured output from \"" + command + "\": " + value );122TestSuite.putVariable(_variableStderr, value );123}124System.out.println("");125}126127class CaptureThread extends Thread {128BufferedReader _br;129StringBuffer _buf;130131CaptureThread( InputStream in, StringBuffer buf ) {132_br = new BufferedReader( new InputStreamReader( in ) );133_buf = buf;134}135136public void run() {137try {138String read;139while ((read = _br.readLine()) != null) {140//System.out.println(read);141if (_buf != null) {142_buf.append( read );143}144}145} catch (IOException ioe) {146/* do nothing; user can fix problem based on captured output */147}148}149}150151public void addArg(String string) {152_args.add(string);153}154}155156157