1 package org.jboss.cache.interceptors; 2 3 import org.jboss.cache.Fqn; 4 import org.jboss.cache.GlobalTransaction; 5 import org.jboss.cache.Modification; 6 import org.jboss.cache.NodeSPI; 7 import org.jboss.cache.TransactionEntry; 8 import org.jboss.cache.TransactionTable; 9 import org.jboss.cache.marshall.MethodCall; 10 import org.jboss.cache.marshall.MethodDeclarations; 11 12 import javax.transaction.TransactionManager ; 13 import java.lang.reflect.Method ; 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 import java.util.Set ; 20 import java.util.concurrent.ConcurrentHashMap ; 21 22 30 public class ActivationInterceptor extends CacheLoaderInterceptor implements ActivationInterceptorMBean 31 { 32 33 protected TransactionManager tx_mgr = null; 34 protected TransactionTable tx_table = null; 35 private HashMap m_txActivations = new HashMap (); 36 private long m_activations = 0; 37 38 41 protected ConcurrentHashMap transactions = new ConcurrentHashMap (16); 42 protected static final Object NULL = new Object (); 43 44 public ActivationInterceptor() 45 { 46 this.useCacheStore = false; 47 isActivation = true; 48 } 49 50 58 public Object invoke(MethodCall m) throws Throwable 59 { 60 61 Fqn fqn = null; 62 Object [] args = m.getArgs(); 63 Object retval; 64 65 retval = super.invoke(m); 67 68 boolean removeData = false, nodeRemoved = false; 70 71 if (tx_mgr != null && tx_mgr.getTransaction() != null) 73 { 74 GlobalTransaction gtx = cache.getInvocationContext().getGlobalTransaction(); 75 switch (m.getMethodId()) 76 { 77 case MethodDeclarations.commitMethod_id: 78 if (hasModifications(args)) 79 { 80 loader.commit(gtx); 81 if (configuration.getExposeManagementStatistics() && getStatisticsEnabled()) 82 { 83 Integer acts = (Integer ) m_txActivations.get(gtx); 84 if (acts != null) 85 { 86 m_activations = m_activations + acts; 87 } 88 m_txActivations.remove(gtx); 89 } 90 } 91 break; 92 case MethodDeclarations.rollbackMethod_id: 93 if (hasModifications(args)) 94 { 95 loader.rollback(gtx); 96 if (configuration.getExposeManagementStatistics() && getStatisticsEnabled()) 97 { 98 m_txActivations.remove(gtx); 99 } 100 } 101 break; 102 case MethodDeclarations.optimisticPrepareMethod_id: 103 case MethodDeclarations.prepareMethod_id: 104 prepareCacheLoader(gtx); 105 break; 106 } 107 } 108 109 111 switch (m.getMethodId()) 114 { 115 case MethodDeclarations.putDataMethodLocal_id: 116 case MethodDeclarations.putDataEraseMethodLocal_id: 117 case MethodDeclarations.putKeyValMethodLocal_id: 118 case MethodDeclarations.removeKeyMethodLocal_id: 119 case MethodDeclarations.addChildMethodLocal_id: 120 fqn = (Fqn) args[1]; 121 break; 122 case MethodDeclarations.getKeyValueMethodLocal_id: 123 case MethodDeclarations.getNodeMethodLocal_id: 124 case MethodDeclarations.getKeysMethodLocal_id: 125 case MethodDeclarations.getChildrenNamesMethodLocal_id: 126 case MethodDeclarations.releaseAllLocksMethodLocal_id: 127 case MethodDeclarations.printMethodLocal_id: 128 fqn = (Fqn) args[0]; 129 break; 130 case MethodDeclarations.removeNodeMethodLocal_id: 131 nodeRemoved = true; 132 fqn = (Fqn) args[1]; 133 break; 134 case MethodDeclarations.removeDataMethodLocal_id: 135 removeData = true; 136 fqn = (Fqn) args[1]; 137 break; 138 } 139 140 synchronized (this) 141 { 142 if (fqn != null) 143 { 144 if (nodeRemoved) 145 { 146 log.trace("This is a remove operation; removing the node from the loader, no activation processing needed."); 147 loader.remove(fqn); 148 } 149 else if (removeData) 150 { 151 log.trace("This is a remove data operation; removing the data from the loader, no activation processing needed."); 152 loader.removeData(fqn); 153 } 154 else if (cache.getRoot().hasChild(fqn) && loader.exists(fqn)) 155 { 156 NodeSPI n = getNode(fqn); if (n != null && n.getDataLoaded()) 163 { 164 if (!n.getChildrenDirect().isEmpty()) 165 { 166 if (allInitialized(n)) 167 { 168 log.debug("children all initialized"); 169 remove(fqn); 170 } 171 } 172 else if (loaderNoChildren(fqn)) 173 { 174 log.debug("no children " + n); 175 remove(fqn); 176 } 177 } 178 } 179 } 180 } 181 return retval; 182 } 183 184 private void remove(Fqn fqn) throws Exception 185 { 186 cache.getNotifier().notifyNodeActivated(fqn, true, true); 187 loader.remove(fqn); 188 if (configuration.getExposeManagementStatistics() && getStatisticsEnabled()) 189 { 190 m_activations++; 191 } 192 } 193 194 197 private boolean allInitialized(NodeSPI n) 198 { 199 if (!n.getChildrenLoaded()) 200 { 201 return false; 202 } 203 204 for (NodeSPI child : n.getChildrenDirect()) 205 { 206 if (!child.getDataLoaded()) 207 { 208 return false; 209 } 210 } 211 return true; 212 } 213 214 218 private boolean loaderNoChildren(Fqn fqn) 219 { 220 try 221 { 222 Set children_names = loader.getChildrenNames(fqn); 223 return (children_names == null); 224 } 225 catch (Exception e) 226 { 227 log.error("failed getting the children names for " + fqn + " from the cache loader", e); 228 return false; 229 } 230 } 231 232 public long getActivations() 233 { 234 return m_activations; 235 } 236 237 public void resetStatistics() 238 { 239 super.resetStatistics(); 240 m_activations = 0; 241 } 242 243 public Map <String , Object > dumpStatistics() 244 { 245 Map <String , Object > retval = super.dumpStatistics(); 246 if (retval == null) 247 { 248 retval = new HashMap <String , Object >(); 249 } 250 retval.put("Activations", m_activations); 251 return retval; 252 } 253 254 protected boolean hasModifications(Object [] args) 255 { 256 int hint = 1; 257 if (args[hint] instanceof Boolean ) return (Boolean ) args[hint]; 258 for (int i = 0; i < args.length; i++) 259 { 260 if (args[i] instanceof Boolean ) return (Boolean ) args[i]; 261 } 262 return false; 263 } 264 265 private void prepareCacheLoader(GlobalTransaction gtx) throws Exception 266 { 267 List modifications; 268 TransactionEntry entry; 269 int txActs = 0; 270 271 entry = tx_table.get(gtx); 272 if (entry == null) 273 { 274 throw new Exception ("entry for transaction " + gtx + " not found in transaction table"); 275 } 276 modifications = entry.getCacheLoaderModifications(); 277 if (modifications.size() == 0) 278 { 279 return; 280 } 281 List cache_loader_modifications = new ArrayList (); 282 for (Iterator it = modifications.iterator(); it.hasNext();) 283 { 284 MethodCall methodCall = (MethodCall) it.next(); 285 Method method = methodCall.getMethod(); 286 Object [] args; 287 if (method == null) 288 { 289 throw new Exception ("method call has no method: " + methodCall); 290 } 291 args = methodCall.getArgs(); 292 switch (methodCall.getMethodId()) 293 { 294 case MethodDeclarations.removeNodeMethodLocal_id: 295 Modification mod = new Modification(Modification.ModificationType.REMOVE_NODE, (Fqn) args[1]); 297 cache_loader_modifications.add(mod); 298 break; 299 case MethodDeclarations.putDataMethodLocal_id: 300 case MethodDeclarations.putDataEraseMethodLocal_id: 301 case MethodDeclarations.putKeyValMethodLocal_id: 302 Fqn fqn = (Fqn) args[1]; 308 if (fqn != null && cache.getRoot().hasChild(fqn) && loader.exists(fqn)) 309 { 310 NodeSPI n = getNode(fqn); if (n != null && n.getDataLoaded()) 313 { 314 if (!n.getChildrenDirect().isEmpty() && allInitialized(n)) 316 { 317 addRemoveMod(cache_loader_modifications, fqn); 319 txActs++; 320 } 321 else if (loaderNoChildren(fqn)) 323 { 324 addRemoveMod(cache_loader_modifications, fqn); 325 txActs++; 326 } 327 } 328 } 329 break; 330 } 331 } 332 if (cache_loader_modifications.size() > 0) 333 { 334 loader.prepare(gtx, cache_loader_modifications, false); 335 if (configuration.getExposeManagementStatistics() && getStatisticsEnabled() && txActs > 0) 336 { 337 m_txActivations.put(gtx, txActs); 338 } 339 } 340 } 341 342 private void addRemoveMod(List l, Fqn fqn) 343 { 344 Modification mod = new Modification(Modification.ModificationType.REMOVE_NODE, fqn); 345 l.add(mod); 346 cache.getNotifier().notifyNodeActivated(fqn, false, true); 347 } 348 349 } 350 | Popular Tags |