View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  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,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.utils.cli;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.util.Objects;
25  
26  /**
27   * Poll InputStream for available data and write the output to an OutputStream.
28   *
29   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
30   */
31  class StreamPollFeeder extends Thread {
32  
33      public static final int BUF_LEN = 80;
34  
35      private final InputStream input;
36      private final OutputStream output;
37  
38      private Throwable exception;
39  
40      private boolean done;
41      private final Object lock = new Object();
42  
43      /**
44       * Create a new StreamPollFeeder
45       *
46       * @param input  Stream to read from
47       * @param output Stream to write to
48       */
49      StreamPollFeeder(InputStream input, OutputStream output) {
50          this.input = Objects.requireNonNull(input);
51          this.output = Objects.requireNonNull(output);
52          this.done = false;
53      }
54  
55      @Override
56      public void run() {
57  
58          byte[] buf = new byte[BUF_LEN];
59  
60          try {
61              while (!done) {
62                  if (input.available() > 0) {
63                      int i = input.read(buf);
64                      if (i > 0) {
65                          output.write(buf, 0, i);
66                          output.flush();
67                      } else {
68                          done = true;
69                      }
70                  } else {
71                      synchronized (lock) {
72                          if (!done) {
73                              lock.wait(100);
74                          }
75                      }
76                  }
77              }
78          } catch (IOException e) {
79              exception = e;
80          } catch (InterruptedException e) {
81              Thread.currentThread().interrupt();
82          } finally {
83              close();
84          }
85      }
86  
87      private void close() {
88          try {
89              output.close();
90          } catch (IOException e) {
91              if (exception == null) {
92                  exception = e;
93              }
94          }
95      }
96  
97      /**
98       * @since 3.2.0
99       */
100     public Throwable getException() {
101         return this.exception;
102     }
103 
104     public void waitUntilDone() {
105 
106         synchronized (lock) {
107             done = true;
108             lock.notifyAll();
109         }
110 
111         try {
112             join();
113         } catch (InterruptedException e) {
114             Thread.currentThread().interrupt();
115         }
116     }
117 }