Ticket #1906: Cache for WMS.patch

File Cache for WMS.patch, 7.4 KB (added by xeen, 4 years ago)

Simple Cache

  • src/wmsplugin/Cache.java

     
     1package wmsplugin; 
     2 
     3import java.awt.image.BufferedImage; 
     4import java.io.File; 
     5import java.io.FileFilter; 
     6import java.util.Date; 
     7import java.util.Iterator; 
     8import java.util.Set; 
     9import java.util.TreeMap; 
     10import javax.imageio.*; 
     11 
     12import org.openstreetmap.josm.Main; 
     13 
     14 
     15public class Cache { 
     16    final File dir; 
     17    // Last 5 days 
     18    private final long expire = Main.pref.getInteger("wmsplugin.cache.expire", 1000*60*60*24*5); 
     19    // 40 MBytes 
     20    private final long maxsize = Main.pref.getInteger("wmsplugin.cache.size", 1000*1000*40); 
     21    private boolean disabled = false; 
     22    // If the cache is full, we don't want to delete just one file 
     23    private final int cleanUpThreshold = 20; 
     24     
     25    Cache() { 
     26        this(Main.pref.getPreferencesDir() + "plugins/wmsplugin/cache"); 
     27    } 
     28     
     29    Cache(String working_dir) { 
     30        // Override default working directory 
     31        this.dir = new File(working_dir); 
     32        try { 
     33            this.dir.mkdirs(); 
     34        } catch(Exception e) { 
     35            // We probably won't be able to do anything anyway 
     36            disabled = true; 
     37        } 
     38         
     39        if(expire <= 0 || maxsize <= 0) 
     40            disabled = true; 
     41    } 
     42     
     43    public BufferedImage getImg(String ident) { 
     44        if(disabled) return null; 
     45        try { 
     46            File img = getPath(ident); 
     47            if(!img.exists()) { 
     48                //System.out.println("Miss"); 
     49                return null; 
     50            }     
     51            if(img.lastModified() < (new Date().getTime() - expire)) { 
     52                img.delete(); 
     53                //System.out.println("Miss"); 
     54                return null; 
     55            } 
     56            //System.out.println("Hit"); 
     57            return ImageIO.read(img); 
     58        } catch(Exception e) { 
     59            System.out.println(e.getMessage()); 
     60        } 
     61        //System.out.println("Miss"); 
     62        return null; 
     63    } 
     64     
     65    public void saveImg(String ident, BufferedImage image) { 
     66        if(disabled) return; 
     67        try { 
     68            ImageIO.write(image, "png", getPath(ident)); 
     69        } catch(Exception e){ 
     70            System.out.println(e.getMessage()); 
     71        } 
     72         
     73        // Clean up must be called manually 
     74    } 
     75     
     76    public BufferedImage saveImg(String ident, BufferedImage image, boolean passThrough) { 
     77        saveImg(ident, image); 
     78        return image; 
     79    } 
     80     
     81    public void cleanUp() { 
     82        if(disabled) return; 
     83         
     84        TreeMap modtime = new TreeMap<Long, File>(); 
     85        long time = new Date().getTime() - expire; 
     86        long dirsize = 0; 
     87         
     88        for(File f : getFiles()) { 
     89            if(f.lastModified() < time) 
     90                f.delete(); 
     91            else { 
     92                dirsize += f.length(); 
     93                modtime.put(f.lastModified(), f); 
     94            } 
     95        } 
     96         
     97        if(dirsize < maxsize) return; 
     98         
     99        Set keySet = modtime.keySet(); 
     100        Iterator it = keySet.iterator(); 
     101        int i=0; 
     102        while (it.hasNext()) { 
     103            i++; 
     104            ((File)modtime.get(it.next())).delete(); 
     105             
     106            // Delete a couple of files, then check again 
     107            if(i % cleanUpThreshold == 0 && getDirSize() < maxsize) 
     108                return; 
     109        } 
     110    } 
     111     
     112    private long getDirSize() { 
     113        long dirsize = 0; 
     114         
     115        for(File f : getFiles())  
     116            dirsize += f.length(); 
     117        return dirsize; 
     118    } 
     119     
     120    private File[] getFiles() { 
     121        return dir.listFiles( 
     122            new FileFilter() { 
     123                public boolean accept(File file) { 
     124                    return file.getName().endsWith(".png"); 
     125                } 
     126            } 
     127        ); 
     128    } 
     129     
     130    private String clean(String ident) {         
     131        return ident.replaceAll("[^a-zA-Z0-9]", ""); 
     132    } 
     133     
     134    private File getPath(String ident) { 
     135        return new File(dir, clean(ident) + ".png"); 
     136    } 
     137} 
     138 No newline at end of file 
  • src/wmsplugin/WMSGrabber.java

     
    2525 
    2626public class WMSGrabber extends Grabber { 
    2727    protected String baseURL; 
     28    protected Cache cache = new wmsplugin.Cache(); 
    2829 
    2930    WMSGrabber(String baseURL, Bounds b, Projection proj, 
    3031            double pixelPerDegree, GeorefImage image, MapView mv, WMSLayer layer) { 
     
    7576    } 
    7677 
    7778    protected BufferedImage grab(URL url) throws IOException { 
     79        BufferedImage cached = cache.getImg(url.toString()); 
     80        if(cached != null) return cached; 
     81     
    7882        HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
    7983 
    8084        String contentType = conn.getHeaderField("Content-Type"); 
     
    8690        InputStream is = new ProgressInputStream(conn, null); 
    8791        BufferedImage img = ImageIO.read(is); 
    8892        is.close(); 
    89         return img; 
     93         
     94        return cache.saveImg(url.toString(), img, true); 
    9095    } 
    9196 
    9297    protected String readException(URLConnection conn) throws IOException { 
  • src/wmsplugin/WMSLayer.java

     
    175175                    executor.submit(gr); 
    176176            } 
    177177        } 
     178 
     179        new wmsplugin.Cache().cleanUp(); 
    178180    } 
    179181 
    180182    @Override public void visitBoundingBox(BoundingXYVisitor v) { 
  • src/wmsplugin/YAHOOGrabber.java

     
    2020 
    2121public class YAHOOGrabber extends WMSGrabber{ 
    2222    protected String browserCmd; 
     23    protected Cache cache = new wmsplugin.Cache(); 
    2324 
    2425    YAHOOGrabber(String baseURL, Bounds b, Projection proj, 
    2526            double pixelPerDegree, GeorefImage image, MapView mv, WMSLayer layer) { 
     
    3031    } 
    3132 
    3233    protected BufferedImage grab(URL url) throws IOException { 
    33         ArrayList<String> cmdParams = new ArrayList<String>(); 
    3434        String urlstring = url.toExternalForm(); 
    3535        // work around a problem in URL removing 2 slashes 
    3636        if(!urlstring.startsWith("file:///")) 
    3737            urlstring = urlstring.replaceFirst("file:", "file://"); 
     38             
     39        BufferedImage cached = cache.getImg(urlstring); 
     40        if(cached != null) return cached; 
     41         
     42        ArrayList<String> cmdParams = new ArrayList<String>(); 
    3843        StringTokenizer st = new StringTokenizer(MessageFormat.format(browserCmd, urlstring)); 
    3944        while( st.hasMoreTokens() ) 
    4045            cmdParams.add(st.nextToken()); 
     
    4954            throw new IOException( "Could not start browser. Please check that the executable path is correct.\n" + ioe.getMessage() ); 
    5055        } 
    5156 
    52         return ImageIO.read(browser.getInputStream()); 
     57        return cache.saveImg(urlstring, ImageIO.read(browser.getInputStream()), true); 
    5358    } 
    5459}