001: /*
002: * $Header: /home/cvs/jakarta-commons/fileupload/src/java/org/apache/commons/fileupload/AThresholdingOutputStream.java,v 1.3 2003/05/31 22:31:08 martinc Exp $
003: * $Revision: 1.3 $
004: * $Date: 2003/05/31 22:31:08 $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Commons", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: */
061:
062: package de.ug2t.extTools.httpFileUpLoad;
063:
064: import java.io.*;
065:
066: /**
067: * An output stream which triggers an event when a specified number of bytes of
068: * data have been written to it. The event can be used, for example, to throw an
069: * exception if a maximum has been reached, or to switch the underlying stream
070: * type when the threshold is exceeded.
071: * <p>
072: * This class overrides all <code>OutputStream</code> methods. However, these
073: * overrides ultimately call the corresponding methods in the underlying output
074: * stream implementation.
075: * <p>
076: * NOTE: This implementation may trigger the event <em>before</em> the
077: * threshold is actually reached, since it triggers when a pending write
078: * operation would cause the threshold to be exceeded.
079: *
080: * @author <a href="mailto:martinc@apache.org">Martin Cooper</a>
081: *
082: * @version $Id: AThresholdingOutputStream.java,v 1.3 2003/05/31 22:31:08 martinc
083: * Exp $
084: */
085: public abstract class AThresholdingOutputStream extends OutputStream {
086:
087: // ----------------------------------------------------------- Data members
088:
089: /**
090: * The threshold at which the event will be triggered.
091: */
092: private int threshold;
093:
094: /**
095: * The number of bytes written to the output stream.
096: */
097: private long written;
098:
099: /**
100: * Whether or not the configured threshold has been exceeded.
101: */
102: private boolean thresholdExceeded;
103:
104: // ----------------------------------------------------------- Constructors
105:
106: /**
107: * Constructs an instance of this class which will trigger an event at the
108: * specified threshold.
109: *
110: * @param threshold
111: * The number of bytes at which to trigger an event.
112: */
113: public AThresholdingOutputStream(int threshold) {
114: this .threshold = threshold;
115: }
116:
117: // --------------------------------------------------- OutputStream methods
118:
119: /**
120: * Writes the specified byte to this output stream.
121: *
122: * @param b
123: * The byte to be written.
124: *
125: * @exception IOException
126: * if an error occurs.
127: */
128: public void write(int b) throws IOException {
129: checkThreshold(1);
130: getStream().write(b);
131: written++;
132: }
133:
134: /**
135: * Writes <code>b.length</code> bytes from the specified byte array to this
136: * output stream.
137: *
138: * @param b
139: * The array of bytes to be written.
140: *
141: * @exception IOException
142: * if an error occurs.
143: */
144: public void write(byte b[]) throws IOException {
145: checkThreshold(b.length);
146: getStream().write(b);
147: written += b.length;
148: }
149:
150: /**
151: * Writes <code>len</code> bytes from the specified byte array starting at
152: * offset <code>off</code> to this output stream.
153: *
154: * @param b
155: * The byte array from which the data will be written.
156: * @param off
157: * The start offset in the byte array.
158: * @param len
159: * The number of bytes to write.
160: *
161: * @exception IOException
162: * if an error occurs.
163: */
164: public void write(byte b[], int off, int len) throws IOException {
165: checkThreshold(len);
166: getStream().write(b, off, len);
167: written += len;
168: }
169:
170: /**
171: * Flushes this output stream and forces any buffered output bytes to be
172: * written out.
173: *
174: * @exception IOException
175: * if an error occurs.
176: */
177: public void flush() throws IOException {
178: getStream().flush();
179: }
180:
181: /**
182: * Closes this output stream and releases any system resources associated with
183: * this stream.
184: *
185: * @exception IOException
186: * if an error occurs.
187: */
188: public void close() throws IOException {
189: try {
190: flush();
191: } catch (IOException ignored) {
192: // ignore
193: }
194: getStream().close();
195: }
196:
197: // --------------------------------------------------------- Public methods
198:
199: /**
200: * Returns the threshold, in bytes, at which an event will be triggered.
201: *
202: * @return The threshold point, in bytes.
203: */
204: public int getThreshold() {
205: return threshold;
206: }
207:
208: /**
209: * Returns the number of bytes that have been written to this output stream.
210: *
211: * @return The number of bytes written.
212: */
213: public long getByteCount() {
214: return written;
215: }
216:
217: /**
218: * Determines whether or not the configured threshold has been exceeded for
219: * this output stream.
220: *
221: * @return <code>true</code> if the threshold has been reached;
222: * <code>false</code> otherwise.
223: */
224: public boolean isThresholdExceeded() {
225: return (written > threshold);
226: }
227:
228: // ------------------------------------------------------ Protected methods
229:
230: /**
231: * Checks to see if writing the specified number of bytes would cause the
232: * configured threshold to be exceeded. If so, triggers an event to allow a
233: * concrete implementation to take action on this.
234: *
235: * @param count
236: * The number of bytes about to be written to the underlying output
237: * stream.
238: *
239: * @exception IOException
240: * if an error occurs.
241: */
242: protected void checkThreshold(int count) throws IOException {
243: if (!thresholdExceeded && (written + count > threshold)) {
244: thresholdReached();
245: thresholdExceeded = true;
246: }
247: }
248:
249: // ------------------------------------------------------- Abstract methods
250:
251: /**
252: * Returns the underlying output stream, to which the corresponding
253: * <code>OutputStream</code> methods in this class will ultimately delegate.
254: *
255: * @return The underlying output stream.
256: *
257: * @exception IOException
258: * if an error occurs.
259: */
260: protected abstract OutputStream getStream() throws IOException;
261:
262: /**
263: * Indicates that the configured threshold has been reached, and that a
264: * subclass should take whatever action necessary on this event. This may
265: * include changing the underlying output stream.
266: *
267: * @exception IOException
268: * if an error occurs.
269: */
270: protected abstract void thresholdReached() throws IOException;
271: }
|