Ticket #14796: bing-attribution.patch

File bing-attribution.patch, 5.0 KB (added by chris.tipper@…, 8 years ago)

patch to load bing attribution asynchronously

  • src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java

    diff --git a/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java b/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java
    index 47447f9..029a445 100644
    a b  
    99import java.util.ArrayList;
    1010import java.util.List;
    1111import java.util.Locale;
    12 import java.util.concurrent.Callable;
    13 import java.util.concurrent.ExecutionException;
    14 import java.util.concurrent.Future;
    15 import java.util.concurrent.FutureTask;
     12import java.util.concurrent.ExecutorService;
     13import java.util.concurrent.CompletableFuture;
    1614import java.util.concurrent.TimeUnit;
     15import java.util.function.Supplier;
     16import java.util.logging.Level;
     17import java.util.logging.Logger;
    1718import java.util.regex.Pattern;
    1819
    1920import javax.imageio.ImageIO;
     
    4344public class BingAerialTileSource extends TMSTileSource {
    4445
    4546    private static final String API_KEY = "Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU";
    46     private static volatile Future<List<Attribution>> attributions; // volatile is required for getAttribution(), see below.
     47    private static volatile List<Attribution> attributions; // volatile is required for getAttribution(), see below.
    4748    private static String imageUrlTemplate;
    4849    private static Integer imageryZoomMax;
    4950    private static String[] subdomains;
     
    5253    private static final Pattern quadkeyPattern = Pattern.compile("\\{quadkey\\}");
    5354    private static final Pattern culturePattern = Pattern.compile("\\{culture\\}");
    5455    private String brandLogoUri;
     56    private ExecutorService executor;
    5557
    5658    /**
    5759     * Constructs a new {@code BingAerialTileSource}.
    public String getTermsOfUseURL() {  
    234236        return "http://opengeodata.org/microsoft-imagery-details";
    235237    }
    236238
    237     protected Callable<List<Attribution>> getAttributionLoaderCallable() {
    238         return new Callable<List<Attribution>>() {
    239 
    240             @Override
    241             public List<Attribution> call() throws Exception {
    242                 int waitTimeSec = 1;
    243                 while (true) {
    244                     try {
    245                         InputSource xml = new InputSource(getAttributionUrl().openStream());
    246                         List<Attribution> r = parseAttributionText(xml);
    247                         return r;
    248                     } catch (IOException ex) {
    249                         System.err.println("Could not connect to Bing API. Will retry in " + waitTimeSec + " seconds.");
    250                         Thread.sleep(TimeUnit.SECONDS.toMillis(waitTimeSec));
    251                         waitTimeSec *= 2;
    252                     }
    253                 }
    254             }
    255         };
    256     }
    257 
    258239    protected List<Attribution> getAttribution() {
    259240        if (attributions == null) {
    260241            // see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
    261242            synchronized (BingAerialTileSource.class) {
    262243                if (attributions == null) {
    263                   final FutureTask<List<Attribution>> loader = new FutureTask<>(getAttributionLoaderCallable());
    264                   new Thread(loader, "bing-attribution-loader").start();
    265                   attributions = loader;
     244                  final Supplier<List<Attribution>> loader = new Supplier<List<Attribution>>() {
     245
     246                      @Override
     247                      public List<Attribution> get() {
     248                          int waitTimeSec = 1;
     249                          while (true) {
     250                              try {
     251                                  InputSource xml = new InputSource(getAttributionUrl().openStream());
     252                                  List<Attribution> r = parseAttributionText(xml);
     253                                  return r;
     254                              } catch (IOException ex) {
     255                                  System.err.println("Could not connect to Bing API. Will retry in " + waitTimeSec + " seconds.");
     256                                  try {
     257                                      Thread.sleep(TimeUnit.SECONDS.toMillis(waitTimeSec));
     258                                  } catch (InterruptedException ex1) {
     259                                      Logger.getLogger(BingAerialTileSource.class.getName()).log(Level.SEVERE, null, ex1);
     260                                  }
     261                                  waitTimeSec *= 2;
     262                              }
     263                          }
     264                      }
     265                  };
     266                  CompletableFuture.supplyAsync(loader, executor).thenAccept(attr -> attributions = attr);
    266267                }
    267268            }
    268269        }
    269         try {
    270             return attributions.get();
    271         } catch (ExecutionException ex) {
    272             throw new RuntimeException(ex.getCause());
    273         } catch (InterruptedException ign) {
    274             System.err.println("InterruptedException: " + ign.getMessage());
    275         }
    276270        return null;
    277271    }
    278272