1. /*
  2. * Copyright 2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.util;
  18. import java.io.IOException;
  19. import java.io.PipedInputStream;
  20. import java.io.PipedOutputStream;
  21. import org.apache.tools.ant.Task;
  22. import org.apache.tools.ant.Project;
  23. /**
  24. * Special <CODE>PipedInputStream</CODE> that will not die
  25. * when the writing <CODE>Thread</CODE> is no longer alive.
  26. * @since Ant 1.6.2
  27. */
  28. public class LeadPipeInputStream extends PipedInputStream {
  29. private Task managingTask;
  30. /**
  31. * Construct a new <CODE>LeadPipeInputStream</CODE>.
  32. */
  33. public LeadPipeInputStream() {
  34. super();
  35. }
  36. /**
  37. * Construct a new <CODE>LeadPipeInputStream</CODE>
  38. * with the specified buffer size.
  39. * @param size the size of the circular buffer.
  40. */
  41. public LeadPipeInputStream(int size) {
  42. super();
  43. setBufferSize(size);
  44. }
  45. /**
  46. * Construct a new <CODE>LeadPipeInputStream</CODE> to pull
  47. * from the specified <CODE>PipedOutputStream</CODE>.
  48. * @param src the <CODE>PipedOutputStream</CODE> source.
  49. */
  50. public LeadPipeInputStream(PipedOutputStream src) throws IOException {
  51. super(src);
  52. }
  53. /**
  54. * Construct a new <CODE>LeadPipeInputStream</CODE> to pull
  55. * from the specified <CODE>PipedOutputStream</CODE>, using a
  56. * circular buffer of the specified size.
  57. * @param src the <CODE>PipedOutputStream</CODE> source.
  58. * @param size the size of the circular buffer.
  59. */
  60. public LeadPipeInputStream(PipedOutputStream src, int size) throws IOException {
  61. super(src);
  62. setBufferSize(size);
  63. }
  64. //inherit doc
  65. public synchronized int read() throws IOException {
  66. int result = -1;
  67. try {
  68. result = super.read();
  69. } catch (IOException eyeOhEx) {
  70. if ("write end dead".equalsIgnoreCase(eyeOhEx.getMessage())) {
  71. if (in > 0 && out < buffer.length && out > in) {
  72. result = buffer[out++] & 0xFF;
  73. }
  74. } else {
  75. log("error at LeadPipeInputStream.read(): "
  76. + eyeOhEx.getMessage(), Project.MSG_INFO);
  77. }
  78. }
  79. return result;
  80. }
  81. /**
  82. * Set the size of the buffer.
  83. * @param size the new buffer size. Ignored if <= current size.
  84. */
  85. public synchronized void setBufferSize(int size) {
  86. if (size > buffer.length) {
  87. byte[] newBuffer = new byte[size];
  88. if (in >= 0) {
  89. if (in > out) {
  90. System.arraycopy(buffer, out, newBuffer, out, in - out);
  91. } else {
  92. int outlen = buffer.length - out;
  93. System.arraycopy(buffer, out, newBuffer, 0, outlen);
  94. System.arraycopy(buffer, 0, newBuffer, outlen, in);
  95. in+= outlen;
  96. out = 0;
  97. }
  98. }
  99. buffer = newBuffer;
  100. }
  101. }
  102. /**
  103. * Set a managing <CODE>Task</CODE> for
  104. * this <CODE>LeadPipeInputStream</CODE>.
  105. * @param task the managing <CODE>Task</CODE>.
  106. */
  107. public void setManagingTask(Task task) {
  108. this.managingTask = task;
  109. }
  110. /**
  111. * Log a message with the specified logging level.
  112. * @param message the <CODE>String</CODE> message.
  113. * @param loglevel the <CODE>int</CODE> logging level.
  114. */
  115. public void log(String message, int loglevel) {
  116. if (managingTask != null) {
  117. managingTask.log(message, loglevel);
  118. } else {
  119. if (loglevel > Project.MSG_WARN) {
  120. System.out.println(message);
  121. } else {
  122. System.err.println(message);
  123. }
  124. }
  125. }
  126. }