Ticket #11193: expires-version1-v3.patch

File expires-version1-v3.patch, 8.5 KB (added by wiktorn, 11 years ago)
  • src/org/openstreetmap/gui/jmapviewer/OsmFileCacheTileLoader.java

     
    4848
    4949    private static final Charset TAGS_CHARSET = Charset.forName("UTF-8");
    5050
    51     public 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
    5353
    5454    protected String cacheDirBase;
    5555
    5656    protected final Map<TileSource, File> sourceCacheDirMap;
    5757
    5858    protected long maxCacheFileAge = Long.MAX_VALUE;  // max. age not limited
    59     protected long recheckAfter = FILE_AGE_ONE_WEEK;
    6059
    6160    public static File getDefaultCacheDir() throws SecurityException {
    6261        String tempDir = null;
     
    6665        } catch (SecurityException e) {
    6766            log.log(Level.WARNING,
    6867                    "Failed to access system property ''java.io.tmpdir'' for security reasons. Exception was: "
    69                     + e.toString());
     68                            + e.toString());
    7069            throw e; // rethrow
    7170        }
    7271        try {
     
    134133        File tileFile = null;
    135134        Long fileMtime = null;
    136135        Long now = null; // current time in milliseconds (keep consistent value for the whole run)
     136        boolean cachePresent = false;
    137137
    138138        public FileLoadJob(Tile tile) {
    139139            this.tile = tile;
     
    156156            now = System.currentTimeMillis();
    157157            tileCacheDir = getSourceCacheDir(tile.getSource());
    158158
    159             if (loadTileFromFile(recheckAfter)) {
     159            cachePresent = loadTagsFromFile();
     160
     161            if (cachePresent && isTileFileValid() && loadTileFromFile()) {
    160162                log.log(Level.FINE, "TMS - found in tile cache: {0}", tile);
    161163                tile.setLoaded(true);
    162164                listener.tileLoadingFinished(tile, true);
    163165                return;
    164166            }
     167
    165168            TileJob job = new TileJob() {
    166169
    167170                @Override
    168171                public void run() {
    169                     if (loadOrUpdateTile()) {
     172                    if (loadOrUpdateTile()  && loadTileFromFile()) {
    170173                        tile.setLoaded(true);
    171174                        listener.tileLoadingFinished(tile, true);
    172175                    } else {
    173176                        // failed to download - use old cache file if available
    174                         if (loadTileFromFile(maxCacheFileAge)) {
     177                        if (cachePresent && loadTileFromFile()) {
    175178                            tile.setLoaded(true);
    176179                            tile.error = false;
    177180                            listener.tileLoadingFinished(tile, true);
     
    242245                    default:
    243246                        break;
    244247                    }
    245                     if (loadTileFromFile(maxCacheFileAge)) {
    246                         tileFile.setLastModified(now);
    247                         return true;
    248                     }
     248                    tileFile.setLastModified(now);
     249                    return true;
    249250                }
    250251
    251252                loadTileMetadata(tile, urlConn);
     
    285286            return false;
    286287        }
    287288
    288         protected boolean loadTileFromFile(long maxAge) {
     289        protected boolean isTileFileValid() {
     290            Long expires = null;
    289291            try {
    290                 tileFile = getTileFile();
    291                 if (!tileFile.exists())
    292                     return false;
    293                 loadTagsFromFile();
     292                expires = Long.parseLong(tile.getValue("expires"));
     293            } catch (NumberFormatException e) {}
    294294
     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
    295303                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");
    297306                    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                     }
    311307                }
    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            }
    313315
     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;
    314325            } catch (Exception e) {
    315326                log.log(Level.WARNING, "TMS - Error while loading image from tile cache: {0}; {1}", new Object[]{e.getMessage(), tile});
    316327                tileFile.delete();
     328                File tileMetaData = getTagsFile();
     329                if (tileMetaData.exists())
     330                    tileMetaData.delete();
    317331                tileFile = null;
    318332                fileMtime = null;
    319333            }
     
    405419            File file = getTileFile();
    406420            file.getParentFile().mkdirs();
    407421            try (
    408                 FileOutputStream f = new FileOutputStream(file)
    409             ) {
     422                    FileOutputStream f = new FileOutputStream(file)
     423                    ) {
    410424                f.write(rawData);
    411425            } catch (Exception e) {
    412426                log.log(Level.SEVERE, "Failed to save tile content: {0}", e.getLocalizedMessage());
     
    429443            }
    430444        }
    431445
    432         protected void loadTagsFromFile() {
     446        protected boolean loadTagsFromFile() {
     447            tileFile = getTileFile();
     448            if (!tileFile.exists())
     449                return false;
    433450            File tagsFile = getTagsFile();
    434451            try (BufferedReader f = new BufferedReader(new InputStreamReader(new FileInputStream(tagsFile), TAGS_CHARSET))) {
    435452                for (String line = f.readLine(); line != null; line = f.readLine()) {
     
    444461            } catch (Exception e) {
    445462                System.err.println("Failed to load tile tags: " + e.getLocalizedMessage());
    446463            }
     464            return true;
    447465        }
    448466    }
    449467
  • src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java

     
    108108        if (str != null) {
    109109            tile.putValue("tile-info", str);
    110110        }
     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        }
    111129    }
    112130
    113131    protected void prepareHttpUrlConnection(HttpURLConnection urlConn) {