KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > core > streams > ProgressMonitorInputStream


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.internal.core.streams;
12
13 import java.io.FilterInputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.InterruptedIOException JavaDoc;
17
18 import org.eclipse.core.runtime.IProgressMonitor;
19
20 /**
21  * Updates a progress monitor as bytes are read from the input stream.
22  * Also starts a background thread to provide responsive cancellation on read().
23  *
24  * Supports resuming partially completed operations after an InterruptedIOException
25  * if the underlying stream does. Check the bytesTransferred field to determine how
26  * much of the operation completed; conversely, at what point to resume.
27  */

28 public abstract class ProgressMonitorInputStream extends FilterInputStream JavaDoc {
29     private IProgressMonitor monitor;
30     private int updateIncrement;
31     private long bytesTotal;
32     private long bytesRead = 0;
33     private long lastUpdate = -1;
34     private long nextUpdate = 0;
35     
36     /**
37      * Creates a progress monitoring input stream.
38      * @param in the underlying input stream
39      * @param bytesTotal the number of bytes to read in total (passed to updateMonitor())
40      * @param updateIncrement the number of bytes read between updates
41      * @param monitor the progress monitor
42      */

43     public ProgressMonitorInputStream(InputStream JavaDoc in, long bytesTotal, int updateIncrement, IProgressMonitor monitor) {
44         super(in);
45         this.bytesTotal = bytesTotal;
46         this.updateIncrement = updateIncrement;
47         this.monitor = monitor;
48         update(true);
49     }
50
51     protected abstract void updateMonitor(long bytesRead, long size, IProgressMonitor monitor);
52
53     /**
54      * Wraps the underlying stream's method.
55      * Updates the progress monitor to the final number of bytes read.
56      * @throws IOException if an i/o error occurs
57      */

58     public void close() throws IOException JavaDoc {
59         try {
60             in.close();
61         } finally {
62             update(true);
63         }
64     }
65
66     /**
67      * Wraps the underlying stream's method.
68      * Updates the progress monitor if the next update increment has been reached.
69      * @throws InterruptedIOException if the operation was interrupted before all of the
70      * bytes specified have been skipped, bytesTransferred will be zero
71      * @throws IOException if an i/o error occurs
72      */

73     public int read() throws IOException JavaDoc {
74         int b = in.read();
75         if (b != -1) {
76             bytesRead += 1;
77             update(false);
78         }
79         return b;
80     }
81     
82     /**
83      * Wraps the underlying stream's method.
84      * Updates the progress monitor if the next update increment has been reached.
85      * @throws InterruptedIOException if the operation was interrupted before all of the
86      * bytes specified have been skipped, bytesTransferred may be non-zero
87      * @throws IOException if an i/o error occurs
88      */

89     public int read(byte[] buffer, int offset, int length) throws IOException JavaDoc {
90         try {
91             int count = in.read(buffer, offset, length);
92             if (count != -1) {
93                 bytesRead += count;
94                 update(false);
95             }
96             return count;
97         } catch (InterruptedIOException JavaDoc e) {
98             bytesRead += e.bytesTransferred;
99             update(false);
100             throw e;
101         }
102     }
103     
104     /**
105      * Wraps the underlying stream's method.
106      * Updates the progress monitor if the next update increment has been reached.
107      * @throws InterruptedIOException if the operation was interrupted before all of the
108      * bytes specified have been skipped, bytesTransferred may be non-zero
109      * @throws IOException if an i/o error occurs
110      */

111     public long skip(long amount) throws IOException JavaDoc {
112         try {
113             long count = in.skip(amount);
114             bytesRead += count;
115             update(false);
116             return count;
117         } catch (InterruptedIOException JavaDoc e) {
118             bytesRead += e.bytesTransferred;
119             update(false);
120             throw e;
121         }
122     }
123     
124     /**
125      * Mark is not supported by the wrapper even if the underlying stream does, returns false.
126      */

127     public boolean markSupported() {
128         return false;
129     }
130     
131     private void update(boolean now) {
132         if (bytesRead >= nextUpdate || now) {
133             nextUpdate = bytesRead - (bytesRead % updateIncrement);
134             if (nextUpdate != lastUpdate) updateMonitor(nextUpdate, bytesTotal, monitor);
135             lastUpdate = nextUpdate;
136             nextUpdate += updateIncrement;
137         }
138     }
139 }
140
Popular Tags