001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.cache.eh; 020 021import java.io.ByteArrayInputStream; 022import java.io.IOException; 023import java.io.OutputStream; 024import java.util.HashMap; 025import java.util.HashSet; 026import java.util.Iterator; 027import java.util.Map; 028import java.util.Map.Entry; 029import java.util.Set; 030 031import lucee.commons.io.CharsetUtil; 032import lucee.commons.io.cache.CacheEntry; 033import lucee.commons.io.cache.exp.CacheException; 034import lucee.commons.io.res.Resource; 035import lucee.commons.io.res.filter.ResourceNameFilter; 036import lucee.commons.lang.ExceptionUtil; 037import lucee.loader.util.Util; 038import lucee.runtime.config.Config; 039import lucee.runtime.engine.ThreadLocalPageContext; 040import lucee.runtime.exp.ApplicationException; 041import lucee.runtime.exp.PageRuntimeException; 042import lucee.runtime.type.Struct; 043import lucee.runtime.type.util.CollectionUtil; 044import net.sf.ehcache.Cache; 045import net.sf.ehcache.CacheManager; 046import net.sf.ehcache.Element; 047import net.sf.ehcache.config.Configuration; 048import net.sf.ehcache.config.ConfigurationFactory; 049 050public class EHCache extends EHCacheSupport { 051 052 private static final boolean DISK_PERSISTENT = true; 053 private static final boolean ETERNAL = false; 054 private static final int MAX_ELEMENTS_IN_MEMEORY = 10000; 055 private static final int MAX_ELEMENTS_ON_DISK = 10000000; 056 private static final String MEMORY_EVICTION_POLICY = "LRU"; 057 private static final boolean OVERFLOW_TO_DISK = true; 058 private static final long TIME_TO_IDLE_SECONDS = 86400; 059 private static final long TIME_TO_LIVE_SECONDS = 86400; 060 061 private static final boolean REPLICATE_PUTS = true; 062 private static final boolean REPLICATE_PUTS_VIA_COPY = true; 063 private static final boolean REPLICATE_UPDATES = true; 064 private static final boolean REPLICATE_UPDATES_VIA_COPY = true; 065 private static final boolean REPLICATE_REMOVALS = true; 066 private static final boolean REPLICATE_ASYNC = true; 067 private static final int ASYNC_REP_INTERVAL = 1000; 068 //private static Map managers=new HashMap(); 069 private static Map<String,CacheManagerAndHash> managers=new HashMap<String,CacheManagerAndHash>(); 070 071 //private net.sf.ehcache.Cache cache; 072 private int hits; 073 private int misses; 074 private String cacheName; 075 private CacheManager manager; 076 private ClassLoader classLoader; 077 078 079 public static void init(Config config,String[] cacheNames,Struct[] arguments) throws IOException { 080 System.setProperty("net.sf.ehcache.enableShutdownHook", "true"); 081 Thread.currentThread().setContextClassLoader(config.getClassLoader()); 082 083 Resource dir = config.getConfigDir().getRealResource("ehcache"),hashDir; 084 if(!dir.isDirectory())dir.createDirectory(true); 085 String[] hashArgs=createHash(arguments); 086 087 // create all xml 088 HashMap<String,String> mapXML = new HashMap<String,String>(); 089 HashMap<String,CacheManagerAndHash> newManagers = new HashMap<String,CacheManagerAndHash>(); 090 for(int i=0;i<hashArgs.length;i++){ 091 if(mapXML.containsKey(hashArgs[i])) continue; 092 093 hashDir=dir.getRealResource(hashArgs[i]); 094 String xml=createXML(hashDir.getAbsolutePath(), cacheNames,arguments,hashArgs,hashArgs[i]); 095 String hash=MD5.getDigestAsString(xml); 096 097 CacheManagerAndHash manager= managers.remove(hashArgs[i]); 098 if(manager!=null && manager.hash.equals(hash)) { 099 newManagers.put(hashArgs[i], manager); 100 } 101 else mapXML.put(hashArgs[i], xml); 102 } 103 104 // shutdown all existing managers that have changed 105 { 106 Iterator<Entry<String, CacheManagerAndHash>> it = managers.entrySet().iterator(); 107 Entry<String, CacheManagerAndHash> entry; 108 synchronized(managers){ 109 it = managers.entrySet().iterator(); 110 while(it.hasNext()){ 111 entry= it.next(); 112 if(entry.getKey().toString().startsWith(dir.getAbsolutePath())){ 113 entry.getValue().manager.shutdown(); 114 } 115 else newManagers.put(entry.getKey(), entry.getValue()); 116 117 } 118 managers=newManagers; 119 } 120 } 121 122 Iterator<Entry<String, String>> it = mapXML.entrySet().iterator(); 123 Entry<String, String> entry; 124 String xml,hashArg,hash; 125 while(it.hasNext()){ 126 entry = it.next(); 127 hashArg=entry.getKey(); 128 xml=entry.getValue(); 129 130 hashDir=dir.getRealResource(hashArg); 131 if(!hashDir.isDirectory())hashDir.createDirectory(true); 132 133 writeEHCacheXML(hashDir,xml); 134 hash=MD5.getDigestAsString(xml); 135 136 moveData(dir,hashArg,cacheNames,arguments); 137 //print.e(xml); 138 Configuration conf = ConfigurationFactory.parseConfiguration(new ByteArrayInputStream(xml.getBytes(CharsetUtil.UTF8))); 139 conf.setName("ehcache_"+config.getId()); 140 CacheManagerAndHash m = new CacheManagerAndHash(CacheManager.newInstance(conf),hash); 141 newManagers.put(hashDir.getAbsolutePath(), m); 142 } 143 144 clean(dir); 145 } 146 147 public static void flushAllCaches() { 148 String[] names; 149 Iterator<Entry<String, CacheManagerAndHash>> it = managers.entrySet().iterator(); 150 Entry<String, CacheManagerAndHash> entry; 151 while(it.hasNext()){ 152 entry = it.next(); 153 CacheManager manager=entry.getValue().manager; 154 names = manager.getCacheNames(); 155 for(int i=0;i<names.length;i++){ 156 manager.getCache(names[i]).flush(); 157 } 158 } 159 } 160 161 private static void clean(Resource dir) { 162 Resource[] dirs = dir.listResources(); 163 Resource[] children; 164 165 for(int i=0;i<dirs.length;i++){ 166 if(dirs[i].isDirectory()){ 167 //print.out(dirs[i]+":"+pathes.contains(dirs[i].getAbsolutePath())); 168 children=dirs[i].listResources(); 169 if(children!=null && children.length>1)continue; 170 clean(children); 171 dirs[i].delete(); 172 } 173 } 174 } 175 176 private static void clean(Resource[] arr) { 177 if(arr!=null)for(int i=0;i<arr.length;i++){ 178 if(arr[i].isDirectory()){ 179 clean(arr[i].listResources()); 180 } 181 arr[i].delete(); 182 } 183 } 184 185 private static void moveData(Resource dir, String hash, String[] cacheNames, Struct[] arguments) { 186 String h; 187 Resource trg = dir.getRealResource(hash); 188 deleteData(dir, cacheNames); 189 for(int i=0;i<cacheNames.length;i++){ 190 h=createHash(arguments[i]); 191 if(h.equals(hash)){ 192 moveData(dir,cacheNames[i],trg); 193 } 194 } 195 196 } 197 198 private static void moveData(Resource dir, String cacheName, Resource trg) { 199 Resource[] dirs = dir.listResources(); 200 Resource index,data; 201 // move 202 for(int i=0;i<dirs.length;i++){ 203 if(!dirs[i].equals(trg) && 204 dirs[i].isDirectory() && 205 (data=dirs[i].getRealResource(cacheName+".data")).exists() && 206 (index=dirs[i].getRealResource(cacheName+".index")).exists() ){ 207 208 try { 209 index.moveTo(trg.getRealResource(cacheName+".index")); 210 data.moveTo(trg.getRealResource(cacheName+".data")); 211 } catch (IOException e) { 212 e.printStackTrace(); 213 } 214 } 215 } 216 } 217 218 private static void deleteData(Resource dir, String[] cacheNames) { 219 Set<String> names=new HashSet<String>(); 220 for(int i=0;i<cacheNames.length;i++){ 221 names.add(cacheNames[i]); 222 } 223 224 Resource[] dirs = dir.listResources(); 225 String name; 226 // move 227 for(int i=0;i<dirs.length;i++){ 228 if(dirs[i].isDirectory()){ 229 Resource[] datas = dirs[i].listResources(new DataFiter()); 230 if(datas!=null) for(int y=0;y<datas.length;y++){ 231 name=datas[y].getName(); 232 name=name.substring(0,name.length()-5); 233 if(!names.contains(name)){ 234 datas[y].delete(); 235 dirs[i].getRealResource(name+".index").delete(); 236 } 237 238 } 239 } 240 } 241 } 242 243 private static void writeEHCacheXML(Resource hashDir, String xml) { 244 ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes(CharsetUtil.UTF8)); 245 OutputStream os=null; 246 try{ 247 os = hashDir.getRealResource("ehcache.xml").getOutputStream(); 248 Util.copy(is, os); 249 } 250 catch(IOException ioe){ioe.printStackTrace();} 251 finally{ 252 Util.closeEL(os); 253 } 254 } 255 256 private static String createHash(Struct args) { 257 258 String dist = args.get("distributed","").toString().trim().toLowerCase(); 259 try { 260 if(dist.equals("off")){ 261 return MD5.getDigestAsString(dist); 262 } 263 else if(dist.equals("automatic")){ 264 return MD5.getDigestAsString( 265 dist+ 266 args.get("automatic_timeToLive","").toString().trim().toLowerCase()+ 267 args.get("automatic_addional","").toString().trim().toLowerCase()+ 268 args.get("automatic_multicastGroupPort","").toString().trim().toLowerCase()+ 269 args.get("automatic_multicastGroupAddress","").toString().trim().toLowerCase()+ 270 args.get("automatic_hostName","").toString().trim().toLowerCase() 271 ); 272 } 273 else { 274 return MD5.getDigestAsString( 275 dist+ 276 args.get("manual_rmiUrls","").toString().trim().toLowerCase()+ 277 args.get("manual_addional","").toString().trim().toLowerCase()+ 278 args.get("listener_hostName","").toString().trim().toLowerCase()+ 279 args.get("listener_port","").toString().trim().toLowerCase()+ 280 args.get("listener_remoteObjectPort","").toString().trim().toLowerCase()+ 281 args.get("listener_socketTimeoutMillis","120000").toString().trim().toLowerCase() 282 ); 283 } 284 285 } catch (IOException e) { 286 e.printStackTrace(); 287 return ""; 288 } 289 } 290 private static String[] createHash(Struct[] arguments) { 291 String[] hashes=new String[arguments.length]; 292 for(int i=0;i<arguments.length;i++){ 293 hashes[i]=createHash(arguments[i]); 294 } 295 return hashes; 296 } 297 298 private static String createXML(String path, String[] cacheNames,Struct[] arguments, String[] hashes, String hash) { 299 boolean isDistributed=false; 300 301 //Cast caster = CFMLEngineFactory.getInstance().getCastUtil(); 302 Struct global=null; 303 for(int i=0;i<hashes.length;i++){ 304 if(hash.equals(hashes[i])){ 305 global=arguments[i]; 306 break; 307 } 308 } 309 310 311 StringBuilder xml=new StringBuilder(); 312 xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 313 xml.append("<ehcache xsi:noNamespaceSchemaLocation=\"ehcache.xsd\">\n"); 314 315 // disk storage 316 xml.append("<diskStore path=\""); 317 xml.append(path); 318 xml.append("\"/>\n"); 319 xml.append("<cacheManagerEventListenerFactory class=\"\" properties=\"\"/>\n"); 320 321 322 // RMI 323 // Automatic 324 if(global!=null && global.get("distributed","").equals("automatic")){ 325 // provider 326 isDistributed=true; 327 xml.append("<cacheManagerPeerProviderFactory \n"); 328 xml.append(" class=\"net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory\"\n "); 329 String add = global.get("automatic_addional","").toString().trim(); 330 String hostName=global.get("automatic_hostName","").toString().trim().toLowerCase(); 331 if(!Util.isEmpty(hostName)) add+=",hostName="+hostName; 332 if(!Util.isEmpty(add) && !add.startsWith(","))add=","+add; 333 add=add.replace('\n', ' '); 334 xml.append(" properties=\"peerDiscovery=automatic" + 335 ", multicastGroupAddress="+global.get("automatic_multicastGroupAddress","").toString().trim().toLowerCase()+ 336 ", multicastGroupPort="+global.get("automatic_multicastGroupPort","").toString().trim().toLowerCase()+ 337 ", timeToLive="+toTimeToLive(global.get("automatic_timeToLive","").toString().trim().toLowerCase())+ 338 add+" \" />\n"); 339 340 //hostName=fully_qualified_hostname_or_ip, 341 342 // listener 343 xml.append("<cacheManagerPeerListenerFactory class=\"net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory\"/>\n"); 344 345 } 346 // Manual 347 else if(global!=null && global.get("distributed","").equals("manual")){ 348 // provider 349 isDistributed=true; 350 xml.append("<cacheManagerPeerProviderFactory"); 351 xml.append(" class=\"net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory\" "); 352 String add = global.get("manual_addional","").toString().trim(); 353 if(!Util.isEmpty(add) && !add.startsWith(","))add=","+add; 354 add=add.replace('\n', ' '); 355 xml.append(" properties=\"peerDiscovery=manual, rmiUrls="+global.get("manual_rmiUrls","").toString().trim().toLowerCase().replace('\n', ' ')+ 356 add+"\"/>\n"); //propertySeparator=\",\" 357 358 // listener 359 StringBuilder sb=new StringBuilder(); 360 361 String hostName=global.get("listener_hostName","").toString().trim().toLowerCase(); 362 if(!Util.isEmpty(hostName)) add(sb,"hostName="+hostName); 363 String port = global.get("listener_port","").toString().trim().toLowerCase(); 364 if(!Util.isEmpty(port)) add(sb,"port="+port); 365 String remoteObjectPort = global.get("listener_remoteObjectPort","").toString().trim().toLowerCase(); 366 if(!Util.isEmpty(remoteObjectPort)) add(sb,"remoteObjectPort="+remoteObjectPort); 367 String socketTimeoutMillis = global.get("listener_socketTimeoutMillis","").toString().trim().toLowerCase(); 368 if(!Util.isEmpty(socketTimeoutMillis) && !"120000".equals(socketTimeoutMillis)) 369 add(sb,"socketTimeoutMillis="+socketTimeoutMillis); 370 371 xml.append("<cacheManagerPeerListenerFactory"); 372 xml.append(" class=\"net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory\""); 373 if(sb.length()>0)xml.append(" properties=\""+sb+"\""); 374 xml.append("/>\n"); 375 376 377 } 378 379 380 381 if(isDistributed){ 382 } 383 384 385 386 387 388 xml.append("<defaultCache \n"); 389 xml.append(" diskPersistent=\"true\"\n"); 390 xml.append(" eternal=\"false\"\n"); 391 xml.append(" maxElementsInMemory=\"10000\"\n"); 392 xml.append(" maxElementsOnDisk=\"10000000\"\n"); 393 xml.append(" memoryStoreEvictionPolicy=\"LRU\"\n"); 394 xml.append(" timeToIdleSeconds=\"86400\"\n"); 395 xml.append(" timeToLiveSeconds=\"86400\"\n"); 396 xml.append(" overflowToDisk=\"true\"\n"); 397 xml.append(" diskSpoolBufferSizeMB=\"30\"\n"); 398 xml.append(" diskExpiryThreadIntervalSeconds=\"3600\"\n"); 399 xml.append(" />\n"); 400 401 // cache 402 for(int i=0;i<cacheNames.length && i<arguments.length;i++){ 403 if(hashes[i].equals(hash))createCacheXml(xml,cacheNames[i],arguments[i],isDistributed); 404 } 405 406 407 xml.append("</ehcache>\n"); 408 return xml.toString(); 409 } 410 411 412 413 private static void add(StringBuilder sb,String str) { 414 if(sb.length()>0)sb.append(", "); 415 sb.append(str); 416 } 417 418 private static int toTimeToLive(String str) { 419 if(str.indexOf("host")!=-1) return 0; 420 if(str.indexOf("site")!=-1) return 1; 421 if(str.indexOf("region")!=-1) return 64; 422 if(str.indexOf("continent")!=-1) return 128; 423 return 255; 424 } 425 426 private static void createCacheXml(StringBuilder xml, String cacheName, Struct arguments, boolean isDistributed) { 427 428 // disk Persistent 429 boolean diskPersistent=toBooleanValue(arguments.get("diskpersistent",Boolean.FALSE),DISK_PERSISTENT); 430 431 // eternal 432 boolean eternal=toBooleanValue(arguments.get("eternal",Boolean.FALSE),ETERNAL); 433 434 // max elements in memory 435 int maxElementsInMemory=toIntValue(arguments.get("maxelementsinmemory",new Integer(MAX_ELEMENTS_IN_MEMEORY)),MAX_ELEMENTS_IN_MEMEORY); 436 437 // max elements on disk 438 int maxElementsOnDisk=toIntValue(arguments.get("maxelementsondisk",new Integer(MAX_ELEMENTS_ON_DISK)),MAX_ELEMENTS_ON_DISK); 439 440 // memory eviction policy 441 String strPolicy=toString(arguments.get("memoryevictionpolicy",MEMORY_EVICTION_POLICY),MEMORY_EVICTION_POLICY); 442 String policy = "LRU"; 443 if("FIFO".equalsIgnoreCase(strPolicy)) policy="FIFO"; 444 else if("LFU".equalsIgnoreCase(strPolicy)) policy="LFU"; 445 446 // overflow to disk 447 boolean overflowToDisk=toBooleanValue(arguments.get("overflowtodisk",Boolean.FALSE),OVERFLOW_TO_DISK); 448 449 // time to idle seconds 450 long timeToIdleSeconds=toLongValue(arguments.get("timeToIdleSeconds",new Long(TIME_TO_IDLE_SECONDS)),TIME_TO_IDLE_SECONDS); 451 452 // time to live seconds 453 long timeToLiveSeconds=toLongValue(arguments.get("timeToLiveSeconds",new Long(TIME_TO_LIVE_SECONDS)),TIME_TO_LIVE_SECONDS); 454 455 // REPLICATION 456 boolean replicatePuts=toBooleanValue(arguments.get("replicatePuts",Boolean.FALSE),REPLICATE_PUTS); 457 boolean replicatePutsViaCopy=toBooleanValue(arguments.get("replicatePutsViaCopy",Boolean.FALSE),REPLICATE_PUTS_VIA_COPY); 458 boolean replicateUpdates=toBooleanValue(arguments.get("replicateUpdates",Boolean.FALSE),REPLICATE_UPDATES); 459 boolean replicateUpdatesViaCopy=toBooleanValue(arguments.get("replicateUpdatesViaCopy",Boolean.FALSE),REPLICATE_UPDATES_VIA_COPY); 460 boolean replicateRemovals=toBooleanValue(arguments.get("replicateRemovals",Boolean.FALSE),REPLICATE_REMOVALS); 461 boolean replicateAsynchronously=toBooleanValue(arguments.get("replicateAsynchronously",Boolean.FALSE),REPLICATE_ASYNC); 462 int asynchronousReplicationInterval=toIntValue(arguments.get("asynchronousReplicationIntervalMillis",new Integer(ASYNC_REP_INTERVAL)),ASYNC_REP_INTERVAL); 463 464 465 466 xml.append("<cache name=\""+cacheName+"\"\n"); 467 xml.append(" diskPersistent=\""+diskPersistent+"\"\n"); 468 xml.append(" eternal=\""+eternal+"\"\n"); 469 xml.append(" maxElementsInMemory=\""+maxElementsInMemory+"\"\n"); 470 xml.append(" maxElementsOnDisk=\""+maxElementsOnDisk+"\"\n"); 471 xml.append(" memoryStoreEvictionPolicy=\""+policy+"\"\n"); 472 xml.append(" timeToIdleSeconds=\""+timeToIdleSeconds+"\"\n"); 473 xml.append(" timeToLiveSeconds=\""+timeToLiveSeconds+"\"\n"); 474 xml.append(" overflowToDisk=\""+overflowToDisk+"\""); 475 xml.append(">\n"); 476 if(isDistributed){ 477 xml.append(" <cacheEventListenerFactory \n"); 478 //xml.append(" class=\"net.sf.ehcache.distribution.RMICacheReplicatorFactory\" "); 479 xml.append(" class=\""+LuceeRMICacheReplicatorFactory.class.getName()+"\" \n"); 480 481 xml.append(" properties=\"replicateAsynchronously="+replicateAsynchronously+ 482 ", asynchronousReplicationIntervalMillis="+asynchronousReplicationInterval+ 483 ", replicatePuts="+replicatePuts+ 484 ", replicatePutsViaCopy="+replicatePutsViaCopy+ 485 ", replicateUpdates="+replicateUpdates+ 486 ", replicateUpdatesViaCopy="+replicateUpdatesViaCopy+ 487 ", replicateRemovals="+replicateRemovals+" \""); 488 xml.append("/>\n"); 489 490 491 // BootStrap 492 if(toBooleanValue(arguments.get("bootstrapType","false"),false)){ 493 xml.append("<bootstrapCacheLoaderFactory \n"); 494 xml.append(" class=\"net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory\" \n"); 495 xml.append(" properties=\"bootstrapAsynchronously="+toBooleanValue(arguments.get("bootstrapAsynchronously","true"),true)+ 496 ", maximumChunkSizeBytes="+toLongValue(arguments.get("maximumChunkSizeBytes","5000000"),5000000L)+"\" \n"); 497 xml.append(" propertySeparator=\",\" /> \n"); 498 } 499 500 501 } 502 xml.append(" </cache>\n"); 503 504 505 } 506 507 508 509 public void init(String cacheName, Struct arguments) { 510 init(ThreadLocalPageContext.getConfig(),cacheName, arguments); 511 512 } 513 @Override 514 public void init(Config config,String cacheName, Struct arguments) { 515 this.classLoader=config.getClassLoader(); 516 this.cacheName=cacheName; 517 518 setClassLoader(); 519 Resource hashDir = config.getConfigDir().getRealResource("ehcache").getRealResource(createHash(arguments)); 520 manager =managers.get(hashDir.getAbsolutePath()).manager; 521 } 522 523 private void setClassLoader() { 524 if(classLoader!=Thread.currentThread().getContextClassLoader()) 525 Thread.currentThread().setContextClassLoader(classLoader); 526 } 527 528 protected net.sf.ehcache.Cache getCache() { 529 setClassLoader(); 530 Cache c = manager.getCache(cacheName); 531 if(c==null) 532 throw new PageRuntimeException(new ApplicationException(ExceptionUtil.similarKeyMessage(CollectionUtil.toKeys(manager.getCacheNames(),false), cacheName, "cache name", "caches", true))); 533 return c; 534 } 535 536 @Override 537 public boolean remove(String key) { 538 try { 539 return getCache().remove(key); 540 } 541 catch(Throwable t){ 542 ExceptionUtil.rethrowIfNecessary(t); 543 return false; 544 } 545 } 546 547 public CacheEntry getCacheEntry(String key) throws CacheException { 548 try { 549 misses++; 550 Element el = getCache().get(key); 551 if(el==null)throw new CacheException("there is no entry in cache with key ["+key+"]"); 552 hits++; 553 misses--; 554 return new EHCacheEntry(el); 555 } 556 catch(IllegalStateException ise) { 557 throw new CacheException(ise.getMessage()); 558 } 559 catch(net.sf.ehcache.CacheException ce) { 560 throw new CacheException(ce.getMessage()); 561 } 562 } 563 564 public CacheEntry getCacheEntry(String key, CacheEntry defaultValue) { 565 try { 566 Element el = getCache().get(key); 567 if(el!=null){ 568 hits++; 569 return new EHCacheEntry(el); 570 } 571 } 572 catch(Throwable t) { 573 ExceptionUtil.rethrowIfNecessary(t); 574 misses++; 575 } 576 return defaultValue; 577 } 578 579 @Override 580 public Object getValue(String key) throws CacheException { 581 try { 582 misses++; 583 Element el = getCache().get(key); 584 if(el==null)throw new CacheException("there is no entry in cache with key ["+key+"]"); 585 misses--; 586 hits++; 587 return el.getObjectValue(); 588 } 589 catch(IllegalStateException ise) { 590 throw new CacheException(ise.getMessage()); 591 } 592 catch(net.sf.ehcache.CacheException ce) { 593 throw new CacheException(ce.getMessage()); 594 } 595 } 596 597 @Override 598 public Object getValue(String key, Object defaultValue) { 599 try { 600 Element el = getCache().get(key); 601 if(el!=null){ 602 hits++; 603 return el.getObjectValue(); 604 } 605 } 606 catch(Throwable t) { 607 ExceptionUtil.rethrowIfNecessary(t); 608 misses++; 609 } 610 return defaultValue; 611 } 612 613 @Override 614 public long hitCount() { 615 return hits; 616 } 617 618 @Override 619 public long missCount() { 620 return misses; 621 } 622 623 public void remove() { 624 setClassLoader(); 625 CacheManager singletonManager = CacheManager.getInstance(); 626 if(singletonManager.cacheExists(cacheName)) 627 singletonManager.removeCache(cacheName); 628 629 } 630 631 632 633 634 private static boolean toBooleanValue(Object o, boolean defaultValue) { 635 if(o instanceof Boolean) return ((Boolean)o).booleanValue(); 636 else if(o instanceof Number) return (((Number)o).doubleValue())!=0; 637 else if(o instanceof String) { 638 String str = o.toString().trim().toLowerCase(); 639 if(str.equals("yes") || str.equals("on") || str.equals("true")) return true; 640 else if(str.equals("no") || str.equals("false") || str.equals("off")) return false; 641 } 642 return defaultValue; 643 } 644 645 private static String toString(Object o, String defaultValue) { 646 if(o instanceof String)return o.toString(); 647 return defaultValue; 648 } 649 650 private static int toIntValue(Object o, int defaultValue) { 651 if(o instanceof Number) return ((Number)o).intValue(); 652 try{ 653 return Integer.parseInt(o.toString()); 654 } 655 catch(Throwable t){ 656 ExceptionUtil.rethrowIfNecessary(t); 657 return defaultValue; 658 } 659 } 660 661 private static long toLongValue(Object o, long defaultValue) { 662 if(o instanceof Number) return ((Number)o).longValue(); 663 try{ 664 return Long.parseLong(o.toString()); 665 } 666 catch(Throwable t){ 667 ExceptionUtil.rethrowIfNecessary(t); 668 return defaultValue; 669 } 670 } 671 672 @Override 673 public int clear() throws IOException { 674 int size=getCache().getSize(); 675 getCache().removeAll(); 676 return size; 677 } 678 679 680}class CacheManagerAndHash { 681 682 CacheManager manager; 683 String hash; 684 685 public CacheManagerAndHash(CacheManager manager, String hash) { 686 this.manager=manager; 687 688 this.hash=hash; 689 } 690 691 } 692 693class DataFiter implements ResourceNameFilter { 694 695 @Override 696 public boolean accept(Resource parent, String name) { 697 return name.endsWith(".data"); 698 } 699 700}