1 19 package org.fjank.jcache; 20 21 import java.io.FileInputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.lang.ref.ReferenceQueue ; 25 import java.net.InetAddress ; 26 import java.net.URL ; 27 import java.util.Enumeration ; 28 import java.util.HashMap ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.Properties ; 33 import java.util.Vector ; 34 import javax.util.jcache.Attributes; 35 import javax.util.jcache.CacheAttributes; 36 import javax.util.jcache.CacheException; 37 import javax.util.jcache.CacheLogger; 38 import javax.util.jcache.CacheNotAvailableException; 39 import javax.util.jcache.DiskCacheException; 40 import javax.util.jcache.NullObjectNameException; 41 import javax.util.jcache.ObjectExistsException; 42 import javax.util.jcache.RegionNotFoundException; 43 import org.fjank.jcache.distribution.DistributionEngine; 44 import org.fjank.jcache.persistence.DiskCache; 45 46 56 public final class CacheImpl implements javax.util.jcache.Cache { 57 private DistributionEngine distributionEngine; 58 59 private static CacheImpl _singleton; 60 61 private DiskCache diskCache; 62 63 private boolean ready; 64 65 private CacheAttributes attributes; 66 67 private float version; 68 69 private final Map userRegions = new HashMap (); 70 74 private final ReferenceQueue refQueue = new ReferenceQueue (); 75 79 84 private final JCacheExecutorPool execPool = new JCacheExecutorPool(); 85 86 89 private CacheImpl() { 90 } 91 92 104 public static synchronized CacheImpl getCache(final boolean init) { 105 if (_singleton == null) { 106 _singleton = new CacheImpl(); 107 if (init) { 108 _singleton.open(null); 109 } 110 } 111 return _singleton; 112 } 113 114 static CacheImpl getCache() { 115 return _singleton; 116 } 117 122 public CacheRegion getRegion() { 123 return CacheRegion.getRegion(); 124 } 125 126 133 public CacheRegion getRegion(final Object name) { 134 return (CacheRegion) this.userRegions.get(name); 135 } 136 137 147 void addRegion(final String name, final Attributes attributes) throws ObjectExistsException, NullObjectNameException { 148 if (name == null) { 149 throw new NullObjectNameException("A region cannot be created with null as its name."); 150 } 151 if ("".equals(name)) { 152 throw new NullObjectNameException("A region cannot be created with an empty string as its name."); 153 } 154 if (userRegions.containsKey(name)) { 155 throw new ObjectExistsException("The object " + name + " already exists in the cache."); 156 } 157 userRegions.put(name, new CacheRegion(name, new AttributesImpl(attributes))); 158 } 159 160 168 public void destroyRegion(final Object name) { 169 CacheRegion localRegion = (CacheRegion) userRegions.get(name); 170 userRegions.remove(localRegion.getName()); 171 localRegion.destroy(); 172 } 173 174 184 public void init(final CacheAttributes attributes) throws CacheNotAvailableException{ 185 synchronized (_singleton) { 186 if (!ready) { 187 this.attributes = attributes; 188 attributes.registerCache(this); 189 startServiceThreads(); 190 if (attributes.getDiskPath() != null) { 191 try { 192 diskCache = new DiskCache(attributes); 193 } catch (DiskCacheException e) { 194 throw new CacheNotAvailableException(e); 195 } 196 } 197 if (attributes.isDistributed()) { 198 distributionEngine = DistributionEngine.getInstance(this); 199 } 200 ready = true; 201 } 202 } 203 } 204 205 209 private void startServiceThreads() { 210 CacheSweeper.getInstance().startSweeper(); 212 } 213 214 218 private void stopServiceThreads() { 219 CacheSweeper.getInstance().stopSweeper(); 221 CacheSweeper.removeInstance(); 222 } 223 224 232 public void open() throws CacheNotAvailableException { 233 open(null); 234 } 235 236 245 private CacheLogger parseLogger(final String logger) throws CacheException { 246 try { 247 return (CacheLogger) Class.forName(logger).newInstance(); 248 } catch (ClassNotFoundException e) { 249 throw new CacheException("The CacheLogger " + logger + " could not be found."); 250 } catch (InstantiationException e) { 251 throw new CacheException("The CacheLogger " + logger + " could not be loaded."); 252 } catch (IllegalAccessException e) { 253 throw new CacheException("The CacheLogger " + logger + " is appearently not a CacheLogger."); 254 } 255 } 256 257 264 private int parseLogSeverity(final String logSeverity) { 265 try { 266 java.lang.reflect.Field [] fields = CacheLogger.class.getDeclaredFields(); 267 for (int i = 0; i < fields.length; i++) { 268 if (fields[i].getName().equals(logSeverity)) { 269 return fields[i].getInt(null); 270 } 271 } 272 } catch (IllegalAccessException e) { 273 ; 274 } 275 return CacheLogger.DEFAULT; 276 } 277 278 285 private java.util.List parseAddresses(final String addresses) { 286 java.util.ArrayList returnValue = new java.util.ArrayList (); 287 java.util.StringTokenizer tokenizer = new java.util.StringTokenizer (addresses, ","); 288 while (tokenizer.hasMoreTokens()) { 289 try { 290 returnValue.add(new java.net.URL ("http://" + tokenizer.nextToken())); 291 } catch (java.net.MalformedURLException e) { 292 e.printStackTrace(); 293 } 294 } 295 return returnValue; 296 } 297 298 307 public void open(final String configFile) { 308 InputStream in = null; 309 try { 310 synchronized (_singleton) { 311 if (!ready) { 312 Properties properties = new Properties (); 313 if (configFile == null) { 314 in = getClass().getClassLoader().getResourceAsStream("./jcache.properties"); 315 } else { 316 in = new FileInputStream (configFile); 317 } 318 if (in == null) { 319 properties = new Properties (); 320 } else { 321 properties.load(in); 322 in.close(); 323 } 324 boolean distribute = Boolean.valueOf(properties.getProperty("distribute", "false")).booleanValue(); 326 String logFileName = properties.getProperty("logFileName", "jcache.log"); 327 int cleanInterval = 30; 328 try { 329 cleanInterval = Integer.parseInt(properties.getProperty("cleanInterval", "30"), 10); 330 } catch (NumberFormatException e) { 331 } 332 int diskSize = 10; 333 try { 334 diskSize = Integer.parseInt(properties.getProperty("diskSize", "10"), 10); 335 } catch (NumberFormatException e) { 336 } 337 String diskPath = properties.getProperty("diskPath"); 338 float version = (float) 1.0; 339 try { 340 version = Float.parseFloat(properties.getProperty("version", "1.0")); 341 } catch (NumberFormatException e) { 342 } 343 int maxObjects = 5000; 344 try { 345 maxObjects = Integer.parseInt(properties.getProperty("maxObjects", "5000"), 10); 346 } catch (NumberFormatException e) { 347 } 348 int maxSize = -1; 349 try { 350 maxSize = Integer.parseInt(properties.getProperty("maxSize", "1"), 10); 351 } catch (NumberFormatException e) { 352 } 353 int logSeverity = parseLogSeverity(properties.getProperty("logSeverity", "DEFAULT")); 354 CacheLogger logger = new DefaultCacheLogger(); 355 try { 356 logger = parseLogger(properties.getProperty("logger", "org.fjank.jcache.DefaultCacheLogger")); 357 logger.setSeverity(logSeverity); 358 } catch (CacheException e) { 359 e.printStackTrace(); 361 } 362 List addresses = parseAddresses(properties.getProperty("discoveryAddress", "localhost:12345")); 363 CacheAttributes attributes = CacheAttributes.getDefaultCacheAttributes(); 365 if (!distribute) { 366 attributes.setLocal(); 367 } 368 attributes.setDefaultLogFileName(logFileName); 369 attributes.setCleanInterval(cleanInterval); 370 attributes.setDiskCacheSize(diskSize); 371 attributes.setDiskPath(diskPath); 372 attributes.setMaxObjects(maxObjects); 373 attributes.setMemoryCacheSize(maxSize); 374 this.version = version; 375 attributes.setLogger(logger); 376 Iterator iter = addresses.iterator(); 377 while (iter.hasNext()) { 378 URL url = (URL ) iter.next(); 379 attributes.addCacheAddr(InetAddress.getByName(url.getHost()), url.getPort()); 380 } 381 init(attributes); 382 } 383 } 384 } catch (IOException e) { 385 throw new IllegalStateException ("Error loading configuration from properties file. Caused by:" + e.getMessage()); 386 } catch (CacheNotAvailableException e) { 387 throw new IllegalStateException ("The cache was not available. "+e.getMessage()); 388 } finally { 389 if (in != null) { 390 try { 391 in.close(); 392 } catch (IOException e1) { 393 throw new IllegalStateException ("Failed to close stream to properties file. Caused by:" + e1.getMessage()); 394 } 395 } 396 } 397 } 398 399 406 public void close() { 407 synchronized (this) { 408 this.ready = false; 409 stopServiceThreads(); 410 if (diskCache != null) { 411 diskCache.close(); 412 } 413 } 414 } 415 416 423 public void flush() throws CacheException { 424 flushMemory(); 425 flushDisk(); 426 } 427 428 436 public void flushMemory() throws CacheException { 437 Iterator iter = userRegions.keySet().iterator(); 438 while (iter.hasNext()) { 439 Object name = iter.next(); 440 CacheRegion reg = (CacheRegion) userRegions.get(name); 441 reg.invalidate(); 442 } 443 CacheRegion.getRegion().invalidate(); 444 } 445 446 454 public void flushDisk() throws CacheException { 455 if (this.diskCache == null) { 456 return; 457 } 458 diskCache.removeAll(); 459 } 460 461 466 public float getVersion() { 467 return version; 468 } 469 470 477 public boolean isReady() { 478 return this.ready; 479 } 480 481 490 public boolean isDistributed() { 491 return this.attributes.isDistributed(); 492 } 493 494 505 public Enumeration listCacheObjects() { 506 Vector temp = new Vector (); 507 addNamedCacheObjects(temp, CacheRegion.getRegion()); 508 Iterator iter = userRegions.keySet().iterator(); 509 while (iter.hasNext()) { 510 addNamedCacheObjects(temp, (CacheRegion) userRegions.get(iter.next())); 511 } 512 return temp.elements(); 513 } 514 515 521 private void addNamedCacheObjects(final Vector vector, final CacheRegion region) { 522 recurseObjects(vector, region); 523 } 524 525 private void recurseObjects(final Vector vector, final CacheGroup group) { 526 Map objects = group.weakReferenceObjects; 527 Iterator iter = objects.keySet().iterator(); 528 while (iter.hasNext()) { 529 vector.add(new CacheObjectInfoImpl((CacheObject) objects.get(iter.next()))); 530 } 531 Map groups = group.getGroups(); 532 for (Iterator iterator = groups.keySet().iterator(); iterator.hasNext();) { 533 Object key = iterator.next(); 534 CacheGroup tmp = (CacheGroup) groups.get(key); 535 recurseObjects(vector, tmp); 536 } 537 } 538 539 555 public Enumeration listCacheObjects(final String region) throws RegionNotFoundException { 556 Vector temp = new Vector (); 557 if (region == null) { 558 throw new RegionNotFoundException("The regionName cannot be null."); 559 } 560 if (!userRegions.containsKey(region)) { 561 throw new RegionNotFoundException("The region " + region + " is not present in the cache."); 562 } 563 addNamedCacheObjects(temp, (CacheRegion) userRegions.get(region)); 564 return temp.elements(); 565 } 566 567 576 public CacheAttributes getAttributes(){ 577 return this.attributes; 578 } 579 580 587 public void setLogSeverity(final int severity) { 588 this.attributes.getLogger().setSeverity(severity); 589 } 590 591 596 public String toString() { 597 return "Fjanks FKache version " + getVersion() + " running in " + (isDistributed() ? "distributed" : "local") + " mode is " + (isReady() ? "" : "not ") 598 + "ready."; 599 } 600 601 606 DiskCache getDiskCache() { 607 return diskCache; 608 } 609 610 615 public ReferenceQueue getReferenceQueue() { 616 return refQueue; 617 } 618 619 622 public JCacheExecutorPool getExecPool() { 623 return execPool; 624 } 625 626 629 Iterator userRegionNames() { 630 return userRegions.keySet().iterator(); 631 } 632 public DistributionEngine getDistributionEngine() { 633 return distributionEngine; 634 } 635 } | Popular Tags |