View Javadoc
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   * @version $Id$
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 }