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 extends AbstractStreamHandler { 88 private final BufferedReader in; 89 90 private final StreamConsumer consumer; 91 92 private final PrintWriter out; 93 94 private volatile Exception exception = null; 95 96 private static final int SIZE = 1024; 97 98 public StreamPumper(InputStream in) { 99 this(in, (StreamConsumer) null); 100 } 101 102 public StreamPumper(InputStream in, StreamConsumer consumer) { 103 this(in, null, consumer); 104 } 105 106 public StreamPumper(InputStream in, PrintWriter writer) { 107 this(in, writer, null); 108 } 109 110 public StreamPumper(InputStream in, PrintWriter writer, StreamConsumer consumer) { 111 super(); 112 this.in = new BufferedReader(new InputStreamReader(in), SIZE); 113 this.out = writer; 114 this.consumer = consumer; 115 } 116 117 @Override 118 public void run() { 119 boolean outError = out != null ? out.checkError() : false; 120 121 try { 122 for (String line = in.readLine(); line != null; line = in.readLine()) { 123 try { 124 if (exception == null && consumer != null && !isDisabled()) { 125 consumer.consumeLine(line); 126 } 127 } catch (Exception t) { 128 exception = t; 129 } 130 131 if (out != null && !outError) { 132 out.println(line); 133 134 out.flush(); 135 136 if (out.checkError()) { 137 outError = true; 138 139 try { 140 // Thrown to fill in stack trace elements. 141 throw new IOException(String.format("Failure printing line '%s'.", line)); 142 } catch (final IOException e) { 143 exception = e; 144 } 145 } 146 } 147 } 148 } catch (IOException e) { 149 exception = e; 150 } finally { 151 try { 152 in.close(); 153 } catch (final IOException e2) { 154 if (exception == null) { 155 exception = e2; 156 } 157 } 158 159 synchronized (this) { 160 setDone(); 161 162 this.notifyAll(); 163 } 164 } 165 } 166 167 public void flush() { 168 if (out != null) { 169 out.flush(); 170 171 if (out.checkError() && exception == null) { 172 try { 173 // Thrown to fill in stack trace elements. 174 throw new IOException("Failure flushing output."); 175 } catch (final IOException e) { 176 exception = e; 177 } 178 } 179 } 180 } 181 182 public void close() { 183 if (out != null) { 184 out.close(); 185 186 if (out.checkError() && exception == null) { 187 try { 188 // Thrown to fill in stack trace elements. 189 throw new IOException("Failure closing output."); 190 } catch (final IOException e) { 191 exception = e; 192 } 193 } 194 } 195 } 196 197 public Exception getException() { 198 return exception; 199 } 200 }