001/* ProgressMonitorInputStream.java -- 002 Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package javax.swing; 040 041import java.awt.Component; 042 043import java.io.FilterInputStream; 044import java.io.InputStream; 045import java.io.InterruptedIOException; 046import java.io.IOException; 047 048/** 049 * An input stream with a {@link ProgressMonitor}. 050 * 051 * @author Andrew Selkirk 052 * @author Robert Schuster (robertschuster@fsfe.org) 053 * @status updated to 1.2 054 * @since 1.2 055 */ 056public class ProgressMonitorInputStream extends FilterInputStream 057{ 058 059 /** 060 * The monitor watching the progress of the input stream. 061 */ 062 private ProgressMonitor monitor; 063 064 /** 065 * read 066 */ 067 private int read; 068 069 /** 070 * Creates a new <code>ProgressMonitorInputStream</code>. 071 * 072 * @param component the parent component for the progress monitor dialog. 073 * @param message the task description. 074 * @param stream the underlying input stream. 075 */ 076 public ProgressMonitorInputStream(Component component, Object message, 077 InputStream stream) 078 { 079 super(stream); 080 081 int max = 0; 082 083 try 084 { 085 max = stream.available(); 086 } 087 catch ( IOException ioe ) 088 { 089 // Behave like the JDK here. 090 } 091 092 monitor = new ProgressMonitor(component, message, null, 0, max); 093 } 094 095 /** 096 * Resets the input stream to the point where {@link #mark(int)} was called. 097 * 098 * @exception IOException TODO 099 */ 100 public void reset() throws IOException 101 { 102 super.reset(); 103 104 checkMonitorCanceled(); 105 106 // TODO: The docs says the monitor should be resetted. But to which 107 // value? (mark is not overridden) 108 } 109 110 /** 111 * Reads an unsigned byte from the input stream and returns it as an 112 * <code>int</code> in the range of 0-255. Returns -1 if the end of the 113 * stream has been reached. The progress monitor is updated. 114 * 115 * @return int 116 * 117 * @exception IOException if there is a problem reading the stream. 118 */ 119 public int read() throws IOException 120 { 121 int t = super.read(); 122 123 monitor.setProgress(++read); 124 125 checkMonitorCanceled(); 126 127 return t; 128 } 129 130 /** 131 * Reads bytes from the input stream and stores them in the supplied array, 132 * and updates the progress monitor (or closes it if the end of the stream 133 * is reached). 134 * 135 * @param data the data array for returning bytes read from the stream. 136 * 137 * @return The number of bytes read, or -1 if there are no more bytes in the 138 * stream. 139 * 140 * @throws IOException if there is a problem reading bytes from the stream. 141 */ 142 public int read(byte[] data) throws IOException 143 { 144 int t = super.read(data); 145 146 if ( t > 0 ) 147 { 148 read += t; 149 monitor.setProgress(read); 150 151 checkMonitorCanceled(); 152 } 153 else 154 { 155 monitor.close(); 156 } 157 158 return t; 159 } 160 161 /** 162 * Reads up to <code>length</code> bytes from the input stream and stores 163 * them in the supplied array at the given index, and updates the progress 164 * monitor (or closes it if the end of the stream is reached). 165 * 166 * @param data the data array for returning bytes read from the stream. 167 * @param offset the offset into the array where the bytes should be written. 168 * @param length the maximum number of bytes to read from the stream. 169 * 170 * @return The number of bytes read, or -1 if there are no more bytes in the 171 * stream. 172 * 173 * @throws IOException if there is a problem reading bytes from the stream. 174 */ 175 public int read(byte[] data, int offset, int length) throws IOException 176 { 177 int t = super.read(data, offset, length); 178 179 if ( t > 0 ) 180 { 181 read += t; 182 monitor.setProgress(read); 183 184 checkMonitorCanceled(); 185 } 186 else 187 { 188 monitor.close(); 189 } 190 191 return t; 192 } 193 194 /** 195 * Skips the specified number of bytes and updates the 196 * {@link ProgressMonitor}. 197 * 198 * @param length the number of bytes to skip. 199 * 200 * @return The actual number of bytes skipped. 201 * 202 * @throws IOException if there is a problem skipping bytes in the stream. 203 */ 204 public long skip(long length) throws IOException 205 { 206 long t = super.skip(length); 207 208 // 'read' may overflow here in rare situations. 209 assert ( (long) read + t <= (long) Integer.MAX_VALUE ); 210 211 read += (int) t; 212 213 monitor.setProgress(read); 214 215 checkMonitorCanceled(); 216 217 return t; 218 } 219 220 /** 221 * Closes the input stream and the associated {@link ProgressMonitor}. 222 * 223 * @throws IOException if there is a problem closing the input stream. 224 */ 225 public void close() throws IOException 226 { 227 super.close(); 228 monitor.close(); 229 } 230 231 /** 232 * Returns the {@link ProgressMonitor} used by this input stream. 233 * 234 * @return The progress monitor. 235 */ 236 public ProgressMonitor getProgressMonitor() 237 { 238 return monitor; 239 } 240 241 private void checkMonitorCanceled() throws InterruptedIOException 242 { 243 if (monitor.isCanceled()) 244 { 245 throw new InterruptedIOException("ProgressMonitor was canceled"); 246 } 247 } 248 249}