001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.util;
019:
020: import org.apache.avalon.cornerstone.services.scheduler.TimeScheduler;
021:
022: import java.io.IOException;
023: import java.io.InputStream;
024:
025: /**
026: * This will reset the scheduler each time a certain amount of data has
027: * been transfered. This allows us to keep the timeout settings low, while
028: * not timing out during large data transfers.
029: */
030: public class SchedulerNotifyInputStream extends InputStream {
031:
032: /**
033: * The wrapped InputStream
034: */
035: InputStream in = null;
036:
037: /**
038: * The scheduler managing the trigger to be reset by this stream
039: */
040: TimeScheduler scheduler = null;
041:
042: /**
043: * The name of the trigger
044: */
045: String triggerName = null;
046:
047: /**
048: * The number of bytes that need to be read before the counter is reset.
049: */
050: int lengthReset = 0;
051:
052: /**
053: * The number of bytes read since the counter was last reset
054: */
055: int readCounter = 0;
056:
057: /**
058: * @param in the InputStream to be wrapped by this stream
059: * @param scheduler the TimeScheduler managing the trigger to be reset by this stream
060: * @param triggerName the name of the particular trigger to be reset by this stream
061: * @param lengthReset the number of bytes to be read in between trigger resets
062: */
063: public SchedulerNotifyInputStream(InputStream in,
064: TimeScheduler scheduler, String triggerName, int lengthReset) {
065: this .in = in;
066: this .scheduler = scheduler;
067: this .triggerName = triggerName;
068: this .lengthReset = lengthReset;
069:
070: readCounter = 0;
071: }
072:
073: /**
074: * Read an array of bytes from the stream
075: *
076: * @param b the array of bytes to read from the stream
077: * @param off the index in the array where we start writing
078: * @param len the number of bytes of the array to read
079: *
080: * @return the number of bytes read
081: *
082: * @throws IOException if an exception is encountered when reading
083: */
084: public int read(byte[] b, int off, int len) throws IOException {
085: int l = in.read(b, off, len);
086: readCounter += l;
087:
088: if (readCounter > lengthReset) {
089: readCounter -= lengthReset;
090: scheduler.resetTrigger(triggerName);
091: }
092:
093: return l;
094: }
095:
096: /**
097: * Read a byte from the stream
098: *
099: * @return the byte read from the stream
100: * @throws IOException if an exception is encountered when reading
101: */
102: public int read() throws IOException {
103: int b = in.read();
104: readCounter++;
105:
106: if (readCounter > lengthReset) {
107: readCounter -= lengthReset;
108: scheduler.resetTrigger(triggerName);
109: }
110:
111: return b;
112: }
113:
114: /**
115: * Close the stream
116: *
117: * @throws IOException if an exception is encountered when closing
118: */
119: public void close() throws IOException {
120: in.close();
121: }
122: }
|