1 package org.codehaus.plexus.util.cli; 2 3 /* 4 * Copyright The Codehaus Foundation. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 /******************************************************************************** 20 * CruiseControl, a Continuous Integration Toolkit 21 * Copyright (c) 2001-2003, ThoughtWorks, Inc. 22 * 651 W Washington Ave. Suite 500 23 * Chicago, IL 60661 USA 24 * All rights reserved. 25 * 26 * Redistribution and use in source and binary forms, with or without 27 * modification, are permitted provided that the following conditions 28 * are met: 29 * 30 * + Redistributions of source code must retain the above copyright 31 * notice, this list of conditions and the following disclaimer. 32 * 33 * + Redistributions in binary form must reproduce the above 34 * copyright notice, this list of conditions and the following 35 * disclaimer in the documentation and/or other materials provided 36 * with the distribution. 37 * 38 * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the 39 * names of its contributors may be used to endorse or promote 40 * products derived from this software without specific prior 41 * written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 47 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 48 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 50 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 51 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 52 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 53 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 ********************************************************************************/ 55 56 /* ==================================================================== 57 * Copyright 2003-2004 The Apache Software Foundation. 58 * 59 * Licensed under the Apache License, Version 2.0 (the "License"); 60 * you may not use this file except in compliance with the License. 61 * You may obtain a copy of the License at 62 * 63 * http://www.apache.org/licenses/LICENSE-2.0 64 * 65 * Unless required by applicable law or agreed to in writing, software 66 * distributed under the License is distributed on an "AS IS" BASIS, 67 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 68 * See the License for the specific language governing permissions and 69 * limitations under the License. 70 * ==================================================================== 71 */ 72 73 import java.io.BufferedReader; 74 import java.io.IOException; 75 import java.io.InputStream; 76 import java.io.InputStreamReader; 77 import java.io.PrintWriter; 78 79 /** 80 * Class to pump the error stream during Process's runtime. Copied from the Ant built-in task. 81 * 82 * @author <a href="mailto:fvancea@maxiq.com">Florin Vancea </a> 83 * @author <a href="mailto:pj@thoughtworks.com">Paul Julius </a> 84 * 85 * @since June 11, 2001 86 */ 87 public class StreamPumper 88 extends AbstractStreamHandler 89 { 90 private final BufferedReader in; 91 92 private final StreamConsumer consumer; 93 94 private final PrintWriter out; 95 96 private volatile Exception exception = null; 97 98 private static final int SIZE = 1024; 99 100 public StreamPumper( InputStream in ) 101 { 102 this( in, (StreamConsumer) null ); 103 } 104 105 public StreamPumper( InputStream in, StreamConsumer consumer ) 106 { 107 this( in, null, consumer ); 108 } 109 110 public StreamPumper( InputStream in, PrintWriter writer ) 111 { 112 this( in, writer, null ); 113 } 114 115 public StreamPumper( InputStream in, PrintWriter writer, StreamConsumer consumer ) 116 { 117 super(); 118 this.in = new BufferedReader( new InputStreamReader( in ), SIZE ); 119 this.out = writer; 120 this.consumer = consumer; 121 } 122 123 @Override 124 public void run() 125 { 126 boolean outError = out != null ? out.checkError() : false; 127 128 try 129 { 130 for ( String line = in.readLine(); line != null; line = in.readLine() ) 131 { 132 try 133 { 134 if ( exception == null && consumer != null && !isDisabled() ) 135 { 136 consumer.consumeLine( line ); 137 } 138 } 139 catch ( Exception t ) 140 { 141 exception = t; 142 } 143 144 if ( out != null && !outError ) 145 { 146 out.println( line ); 147 148 out.flush(); 149 150 if ( out.checkError() ) 151 { 152 outError = true; 153 154 try 155 { 156 // Thrown to fill in stack trace elements. 157 throw new IOException( String.format( "Failure printing line '%s'.", line ) ); 158 } 159 catch ( final IOException e ) 160 { 161 exception = e; 162 } 163 } 164 } 165 } 166 } 167 catch ( IOException e ) 168 { 169 exception = e; 170 } 171 finally 172 { 173 try 174 { 175 in.close(); 176 } 177 catch ( final IOException e2 ) 178 { 179 if ( exception == null ) 180 { 181 exception = e2; 182 } 183 } 184 185 synchronized ( this ) 186 { 187 setDone(); 188 189 this.notifyAll(); 190 } 191 } 192 } 193 194 public void flush() 195 { 196 if ( out != null ) 197 { 198 out.flush(); 199 200 if ( out.checkError() && exception == null ) 201 { 202 try 203 { 204 // Thrown to fill in stack trace elements. 205 throw new IOException( "Failure flushing output." ); 206 } 207 catch ( final IOException e ) 208 { 209 exception = e; 210 } 211 } 212 } 213 } 214 215 public void close() 216 { 217 if ( out != null ) 218 { 219 out.close(); 220 221 if ( out.checkError() && exception == null ) 222 { 223 try 224 { 225 // Thrown to fill in stack trace elements. 226 throw new IOException( "Failure closing output." ); 227 } 228 catch ( final IOException e ) 229 { 230 exception = e; 231 } 232 } 233 } 234 } 235 236 public Exception getException() 237 { 238 return exception; 239 } 240 }