Ticket #11193: expires-version1-v5.patch

File expires-version1-v5.patch, 8.4 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
     
    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                    loadTileFromFile();
     249                    tileFile.setLastModified(now);
     250                    return true;
    249251                }
    250252
    251253                loadTileMetadata(tile, urlConn);
     
    285287            return false;
    286288        }
    287289
    288         protected boolean loadTileFromFile(long maxAge) {
     290        protected boolean isTileFileValid() {
     291            Long expires = null;
    289292            try {
    290                 tileFile = getTileFile();
    291                 if (!tileFile.exists())
    292                     return false;
    293                 loadTagsFromFile();
     293                expires = Long.parseLong(tile.getValue("expires"));
     294            } catch (NumberFormatException e) {}
    294295
     296            if(expires != null && !expires.equals(0L)) {
     297                // check by expire date set by server
     298                if (now > expires) {
     299                    log.log(Level.FINE, "TMS - Tile has expired -> not valid {0}", tile);
     300                    return false;
     301                }
     302            } else {
     303                // check by file modification date
    295304                fileMtime = tileFile.lastModified();
    296                 if (now - fileMtime > maxAge)
     305                if (now - fileMtime > DEFAULT_EXPIRES_TIME) {
     306                    log.log(Level.FINE, "TMS - Tile has expired, maximum file age reached {0}", tile);
    297307                    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                     }
    311308                }
    312                 return true;
     309            }
     310            if ("no-tile".equals(tile.getValue("tile-info"))) {
     311                // do not remove file - keep the information, that there is no tile, for further requests
     312                log.fine("TMS - Tile valid, but no file, as no tiles at this level");
     313                tile.setError("No tile at this zoom level");
     314                tileFile = null;
     315            }
    313316
     317            return true;
     318        }
     319
     320        protected boolean loadTileFromFile() {
     321            try (FileInputStream fin = new FileInputStream(tileFile)) {
     322                if (fin.available() == 0)
     323                    throw new IOException("File empty");
     324                tile.loadImage(fin);
     325                return true;
    314326            } catch (Exception e) {
    315327                log.log(Level.WARNING, "TMS - Error while loading image from tile cache: {0}; {1}", new Object[]{e.getMessage(), tile});
    316328                tileFile.delete();
     329                File tileMetaData = getTagsFile();
     330                if (tileMetaData.exists())
     331                    tileMetaData.delete();
    317332                tileFile = null;
    318333                fileMtime = null;
    319334            }
     
    405420            File file = getTileFile();
    406421            file.getParentFile().mkdirs();
    407422            try (
    408                 FileOutputStream f = new FileOutputStream(file)
    409             ) {
     423                    FileOutputStream f = new FileOutputStream(file)
     424                    ) {
    410425                f.write(rawData);
    411426            } catch (Exception e) {
    412427                log.log(Level.SEVERE, "Failed to save tile content: {0}", e.getLocalizedMessage());
     
    429444            }
    430445        }
    431446
    432         protected void loadTagsFromFile() {
     447        protected boolean loadTagsFromFile() {
     448            tileFile = getTileFile();
     449            if (!tileFile.exists())
     450                return false;
    433451            File tagsFile = getTagsFile();
    434452            try (BufferedReader f = new BufferedReader(new InputStreamReader(new FileInputStream(tagsFile), TAGS_CHARSET))) {
    435453                for (String line = f.readLine(); line != null; line = f.readLine()) {
     
    444462            } catch (Exception e) {
    445463                System.err.println("Failed to load tile tags: " + e.getLocalizedMessage());
    446464            }
     465            return true;
    447466        }
    448467    }
    449468
  • 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) {