diff --git src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
index 6db0ec3..d636de4 100644
|
|
|
import java.io.IOException;
|
| 7 | 7 | import java.io.InputStream; |
| 8 | 8 | import java.net.HttpURLConnection; |
| 9 | 9 | import java.net.MalformedURLException; |
| | 10 | import java.net.URL; |
| 10 | 11 | import java.net.URLConnection; |
| 11 | 12 | import java.util.HashSet; |
| 12 | 13 | import java.util.Map; |
| … |
… |
public abstract class JCSCachedTileLoaderJob<K, V extends CacheEntry> implements
|
| 125 | 126 | @Override |
| 126 | 127 | public void submit(ICachedLoaderListener listener) { |
| 127 | 128 | boolean first = false; |
| 128 | | String url = getUrl().toString(); |
| 129 | | if (url == null) { |
| | 129 | URL url = getUrl(); |
| | 130 | String deduplicationKey = null; |
| | 131 | if (url != null) { |
| | 132 | // url might be null, for example when Bing Attribution is not loaded yet |
| | 133 | deduplicationKey = url.toString(); |
| | 134 | } |
| | 135 | if (deduplicationKey == null) { |
| 130 | 136 | log.log(Level.WARNING, "No url returned for: {0}, skipping", getCacheKey()); |
| 131 | 137 | return; |
| 132 | 138 | } |
| 133 | 139 | synchronized (inProgress) { |
| 134 | | Set<ICachedLoaderListener> newListeners = inProgress.get(url); |
| | 140 | Set<ICachedLoaderListener> newListeners = inProgress.get(deduplicationKey); |
| 135 | 141 | if (newListeners == null) { |
| 136 | 142 | newListeners = new HashSet<>(); |
| 137 | | inProgress.put(url, newListeners); |
| | 143 | inProgress.put(deduplicationKey, newListeners); |
| 138 | 144 | first = true; |
| 139 | 145 | } |
| 140 | 146 | newListeners.add(listener); |
| … |
… |
public abstract class JCSCachedTileLoaderJob<K, V extends CacheEntry> implements
|
| 161 | 167 | } |
| 162 | 168 | |
| 163 | 169 | /** |
| 164 | | * |
| | 170 | * |
| 165 | 171 | * @return checks if object from cache has sufficient data to be returned |
| 166 | 172 | */ |
| 167 | 173 | protected boolean isObjectLoadable() { |
| … |
… |
public abstract class JCSCachedTileLoaderJob<K, V extends CacheEntry> implements
|
| 170 | 176 | } |
| 171 | 177 | |
| 172 | 178 | /** |
| 173 | | * |
| | 179 | * |
| 174 | 180 | * @return cache object as empty, regardless of what remote resource has returned (ex. based on headers) |
| 175 | 181 | */ |
| 176 | 182 | protected boolean cacheAsEmpty() { |
| … |
… |
public abstract class JCSCachedTileLoaderJob<K, V extends CacheEntry> implements
|
| 263 | 269 | return true; |
| 264 | 270 | } |
| 265 | 271 | |
| | 272 | /** |
| | 273 | * @return true if object was successfully downloaded, false, if there was a loading failure |
| | 274 | */ |
| | 275 | |
| 266 | 276 | private boolean loadObject() { |
| 267 | 277 | try { |
| 268 | 278 | // if we have object in cache, and host doesn't support If-Modified-Since nor If-None-Match |
| … |
… |
public abstract class JCSCachedTileLoaderJob<K, V extends CacheEntry> implements
|
| 315 | 325 | log.log(Level.FINE, "JCS - downloaded key: {0}, length: {1}, url: {2}", |
| 316 | 326 | new Object[] {getCacheKey(), raw.length, getUrl()}); |
| 317 | 327 | return true; |
| 318 | | } else { |
| | 328 | } else { |
| 319 | 329 | cacheData = createCacheEntry(new byte[]{}); |
| 320 | 330 | cache.put(getCacheKey(), cacheData, attributes); |
| 321 | 331 | log.log(Level.FINE, "JCS - Caching empty object {0}", getUrl()); |
| … |
… |
public abstract class JCSCachedTileLoaderJob<K, V extends CacheEntry> implements
|
| 325 | 335 | } catch (FileNotFoundException e) { |
| 326 | 336 | log.log(Level.FINE, "JCS - Caching empty object as server returned 404 for: {0}", getUrl()); |
| 327 | 337 | cache.put(getCacheKey(), createCacheEntry(new byte[]{}), attributes); |
| 328 | | handleNotFound(); |
| 329 | | return true; |
| | 338 | return handleNotFound(); |
| 330 | 339 | } catch (Exception e) { |
| 331 | 340 | log.log(Level.WARNING, "JCS - Exception during download " + getUrl(), e); |
| 332 | 341 | } |
| … |
… |
public abstract class JCSCachedTileLoaderJob<K, V extends CacheEntry> implements
|
| 335 | 344 | |
| 336 | 345 | } |
| 337 | 346 | |
| 338 | | protected abstract void handleNotFound(); |
| | 347 | /** |
| | 348 | * @return if we should treat this object as properly loaded |
| | 349 | */ |
| | 350 | protected abstract boolean handleNotFound(); |
| 339 | 351 | |
| 340 | 352 | protected abstract V createCacheEntry(byte[] content); |
| 341 | 353 | |
diff --git src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java
index 7d40dac..d2709aa 100644
|
|
|
import org.openstreetmap.josm.data.preferences.IntegerProperty;
|
| 18 | 18 | |
| 19 | 19 | /** |
| 20 | 20 | * @author Wiktor Niesiobędzki |
| 21 | | * |
| | 21 | * |
| 22 | 22 | * Wrapper class that bridges between JCS cache and Tile Loaders |
| 23 | 23 | * |
| 24 | 24 | */ |
| … |
… |
public class TMSCachedTileLoader implements TileLoader, CachedTileLoader, TileCa
|
| 72 | 72 | |
| 73 | 73 | @Override |
| 74 | 74 | public void addTile(Tile tile) { |
| 75 | | createTileLoaderJob(tile).submit(); |
| | 75 | createTileLoaderJob(tile).getTile(); |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | 78 | @Override |
diff --git src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
index 0159714..cb7754f 100644
|
|
|
public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, Buffe
|
| 124 | 124 | if (cacheData != null) { |
| 125 | 125 | byte[] content = cacheData.getContent(); |
| 126 | 126 | try { |
| 127 | | return (content != null && content.length > 0) || cacheData.getImage() != null || cacheAsEmpty(); |
| | 127 | return content != null || cacheData.getImage() != null || cacheAsEmpty(); |
| 128 | 128 | } catch (IOException e) { |
| 129 | 129 | log.log(Level.WARNING, "JCS TMS - error loading from cache for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()}); |
| 130 | 130 | } |
| … |
… |
public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, Buffe
|
| 142 | 142 | tile.putValue("tile-info", "no-tile"); |
| 143 | 143 | return true; |
| 144 | 144 | } |
| 145 | | return false; |
| | 145 | return false; // as there is no other cache to cache the Tile, also cache other empty requests |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | @Override |
| … |
… |
public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, Buffe
|
| 158 | 158 | @Override |
| 159 | 159 | public void loadingFinished(CacheEntry object, boolean success) { |
| 160 | 160 | try { |
| 161 | | loadTile(object); |
| | 161 | loadTile(object, success); |
| 162 | 162 | if (listener != null) { |
| 163 | 163 | listener.tileLoadingFinished(tile, success); |
| 164 | 164 | } |
| … |
… |
public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, Buffe
|
| 177 | 177 | * @return tile or null, if nothing (useful) was found in cache |
| 178 | 178 | */ |
| 179 | 179 | public Tile getCachedTile() { |
| 180 | | BufferedImageCacheEntry data = super.get(); |
| | 180 | BufferedImageCacheEntry data = get(); |
| 181 | 181 | if (isObjectLoadable()) { |
| 182 | 182 | try { |
| 183 | 183 | loadTile(data); |
| … |
… |
public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, Buffe
|
| 192 | 192 | } |
| 193 | 193 | } |
| 194 | 194 | |
| 195 | | private void loadTile(CacheEntry object) throws IOException { |
| | 195 | // loads tile when calling back from cache |
| | 196 | private void loadTile(CacheEntry object, boolean success) throws IOException { |
| 196 | 197 | tile.finishLoading(); |
| 197 | 198 | if (object != null) { |
| 198 | 199 | byte[] content = object.getContent(); |
| … |
… |
public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, Buffe
|
| 200 | 201 | tile.loadImage(new ByteArrayInputStream(content)); |
| 201 | 202 | } |
| 202 | 203 | } |
| | 204 | if (!success) { |
| | 205 | tile.setError("Problem loading tile"); |
| | 206 | } |
| 203 | 207 | } |
| 204 | 208 | |
| | 209 | // loads tile when geting stright from cache |
| 205 | 210 | private void loadTile(BufferedImageCacheEntry object) throws IOException { |
| 206 | 211 | tile.finishLoading(); |
| 207 | | if (object != null) { |
| | 212 | if (cacheAsEmpty() || object != null) { // if cache as empty object, do not try to load image |
| 208 | 213 | if (object.getImage() != null) { |
| 209 | 214 | tile.setImage(object.getImage()); |
| 210 | 215 | } |
| … |
… |
public class TMSCachedTileLoaderJob extends JCSCachedTileLoaderJob<String, Buffe
|
| 212 | 217 | } |
| 213 | 218 | |
| 214 | 219 | @Override |
| 215 | | protected void handleNotFound() { |
| | 220 | protected boolean handleNotFound() { |
| 216 | 221 | tile.setError("No tile at this zoom level"); |
| 217 | 222 | tile.putValue("tile-info", "no-tile"); |
| | 223 | return true; |
| 218 | 224 | } |
| 219 | 225 | |
| | 226 | /** |
| | 227 | * For TMS use BaseURL as settings discovery, so for different paths, we will have different settings (useful for developer servers) |
| | 228 | * |
| | 229 | * @return base URL of TMS or server url as defined in super class |
| | 230 | */ |
| 220 | 231 | @Override |
| 221 | 232 | protected String getServerKey() { |
| 222 | 233 | TileSource ts = tile.getSource(); |