001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.plugins.streetside.cache;
003
004import java.io.File;
005import java.io.IOException;
006import java.io.Serializable;
007
008import javax.swing.ImageIcon;
009
010import org.apache.commons.jcs.access.CacheAccess;
011import org.apache.commons.jcs.engine.behavior.IElementAttributes;
012import org.apache.log4j.Logger;
013import org.openstreetmap.josm.Main;
014import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
015import org.openstreetmap.josm.data.cache.JCSCacheManager;
016import org.openstreetmap.josm.plugins.streetside.model.UserProfile;
017import org.openstreetmap.josm.tools.Logging;
018
019public final class Caches {
020
021  final static Logger logger = Logger.getLogger(Caches.class);
022
023        private Caches() {
024                // Private constructor to avoid instantiation
025        }
026
027        public static File getCacheDirectory() {
028                final File f = new File(Main.pref.getPluginsDirectory().getPath() + "/MicrosoftStreetside/cache");
029                if (!f.exists()) {
030                        f.mkdirs();
031                }
032                return f;
033        }
034
035        public abstract static class CacheProxy<K, V extends Serializable> {
036                private final CacheAccess<K, V> cache;
037
038                public CacheProxy() {
039                        CacheAccess<K, V> c;
040                        try {
041                                c = createNewCache();
042                        } catch (IOException e) {
043                                logger.warn("Could not initialize cache for " + getClass().getName(), e);
044                                c = null;
045                        }
046                        cache = c;
047                }
048
049                protected abstract CacheAccess<K, V> createNewCache() throws IOException;
050
051                public V get(final K key) {
052                        return cache == null ? null : cache.get(key);
053                }
054
055                public void put(final K key, final V value) {
056                        if (cache != null) {
057                                cache.put(key, value);
058                        }
059                }
060        }
061
062        public static class ImageCache {
063                private static ImageCache instance;
064                private final CacheAccess<String, BufferedImageCacheEntry> cache;
065
066                public ImageCache() {
067                        CacheAccess<String, BufferedImageCacheEntry> c;
068                        try {
069                                c = JCSCacheManager.getCache("streetside", 10, 10000, Caches.getCacheDirectory().getPath());
070                        } catch (Exception e) {
071                                Logging.log(Logging.LEVEL_WARN, "Could not initialize the Streetside image cache.", e);
072                                c = null;
073                        }
074                        cache = c;
075                }
076
077                public CacheAccess<String, BufferedImageCacheEntry> getCache() {
078                        return cache;
079                }
080
081                public static ImageCache getInstance() {
082                        synchronized (ImageCache.class) {
083                                if (ImageCache.instance == null) {
084                                        ImageCache.instance = new ImageCache();
085                                }
086                                return ImageCache.instance;
087                        }
088                }
089        }
090
091        public static class CubemapCache {
092                private static CubemapCache instance;
093                private final CacheAccess<String, BufferedImageCacheEntry> cache;
094
095                public CubemapCache() {
096                        CacheAccess<String, BufferedImageCacheEntry> c;
097                        try {
098                                c = JCSCacheManager.getCache("streetside", 10, 10000, Caches.getCacheDirectory().getPath());
099                        } catch (Exception e) {
100                                logger.warn("Could not initialize the Streetside cubemap cache.", e);
101                                c = null;
102                        }
103                        cache = c;
104                }
105
106                public CacheAccess<String, BufferedImageCacheEntry> getCache() {
107                        return cache;
108                }
109
110                public static CubemapCache getInstance() {
111                        synchronized (CubemapCache.class) {
112                                if (CubemapCache.instance == null) {
113                                        CubemapCache.instance = new CubemapCache();
114                                }
115                                return CubemapCache.instance;
116                        }
117                }
118        }
119
120        public static class MapObjectIconCache extends CacheProxy<String, ImageIcon> {
121                private static CacheProxy<String, ImageIcon> instance;
122
123                public static CacheProxy<String, ImageIcon> getInstance() {
124                        synchronized (MapObjectIconCache.class) {
125                                if (MapObjectIconCache.instance == null) {
126                                        MapObjectIconCache.instance = new MapObjectIconCache();
127                                }
128                                return MapObjectIconCache.instance;
129                        }
130                }
131
132                @Override
133                protected CacheAccess<String, ImageIcon> createNewCache() throws IOException {
134                        return JCSCacheManager.getCache("streetsideObjectIcons", 100, 1000, Caches.getCacheDirectory().getPath());
135                }
136        }
137
138        public static class UserProfileCache extends CacheProxy<String, UserProfile> {
139                private static CacheProxy<String, UserProfile> instance;
140
141                public static CacheProxy<String, UserProfile> getInstance() {
142                        synchronized (UserProfileCache.class) {
143                                if (UserProfileCache.instance == null) {
144                                        UserProfileCache.instance = new UserProfileCache();
145                                }
146                                return UserProfileCache.instance;
147                        }
148                }
149
150                @Override
151                protected CacheAccess<String, UserProfile> createNewCache() throws IOException {
152                        CacheAccess<String, UserProfile> cache =
153                                        JCSCacheManager.getCache("userProfile", 100, 1000, Caches.getCacheDirectory().getPath());
154                        IElementAttributes atts = cache.getDefaultElementAttributes();
155                        atts.setMaxLife(604_800_000); // Sets lifetime to 7 days (604800000=1000*60*60*24*7)
156                        cache.setDefaultElementAttributes(atts);
157                        return cache;
158                }
159        }
160}