// $Id: /** * This class is intended to be used with the SystemCommandExecutor class to let * users execute system commands from Java applications. * * This class is based on work that was shared in a JavaWorld article named * "When System.exec() won't". That article is available at this url: * * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html * * Documentation for this class is available at this URL: * * http://devdaily.com/java/java-processbuilder-process-system-exec * * * Copyright 2010 alvin j. alexander, devdaily.com. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser Public License for more details. * * You should have received a copy of the GNU Lesser Public License along with * this program. If not, see . * * Please ee the following page for the LGPL license: * http://www.gnu.org/licenses/lgpl.txt * */ package org.forester.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; class ThreadedStreamHandler extends Thread { InputStream inputStream; String adminPassword; OutputStream outputStream; PrintWriter printWriter; StringBuilder outputBuffer = new StringBuilder( 65536 ); private boolean sudoIsRequested = false; /** * A simple constructor for when the sudo command is not necessary. * This constructor will just run the command you provide, without * running sudo before the command, and without expecting a password. * * @param inputStream * @param streamType */ ThreadedStreamHandler( final InputStream inputStream ) { this.inputStream = inputStream; } /** * Use this constructor when you want to invoke the 'sudo' command. * The outputStream must not be null. If it is, you'll regret it. :) * * TODO this currently hangs if the admin password given for the sudo command is wrong. * * @param inputStream * @param streamType * @param outputStream * @param adminPassword */ ThreadedStreamHandler( final InputStream inputStream, final OutputStream outputStream, final String adminPassword ) { this.inputStream = inputStream; this.outputStream = outputStream; printWriter = new PrintWriter( outputStream ); this.adminPassword = adminPassword; sudoIsRequested = true; } ThreadedStreamHandler( final InputStream inputStream, final OutputStream outputStream ) { this.inputStream = inputStream; this.outputStream = outputStream; printWriter = new PrintWriter( outputStream ); sudoIsRequested = false; } private void doSleep( final long millis ) { try { Thread.sleep( millis ); } catch ( final InterruptedException e ) { // ignore } } public StringBuilder getOutputBuffer() { return outputBuffer; } @Override public void run() { // on mac os x 10.5.x, when i run a 'sudo' command, i need to write // the admin password out immediately; that's why this code is // here. if ( sudoIsRequested ) { //doSleep(500); printWriter.println( adminPassword ); printWriter.flush(); } BufferedReader bufferedReader = null; final String newline = ForesterUtil.LINE_SEPARATOR; try { bufferedReader = new BufferedReader( new InputStreamReader( inputStream ) ); String line = null; while ( ( line = bufferedReader.readLine() ) != null ) { // outputBuffer.append( line + "\n" ); // CMZ change outputBuffer.append( line ); outputBuffer.append( newline ); } } catch ( final IOException ioe ) { // TODO handle this better ioe.printStackTrace(); } catch ( final Throwable t ) { // TODO handle this better t.printStackTrace(); } finally { try { bufferedReader.close(); } catch ( final IOException e ) { // ignore this one } } } }