You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

PumpStreamHandler.java 6.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package org.apache.tools.ant.taskdefs;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.OutputStream;
  22. /**
  23. * Copies standard output and error of subprocesses to standard output and
  24. * error of the parent process.
  25. *
  26. * @since Ant 1.2
  27. */
  28. public class PumpStreamHandler implements ExecuteStreamHandler {
  29. private Thread outputThread;
  30. private Thread errorThread;
  31. private StreamPumper inputPump;
  32. private OutputStream out;
  33. private OutputStream err;
  34. private InputStream input;
  35. /**
  36. * Construct a new <code>PumpStreamHandler</code>.
  37. * @param out the output <code>OutputStream</code>.
  38. * @param err the error <code>OutputStream</code>.
  39. * @param input the input <code>InputStream</code>.
  40. */
  41. public PumpStreamHandler(OutputStream out, OutputStream err,
  42. InputStream input) {
  43. this.out = out;
  44. this.err = err;
  45. this.input = input;
  46. }
  47. /**
  48. * Construct a new <code>PumpStreamHandler</code>.
  49. * @param out the output <code>OutputStream</code>.
  50. * @param err the error <code>OutputStream</code>.
  51. */
  52. public PumpStreamHandler(OutputStream out, OutputStream err) {
  53. this(out, err, null);
  54. }
  55. /**
  56. * Construct a new <code>PumpStreamHandler</code>.
  57. * @param outAndErr the output/error <code>OutputStream</code>.
  58. */
  59. public PumpStreamHandler(OutputStream outAndErr) {
  60. this(outAndErr, outAndErr);
  61. }
  62. /**
  63. * Construct a new <code>PumpStreamHandler</code>.
  64. */
  65. public PumpStreamHandler() {
  66. this(System.out, System.err);
  67. }
  68. /**
  69. * Set the <code>InputStream</code> from which to read the
  70. * standard output of the process.
  71. * @param is the <code>InputStream</code>.
  72. */
  73. public void setProcessOutputStream(InputStream is) {
  74. createProcessOutputPump(is, out);
  75. }
  76. /**
  77. * Set the <code>InputStream</code> from which to read the
  78. * standard error of the process.
  79. * @param is the <code>InputStream</code>.
  80. */
  81. public void setProcessErrorStream(InputStream is) {
  82. if (err != null) {
  83. createProcessErrorPump(is, err);
  84. }
  85. }
  86. /**
  87. * Set the <code>OutputStream</code> by means of which
  88. * input can be sent to the process.
  89. * @param os the <code>OutputStream</code>.
  90. */
  91. public void setProcessInputStream(OutputStream os) {
  92. if (input != null) {
  93. inputPump = createInputPump(input, os, true);
  94. } else {
  95. try {
  96. os.close();
  97. } catch (IOException e) {
  98. //ignore
  99. }
  100. }
  101. }
  102. /**
  103. * Start the <code>Thread</code>s.
  104. */
  105. public void start() {
  106. outputThread.start();
  107. errorThread.start();
  108. if (inputPump != null) {
  109. Thread inputThread = new Thread(inputPump);
  110. inputThread.setDaemon(true);
  111. inputThread.start();
  112. }
  113. }
  114. /**
  115. * Stop pumping the streams.
  116. */
  117. public void stop() {
  118. try {
  119. outputThread.join();
  120. } catch (InterruptedException e) {
  121. // ignore
  122. }
  123. try {
  124. errorThread.join();
  125. } catch (InterruptedException e) {
  126. // ignore
  127. }
  128. if (inputPump != null) {
  129. inputPump.stop();
  130. }
  131. try {
  132. err.flush();
  133. } catch (IOException e) {
  134. // ignore
  135. }
  136. try {
  137. out.flush();
  138. } catch (IOException e) {
  139. // ignore
  140. }
  141. }
  142. /**
  143. * Get the error stream.
  144. * @return <code>OutputStream</code>.
  145. */
  146. protected OutputStream getErr() {
  147. return err;
  148. }
  149. /**
  150. * Get the output stream.
  151. * @return <code>OutputStream</code>.
  152. */
  153. protected OutputStream getOut() {
  154. return out;
  155. }
  156. /**
  157. * Create the pump to handle process output.
  158. * @param is the <code>InputStream</code>.
  159. * @param os the <code>OutputStream</code>.
  160. */
  161. protected void createProcessOutputPump(InputStream is, OutputStream os) {
  162. outputThread = createPump(is, os);
  163. }
  164. /**
  165. * Create the pump to handle error output.
  166. * @param is the input stream to copy from.
  167. * @param os the output stream to copy to.
  168. */
  169. protected void createProcessErrorPump(InputStream is, OutputStream os) {
  170. errorThread = createPump(is, os);
  171. }
  172. /**
  173. * Creates a stream pumper to copy the given input stream to the
  174. * given output stream.
  175. * @param is the input stream to copy from.
  176. * @param os the output stream to copy to.
  177. * @return a thread object that does the pumping.
  178. */
  179. protected Thread createPump(InputStream is, OutputStream os) {
  180. return createPump(is, os, false);
  181. }
  182. /**
  183. * Creates a stream pumper to copy the given input stream to the
  184. * given output stream.
  185. * @param is the input stream to copy from.
  186. * @param os the output stream to copy to.
  187. * @param closeWhenExhausted if true close the inputstream.
  188. * @return a thread object that does the pumping.
  189. */
  190. protected Thread createPump(InputStream is, OutputStream os,
  191. boolean closeWhenExhausted) {
  192. final Thread result
  193. = new Thread(new StreamPumper(is, os, closeWhenExhausted));
  194. result.setDaemon(true);
  195. return result;
  196. }
  197. /**
  198. * Creates a stream pumper to copy the given input stream to the
  199. * given output stream. Used for standard input.
  200. * @since Ant 1.6.3
  201. */
  202. /*protected*/ StreamPumper createInputPump(InputStream is, OutputStream os,
  203. boolean closeWhenExhausted) {
  204. StreamPumper pumper = new StreamPumper(is, os, closeWhenExhausted);
  205. pumper.setAutoflush(true);
  206. return pumper;
  207. }
  208. }