001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.tools.ant.util;
020:
021: import java.io.IOException;
022: import java.io.PipedInputStream;
023: import java.io.PipedOutputStream;
024:
025: import org.apache.tools.ant.ProjectComponent;
026: import org.apache.tools.ant.Task;
027: import org.apache.tools.ant.Project;
028:
029: /**
030: * Special <code>PipedInputStream</code> that will not die
031: * when the writing <code>Thread</code> is no longer alive.
032: * @since Ant 1.6.2
033: */
034: public class LeadPipeInputStream extends PipedInputStream {
035: private ProjectComponent managingPc;
036:
037: /**
038: * Construct a new <code>LeadPipeInputStream</code>.
039: */
040: public LeadPipeInputStream() {
041: super ();
042: }
043:
044: /**
045: * Construct a new <code>LeadPipeInputStream</code>
046: * with the specified buffer size.
047: * @param size the size of the circular buffer.
048: */
049: public LeadPipeInputStream(int size) {
050: super ();
051: setBufferSize(size);
052: }
053:
054: /**
055: * Construct a new <code>LeadPipeInputStream</code> to pull
056: * from the specified <code>PipedOutputStream</code>.
057: * @param src the <code>PipedOutputStream</code> source.
058: * @throws IOException if unable to construct the stream.
059: */
060: public LeadPipeInputStream(PipedOutputStream src)
061: throws IOException {
062: super (src);
063: }
064:
065: /**
066: * Construct a new <code>LeadPipeInputStream</code> to pull
067: * from the specified <code>PipedOutputStream</code>, using a
068: * circular buffer of the specified size.
069: * @param src the <code>PipedOutputStream</code> source.
070: * @param size the size of the circular buffer.
071: * @throws IOException if there is an error.
072: */
073: public LeadPipeInputStream(PipedOutputStream src, int size)
074: throws IOException {
075: super (src);
076: setBufferSize(size);
077: }
078:
079: //inherit doc
080: /**
081: * Read a byte from the stream.
082: * @return the byte (0 to 255) or -1 if there are no more.
083: * @throws IOException if there is an error.
084: */
085: public synchronized int read() throws IOException {
086: int result = -1;
087: try {
088: result = super .read();
089: } catch (IOException eyeOhEx) {
090: if ("write end dead".equalsIgnoreCase(eyeOhEx.getMessage())) {
091: if (super .in > 0 && super .out < super .buffer.length
092: && super .out > super .in) {
093: result = super .buffer[super .out++] & 0xFF;
094: }
095: } else {
096: log("error at LeadPipeInputStream.read(): "
097: + eyeOhEx.getMessage(), Project.MSG_INFO);
098: }
099: }
100: return result;
101: }
102:
103: /**
104: * Set the size of the buffer.
105: * @param size the new buffer size. Ignored if <= current size.
106: */
107: public synchronized void setBufferSize(int size) {
108: if (size > buffer.length) {
109: byte[] newBuffer = new byte[size];
110: if (in >= 0) {
111: if (in > out) {
112: System.arraycopy(buffer, out, newBuffer, out, in
113: - out);
114: } else {
115: int outlen = buffer.length - out;
116: System.arraycopy(buffer, out, newBuffer, 0, outlen);
117: System.arraycopy(buffer, 0, newBuffer, outlen, in);
118: in += outlen;
119: out = 0;
120: }
121: }
122: buffer = newBuffer;
123: }
124: }
125:
126: /**
127: * Set a managing <code>Task</code> for
128: * this <code>LeadPipeInputStream</code>.
129: * @param task the managing <code>Task</code>.
130: */
131: public void setManagingTask(Task task) {
132: setManagingComponent(task);
133: }
134:
135: /**
136: * Set a managing <code>ProjectComponent</code> for
137: * this <code>LeadPipeInputStream</code>.
138: * @param pc the managing <code>ProjectComponent</code>.
139: */
140: public void setManagingComponent(ProjectComponent pc) {
141: this .managingPc = pc;
142: }
143:
144: /**
145: * Log a message with the specified logging level.
146: * @param message the <code>String</code> message.
147: * @param loglevel the <code>int</code> logging level.
148: */
149: public void log(String message, int loglevel) {
150: if (managingPc != null) {
151: managingPc.log(message, loglevel);
152: } else {
153: if (loglevel > Project.MSG_WARN) {
154: System.out.println(message);
155: } else {
156: System.err.println(message);
157: }
158: }
159: }
160: }
|