001 // License: GPL. Copyright 2007 by Immanuel Scholz and others
002 package org.openstreetmap.josm.io;
003
004 import static org.openstreetmap.josm.tools.I18n.tr;
005
006 import java.io.IOException;
007 import java.io.InputStream;
008 import java.net.URLConnection;
009
010 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
011 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
012
013 /**
014 * Read from an other reader and increment an progress counter while on the way.
015 * @author Imi
016 */
017 public class ProgressInputStream extends InputStream {
018
019 private final InputStream in;
020 private int readSoFar = 0;
021 private int lastDialogUpdate = 0;
022 private boolean sizeKnown;
023 private final URLConnection connection;
024 private final ProgressMonitor progressMonitor;
025
026 public ProgressInputStream(URLConnection con, ProgressMonitor progressMonitor) throws OsmTransferException {
027 this.connection = con;
028 if (progressMonitor == null) {
029 progressMonitor = NullProgressMonitor.INSTANCE;
030 }
031 this.progressMonitor = progressMonitor;
032 progressMonitor.beginTask(tr("Contacting OSM Server..."), 1);
033 progressMonitor.indeterminateSubTask(null);
034
035 try {
036 this.in = con.getInputStream();
037 } catch (IOException e) {
038 progressMonitor.finishTask();
039 if (con.getHeaderField("Error") != null)
040 throw new OsmTransferException(tr(con.getHeaderField("Error")));
041 throw new OsmTransferException(e);
042 }
043
044 updateSize();
045 if (!sizeKnown) {
046 progressMonitor.indeterminateSubTask(tr("Downloading OSM data..."));
047 }
048 }
049
050 @Override public void close() throws IOException {
051 in.close();
052 progressMonitor.finishTask();
053 }
054
055 @Override public int read(byte[] b, int off, int len) throws IOException {
056 int read = in.read(b, off, len);
057 if (read != -1) {
058 advanceTicker(read);
059 } else {
060 progressMonitor.finishTask();
061 }
062 return read;
063 }
064
065 @Override public int read() throws IOException {
066 int read = in.read();
067 if (read != -1) {
068 advanceTicker(1);
069 } else {
070 progressMonitor.finishTask();
071 }
072 return read;
073 }
074
075 /**
076 * Increase ticker (progress counter and displayed text) by the given amount.
077 * @param amount
078 */
079 private void advanceTicker(int amount) {
080 readSoFar += amount;
081 updateSize();
082
083 if (readSoFar / 1024 != lastDialogUpdate) {
084 lastDialogUpdate++;
085 if (sizeKnown) {
086 progressMonitor.setTicks(readSoFar);
087 }
088 progressMonitor.setExtraText(readSoFar/1024 + " KB");
089 }
090 }
091
092 private void updateSize() {
093 if (!sizeKnown && connection.getContentLength() > 0) {
094 sizeKnown = true;
095 progressMonitor.subTask(tr("Downloading OSM data..."));
096 progressMonitor.setTicksCount(connection.getContentLength());
097 }
098 }
099 }