~ubuntu-branches/ubuntu/saucy/gpsprune/saucy

« back to all changes in this revision

Viewing changes to tim/prune/gui/map/DiskTileCacher.java

  • Committer: Bazaar Package Importer
  • Author(s): David Paleino
  • Date: 2010-05-06 00:08:17 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100506000817-uxan1bazwz66g0q5
Tags: 10-1
* New upstream version
* debian/copyright:
  - updated to include new info about generated and binary files in
    tim/prune/function/srtm/
* debian/scripts/get-tiles.py added, can be used to re-generate
  tiles*.txt files (see debian/copyright)
* debian/rules:
  - added srtmtiles target; re-build the srtmtiles.dat binary file
    at build-time
  - added tim/prune/function/srtm/srtmtiles.dat to JH_JAR_EXTRA
* debian/patches/00-fix_readme_in_about.patch removed, merged upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package tim.prune.gui.map;
 
2
 
 
3
import java.awt.Image;
 
4
import java.awt.Toolkit;
 
5
import java.awt.image.ImageObserver;
 
6
import java.io.File;
 
7
import java.io.FileOutputStream;
 
8
import java.io.IOException;
 
9
import java.io.InputStream;
 
10
import java.net.URL;
 
11
 
 
12
/**
 
13
 * Class to control the reading and saving of map tiles
 
14
 * to a cache on disk
 
15
 */
 
16
public class DiskTileCacher implements Runnable
 
17
{
 
18
        /** URL to get image from */
 
19
        private URL _url = null;
 
20
        /** File to save image to */
 
21
        private File _file = null;
 
22
        /** Observer to be notified */
 
23
        private ImageObserver _observer = null;
 
24
        /** Time limit to cache images for */
 
25
        private static final long CACHE_TIME_LIMIT = 20 * 24 * 60 * 60 * 1000; // 20 days in ms
 
26
 
 
27
        /**
 
28
         * Private constructor
 
29
         * @param inUrl URL to get
 
30
         * @param inFile file to save to
 
31
         */
 
32
        private DiskTileCacher(URL inUrl, File inFile, ImageObserver inObserver)
 
33
        {
 
34
                _url = inUrl;
 
35
                _file = inFile;
 
36
                _observer = inObserver;
 
37
                new Thread(this).start();
 
38
        }
 
39
 
 
40
        /**
 
41
         * Get the specified tile from the disk cache
 
42
         * @param inBasePath base path to whole disk cache
 
43
         * @param inTilePath relative path to requested tile
 
44
         * @param inCheckAge true to check age of file, false to ignore
 
45
         * @return tile image if available, or null if not there
 
46
         */
 
47
        public static Image getTile(String inBasePath, String inTilePath, boolean inCheckAge)
 
48
        {
 
49
                if (inBasePath == null) {return null;}
 
50
                File tileFile = new File(inBasePath, inTilePath);
 
51
                Image image = null;
 
52
                if (tileFile.exists() && tileFile.canRead() && tileFile.length() > 0) {
 
53
                        long fileStamp = tileFile.lastModified();
 
54
                        if (!inCheckAge || ((System.currentTimeMillis()-fileStamp) < CACHE_TIME_LIMIT))
 
55
                        {
 
56
                                try {
 
57
                                        image = Toolkit.getDefaultToolkit().createImage(tileFile.getAbsolutePath());
 
58
                                }
 
59
                                catch (Exception e) {}
 
60
                        }
 
61
                }
 
62
                return image;
 
63
        }
 
64
 
 
65
        /**
 
66
         * Save the specified image tile to disk
 
67
         * @param inUrl url to get image from
 
68
         * @param inBasePath base path to disk cache
 
69
         * @param inTilePath relative path to this tile
 
70
         * @param inObserver observer to inform when load complete
 
71
         */
 
72
        public static void saveTile(URL inUrl, String inBasePath, String inTilePath, ImageObserver inObserver)
 
73
        {
 
74
                if (inBasePath == null || inTilePath == null) {return;}
 
75
                // save file if possible
 
76
                File basePath = new File(inBasePath);
 
77
                if (!basePath.exists() || !basePath.isDirectory() || !basePath.canWrite()) {
 
78
                        //System.err.println("Can't write");
 
79
                        // Can't write to base path
 
80
                        return;
 
81
                }
 
82
                File tileFile = new File(basePath, inTilePath);
 
83
                // Check if this file is already being loaded
 
84
                if (!isBeingLoaded(tileFile))
 
85
                {
 
86
                        File dir = tileFile.getParentFile();
 
87
                        // Start a new thread to load the image if necessary
 
88
                        if (dir.exists() || dir.mkdirs())
 
89
                        {
 
90
                                new DiskTileCacher(inUrl, tileFile, inObserver);
 
91
                        }
 
92
                }
 
93
        }
 
94
 
 
95
        /**
 
96
         * Check whether the given tile is already being loaded
 
97
         * @param inFile desired file
 
98
         * @return true if temporary file with this name exists
 
99
         */
 
100
        private static boolean isBeingLoaded(File inFile)
 
101
        {
 
102
                File tempFile = new File(inFile.getAbsolutePath() + ".temp");
 
103
                return tempFile.exists();
 
104
        }
 
105
 
 
106
        /**
 
107
         * Run method for loading URL asynchronously and saving to file
 
108
         */
 
109
        public void run()
 
110
        {
 
111
                boolean finished = false;
 
112
                InputStream in = null;
 
113
                FileOutputStream out = null;
 
114
                File tempFile = new File(_file.getAbsolutePath() + ".temp");
 
115
                // Use a synchronized block across all threads to make sure this url is only fetched once
 
116
                synchronized (DiskTileCacher.class) {
 
117
                        if (tempFile.exists()) {return;}
 
118
                        try {
 
119
                                if (!tempFile.createNewFile()) {return;}
 
120
                        }
 
121
                        catch (Exception e) {return;}
 
122
                }
 
123
                try {
 
124
                        // Open streams from URL and to file
 
125
                        out = new FileOutputStream(tempFile);
 
126
                        in = _url.openStream();
 
127
                        int d = 0;
 
128
                        // Loop over each byte in the stream (maybe buffering is more efficient?)
 
129
                        while ((d = in.read()) >= 0) {
 
130
                                out.write(d);
 
131
                        }
 
132
                        finished = true;
 
133
                } catch (IOException e) {}
 
134
                finally {
 
135
                        try {
 
136
                                in.close();
 
137
                                out.close();
 
138
                                if (!finished) {tempFile.delete();}
 
139
                        }
 
140
                        catch (Exception e) {} // ignore
 
141
                }
 
142
                // Move temp file to desired file location
 
143
                if (!tempFile.renameTo(_file)) {
 
144
                        // File couldn't be moved - delete both to be sure
 
145
                        tempFile.delete();
 
146
                        _file.delete();
 
147
                }
 
148
                // Tell parent that load is finished (parameters ignored)
 
149
                _observer.imageUpdate(null, ImageObserver.ALLBITS, 0, 0, 0, 0);
 
150
        }
 
151
}