View Javadoc

1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  
21  package org.apache.james.util;
22  
23  import org.apache.avalon.cornerstone.services.scheduler.TimeScheduler;
24  
25  import java.io.IOException;
26  import java.io.InputStream;
27  
28  /***
29   * This will reset the scheduler each time a certain amount of data has
30   * been transfered.  This allows us to keep the timeout settings low, while
31   * not timing out during large data transfers.
32   */
33  public class SchedulerNotifyInputStream extends InputStream {
34  
35      /***
36       * The wrapped InputStream
37       */
38      InputStream in = null;
39  
40      /***
41       * The scheduler managing the trigger to be reset by this stream
42       */
43      TimeScheduler scheduler = null;
44  
45      /***
46       * The name of the trigger
47       */
48      String triggerName = null;
49  
50      /***
51       * The number of bytes that need to be read before the counter is reset.
52       */
53      int lengthReset = 0;
54  
55      /***
56       * The number of bytes read since the counter was last reset
57       */
58      int readCounter = 0;
59  
60      /***
61       * @param in the InputStream to be wrapped by this stream
62       * @param scheduler the TimeScheduler managing the trigger to be reset by this stream
63       * @param triggerName the name of the particular trigger to be reset by this stream
64       * @param lengthReset the number of bytes to be read in between trigger resets
65       */
66      public SchedulerNotifyInputStream(InputStream in,
67              TimeScheduler scheduler, String triggerName, int lengthReset) {
68          this.in = in;
69          this.scheduler = scheduler;
70          this.triggerName = triggerName;
71          this.lengthReset = lengthReset;
72  
73          readCounter = 0;
74      }
75  
76      /***
77       * Read an array of bytes from the stream
78       *
79       * @param b the array of bytes to read from the stream
80       * @param off the index in the array where we start writing
81       * @param len the number of bytes of the array to read
82       *
83       * @return the number of bytes read
84       *
85       * @throws IOException if an exception is encountered when reading
86       */
87      public int read(byte[] b, int off, int len) throws IOException {
88          int l = in.read(b, off, len);
89          readCounter += l;
90  
91          if (readCounter > lengthReset) {
92              readCounter -= lengthReset;
93              scheduler.resetTrigger(triggerName);
94          }
95  
96          return l;
97      }
98  
99      /***
100      * Read a byte from the stream
101      *
102      * @return the byte read from the stream
103      * @throws IOException if an exception is encountered when reading
104      */
105     public int read() throws IOException {
106         int b = in.read();
107         readCounter++;
108 
109         if (readCounter > lengthReset) {
110             readCounter -= lengthReset;
111             scheduler.resetTrigger(triggerName);
112         }
113 
114         return b;
115     }
116 
117     /***
118      * Close the stream
119      *
120      * @throws IOException if an exception is encountered when closing
121      */
122     public void close() throws IOException {
123         in.close();
124     }
125 }