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