001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.io.imagery;
003
004 import org.openstreetmap.josm.Main;
005 import org.openstreetmap.josm.data.ProjectionBounds;
006 import org.openstreetmap.josm.data.imagery.GeorefImage.State;
007 import org.openstreetmap.josm.gui.MapView;
008 import org.openstreetmap.josm.gui.layer.WMSLayer;
009
010 abstract public class Grabber implements Runnable {
011 protected final MapView mv;
012 protected final WMSLayer layer;
013 private final boolean localOnly;
014
015 protected ProjectionBounds b;
016 protected volatile boolean canceled;
017
018 Grabber(MapView mv, WMSLayer layer, boolean localOnly) {
019 this.mv = mv;
020 this.layer = layer;
021 this.localOnly = localOnly;
022 }
023
024 abstract void fetch(WMSRequest request, int attempt) throws Exception; // the image fetch code
025
026 int width(){
027 return layer.getBaseImageWidth();
028 }
029 int height(){
030 return layer.getBaseImageHeight();
031 }
032
033 @Override
034 public void run() {
035 while (true) {
036 if (canceled)
037 return;
038 WMSRequest request = layer.getRequest(localOnly);
039 if (request == null)
040 return;
041 this.b = layer.getBounds(request);
042 if (request.isPrecacheOnly()) {
043 if (!layer.cache.hasExactMatch(Main.getProjection(), request.getPixelPerDegree(), b.minEast, b.minNorth)) {
044 attempt(request);
045 }
046 } else {
047 if(!loadFromCache(request)){
048 attempt(request);
049 }
050 }
051 layer.finishRequest(request);
052 }
053 }
054
055 protected void attempt(WMSRequest request){ // try to fetch the image
056 int maxTries = 5; // n tries for every image
057 for (int i = 1; i <= maxTries; i++) {
058 if (canceled)
059 return;
060 try {
061 if (!request.isPrecacheOnly() && !layer.requestIsVisible(request))
062 return;
063 fetch(request, i);
064 break; // break out of the retry loop
065 } catch (Exception e) {
066 try { // sleep some time and then ask the server again
067 Thread.sleep(random(1000, 2000));
068 } catch (InterruptedException e1) {}
069
070 if(i == maxTries) {
071 e.printStackTrace();
072 request.finish(State.FAILED, null);
073 }
074 }
075 }
076 }
077
078 public static int random(int min, int max) {
079 return (int)(Math.random() * ((max+1)-min) ) + min;
080 }
081
082 abstract public boolean loadFromCache(WMSRequest request);
083
084 public void cancel() {
085 canceled = true;
086 }
087
088 }