Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 379   Methods: 16
NCLOC: 289   Classes: 10
 
 Source file Conditionals Statements Methods TOTAL
EvictionInterceptor.java 66.1% 86.7% 100% 82%
coverage coverage
 1    /*
 2    * JBoss, the OpenSource J2EE webOS
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    * Created on March 25 2003
 7    */
 8    package org.jboss.cache.interceptors;
 9   
 10    import org.apache.commons.logging.Log;
 11    import org.apache.commons.logging.LogFactory;
 12    import org.jboss.cache.CacheSPI;
 13    import org.jboss.cache.Fqn;
 14    import org.jboss.cache.InvocationContext;
 15    import org.jboss.cache.Region;
 16    import org.jboss.cache.RegionManager;
 17    import org.jboss.cache.eviction.EvictedEventNode;
 18    import org.jboss.cache.eviction.NodeEventType;
 19    import org.jboss.cache.marshall.MethodCall;
 20    import org.jboss.cache.marshall.MethodDeclarations;
 21   
 22    import java.util.HashMap;
 23    import java.util.Map;
 24   
 25    /**
 26    * Eviction Interceptor.
 27    * <p/>
 28    * This interceptor is used to handle eviction events.
 29    *
 30    * @author Daniel Huang
 31    * @version $Revision: 1.16 $
 32    */
 33    public class EvictionInterceptor extends Interceptor
 34    {
 35    private static final Log log = LogFactory.getLog(EvictionInterceptor.class);
 36   
 37    protected RegionManager regionManager;
 38    protected Map<Integer, EvictionMethodHandler> evictionMethodHandlers = new HashMap<Integer, EvictionMethodHandler>();
 39   
 40  383 public EvictionInterceptor()
 41    {
 42  383 EvictionMethodHandler handler = new GetNodeEvictionMethodHandler();
 43  383 evictionMethodHandlers.put(MethodDeclarations.getNodeMethodLocal_id, handler);
 44  383 evictionMethodHandlers.put(MethodDeclarations.getDataMapMethodLocal_id, handler);
 45   
 46  383 handler = new GetKeyEvictionMethodHandler();
 47  383 evictionMethodHandlers.put(MethodDeclarations.getKeyValueMethodLocal_id, handler);
 48   
 49  383 handler = new RemoveNodeEvictionMethodHandler();
 50  383 evictionMethodHandlers.put(MethodDeclarations.removeNodeMethodLocal_id, handler);
 51  383 evictionMethodHandlers.put(MethodDeclarations.removeDataMethodLocal_id, handler);
 52   
 53  383 handler = new RemoveKeyEvictionMethodHandler();
 54  383 evictionMethodHandlers.put(MethodDeclarations.removeKeyMethodLocal_id, handler);
 55   
 56  383 handler = new PutDataEvictionMethodHandler();
 57  383 evictionMethodHandlers.put(MethodDeclarations.putDataMethodLocal_id, handler);
 58   
 59  383 handler = new PutDataEraseEvictionMethodHandler();
 60  383 evictionMethodHandlers.put(MethodDeclarations.putDataEraseMethodLocal_id, handler);
 61   
 62  383 handler = new PutKeyEvictionMethodHandler();
 63  383 evictionMethodHandlers.put(MethodDeclarations.putKeyValMethodLocal_id, handler);
 64  383 evictionMethodHandlers.put(MethodDeclarations.putForExternalReadMethodLocal_id, handler);
 65   
 66  383 handler = new PartialEvictionEvictionMethodHandler();
 67  383 evictionMethodHandlers.put(MethodDeclarations.evictNodeMethodLocal_id, handler);
 68  383 evictionMethodHandlers.put(MethodDeclarations.evictVersionedNodeMethodLocal_id, handler);
 69    }
 70   
 71    /**
 72    * this method is for ease of unit testing. thus package access.
 73    * <p/>
 74    * Not to be attempted to be used anywhere else.
 75    */
 76  7 void setRegionManager(RegionManager regionManager)
 77    {
 78  7 this.regionManager = regionManager;
 79    }
 80   
 81  760 public void setCache(CacheSPI cache)
 82    {
 83  760 super.setCache(cache);
 84  760 this.regionManager = cache.getRegionManager();
 85    }
 86   
 87  2344460 public Object invoke(InvocationContext ctx) throws Throwable
 88    {
 89  2344460 MethodCall m = ctx.getMethodCall();
 90  2344460 Object ret = super.invoke(ctx);
 91   
 92  2344460 if (log.isTraceEnabled())
 93    {
 94  0 log.trace("Invoking EvictionInterceptor");
 95    }
 96   
 97    // skip the TX. this interceptor will invoke around/after the call and lock. if the ret == null or if an exception
 98    // is thrown, this interceptor is terminated. there is no need for explicit rollback logic.
 99  2344460 this.updateNode(m, ret);
 100   
 101  2344460 if (log.isTraceEnabled())
 102    {
 103  0 log.trace("Finished invoking EvictionInterceptor");
 104    }
 105   
 106  2344460 return ret;
 107    }
 108   
 109  2344460 protected void updateNode(MethodCall m, Object retVal)
 110    {
 111  2344460 if (log.isTraceEnabled())
 112    {
 113  0 log.trace("Updating node/element events with no tx");
 114    }
 115   
 116  2344460 EvictedEventNode event = this.extractEvent(m, retVal);
 117  2344458 if (event == null)
 118    {
 119    // no node modifications.
 120  1338511 return;
 121    }
 122   
 123  1005949 this.doEventUpdatesOnRegionManager(event);
 124   
 125  1005905 if (log.isTraceEnabled())
 126    {
 127  0 log.trace("Finished updating node");
 128    }
 129    }
 130   
 131  2344460 protected EvictedEventNode extractEvent(MethodCall m, Object retVal)
 132    {
 133  2344460 EvictionMethodHandler handler = this.evictionMethodHandlers.get(m.getMethodId());
 134  2344460 if (handler == null)
 135    {
 136  117330 return null;
 137    }
 138   
 139  2227130 return handler.extractEvictedEventNode(m, retVal);
 140    }
 141   
 142  1362449 protected boolean canIgnoreEvent(Fqn fqn, NodeEventType type)
 143    {
 144  1362619 Region r = regionManager.getRegion(fqn, Region.Type.EVICTION, false);
 145  0 if (r == null) return true;// should never happen, we should at least get the default region.
 146  1362619 return r.getEvictionPolicy().canIgnoreEvent(fqn, type);
 147    }
 148   
 149  1005896 protected void doEventUpdatesOnRegionManager(EvictedEventNode event)
 150    {
 151  1005949 Region region = regionManager.getRegion(event.getFqn(), false);
 152  1005949 region.putNodeEvent(event);
 153   
 154  1005949 if (log.isTraceEnabled())
 155    {
 156  0 log.trace("Adding event " + event + " to region at " + region.getFqn());
 157    }
 158    }
 159   
 160    protected class GetNodeEvictionMethodHandler implements EvictionMethodHandler
 161    {
 162  367753 public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
 163    {
 164  367753 if (retVal == null)
 165    {
 166  13267 if (log.isTraceEnabled())
 167    {
 168  0 log.trace("No event added. Node does not exist");
 169    }
 170   
 171  13267 return null;
 172    }
 173   
 174  354486 Object args[] = mc.getArgs();
 175  354486 Fqn fqn = (Fqn) args[0];
 176   
 177  354486 if (fqn != null && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.VISIT_NODE_EVENT))
 178    {
 179  354478 if (fqn != null
 180    && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.VISIT_NODE_EVENT))
 181    {
 182  354478 return new EvictedEventNode(fqn, NodeEventType.VISIT_NODE_EVENT);
 183    }
 184    }
 185   
 186  8 return null;
 187    }
 188    }
 189   
 190    protected class GetKeyEvictionMethodHandler implements EvictionMethodHandler
 191    {
 192  1467158 public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
 193    {
 194  1467158 if (retVal == null)
 195    {
 196  1116923 if (log.isTraceEnabled())
 197    {
 198  0 log.trace("No event added. Element does not exist");
 199    }
 200   
 201  1116923 return null;
 202    }
 203   
 204  350235 Object args[] = mc.getArgs();
 205  350235 Fqn fqn = (Fqn) args[0];
 206  350235 Object key = args[1];
 207  350235 if (fqn != null && key != null
 208    && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.VISIT_NODE_EVENT))
 209    {
 210  350235 return new EvictedEventNode(fqn, NodeEventType.VISIT_NODE_EVENT);
 211    }
 212   
 213  0 return null;
 214    }
 215   
 216    }
 217   
 218    protected class RemoveNodeEvictionMethodHandler implements EvictionMethodHandler
 219    {
 220  16307 public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
 221    {
 222  16307 Object args[] = mc.getArgs();
 223  16307 Fqn fqn = (Fqn) args[1];
 224   
 225  16307 if (fqn != null
 226    && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.REMOVE_NODE_EVENT))
 227    {
 228  16307 return new EvictedEventNode(fqn, NodeEventType.REMOVE_NODE_EVENT);
 229    }
 230   
 231  0 return null;
 232    }
 233   
 234    }
 235   
 236    protected class RemoveKeyEvictionMethodHandler implements EvictionMethodHandler
 237    {
 238  4069 public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
 239    {
 240  4069 if (retVal == null)
 241    {
 242  2001 if (log.isTraceEnabled())
 243    {
 244  0 log.trace("No event added. Element does not exist");
 245    }
 246   
 247  2001 return null;
 248    }
 249   
 250  2068 Object args[] = mc.getArgs();
 251  2068 Fqn fqn = (Fqn) args[1];
 252  2068 Object key = args[2];
 253  2068 if (fqn != null && key != null
 254    && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.REMOVE_ELEMENT_EVENT))
 255    {
 256  2067 return new EvictedEventNode(fqn, NodeEventType.REMOVE_ELEMENT_EVENT, 1);
 257    }
 258  1 return null;
 259    }
 260   
 261    }
 262   
 263    protected class PutDataEvictionMethodHandler implements EvictionMethodHandler
 264    {
 265  9514 public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
 266    {
 267  9514 Object[] args = mc.getArgs();
 268  9514 Fqn fqn = (Fqn) args[1];
 269  9514 Map putData = (Map) args[2];
 270  9514 if (fqn != null
 271    && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.ADD_NODE_EVENT))
 272    {
 273  9514 if (putData == null)
 274    {
 275  2184 if (log.isTraceEnabled())
 276    {
 277  0 log.trace("Putting null data under fqn " + fqn + ".");
 278    }
 279   
 280  2184 return null;
 281    }
 282   
 283  7330 int size;
 284  7330 synchronized (putData)
 285    {
 286  7330 size = putData.size();
 287    }
 288   
 289  7330 return new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, size);
 290    }
 291   
 292  0 return null;
 293    }
 294   
 295    }
 296   
 297    protected class PutDataEraseEvictionMethodHandler implements EvictionMethodHandler
 298    {
 299  4 public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
 300    {
 301  4 Object[] args = mc.getArgs();
 302  4 Fqn fqn = (Fqn) args[1];
 303  4 Map putData = (Map) args[2];
 304  4 Boolean resetElementCount = (Boolean) args[4];
 305  4 if (fqn != null
 306    && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.ADD_NODE_EVENT))
 307    {
 308  4 if (putData == null)
 309    {
 310  0 if (log.isTraceEnabled())
 311    {
 312  0 log.trace("Putting null data under fqn " + fqn + ".");
 313    }
 314   
 315  0 return null;
 316    }
 317   
 318  4 int size;
 319  4 synchronized (putData)
 320    {
 321  4 size = putData.size();
 322    }
 323   
 324  4 EvictedEventNode event = new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, size);
 325  4 event.setResetElementCount(resetElementCount);
 326  4 return event;
 327    }
 328   
 329  0 return null;
 330    }
 331    }
 332   
 333    protected class PutKeyEvictionMethodHandler implements EvictionMethodHandler
 334    {
 335  275488 public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
 336    {
 337  275488 Object[] args = mc.getArgs();
 338  275488 Fqn fqn = (Fqn) args[1];
 339  275488 Object key = args[2];
 340  275488 if (fqn != null && key != null
 341    && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.ADD_ELEMENT_EVENT))
 342    {
 343  275487 return new EvictedEventNode(fqn, NodeEventType.ADD_ELEMENT_EVENT, 1);
 344    }
 345   
 346  1 return null;
 347    }
 348   
 349    }
 350   
 351    protected class PartialEvictionEvictionMethodHandler implements EvictionMethodHandler
 352    {
 353  86837 public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
 354    {
 355    // See if the node still exists; i.e. was only data removed
 356    // because it still has children.
 357    // If yes, put an ADD event in the queue so the node gets revisited
 358   
 359  86837 boolean complete = (retVal != null && (Boolean) retVal);
 360  86837 if (!complete)
 361    {
 362  41 Object[] args = mc.getArgs();
 363  41 Fqn fqn = (Fqn) args[0];
 364  41 if (fqn != null
 365    && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.ADD_NODE_EVENT))
 366    {
 367  41 return new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, 0);
 368    }
 369    }
 370  86796 return null;
 371    }
 372    }
 373   
 374    protected interface EvictionMethodHandler
 375    {
 376    EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal);
 377    }
 378   
 379    }