KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > util > OutputStreamFunneler


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
19 package org.apache.tools.ant.util;
20
21 import java.io.IOException JavaDoc;
22 import java.io.OutputStream JavaDoc;
23
24 /**
25  * Manages a set of <code>OutputStream</code>s to
26  * write to a single underlying stream, which is
27  * closed only when the last &quot;funnel&quot;
28  * has been closed.
29  */

30 public class OutputStreamFunneler {
31
32     /**
33      * Default timeout.
34      * @see #setTimeout(long)
35      */

36     public static final long DEFAULT_TIMEOUT_MILLIS = 1000;
37
38     private final class Funnel extends OutputStream JavaDoc {
39         private boolean closed = false;
40
41         private Funnel() {
42             synchronized (OutputStreamFunneler.this) {
43                 ++count;
44             }
45         }
46
47         public void flush() throws IOException JavaDoc {
48             synchronized (OutputStreamFunneler.this) {
49                 dieIfClosed();
50                 out.flush();
51             }
52         }
53
54         public void write(int b) throws IOException JavaDoc {
55             synchronized (OutputStreamFunneler.this) {
56                 dieIfClosed();
57                 out.write(b);
58             }
59         }
60
61         public void write(byte[] b) throws IOException JavaDoc {
62             synchronized (OutputStreamFunneler.this) {
63                 dieIfClosed();
64                 out.write(b);
65             }
66         }
67
68         public void write(byte[] b, int off, int len) throws IOException JavaDoc {
69             synchronized (OutputStreamFunneler.this) {
70                 dieIfClosed();
71                 out.write(b, off, len);
72             }
73         }
74
75         public void close() throws IOException JavaDoc {
76             release(this);
77         }
78     }
79
80     private OutputStream JavaDoc out;
81     private int count = 0;
82     private boolean closed;
83     private long timeoutMillis;
84
85     /**
86      * Create a new <code>OutputStreamFunneler</code> for
87      * the specified <code>OutputStream</code>.
88      * @param out <code>OutputStream</code>.
89      */

90     public OutputStreamFunneler(OutputStream JavaDoc out) {
91         this(out, DEFAULT_TIMEOUT_MILLIS);
92     }
93
94     /**
95      * Create a new <code>OutputStreamFunneler</code> for
96      * the specified <code>OutputStream</code>, with the
97      * specified timeout value.
98      * @param out <code>OutputStream</code>.
99      * @param timeoutMillis <code>long</code>.
100      * @see #setTimeout(long)
101      */

102     public OutputStreamFunneler(OutputStream JavaDoc out, long timeoutMillis) {
103         if (out == null) {
104             throw new IllegalArgumentException JavaDoc(
105                 "OutputStreamFunneler.<init>: out == null");
106         }
107         this.out = out;
108         this.closed = false; //as far as we know
109
setTimeout(timeoutMillis);
110     }
111
112     /**
113      * Set the timeout for this <code>OutputStreamFunneler</code>.
114      * This is the maximum time that may elapse between the closure
115      * of the last &quot;funnel&quot; and the next call to
116      * <code>getOutputStream()</code> without closing the
117      * underlying stream.
118      * @param timeoutMillis <code>long</code> timeout value.
119      */

120     public synchronized void setTimeout(long timeoutMillis) {
121         this.timeoutMillis = timeoutMillis;
122     }
123
124     /**
125      * Get a &quot;funnel&quot; <code>OutputStream</code> instance to
126      * write to this <code>OutputStreamFunneler</code>'s underlying
127      * <code>OutputStream</code>.
128      * @return <code>OutputStream</code>.
129      * @throws IOException if unable to create the funnel.
130      */

131     public synchronized OutputStream JavaDoc getFunnelInstance()
132         throws IOException JavaDoc {
133         dieIfClosed();
134         try {
135             return new Funnel();
136         } finally {
137             notifyAll();
138         }
139     }
140
141     private synchronized void release(Funnel funnel) throws IOException JavaDoc {
142         //ignore release of an already-closed funnel
143
if (!funnel.closed) {
144             try {
145                 if (timeoutMillis > 0) {
146                     try {
147                         wait(timeoutMillis);
148                     } catch (InterruptedException JavaDoc eyeEx) {
149                         //ignore
150
}
151                 }
152                 if (--count == 0) {
153                     close();
154                 }
155             } finally {
156                 funnel.closed = true;
157             }
158         }
159    }
160
161     private synchronized void close() throws IOException JavaDoc {
162         try {
163             dieIfClosed();
164             out.close();
165         } finally {
166             closed = true;
167         }
168     }
169
170     private synchronized void dieIfClosed() throws IOException JavaDoc {
171         if (closed) {
172             throw new IOException JavaDoc("The funneled OutputStream has been closed.");
173         }
174     }
175
176 }
177
Popular Tags