Ignore:
Timestamp:
2008-08-15T13:03:46+02:00 (16 years ago)
Author:
stotz
Message:

Dispatcher now created and disposes Thread dynamically;
OsmFileCacheTileLoader now supports ETag and If-None-Match for detecting updated tiles

Location:
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer
Files:
1 added
1 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/Demo.java

    r9780 r9846  
    1616import javax.swing.JPanel;
    1717
     18import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
    1819import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
    1920
     
    3435                final JMapViewer map = new JMapViewer();
    3536                // final JMapViewer map = new JMapViewer(new MemoryTileCache(),4);
    36                 map.setTileLoader(new OsmFileCacheTileLoader(map));
     37                // map.setTileLoader(new OsmFileCacheTileLoader(map));
    3738                // new DefaultMapController(map);
    3839                setLayout(new BorderLayout());
     
    5556                });
    5657                JComboBox tileSourceSelector =
    57                                 new JComboBox(new Object[] { new OsmTileSource.Mapnik(),
     58                                new JComboBox(new TileSource[] { new OsmTileSource.Mapnik(),
    5859                                                new OsmTileSource.TilesAtHome(), new OsmTileSource.CycleMap() });
    5960                tileSourceSelector.addItemListener(new ItemListener() {
     
    6263                        }
    6364                });
     65                JComboBox tileLoaderSelector =
     66                                new JComboBox(new TileLoader[] { new OsmFileCacheTileLoader(map),
     67                                                new OsmTileLoader(map) });
     68                tileLoaderSelector.addItemListener(new ItemListener() {
     69                        public void itemStateChanged(ItemEvent e) {
     70                                map.setTileLoader((TileLoader) e.getItem());
     71                        }
     72                });
     73                map.setTileLoader((TileLoader) tileLoaderSelector.getSelectedItem());
    6474                panel.add(tileSourceSelector);
     75                panel.add(tileLoaderSelector);
    6576                final JCheckBox showMapMarker = new JCheckBox("Map markers visible");
    6677                showMapMarker.setSelected(map.getMapMarkersVisible());
     
    108119         */
    109120        public static void main(String[] args) {
    110                 // Properties systemProperties = System.getProperties();
    111                 // systemProperties.setProperty("http.proxyHost","localhost");
    112                 // systemProperties.setProperty("http.proxyPort","8008");
     121                // java.util.Properties systemProperties = System.getProperties();
     122                // systemProperties.setProperty("http.proxyHost", "localhost");
     123                // systemProperties.setProperty("http.proxyPort", "8008");
    113124                new Demo().setVisible(true);
    114125        }
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java

    r9785 r9846  
    2626import org.openstreetmap.gui.jmapviewer.interfaces.MapMarker;
    2727import org.openstreetmap.gui.jmapviewer.interfaces.TileCache;
     28import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
     29import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
    2830import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
    29 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
    3031
    3132/**
     
    3738 *
    3839 */
    39 public class JMapViewer extends JPanel {
     40public class JMapViewer extends JPanel implements TileLoaderListener {
    4041
    4142        private static final long serialVersionUID = 1L;
     
    9798                tileLoader = new OsmTileLoader(this);
    9899                this.tileCache = tileCache;
    99                 jobDispatcher = new JobDispatcher(downloadThreadCount);
     100                jobDispatcher = JobDispatcher.getInstance();
    100101                mapMarkerList = new LinkedList<MapMarker>();
    101102                mapMarkersVisible = true;
     
    367368                int mapSize = Tile.SIZE << zoom;
    368369                g.drawRect(w2 - center.x, h2 - center.y, mapSize, mapSize);
    369                
     370
    370371                // g.drawString("Tiles in cache: " + tileCache.getTileCount(), 50, 20);
    371372                if (!mapMarkersVisible || mapMarkerList == null)
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JobDispatcher.java

    r9494 r9846  
    55import java.util.concurrent.BlockingQueue;
    66import java.util.concurrent.LinkedBlockingQueue;
    7 
    8 import org.openstreetmap.gui.jmapviewer.interfaces.Job;
     7import java.util.concurrent.TimeUnit;
    98
    109/**
    1110 * A generic class that processes a list of {@link Runnable} one-by-one using
    12  * one or more {@link Thread}-instances.
     11 * one or more {@link Thread}-instances. The number of instances varies between
     12 * 1 and {@link #WORKER_THREAD_MAX_COUNT} (default: 8). If an instance is idle
     13 * more than {@link #WORKER_THREAD_TIMEOUT} seconds (default: 30), the instance
     14 * ends itself.
    1315 *
    1416 * @author Jan Peter Stotz
     
    1618public class JobDispatcher {
    1719
     20        private static JobDispatcher instance;
     21
     22        /**
     23         * @return the singelton instance of the {@link JobDispatcher}
     24         */
     25        public static JobDispatcher getInstance() {
     26                if (instance == null)
     27                        instance = new JobDispatcher();
     28                return instance;
     29        }
     30
     31        private JobDispatcher() {
     32                addWorkerThread().firstThread = true;
     33        }
     34
    1835        protected BlockingQueue<Runnable> jobQueue = new LinkedBlockingQueue<Runnable>();
    1936
    20         JobThread[] threads;
    21 
    22         public JobDispatcher(int threadCound) {
    23                 threads = new JobThread[threadCound];
    24                 for (int i = 0; i < threadCound; i++) {
    25                         threads[i] = new JobThread(i + 1);
    26                 }
    27         }
     37        public static int WORKER_THREAD_MAX_COUNT = 8;
    2838
    2939        /**
    30          * Removes all jobs from the queue that are currently not being processed
    31          * and stops those currently being processed.
     40         * Specifies the time span in seconds that a worker thread waits for new
     41         * jobs to perform. If the time span has elapsed the worker thread
     42         * terminates itself. Only the first worker thread works differently, it
     43         * ignores the timeout and will never terminate itself.
     44         */
     45        public static int WORKER_THREAD_TIMEOUT = 30;
     46
     47        /**
     48         * Total number of worker threads currently idle or active
     49         */
     50        protected int workerThreadCount = 0;
     51
     52        /**
     53         * Number of worker threads currently idle
     54         */
     55        protected int workerThreadIdleCount = 0;
     56
     57        /**
     58         * Just an id for identifying an worker thread instance
     59         */
     60        protected int workerThreadId = 0;
     61
     62        /**
     63         * Removes all jobs from the queue that are currently not being processed.
    3264         */
    3365        public void cancelOutstandingJobs() {
    3466                jobQueue.clear();
    35                 for (int i = 0; i < threads.length; i++) {
    36                         try {
    37                                 Runnable job = threads[i].getJob();
    38                                 if ((job != null) && (job instanceof Job))
    39                                         ((Job) job).stop();
    40                         } catch (Exception e) {
    41                                 e.printStackTrace();
    42                         }
    43                 }
    4467        }
    4568
     
    4770                try {
    4871                        jobQueue.put(job);
     72                        if (workerThreadIdleCount == 0 && workerThreadCount < WORKER_THREAD_MAX_COUNT)
     73                                addWorkerThread();
    4974                } catch (InterruptedException e) {
    5075                }
     76        }
     77
     78        protected JobThread addWorkerThread() {
     79                JobThread jobThread = new JobThread(++workerThreadId);
     80                synchronized (this) {
     81                        workerThreadCount++;
     82                }
     83                return jobThread;
    5184        }
    5285
     
    5487
    5588                Runnable job;
     89                boolean firstThread = false;
    5690
    5791                public JobThread(int threadId) {
     
    6498                @Override
    6599                public void run() {
     100                        executeJobs();
     101                        synchronized (instance) {
     102                                workerThreadCount--;
     103                        }
     104                }
     105
     106                protected void executeJobs() {
    66107                        while (!isInterrupted()) {
    67108                                try {
    68                                         job = jobQueue.take();
     109                                        synchronized (instance) {
     110                                                workerThreadIdleCount++;
     111                                        }
     112                                        if (firstThread)
     113                                                job = jobQueue.take();
     114                                        else
     115                                                job = jobQueue.poll(WORKER_THREAD_TIMEOUT, TimeUnit.SECONDS);
    69116                                } catch (InterruptedException e1) {
    70117                                        return;
     118                                } finally {
     119                                        synchronized (instance) {
     120                                                workerThreadIdleCount--;
     121                                        }
    71122                                }
     123                                if (job == null)
     124                                        return;
    72125                                try {
    73126                                        job.run();
     
    78131                        }
    79132                }
    80 
    81                 /**
    82                  * @return the job being executed at the moment or <code>null</code> if
    83                  *         the thread is idle.
    84                  */
    85                 public Runnable getJob() {
    86                         return job;
    87                 }
    88 
    89133        }
    90134
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmFileCacheTileLoader.java

    r9780 r9846  
    1313import java.net.URL;
    1414import java.net.URLConnection;
    15 
    16 import org.openstreetmap.gui.jmapviewer.interfaces.Job;
     15import java.nio.charset.Charset;
     16
    1717import org.openstreetmap.gui.jmapviewer.interfaces.TileCache;
     18import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
     19import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
    1820import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
    19 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
     21import org.openstreetmap.gui.jmapviewer.interfaces.TileSource.TileUpdate;
    2022
    2123/**
     
    2830public class OsmFileCacheTileLoader extends OsmTileLoader {
    2931
    30         private static final String FILE_EXT = ".png";
     32        private static final String TILE_FILE_EXT = ".png";
     33        private static final String ETAG_FILE_EXT = ".etag";
     34
     35        private static final Charset ETAG_CHARSET = Charset.forName("UTF-8");
    3136
    3237        public static final long FILE_AGE_ONE_DAY = 1000 * 60 * 60 * 24;
     
    3540        protected String cacheDirBase;
    3641
    37         protected long maxFileAge = FILE_AGE_ONE_WEEK;
    38 
    39         public OsmFileCacheTileLoader(JMapViewer map) {
     42        protected long maxCacheFileAge = FILE_AGE_ONE_WEEK;
     43        protected long recheckAfter = FILE_AGE_ONE_DAY;
     44
     45        public OsmFileCacheTileLoader(TileLoaderListener map) {
    4046                super(map);
    4147                String tempDir = System.getProperty("java.io.tmpdir");
     
    5359        }
    5460
    55         public Job createTileLoaderJob(final TileSource source, final int tilex, final int tiley,
     61        public Runnable createTileLoaderJob(final TileSource source, final int tilex, final int tiley,
    5662                        final int zoom) {
    5763                return new FileLoadJob(source, tilex, tiley, zoom);
    5864        }
    5965
    60         protected class FileLoadJob implements Job {
     66        protected class FileLoadJob implements Runnable {
    6167                InputStream input = null;
    6268
    6369                int tilex, tiley, zoom;
     70                Tile tile;
    6471                TileSource source;
    6572                File tileCacheDir;
     73                File tileFile = null;
     74                long fileAge = 0;
     75                boolean fileTilePainted = false;
    6676
    6777                public FileLoadJob(TileSource source, int tilex, int tiley, int zoom) {
     
    7484
    7585                public void run() {
    76                         TileCache cache = map.getTileCache();
    77                         Tile tile;
     86                        TileCache cache = listener.getTileCache();
    7887                        synchronized (cache) {
    7988                                tile = cache.getTile(source, tilex, tiley, zoom);
     
    8594                        if (!tileCacheDir.exists())
    8695                                tileCacheDir.mkdirs();
    87                         try {
    88                                 long fileAge = 0;
    89                                 FileInputStream fin = null;
    90                                 File f = null;
    91                                 try {
    92                                         f = getTileFile(tile);
    93                                         fin = new FileInputStream(f);
    94                                         tile.loadImage(fin);
    95                                         fin.close();
    96                                         fileAge = f.lastModified();
    97                                         boolean oldTile = System.currentTimeMillis() - fileAge > maxFileAge;
    98                                         System.out.println("Loaded from file: " + tile);
    99                                         if (!oldTile) {
    100                                                 tile.setLoaded(true);
    101                                                 map.repaint();
    102                                                 return;
     96                        if (loadTileFromFile())
     97                                return;
     98                        if (fileTilePainted) {
     99                                Runnable job = new Runnable() {
     100
     101                                        public void run() {
     102                                                loadorUpdateTile();
    103103                                        }
    104                                         // System.out.println("Cache hit for " + tile +
    105                                         // " but file age is high: "
    106                                         // + new Date(fileAge));
    107                                         map.repaint();
    108                                         // if (!isOsmTileNewer(tile, fileAge)) {
    109                                         // tile.setLoaded(true);
    110                                         // return;
    111                                         // }
    112                                 } catch (Exception e) {
    113                                         try {
    114                                                 if (fin != null) {
    115                                                         fin.close();
    116                                                         f.delete();
    117                                                 }
    118                                         } catch (Exception e1) {
    119                                         }
    120                                 }
    121                                 // Thread.sleep(500);
     104                                };
     105                                JobDispatcher.getInstance().addJob(job);
     106                        } else {
     107                                loadorUpdateTile();
     108                        }
     109                }
     110
     111                protected void loadorUpdateTile() {
     112
     113                        try {
    122114                                // System.out.println("Loading tile from OSM: " + tile);
    123115                                HttpURLConnection urlConn = loadTileFromOsm(tile);
    124                                 // if (fileAge > 0)
    125                                 // urlConn.setIfModifiedSince(fileAge);
    126                                 //
    127                                 // if (urlConn.getResponseCode() == 304) {
    128                                 // System.out.println("Local version is up to date");
    129                                 // tile.setLoaded(true);
    130                                 // return;
    131                                 // }
     116                                if (tileFile != null) {
     117                                        switch (source.getTileUpdate()) {
     118                                        case IfModifiedSince:
     119                                                urlConn.setIfModifiedSince(fileAge);
     120                                                break;
     121                                        case LastModified:
     122                                                if (!isOsmTileNewer(fileAge)) {
     123                                                        System.out
     124                                                                        .println("LastModified: Local version is up to date: " + tile);
     125                                                        tile.setLoaded(true);
     126                                                        tileFile.setLastModified(System.currentTimeMillis() - maxCacheFileAge
     127                                                                        + recheckAfter);
     128                                                        return;
     129                                                }
     130                                                break;
     131                                        }
     132                                }
     133                                if (source.getTileUpdate() == TileUpdate.ETag
     134                                                || source.getTileUpdate() == TileUpdate.IfNoneMatch) {
     135                                        if (tileFile != null) {
     136                                                String fileETag = loadETagfromFile();
     137                                                if (fileETag != null) {
     138                                                        switch (source.getTileUpdate()) {
     139                                                        case IfNoneMatch:
     140                                                                urlConn.addRequestProperty("If-None-Match", fileETag);
     141                                                                break;
     142                                                        case ETag:
     143                                                                if (hasOsmTileETag(fileETag)) {
     144                                                                        tile.setLoaded(true);
     145                                                                        tileFile.setLastModified(System.currentTimeMillis() - maxCacheFileAge
     146                                                                                        + recheckAfter);
     147                                                                        return;
     148                                                                }
     149                                                        }
     150                                                }
     151                                        }
     152
     153                                        String eTag = urlConn.getHeaderField("ETag");
     154                                        saveETagToFile(eTag);
     155                                }
     156                                if (urlConn.getResponseCode() == 304) {
     157                                        // If we are isModifiedSince or If-None-Match has been set
     158                                        // and the server answers with a HTTP 304 = "Not Modified"
     159                                        System.out.println("Local version is up to date: " + tile);
     160                                        tile.setLoaded(true);
     161                                        tileFile.setLastModified(System.currentTimeMillis() - maxCacheFileAge
     162                                                        + recheckAfter);
     163                                        return;
     164                                }
     165
    132166                                byte[] buffer = loadTileInBuffer(urlConn);
    133                                 tile.loadImage(new ByteArrayInputStream(buffer));
    134                                 tile.setLoaded(true);
    135                                 map.repaint();
    136                                 input = null;
    137                                 saveTileToFile(tile, buffer);
     167                                if (buffer != null) {
     168                                        tile.loadImage(new ByteArrayInputStream(buffer));
     169                                        tile.setLoaded(true);
     170                                        listener.repaint();
     171                                        saveTileToFile(buffer);
     172                                } else {
     173                                        tile.setLoaded(true);
     174                                }
    138175                        } catch (Exception e) {
    139176                                if (input == null /* || !input.isStopped() */)
     
    143180                                tile.loading = false;
    144181                        }
     182                }
     183
     184                protected boolean loadTileFromFile() {
     185                        FileInputStream fin = null;
     186                        try {
     187                                tileFile = getTileFile();
     188                                fin = new FileInputStream(tileFile);
     189                                if (fin.available() == 0)
     190                                        throw new IOException("File empty");
     191                                tile.loadImage(fin);
     192                                fin.close();
     193                                fileAge = tileFile.lastModified();
     194                                boolean oldTile = System.currentTimeMillis() - fileAge > maxCacheFileAge;
     195                                // System.out.println("Loaded from file: " + tile);
     196                                if (!oldTile) {
     197                                        tile.setLoaded(true);
     198                                }
     199                                listener.repaint();
     200                                fileTilePainted = true;
     201                        } catch (Exception e) {
     202                                try {
     203                                        if (fin != null) {
     204                                                fin.close();
     205                                                tileFile.delete();
     206                                        }
     207                                } catch (Exception e1) {
     208                                }
     209                                tileFile = null;
     210                                fileAge = 0;
     211                        }
     212                        return false;
    145213                }
    146214
     
    157225                                        finished = true;
    158226                        } while (!finished);
     227                        if (bout.size() == 0)
     228                                return null;
    159229                        return bout.toByteArray();
    160230                }
     
    171241                 * </ul>
    172242                 *
    173                  * @param tile
    174243                 * @param fileAge
    175244                 * @return <code>true</code> if the tile on the server is newer than the
     
    177246                 * @throws IOException
    178247                 */
    179                 protected boolean isOsmTileNewer(Tile tile, long fileAge) throws IOException {
     248                protected boolean isOsmTileNewer(long fileAge) throws IOException {
    180249                        URL url;
    181250                        url = new URL(tile.getUrl());
    182251                        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
    183252                        urlConn.setRequestMethod("HEAD");
    184                         urlConn.setReadTimeout(30000); // 30 seconds read
     253                        urlConn.setReadTimeout(30000); // 30 seconds read timeout
    185254                        // System.out.println("Tile age: " + new
    186255                        // Date(urlConn.getLastModified()) + " / "
     
    188257                        long lastModified = urlConn.getLastModified();
    189258                        if (lastModified == 0)
     259                                return true; // no LastModified time returned
     260                        return (lastModified > fileAge);
     261                }
     262
     263                protected boolean hasOsmTileETag(String eTag) throws IOException {
     264                        URL url;
     265                        url = new URL(tile.getUrl());
     266                        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
     267                        urlConn.setRequestMethod("HEAD");
     268                        urlConn.setReadTimeout(30000); // 30 seconds read timeout
     269                        // System.out.println("Tile age: " + new
     270                        // Date(urlConn.getLastModified()) + " / "
     271                        // + new Date(fileAge));
     272                        String osmETag = urlConn.getHeaderField("ETag");
     273                        if (osmETag == null)
    190274                                return true;
    191                         return (lastModified > fileAge);
    192                 }
    193 
    194                 protected File getTileFile(Tile tile) throws IOException {
     275                        return (osmETag.equals(eTag));
     276                }
     277
     278                protected File getTileFile() throws IOException {
    195279                        return new File(tileCacheDir + "/" + tile.getZoom() + "_" + tile.getXtile() + "_"
    196                                         + tile.getYtile() + FILE_EXT);
    197                 }
    198 
    199                 protected void saveTileToFile(Tile tile, byte[] rawData) {
     280                                        + tile.getYtile() + TILE_FILE_EXT);
     281                }
     282
     283                protected void saveTileToFile(byte[] rawData) {
    200284                        try {
    201285                                FileOutputStream f =
    202286                                                new FileOutputStream(tileCacheDir + "/" + tile.getZoom() + "_"
    203                                                                 + tile.getXtile() + "_" + tile.getYtile() + FILE_EXT);
     287                                                                + tile.getXtile() + "_" + tile.getYtile() + TILE_FILE_EXT);
    204288                                f.write(rawData);
    205289                                f.close();
     
    210294                }
    211295
    212                 public void stop() {
    213                 }
     296                protected void saveETagToFile(String eTag) {
     297                        try {
     298                                FileOutputStream f =
     299                                                new FileOutputStream(tileCacheDir + "/" + tile.getZoom() + "_"
     300                                                                + tile.getXtile() + "_" + tile.getYtile() + ETAG_FILE_EXT);
     301                                f.write(eTag.getBytes(ETAG_CHARSET));
     302                                f.close();
     303                        } catch (Exception e) {
     304                                System.err.println("Failed to save ETag: " + e.getLocalizedMessage());
     305                        }
     306                }
     307
     308                protected String loadETagfromFile() {
     309                        try {
     310                                FileInputStream f =
     311                                                new FileInputStream(tileCacheDir + "/" + tile.getZoom() + "_"
     312                                                                + tile.getXtile() + "_" + tile.getYtile() + ETAG_FILE_EXT);
     313                                byte[] buf = new byte[f.available()];
     314                                f.read(buf);
     315                                f.close();
     316                                return new String(buf, ETAG_CHARSET);
     317                        } catch (Exception e) {
     318                                return null;
     319                        }
     320                }
     321
    214322        }
    215323
    216324        public long getMaxFileAge() {
    217                 return maxFileAge;
     325                return maxCacheFileAge;
    218326        }
    219327
    220328        /**
    221          * Sets the maximum age of the local cached tile in the file system.
     329         * Sets the maximum age of the local cached tile in the file system. If a
     330         * local tile is older than the specified file age
     331         * {@link OsmFileCacheTileLoader} will connect to the tile server and check
     332         * if a newer tile is available using the mechanism specified for the
     333         * selected tile source/server.
    222334         *
    223335         * @param maxFileAge
     
    225337         * @see #FILE_AGE_ONE_DAY
    226338         * @see #FILE_AGE_ONE_WEEK
     339         * @see TileSource#getTileUpdate()
    227340         */
    228         public void setMaxFileAge(long maxFileAge) {
    229                 this.maxFileAge = maxFileAge;
     341        public void setCacheMaxFileAge(long maxFileAge) {
     342                this.maxCacheFileAge = maxFileAge;
    230343        }
    231344
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java

    r9780 r9846  
    88import java.net.URL;
    99
    10 import org.openstreetmap.gui.jmapviewer.interfaces.Job;
    1110import org.openstreetmap.gui.jmapviewer.interfaces.TileCache;
     11import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
     12import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
    1213import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
    13 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
    1414
    1515/**
     
    2020public class OsmTileLoader implements TileLoader {
    2121
    22         protected JMapViewer map;
     22        protected TileLoaderListener listener;
    2323
    24         public OsmTileLoader(JMapViewer map) {
    25                 this.map = map;
     24        public OsmTileLoader(TileLoaderListener listener) {
     25                this.listener = listener;
    2626        }
    2727
    28         public Job createTileLoaderJob(final TileSource source, final int tilex, final int tiley,
     28        public Runnable createTileLoaderJob(final TileSource source, final int tilex, final int tiley,
    2929                        final int zoom) {
    30                 return new Job() {
     30                return new Runnable() {
    3131
    3232                        InputStream input = null;
    3333
    3434                        public void run() {
    35                                 TileCache cache = map.getTileCache();
     35                                TileCache cache = listener.getTileCache();
    3636                                Tile tile;
    3737                                synchronized (cache) {
     
    4646                                        tile.loadImage(input);
    4747                                        tile.setLoaded(true);
    48                                         map.repaint();
     48                                        listener.repaint();
    4949                                        input.close();
    5050                                        input = null;
    5151                                } catch (Exception e) {
    5252                                        if (input == null /* || !input.isStopped() */)
    53                                                 System.err.println("failed loading " + zoom + "/"
    54                                                                 + tilex + "/" + tiley + " " + e.getMessage());
     53                                                System.err.println("failed loading " + zoom + "/" + tilex + "/" + tiley
     54                                                                + " " + e.getMessage());
    5555                                } finally {
    5656                                        tile.loading = false;
     
    5858                        }
    5959
    60                         /**
    61                          * Terminating all transfers that are currently in progress
    62                          */
    63                         public void stop() {
    64 
    65                                 try {
    66                                         // if (input != null)
    67                                         // input.stop();
    68                                 } catch (Exception e) {
    69                                 }
    70                         }
    7160                };
    7261        }
     
    8069                return urlConn;
    8170        }
     71
     72        @Override
     73        public String toString() {
     74                return getClass().getSimpleName();
     75        }
     76       
    8277}
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmTileSource.java

    r9780 r9846  
    3636                }
    3737
     38                public TileUpdate getTileUpdate() {
     39                        return TileUpdate.IfNoneMatch;
     40                }
     41
    3842        }
    3943
     
    4852                        return MAP_CYCLE + super.getTileUrl(zoom, tilex, tiley);
    4953                }
     54
     55                public TileUpdate getTileUpdate() {
     56                        return TileUpdate.LastModified;
     57                }
     58
    5059        }
    5160
     
    6574                }
    6675
     76                public TileUpdate getTileUpdate() {
     77                        return TileUpdate.IfModifiedSince;
     78                }
    6779        }
    6880}
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileLoader.java

    r9780 r9846  
    2020         * @param tiley
    2121         * @param zoom
    22          * @returns {@link Job} implementation that performs the desired load
     22         * @returns {@link Runnable} implementation that performs the desired load
    2323         *          action.
    2424         */
    25         public Job createTileLoaderJob(TileSource tileLayerSource, int tilex, int tiley, int zoom);
     25        public Runnable createTileLoaderJob(TileSource tileLayerSource, int tilex, int tiley, int zoom);
    2626}
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/interfaces/TileSource.java

    r9780 r9846  
    2828         * all tiles but <b>does not support</b> conditional download via
    2929         * <code>If-Modified-Since</code> header entry.</li>
     30         * <li>{@link #None} The server does not support any of the listed
     31         * mechanisms.</li>
    3032         * </ul>
    3133         *
    3234         */
    33         public enum TileUpdateDetection {
    34                 IfNoneMatch, ETag, IfModifiedSince, LastModified
     35        public enum TileUpdate {
     36                IfNoneMatch, ETag, IfModifiedSince, LastModified, None
    3537        };
    3638
     
    4345         */
    4446        public int getMaxZoom();
     47
     48        /**
     49         * @return The supported tile update mechanism
     50         * @see TileUpdate
     51         */
     52        public TileUpdate getTileUpdate();
    4553
    4654        /**
Note: See TracChangeset for help on using the changeset viewer.