View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  
22  package org.opencastproject.util;
23  
24  import org.apache.commons.io.input.ProxyInputStream;
25  
26  import java.beans.PropertyChangeListener;
27  import java.beans.PropertyChangeSupport;
28  import java.io.IOException;
29  import java.io.InputStream;
30  
31  /**
32   * An {@link InputStream} that counts the number of bytes read.
33   */
34  public class ProgressInputStream extends ProxyInputStream {
35  
36    private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
37  
38    private volatile long totalNumBytesRead;
39  
40    public ProgressInputStream(InputStream in) {
41      super(in);
42    }
43  
44    public long getTotalNumBytesRead() {
45      return totalNumBytesRead;
46    }
47  
48    /**
49     * Adds a {@link PropertyChangeListener}
50     *
51     * The listener gets notified as soon as the input stream is read.
52     *
53     * @param l
54     *          the {@link PropertyChangeListener}
55     */
56    public void addPropertyChangeListener(PropertyChangeListener l) {
57      propertyChangeSupport.addPropertyChangeListener(l);
58    }
59  
60    /**
61     * Removes a {@link PropertyChangeListener}
62     *
63     * The listener gets notified as soon as the input stream is read.
64     *
65     * @param l
66     *          the {@link PropertyChangeListener}
67     */
68    public void removePropertyChangeListener(PropertyChangeListener l) {
69      propertyChangeSupport.removePropertyChangeListener(l);
70    }
71  
72    @Override
73    public int read() throws IOException {
74      return (int) updateProgress(super.read());
75    }
76  
77    @Override
78    public int read(byte[] b) throws IOException {
79      return (int) updateProgress(super.read(b));
80    }
81  
82    @Override
83    public int read(byte[] b, int off, int len) throws IOException {
84      return (int) updateProgress(super.read(b, off, len));
85    }
86  
87    @Override
88    public long skip(long n) throws IOException {
89      return updateProgress(super.skip(n));
90    }
91  
92    @Override
93    public void mark(int readlimit) {
94      throw new UnsupportedOperationException();
95    }
96  
97    @Override
98    public void reset() throws IOException {
99      throw new UnsupportedOperationException();
100   }
101 
102   @Override
103   public boolean markSupported() {
104     return false;
105   }
106 
107   private long updateProgress(long numBytesRead) {
108     if (numBytesRead > 0) {
109       long oldTotalNumBytesRead = totalNumBytesRead;
110       totalNumBytesRead += numBytesRead;
111       propertyChangeSupport.firePropertyChange("totalNumBytesRead", oldTotalNumBytesRead, totalNumBytesRead);
112     }
113     return numBytesRead;
114   }
115 }