001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.io.IOException; 007import java.io.InputStream; 008import java.net.URLConnection; 009 010import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 011import 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 */ 017public 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 try { 052 in.close(); 053 } finally { 054 progressMonitor.finishTask(); 055 } 056 } 057 058 @Override public int read(byte[] b, int off, int len) throws IOException { 059 int read = in.read(b, off, len); 060 if (read != -1) { 061 advanceTicker(read); 062 } else { 063 progressMonitor.finishTask(); 064 } 065 return read; 066 } 067 068 @Override public int read() throws IOException { 069 int read = in.read(); 070 if (read != -1) { 071 advanceTicker(1); 072 } else { 073 progressMonitor.finishTask(); 074 } 075 return read; 076 } 077 078 /** 079 * Increase ticker (progress counter and displayed text) by the given amount. 080 * @param amount 081 */ 082 private void advanceTicker(int amount) { 083 readSoFar += amount; 084 updateSize(); 085 086 if (readSoFar / 1024 != lastDialogUpdate) { 087 lastDialogUpdate++; 088 if (sizeKnown) { 089 progressMonitor.setTicks(readSoFar); 090 } 091 progressMonitor.setExtraText(readSoFar/1024 + " KB"); 092 } 093 } 094 095 private void updateSize() { 096 if (!sizeKnown && connection.getContentLength() > 0) { 097 sizeKnown = true; 098 progressMonitor.subTask(tr("Downloading OSM data...")); 099 progressMonitor.setTicksCount(connection.getContentLength()); 100 } 101 } 102}