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 }