1 package org.apache.turbine.services.cache; 2 3 18 19 import java.io.ByteArrayOutputStream ; 20 import java.io.IOException ; 21 import java.io.ObjectOutputStream ; 22 23 import java.util.Enumeration ; 24 import java.util.Hashtable ; 25 import java.util.Vector ; 26 27 import org.apache.commons.configuration.Configuration; 28 29 import org.apache.turbine.services.InitializationException; 30 import org.apache.turbine.services.TurbineBaseService; 31 32 64 public class TurbineGlobalCacheService 65 extends TurbineBaseService 66 implements GlobalCacheService, 67 Runnable 68 { 69 74 public static final int DEFAULT_INITIAL_CACHE_SIZE = 20; 75 76 79 public static final String INITIAL_CACHE_SIZE = "cache.initial.size"; 80 81 84 public static final String CACHE_CHECK_FREQUENCY = "cache.check.frequency"; 85 86 91 public static final long DEFAULT_CACHE_CHECK_FREQUENCY = 5000; 93 94 private Hashtable cache = null; 95 96 97 private long cacheCheckFrequency = DEFAULT_CACHE_CHECK_FREQUENCY; 98 99 102 public TurbineGlobalCacheService() 103 { 104 } 105 106 109 public void init() 110 throws InitializationException 111 { 112 int cacheInitialSize = DEFAULT_INITIAL_CACHE_SIZE; 113 Configuration conf = getConfiguration(); 114 if (conf != null) 115 { 116 try 117 { 118 cacheInitialSize = conf.getInt(INITIAL_CACHE_SIZE, DEFAULT_INITIAL_CACHE_SIZE); 119 if (cacheInitialSize <= 0) 120 { 121 throw new IllegalArgumentException (INITIAL_CACHE_SIZE + " must be >0"); 122 } 123 cacheCheckFrequency = conf.getLong(CACHE_CHECK_FREQUENCY, DEFAULT_CACHE_CHECK_FREQUENCY); 124 if (cacheCheckFrequency <= 0) 125 { 126 throw new IllegalArgumentException (CACHE_CHECK_FREQUENCY + " must be >0"); 127 } 128 } 129 catch (Exception x) 130 { 131 throw new InitializationException( 132 "Failed to initialize TurbineGlobalCacheService", x); 133 } 134 } 135 136 try 137 { 138 cache = new Hashtable (cacheInitialSize); 139 140 Thread housekeeping = new Thread (this); 142 housekeeping.setDaemon(true); 147 housekeeping.start(); 148 149 setInit(true); 150 } 151 catch (Exception e) 152 { 153 throw new InitializationException( 154 "TurbineGlobalCacheService failed to initialize", e); 155 } 156 } 157 158 167 public CachedObject getObject(String id) 168 throws ObjectExpiredException 169 { 170 CachedObject obj = null; 171 172 obj = (CachedObject) cache.get(id); 173 174 if (obj == null) 175 { 176 throw new ObjectExpiredException(); 178 } 179 180 if (obj.isStale()) 181 { 182 if (obj instanceof RefreshableCachedObject) 183 { 184 RefreshableCachedObject rco = (RefreshableCachedObject) obj; 185 if (rco.isUntouched()) 186 throw new ObjectExpiredException(); 188 rco.refresh(); 190 if (rco.isStale()) 191 throw new ObjectExpiredException(); 193 } 194 else 195 { 196 throw new ObjectExpiredException(); 198 } 199 } 200 201 if (obj instanceof RefreshableCachedObject) 202 { 203 RefreshableCachedObject rco = (RefreshableCachedObject) obj; 205 rco.touch(); 206 } 207 208 return obj; 209 } 210 211 217 public void addObject(String id, 218 CachedObject o) 219 { 220 if (cache.containsKey(id)) 223 { 224 cache.remove(id); 225 } 226 cache.put(id, o); 227 } 228 229 234 public void removeObject(String id) 235 { 236 cache.remove(id); 237 } 238 239 243 public void run() 244 { 245 while (true) 246 { 247 try 250 { 251 Thread.sleep(cacheCheckFrequency); 252 } 253 catch (InterruptedException exc) 254 { 255 } 256 257 clearCache(); 258 } 259 } 260 261 264 public void clearCache() 265 { 266 Vector refreshThese = new Vector (20); 267 synchronized (this) 270 { 271 for (Enumeration e = cache.keys(); e.hasMoreElements();) 272 { 273 String key = (String ) e.nextElement(); 274 CachedObject co = (CachedObject) cache.get(key); 275 if (co instanceof RefreshableCachedObject) 276 { 277 RefreshableCachedObject rco = (RefreshableCachedObject) co; 278 if (rco.isUntouched()) 279 cache.remove(key); 280 else if (rco.isStale()) 281 refreshThese.addElement(key); 284 } 285 else if (co.isStale()) 286 { 287 cache.remove(key); 288 } 289 } 290 } 291 292 for (Enumeration e = refreshThese.elements(); e.hasMoreElements();) 293 { 294 String key = (String ) e.nextElement(); 295 CachedObject co = (CachedObject) cache.get(key); 296 RefreshableCachedObject rco = (RefreshableCachedObject) co; 297 rco.refresh(); 298 } 299 } 300 301 306 public int getNumberOfObjects() 307 { 308 return cache.size(); 309 } 310 311 316 public int getCacheSize() 317 throws IOException 318 { 319 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 320 ObjectOutputStream out = new ObjectOutputStream (baos); 321 out.writeObject(cache); 322 out.flush(); 323 int objectsize = baos.toByteArray().length - 4; 329 return objectsize; 330 } 331 332 335 public void flushCache() 336 { 337 338 synchronized (this) 339 { 340 for (Enumeration e = cache.keys(); e.hasMoreElements();) 341 { 342 String key = (String ) e.nextElement(); 343 cache.remove(key); 344 } 345 } 346 } 347 } 348 | Popular Tags |