// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.imagery;
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import org.openstreetmap.gui.jmapviewer.tilesources.BingAerialTileSource;
import org.openstreetmap.gui.jmapviewer.tilesources.TileSourceInfo;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.gui.util.GuiHelper;
import org.openstreetmap.josm.io.CacheCustomContent;
import org.openstreetmap.josm.io.OnlineResource;
import org.openstreetmap.josm.tools.HttpClient;
import org.xml.sax.InputSource;
/**
* Bing TileSource with cached attribution
*
* @author Wiktor Niesiobędzki
* @since 8526
*/
public class CachedAttributionBingAerialTileSource extends BingAerialTileSource {
private Runnable attributionDownloadedTask;
/**
* Creates tile source
* @param info ImageryInfo description of this tile source
*/
public CachedAttributionBingAerialTileSource(ImageryInfo info) {
super(info);
}
/**
* Creates tile source
* @param info ImageryInfo description of this tile source
* @param attributionDownloadedTask runnable to be executed once attribution is loaded
*/
public CachedAttributionBingAerialTileSource(TileSourceInfo info, Runnable attributionDownloadedTask) {
super(info);
this.attributionDownloadedTask = attributionDownloadedTask;
}
class BingAttributionData extends CacheCustomContent<IOException> {
BingAttributionData() {
super("bing.attribution.xml", CacheCustomContent.INTERVAL_HOURLY);
}
@Override
protected byte[] updateData() throws IOException {
URL u = getAttributionUrl();
final String r = HttpClient.create(u).connect().fetchContent();
Main.info("Successfully loaded Bing attribution data.");
return r.getBytes("UTF-8");
}
@Override
protected void checkOfflineAccess() {
try {
String attributionUrl = getAttributionUrl().toExternalForm();
OnlineResource.ALL.checkOfflineAccess(attributionUrl, attributionUrl);
} catch (MalformedURLException e) {
Main.error(e);
}
}
}
@Override
protected Callable<List<Attribution>> getAttributionLoaderCallable() {
return () -> {
BingAttributionData attributionLoader = new BingAttributionData();
int waitTimeSec = 1;
while (true) {
try {
String xml = attributionLoader.updateIfRequiredString();
List<Attribution> ret = parseAttributionText(new InputSource(new StringReader(xml)));
if (attributionDownloadedTask != null) {
GuiHelper.runInEDT(attributionDownloadedTask);
attributionDownloadedTask = null;
}
return ret;
} catch (IOException ex) {
Main.warn(ex, "Could not connect to Bing API. Will retry in " + waitTimeSec + " seconds.");
Thread.sleep(TimeUnit.SECONDS.toMillis(waitTimeSec));
waitTimeSec *= 2;
}
}
};
}
}