001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.plugins.streetside.io.download; 003 004import java.awt.GraphicsEnvironment; 005import java.io.IOException; 006import java.net.HttpURLConnection; 007import java.net.URL; 008import java.net.URLConnection; 009import java.util.function.Function; 010 011import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3; 012 013import org.openstreetmap.josm.data.Bounds; 014import org.openstreetmap.josm.gui.Notification; 015import org.openstreetmap.josm.plugins.streetside.StreetsidePlugin; 016import org.openstreetmap.josm.tools.I18n; 017import org.openstreetmap.josm.tools.ImageProvider.ImageSizes; 018import org.openstreetmap.josm.tools.Logging; 019 020public abstract class BoundsDownloadRunnable implements Runnable { 021 022 protected Bounds bounds; 023 protected abstract Function<Bounds, URL> getUrlGenerator(); 024 025 public BoundsDownloadRunnable(final Bounds bounds) { 026 this.bounds = bounds; 027 } 028 029 @Override 030 public void run() { 031 URL nextURL = getUrlGenerator().apply(bounds); 032 try { 033 while (nextURL != null) { 034 if (Thread.interrupted()) { 035 Logging.debug("{} for {} interrupted!", getClass().getSimpleName(), bounds.toString()); 036 return; 037 } 038 final URLConnection con = nextURL.openConnection(); 039 run(con); 040 nextURL = APIv3.parseNextFromLinkHeaderValue(con.getHeaderField("Link")); 041 } 042 } catch (IOException e) { 043 String message = I18n.tr("Could not read from URL {0}!", nextURL.toString()); 044 Logging.log(Logging.LEVEL_WARN, message, e); 045 if (!GraphicsEnvironment.isHeadless()) { 046 new Notification(message) 047 .setIcon(StreetsidePlugin.LOGO.setSize(ImageSizes.LARGEICON).get()) 048 .setDuration(Notification.TIME_LONG) 049 .show(); 050 } 051 e.printStackTrace(); 052 } 053 } 054 055 /** 056 * Logs information about the given connection via {@link Logging#info(String)}. 057 * If it's a {@link HttpURLConnection}, the request method, the response code and the URL itself are logged. 058 * Otherwise only the URL is logged. 059 * @param con the {@link URLConnection} for which information is logged 060 * @param info an additional info text, which is appended to the output in braces 061 * @throws IOException if {@link HttpURLConnection#getResponseCode()} throws an {@link IOException} 062 */ 063 public static void logConnectionInfo(final URLConnection con, final String info) throws IOException { 064 final StringBuilder message; 065 if (con instanceof HttpURLConnection) { 066 message = new StringBuilder(((HttpURLConnection) con).getRequestMethod()) 067 .append(' ').append(con.getURL()) 068 .append(" → ").append(((HttpURLConnection) con).getResponseCode()); 069 } else { 070 message = new StringBuilder("Download from ").append(con.getURL()); 071 } 072 if (info != null && info.length() >= 1) { 073 message.append(" (").append(info).append(')'); 074 } 075 Logging.info(message.toString()); 076 } 077 078 public abstract void run(final URLConnection connection) throws IOException; 079}