Ticket #11193: expires-version1-v3.patch
| File expires-version1-v3.patch, 8.5 KB (added by , 11 years ago) |
|---|
-
src/org/openstreetmap/gui/jmapviewer/OsmFileCacheTileLoader.java
48 48 49 49 private static final Charset TAGS_CHARSET = Charset.forName("UTF-8"); 50 50 51 p ublic static final long FILE_AGE_ONE_DAY = 1000 * 60 * 60 * 24;52 public static final long FILE_AGE_ONE_WEEK = FILE_AGE_ONE_DAY * 7; 51 private static final long DEFAULT_EXPIRES_TIME = 1000 * 60 * 60 * 24 * 7; 52 53 53 54 54 protected String cacheDirBase; 55 55 56 56 protected final Map<TileSource, File> sourceCacheDirMap; 57 57 58 58 protected long maxCacheFileAge = Long.MAX_VALUE; // max. age not limited 59 protected long recheckAfter = FILE_AGE_ONE_WEEK;60 59 61 60 public static File getDefaultCacheDir() throws SecurityException { 62 61 String tempDir = null; … … 66 65 } catch (SecurityException e) { 67 66 log.log(Level.WARNING, 68 67 "Failed to access system property ''java.io.tmpdir'' for security reasons. Exception was: " 69 + e.toString());68 + e.toString()); 70 69 throw e; // rethrow 71 70 } 72 71 try { … … 134 133 File tileFile = null; 135 134 Long fileMtime = null; 136 135 Long now = null; // current time in milliseconds (keep consistent value for the whole run) 136 boolean cachePresent = false; 137 137 138 138 public FileLoadJob(Tile tile) { 139 139 this.tile = tile; … … 156 156 now = System.currentTimeMillis(); 157 157 tileCacheDir = getSourceCacheDir(tile.getSource()); 158 158 159 if (loadTileFromFile(recheckAfter)) { 159 cachePresent = loadTagsFromFile(); 160 161 if (cachePresent && isTileFileValid() && loadTileFromFile()) { 160 162 log.log(Level.FINE, "TMS - found in tile cache: {0}", tile); 161 163 tile.setLoaded(true); 162 164 listener.tileLoadingFinished(tile, true); 163 165 return; 164 166 } 167 165 168 TileJob job = new TileJob() { 166 169 167 170 @Override 168 171 public void run() { 169 if (loadOrUpdateTile() ) {172 if (loadOrUpdateTile() && loadTileFromFile()) { 170 173 tile.setLoaded(true); 171 174 listener.tileLoadingFinished(tile, true); 172 175 } else { 173 176 // failed to download - use old cache file if available 174 if ( loadTileFromFile(maxCacheFileAge)) {177 if (cachePresent && loadTileFromFile()) { 175 178 tile.setLoaded(true); 176 179 tile.error = false; 177 180 listener.tileLoadingFinished(tile, true); … … 242 245 default: 243 246 break; 244 247 } 245 if (loadTileFromFile(maxCacheFileAge)) { 246 tileFile.setLastModified(now); 247 return true; 248 } 248 tileFile.setLastModified(now); 249 return true; 249 250 } 250 251 251 252 loadTileMetadata(tile, urlConn); … … 285 286 return false; 286 287 } 287 288 288 protected boolean loadTileFromFile(long maxAge) { 289 protected boolean isTileFileValid() { 290 Long expires = null; 289 291 try { 290 tileFile = getTileFile(); 291 if (!tileFile.exists()) 292 return false; 293 loadTagsFromFile(); 292 expires = Long.parseLong(tile.getValue("expires")); 293 } catch (NumberFormatException e) {} 294 294 295 if(expires != null && !expires.equals(0L)) { 296 // check by expire date set by server 297 if (now > expires) { 298 log.fine("TMS - Tile has expired -> not valid"); 299 return false; 300 } 301 } else { 302 // check by file modification date 295 303 fileMtime = tileFile.lastModified(); 296 if (now - fileMtime > maxAge) 304 if (now - fileMtime > DEFAULT_EXPIRES_TIME) { 305 log.fine("TMS - Tile has expired, maximum file age reached"); 297 306 return false; 298 299 if ("no-tile".equals(tile.getValue("tile-info"))) {300 tile.setError("No tile at this zoom level");301 if (tileFile.exists()) {302 tileFile.delete();303 }304 tileFile = null;305 } else {306 try (FileInputStream fin = new FileInputStream(tileFile)) {307 if (fin.available() == 0)308 throw new IOException("File empty");309 tile.loadImage(fin);310 }311 307 } 312 return true; 308 } 309 if ("no-tile".equals(tile.getValue("tile-info"))) { 310 // do not remove file - keep the information, that there is no tile, for further requests 311 log.fine("TMS - Tile valid, but no file, as no tiles at this level"); 312 tile.setError("No tile at this zoom level"); 313 tileFile = null; 314 } 313 315 316 return true; 317 } 318 319 protected boolean loadTileFromFile() { 320 try (FileInputStream fin = new FileInputStream(tileFile)) { 321 if (fin.available() == 0) 322 throw new IOException("File empty"); 323 tile.loadImage(fin); 324 return true; 314 325 } catch (Exception e) { 315 326 log.log(Level.WARNING, "TMS - Error while loading image from tile cache: {0}; {1}", new Object[]{e.getMessage(), tile}); 316 327 tileFile.delete(); 328 File tileMetaData = getTagsFile(); 329 if (tileMetaData.exists()) 330 tileMetaData.delete(); 317 331 tileFile = null; 318 332 fileMtime = null; 319 333 } … … 405 419 File file = getTileFile(); 406 420 file.getParentFile().mkdirs(); 407 421 try ( 408 FileOutputStream f = new FileOutputStream(file)409 ) {422 FileOutputStream f = new FileOutputStream(file) 423 ) { 410 424 f.write(rawData); 411 425 } catch (Exception e) { 412 426 log.log(Level.SEVERE, "Failed to save tile content: {0}", e.getLocalizedMessage()); … … 429 443 } 430 444 } 431 445 432 protected void loadTagsFromFile() { 446 protected boolean loadTagsFromFile() { 447 tileFile = getTileFile(); 448 if (!tileFile.exists()) 449 return false; 433 450 File tagsFile = getTagsFile(); 434 451 try (BufferedReader f = new BufferedReader(new InputStreamReader(new FileInputStream(tagsFile), TAGS_CHARSET))) { 435 452 for (String line = f.readLine(); line != null; line = f.readLine()) { … … 444 461 } catch (Exception e) { 445 462 System.err.println("Failed to load tile tags: " + e.getLocalizedMessage()); 446 463 } 464 return true; 447 465 } 448 466 } 449 467 -
src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java
108 108 if (str != null) { 109 109 tile.putValue("tile-info", str); 110 110 } 111 112 Long lng = urlConn.getExpiration(); 113 if (lng.equals(0L)) { 114 try { 115 str = urlConn.getHeaderField("Cache-Control"); 116 if (str != null) { 117 for (String token: str.split(",")) { 118 if (token.startsWith("max-age=")) { 119 lng = Long.parseLong(token.substring(8))*1000 + 120 System.currentTimeMillis(); 121 } 122 } 123 } 124 } catch (NumberFormatException e) {} //ignore malformed Cache-Control headers 125 } 126 if (!lng.equals(0)) { 127 tile.putValue("expires", lng.toString()); 128 } 111 129 } 112 130 113 131 protected void prepareHttpUrlConnection(HttpURLConnection urlConn) {
