1 package org.jahia.services.cache.treecache; 2 3 import java.util.ArrayList ; 4 import java.util.Arrays ; 5 import java.util.HashMap ; 6 import java.util.HashSet ; 7 import java.util.List ; 8 import java.util.Set ; 9 10 import javax.transaction.SystemException ; 11 import javax.transaction.Transaction ; 12 import javax.transaction.TransactionManager ; 13 14 import org.apache.log4j.Logger; 15 import org.jahia.exceptions.JahiaInitializationException; 16 import org.jahia.services.cache.Cache; 17 import org.jahia.services.cache.CacheEntry; 18 import org.jahia.services.cache.CacheListener; 19 import org.jboss.cache.CacheException; 20 import org.jboss.cache.ConfigureException; 21 import org.jboss.cache.Fqn; 22 import org.jboss.cache.Node; 23 import org.jboss.cache.PropertyConfigurator; 24 import org.jboss.cache.TreeCache; 25 import org.jboss.cache.TreeCacheMBean; 26 import org.jboss.mx.util.MBeanProxyExt; 27 import org.jboss.mx.util.MBeanServerLocator; 28 29 public class JahiaTreeCache implements Cache { 30 31 private static final Logger logger = Logger.getLogger(JahiaTreeCache.class); 32 33 private static final String TX_CACHE = "jboss.cache:service=jahiaTxTreeCache"; 34 private static final String NON_TX_CACHE = "jboss.cache:service=jahiaNonTxTreeCache"; 35 36 private static final String [] clusteredCacheNames = {TX_CACHE, NON_TX_CACHE}; 37 38 private static TreeCache globalNonTxTreeCache = null; 39 private static TreeCache globalTxTreeCache = null; 40 41 private TreeCache treeCache = null; 42 43 private Fqn fqn; 44 45 private ArrayList listeners = null; 46 47 private static final Set nonTxCaches = new HashSet (Arrays 48 .asList(new String [] { "LockPrerequisitesResultMap", "LockCache" })); 49 50 61 protected JahiaTreeCache(final String aName, boolean propagatedMode) 62 throws JahiaInitializationException { 63 try { 64 init(aName, propagatedMode); 65 } catch (Exception e) { 66 throw new JahiaInitializationException("Cannot initialize cache: " 67 + aName, e); 68 } 69 } 70 71 82 private void init(String aName, boolean propagatedMode) throws Exception { 83 setTreeCache(getTreeCache(aName)); 84 setFqn(new Fqn(aName)); 85 TreeCache cache = getTreeCache(); 86 if (!cache.exists(aName)){ 87 cache.put(aName, new HashMap ()); 88 } 89 } 90 91 94 protected TreeCache getTreeCache() { 95 return treeCache; 96 } 97 98 102 private void setTreeCache(TreeCache aTreeCache) { 103 this.treeCache = aTreeCache; 104 } 105 106 public boolean containsKey(Object entryKey) { 107 boolean containsKey = false; 108 Node node = getTreeNode(); 109 if (node != null) { 110 containsKey = node.childExists(entryKey); 111 } 112 return containsKey; 113 } 114 115 public void flush() { 116 flush(true); 117 } 118 119 public void flush(boolean propagate) { 120 try { 121 if (!propagate) { 122 getTreeCache().evict(getFqn()); 123 } else { 124 getTreeCache().remove(getFqn()); 125 } 126 127 getTreeCache().put(getName(), new HashMap ()); 128 129 if (propagate) { 130 if ((listeners != null) && (listeners.size() > 0)) { 132 for (int i = 0; i < listeners.size(); i++) { 133 CacheListener listener = (CacheListener) listeners 134 .get(i); 135 if (listener != null) 136 listener.onCacheFlush(getName()); 137 } 138 } 139 } 140 } catch (Exception e) { 141 logger.warn(getName(), e); 142 } 143 } 144 145 public Object get(Object entryKey) { 146 Object result = null; 147 148 CacheEntry entry = getCacheEntry(entryKey); 149 if (entry != null) { 150 result = entry.getObject(); 151 } 152 153 return result; 154 } 155 156 protected Fqn getFqn() { 157 return fqn; 158 } 159 160 public String getName() { 161 return (String ) fqn.get(0); 162 } 163 164 public Object [] keys() { 165 Object [] keys = null; 166 try { 167 Set treeKeys = getTreeCache().getChildrenNames(getFqn()); 168 169 if (treeKeys != null) { 170 keys = treeKeys.toArray(); 171 } 172 } catch (CacheException e) { 173 logger.warn(getName(), e); 174 } 175 if (keys == null) { 176 keys = new Object [] {}; 177 } 178 179 return keys; 180 } 181 182 public void put(Object entryKey, Object entryObj) { 183 CacheEntry entry = new CacheEntry(entryObj); 184 putCacheEntry(entryKey, entry, true); 185 } 186 187 201 public synchronized void registerListener(CacheListener listener) { 202 if (listener == null) 203 return; 204 205 if (listeners == null) { 206 listeners = new ArrayList (); 207 208 } else if (listeners.contains(listener)) { 209 return; 210 } 211 212 listeners.add(listener); 213 getTreeCache().addTreeCacheListener( 214 new TreeCacheListenerWrapper(listener)); 215 } 216 217 231 public synchronized void unregisterListener(CacheListener listener) { 232 if ((listeners == null) || (listener == null)) 233 return; 234 235 listeners.remove(listener); 236 getTreeCache().removeTreeCacheListener( 237 new TreeCacheListenerWrapper(listener)); 238 } 239 240 public void remove(Object entryKey) { 241 try { 242 Fqn localFqn = null; 243 if (entryKey instanceof List ) { 244 List entryList = (List ) entryKey; 245 localFqn = new Fqn(getFqn(), entryList); 246 } else { 247 localFqn = new Fqn(getFqn(), entryKey); 248 } 249 250 TreeCache localTreeCache = getTreeCache(); 251 localTreeCache.remove(localFqn); 253 } catch (CacheException e) { 255 logger.warn(getName() + entryKey, e); 256 } 257 } 258 259 public int size() { 260 return getTreeCache().getNumberOfAttributes(getFqn()); 261 } 262 263 270 final public boolean isEmpty() { 271 return !getTreeCache().hasChild(getFqn()); 272 } 273 274 public CacheEntry getCacheEntry(Object entryKey) { 275 CacheEntry entry = null; 276 try { 277 if (entryKey instanceof List ) { 278 List entryList = (List ) entryKey; 279 entry = (CacheEntry) getTreeCache().get( 280 new Fqn(getFqn(), entryList), "entry"); 281 } else { 282 entry = (CacheEntry) getTreeCache().get( 283 new Fqn(getFqn(), entryKey), "entry"); 284 } 285 } catch (CacheException e) { 286 logger.warn(getName() + entryKey, e); 287 } 288 return entry; 289 } 290 291 public void putCacheEntry(Object entryKey, CacheEntry entry, 292 boolean propagate) { 293 try { 294 if (entryKey instanceof List ) { 295 List entryList = (List ) entryKey; 296 getTreeCache() 297 .put(new Fqn(getFqn(), entryList), "entry", entry); 298 } else { 299 getTreeCache().put(new Fqn(getFqn(), entryKey), "entry", entry); 300 } 301 } catch (Exception e) { 302 logger.warn(getName() + entryKey, e); 303 } 304 } 305 306 public int getCacheLimit() { 307 int cacheLimit = -1; 308 314 return cacheLimit; 315 } 316 317 public void setCacheLimit(int limit) { 318 320 } 321 322 public double getCacheEfficiency() { 323 return 0; 325 } 326 327 public long getSuccessHits() { 328 return 0; 330 } 331 332 public long getTotalHits() { 333 return 0; 335 } 336 337 protected TreeCache getTreeCache(String aName) throws Exception { 338 boolean isTxCache = isTxCache(aName); 339 340 treeCache = isTxCache ? getTxTreeCache() : getNonTxTreeCache(); 341 342 return treeCache; 343 } 344 345 349 private void setFqn(Fqn aFqn) { 350 this.fqn = aFqn; 351 } 352 353 private Node getTreeNode() { 354 Node treeNode = null; 355 try { 356 treeNode = getTreeCache().get(getFqn()); 357 } catch (CacheException e) { 358 logger.warn(getName(), e); 359 } 360 return treeNode; 361 } 362 363 public static void activateService() { 364 globalNonTxTreeCache = createAndActivateCache("jahia-cache-service.xml"); 365 globalTxTreeCache = createAndActivateCache("jahia-tx-cache-service.xml"); 366 } 367 368 private static TreeCache createAndActivateCache (String cacheConfigFileName) { 369 TreeCache currentCache = null; 370 try { 371 currentCache = new TreeCache(); 372 PropertyConfigurator config = new PropertyConfigurator(); 373 config.configure(currentCache, cacheConfigFileName); 374 currentCache.start(); 375 currentCache.registerClassLoader("", Thread.currentThread() 376 .getContextClassLoader()); 377 currentCache.activateRegion(""); 378 } catch (ConfigureException e) { 379 logger.error("Jahia Tree-Cache could not be started due to configuration errors", e); 380 } catch (Exception e) { 381 logger.error("Jahia Tree-Cache could not be started", e); 382 } 383 return currentCache; 384 } 385 386 public static void inactivateService(){ 387 try { 388 globalNonTxTreeCache.unregisterClassLoader(""); 389 globalNonTxTreeCache.inactivateRegion(""); 390 globalTxTreeCache.unregisterClassLoader(""); 391 globalTxTreeCache.inactivateRegion(""); 392 } catch (Exception e) { 393 logger.warn("Cannot inactivate cache service!", e); 394 } 395 396 } 397 398 public Transaction getCurrentTransaction() 399 { 400 Transaction trx = null; 401 TransactionManager trxManager = getTreeCache().getTransactionManager(); 402 if (trxManager != null) 403 { 404 try 405 { 406 trx = trxManager.getTransaction(); 407 } 408 catch (SystemException ex) 409 { 410 logger.warn("Unable to retrieve current transaction", ex); 411 } 412 } 413 414 return trx; 415 } 416 417 private boolean isTxCache (String aName) { 418 boolean isTxCache = !nonTxCaches.contains(aName); 419 420 return isTxCache; 421 } 422 425 private TreeCache getNonTxTreeCache() { 426 return globalNonTxTreeCache; 427 } 428 429 432 private TreeCache getTxTreeCache() { 433 return globalTxTreeCache; 434 } 435 } 436 | Popular Tags |