Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 709   Methods: 13
NCLOC: 550   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
InterceptorChainFactory.java 66% 84.3% 100% 78.4%
coverage coverage
 1    /*
 2    * JBoss, Home of Professional Open Source
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7    package org.jboss.cache.factories;
 8   
 9    import org.apache.commons.logging.Log;
 10    import org.apache.commons.logging.LogFactory;
 11    import org.jboss.cache.CacheImpl;
 12    import org.jboss.cache.CacheSPI;
 13    import org.jboss.cache.interceptors.*;
 14    import org.jboss.cache.loader.CacheLoaderManager;
 15    import org.jboss.cache.util.Util;
 16   
 17    import java.util.ArrayList;
 18    import java.util.List;
 19   
 20    /**
 21    * Factory class that builds an interceptor chain based on CacheImpl config.
 22    *
 23    * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 24    */
 25    public class InterceptorChainFactory
 26    {
 27    private Log log = LogFactory.getLog(InterceptorChainFactory.class);
 28    private static InterceptorChainFactory singleton;
 29   
 30  280 private InterceptorChainFactory()
 31    {
 32    // private ctor
 33    }
 34   
 35  9264 public static InterceptorChainFactory getInstance()
 36    {
 37  9264 if (singleton == null)
 38    {
 39  280 synchronized (InterceptorChainFactory.class)
 40    {
 41  280 if (singleton == null) singleton = new InterceptorChainFactory();
 42    }
 43    }
 44   
 45  9264 return singleton;
 46    }
 47   
 48   
 49  2847 public Interceptor buildInterceptorChain(CacheImpl cache) throws IllegalAccessException, ClassNotFoundException, InstantiationException
 50    {
 51  2847 if (cache.getConfiguration().isNodeLockingOptimistic())
 52    {
 53  424 return createOptimisticInterceptorChain(cache);
 54    }
 55    else
 56    {
 57  2423 return createPessimisticInterceptorChain(cache);
 58    }
 59    }
 60   
 61  2860 public Interceptor setLastInterceptorPointer(Interceptor first, Interceptor last)
 62    {
 63  2860 Interceptor i = first;
 64  2860 while (i != null)
 65    {
 66  24603 i.setLast(last);
 67  24603 i = i.getNext();
 68    }
 69  2860 return first;
 70    }
 71   
 72   
 73  376 private Interceptor createInterceptor(String classname, CacheSPI cache) throws ClassNotFoundException, IllegalAccessException, InstantiationException
 74    {
 75  376 Class<Interceptor> clazz = Util.loadClass(classname);
 76  376 return createInterceptor(clazz, cache);
 77    }
 78   
 79  24511 private Interceptor createInterceptor(Class<? extends Interceptor> clazz, CacheSPI cache) throws IllegalAccessException, InstantiationException
 80    {
 81  24511 Interceptor i = clazz.newInstance();
 82  24511 i.setCache(cache);
 83  24511 i.setStatisticsEnabled(cache.getConfiguration().getExposeManagementStatistics());
 84  24511 return i;
 85    }
 86   
 87   
 88    /**
 89    * Adds an interceptor at the end of the chain
 90    */
 91  22246 private void addInterceptor(Interceptor first, Interceptor i)
 92    {
 93  0 if (first == null) return;
 94  76157 while (first.getNext() != null) first = first.getNext();
 95  22246 first.setNext(i);
 96    }
 97   
 98  2423 private Interceptor createPessimisticInterceptorChain(CacheImpl cache) throws IllegalAccessException, InstantiationException, ClassNotFoundException
 99    {
 100  2423 Interceptor call_interceptor;
 101  2423 Interceptor lock_interceptor;
 102  2423 Interceptor repl_interceptor = null;
 103  2423 Interceptor cache_loader_interceptor = null;
 104  2423 Interceptor cache_store_interceptor = null;
 105  2423 Interceptor unlock_interceptor;
 106  2423 Interceptor passivation_interceptor = null;
 107  2423 Interceptor activation_interceptor = null;
 108  2423 Interceptor cacheMgmtInterceptor;
 109  2423 Interceptor txInterceptor;
 110  2423 Interceptor eviction_interceptor;
 111  2423 Interceptor dataGravitatorInterceptor = null;
 112  2423 Interceptor invocationCtxInterceptor = createInterceptor(InvocationContextInterceptor.class, cache);
 113  2423 Interceptor notificationInterceptor = createInterceptor(NotificationInterceptor.class, cache);
 114  2423 Interceptor first = null;
 115   
 116   
 117  2423 call_interceptor = createInterceptor(CallInterceptor.class, cache);
 118  2423 ((CallInterceptor) call_interceptor).setTreeCacheInstance(cache);
 119   
 120  2423 if (cache.getBuddyManager() != null)
 121    {
 122  154 dataGravitatorInterceptor = createInterceptor(DataGravitatorInterceptor.class, cache);
 123    }
 124   
 125  2423 lock_interceptor = createInterceptor(PessimisticLockInterceptor.class, cache);
 126   
 127  2423 unlock_interceptor = createInterceptor(UnlockInterceptor.class, cache);
 128   
 129  2423 cacheMgmtInterceptor = createInterceptor(CacheMgmtInterceptor.class, cache);
 130   
 131  2423 txInterceptor = createInterceptor(TxInterceptor.class, cache);
 132   
 133  2423 switch (cache.getConfiguration().getCacheMode())
 134    {
 135  683 case REPL_SYNC:
 136  175 case REPL_ASYNC:
 137  858 repl_interceptor = createInterceptor(ReplicationInterceptor.class, cache);
 138  858 break;
 139  28 case INVALIDATION_SYNC:
 140  15 case INVALIDATION_ASYNC:
 141  43 repl_interceptor = createInterceptor(InvalidationInterceptor.class, cache);
 142  43 break;
 143  1522 case LOCAL:
 144    //Nothing...
 145    }
 146   
 147  2423 CacheLoaderManager cacheLoaderMgr = cache.getCacheLoaderManager();
 148   
 149  2423 if (cacheLoaderMgr != null && cacheLoaderMgr.getCacheLoader() != null)
 150    {
 151  1005 if (cacheLoaderMgr.isPassivation())
 152    {
 153  231 activation_interceptor = createInterceptor(ActivationInterceptor.class, cache);
 154  231 passivation_interceptor = createInterceptor(PassivationInterceptor.class, cache);
 155    }
 156    else
 157    {
 158  774 cache_loader_interceptor = createInterceptor(CacheLoaderInterceptor.class, cache);
 159  774 cache_store_interceptor = createInterceptor(CacheStoreInterceptor.class, cache);
 160    }
 161    }
 162   
 163    // load the icInterceptor first
 164  2423 if (first == null) first = invocationCtxInterceptor;
 165   
 166    // load the cache management interceptor next
 167  2423 if (cache.getConfiguration().getExposeManagementStatistics())
 168    {
 169  2410 if (first == null)
 170    {
 171  0 first = cacheMgmtInterceptor;
 172    }
 173    else
 174    {
 175  2410 addInterceptor(first, cacheMgmtInterceptor);
 176    }
 177    }
 178   
 179    // load the tx interceptor
 180  2423 if (first == null)
 181    {
 182  0 first = txInterceptor;
 183    }
 184    else
 185    {
 186  2423 addInterceptor(first, txInterceptor);
 187    }
 188   
 189  2423 if (first == null)
 190  0 first = notificationInterceptor;
 191    else
 192  2423 addInterceptor(first, notificationInterceptor);
 193   
 194    // create the stack from the bottom up
 195    // if (activation_interceptor != null)
 196    // {
 197    // if (!cacheLoaderMgr.isFetchPersistentState())
 198    // {
 199    // if (first == null)
 200    // {
 201    // first = passivation_interceptor;
 202    // }
 203    // else
 204    // {
 205    // addInterceptor(first, passivation_interceptor);
 206    // }
 207    // }
 208    // }
 209    //
 210    // if (cache_loader_interceptor != null)
 211    // {
 212    // if (!cacheLoaderMgr.isFetchPersistentState())
 213    // {
 214    // if (first == null)
 215    // {
 216    // first = cache_store_interceptor;
 217    // }
 218    // else
 219    // {
 220    // addInterceptor(first, cache_store_interceptor);
 221    // }
 222    // }
 223    // }
 224   
 225  2423 if (repl_interceptor != null)
 226    {
 227  901 if (first == null)
 228    {
 229  0 first = repl_interceptor;
 230    }
 231    else
 232    {
 233  901 addInterceptor(first, repl_interceptor);
 234    }
 235    }
 236   
 237  2423 if (first == null)
 238    {
 239  0 first = lock_interceptor;
 240    }
 241    else
 242    {
 243  2423 addInterceptor(first, lock_interceptor);
 244    }
 245   
 246   
 247  2423 if (unlock_interceptor != null)
 248    {
 249  2423 if (first == null)
 250    {
 251  0 first = unlock_interceptor;
 252    }
 253    else
 254    {
 255  2423 addInterceptor(first, unlock_interceptor);
 256    }
 257    }
 258   
 259  2423 if (activation_interceptor != null)
 260    {
 261    // if (!cacheLoaderMgr.isFetchPersistentState())
 262  231 if (false)
 263    {
 264  0 if (first == null)
 265    {
 266  0 first = activation_interceptor;
 267    }
 268    else
 269    {
 270  0 addInterceptor(first, activation_interceptor);
 271    }
 272    }
 273    else
 274    {
 275  231 if (first == null)
 276    {
 277  0 first = activation_interceptor;
 278    }
 279    else
 280    {
 281  231 addInterceptor(first, activation_interceptor);
 282    }
 283  231 if (first == null)
 284    {
 285  0 first = passivation_interceptor;
 286    }
 287    else
 288    {
 289  231 addInterceptor(first, passivation_interceptor);
 290    }
 291    }
 292    }
 293   
 294  2423 if (cache_loader_interceptor != null)
 295    {
 296    // if (!cacheLoaderMgr.isFetchPersistentState())
 297  774 if (false)
 298    {
 299  0 if (first == null)
 300    {
 301  0 first = cache_loader_interceptor;
 302    }
 303    else
 304    {
 305  0 addInterceptor(first, cache_loader_interceptor);
 306    }
 307    }
 308    else
 309    {
 310  774 if (first == null)
 311    {
 312  0 first = cache_loader_interceptor;
 313    }
 314    else
 315    {
 316  774 addInterceptor(first, cache_loader_interceptor);
 317    }
 318  774 if (first == null)
 319    {
 320  0 first = cache_store_interceptor;
 321    }
 322    else
 323    {
 324  774 addInterceptor(first, cache_store_interceptor);
 325    }
 326    }
 327    }
 328   
 329  2423 if (dataGravitatorInterceptor != null)
 330    {
 331  154 if (first == null)
 332    {
 333  0 first = dataGravitatorInterceptor;
 334    }
 335    else
 336    {
 337  154 addInterceptor(first, dataGravitatorInterceptor);
 338    }
 339    }
 340    //
 341    // if (first == null)
 342    // {
 343    // first = lock_interceptor;
 344    // }
 345    // else
 346    // {
 347    // addInterceptor(first, lock_interceptor);
 348    // }
 349   
 350  2423 if (cache.getConfiguration().getEvictionConfig() != null && cache.getConfiguration().getEvictionConfig().isValidConfig())
 351    {
 352  336 eviction_interceptor = createInterceptor(cache.getEvictionInterceptorClass(), cache);
 353  336 if (first == null)
 354    {
 355  0 first = eviction_interceptor;
 356    }
 357    else
 358    {
 359  336 addInterceptor(first, eviction_interceptor);
 360    }
 361    }
 362   
 363  2423 if (first == null)
 364    {
 365  0 first = call_interceptor;
 366    }
 367    else
 368    {
 369  2423 addInterceptor(first, call_interceptor);
 370    }
 371   
 372  2423 if (log.isInfoEnabled())
 373    {
 374  2423 log.info("interceptor chain is:\n" + printInterceptorChain(first));
 375    }
 376   
 377  2423 return setLastInterceptorPointer(first, call_interceptor);
 378    }
 379   
 380  424 private Interceptor createOptimisticInterceptorChain(CacheImpl cache) throws IllegalAccessException, InstantiationException, ClassNotFoundException
 381    {
 382  424 Interceptor txInterceptor, replicationInterceptor = null, lockInterceptor, validationInterceptor;
 383  424 Interceptor createIfNotExistsInterceptor, nodeInterceptor, invokerInterceptor, activationInterceptor = null;
 384  424 Interceptor passivationInterceptor = null, cacheLoaderInterceptor = null, cacheStoreInterceptor = null, first = null;
 385  424 Interceptor cacheMgmtInterceptor, evictionInterceptor = null, dataGravitatorInterceptor = null;
 386  424 Interceptor invocationCtxInterceptor = createInterceptor(InvocationContextInterceptor.class, cache);
 387  424 Interceptor notificationInterceptor = createInterceptor(NotificationInterceptor.class, cache);
 388   
 389  424 CacheLoaderManager cacheLoaderManager = cache.getCacheLoaderManager();
 390  424 if (cacheLoaderManager != null && cacheLoaderManager.getCacheLoader() != null)
 391    {
 392  36 if (cacheLoaderManager.isPassivation())
 393    {
 394  16 activationInterceptor = createInterceptor(ActivationInterceptor.class, cache);
 395  16 passivationInterceptor = createInterceptor(PassivationInterceptor.class, cache);
 396    }
 397    else
 398    {
 399  20 cacheLoaderInterceptor = createInterceptor(CacheLoaderInterceptor.class, cache);
 400  20 cacheStoreInterceptor = createInterceptor(CacheStoreInterceptor.class, cache);
 401    }
 402    }
 403   
 404  424 txInterceptor = createInterceptor(TxInterceptor.class, cache);
 405   
 406  424 if (cache.getBuddyManager() != null)
 407    {
 408  14 dataGravitatorInterceptor = createInterceptor(DataGravitatorInterceptor.class, cache);
 409    }
 410   
 411  424 switch (cache.getConfiguration().getCacheMode())
 412    {
 413  144 case REPL_SYNC:
 414  39 case REPL_ASYNC:
 415  183 replicationInterceptor = createInterceptor(OptimisticReplicationInterceptor.class, cache);
 416  183 break;
 417  20 case INVALIDATION_SYNC:
 418  10 case INVALIDATION_ASYNC:
 419  30 replicationInterceptor = createInterceptor(InvalidationInterceptor.class, cache);
 420  30 break;
 421  211 case LOCAL:
 422    //Nothing...
 423    }
 424   
 425  424 lockInterceptor = createInterceptor(OptimisticLockingInterceptor.class, cache);
 426   
 427  424 validationInterceptor = createInterceptor(OptimisticValidatorInterceptor.class, cache);
 428   
 429  424 createIfNotExistsInterceptor = createInterceptor(OptimisticCreateIfNotExistsInterceptor.class, cache);
 430   
 431  424 nodeInterceptor = createInterceptor(OptimisticNodeInterceptor.class, cache);
 432   
 433  424 invokerInterceptor = createInterceptor(CallInterceptor.class, cache);
 434  424 ((CallInterceptor) invokerInterceptor).setTreeCacheInstance(cache);
 435   
 436  424 if (cache.getConfiguration().getEvictionConfig() != null && cache.getConfiguration().getEvictionConfig().isValidConfig())
 437    {
 438  40 evictionInterceptor = createInterceptor(cache.getEvictionInterceptorClass(), cache);
 439    }
 440   
 441  424 if (first == null) first = invocationCtxInterceptor;
 442   
 443  424 if (cache.getConfiguration().getExposeManagementStatistics())
 444    {
 445  418 cacheMgmtInterceptor = createInterceptor(CacheMgmtInterceptor.class, cache);
 446  418 if (first == null)
 447    {
 448  0 first = cacheMgmtInterceptor;
 449    }
 450    else
 451    {
 452  418 addInterceptor(first, cacheMgmtInterceptor);
 453    }
 454    }
 455   
 456  424 if (txInterceptor != null)
 457    {
 458  424 if (first == null)
 459    {
 460  0 first = txInterceptor;
 461    }
 462    else
 463    {
 464  424 addInterceptor(first, txInterceptor);
 465    }
 466    }
 467   
 468  424 if (first == null)
 469  0 first = notificationInterceptor;
 470    else
 471  424 addInterceptor(first, notificationInterceptor);
 472   
 473  424 if (first == null)
 474    {
 475  0 first = replicationInterceptor;
 476    }
 477    else
 478    {
 479  424 addInterceptor(first, replicationInterceptor);
 480    }
 481   
 482  424 if (passivationInterceptor != null && !cacheLoaderManager.isFetchPersistentState())
 483    {
 484  16 if (first == null)
 485    {
 486  0 first = passivationInterceptor;
 487    }
 488    else
 489    {
 490  16 addInterceptor(first, passivationInterceptor);
 491    }
 492    }
 493   
 494    // add the cache store interceptor here
 495  424 if (cacheStoreInterceptor != null && !cacheLoaderManager.isFetchPersistentState())
 496    {
 497  14 if (first == null)
 498    {
 499  0 first = cacheStoreInterceptor;
 500    }
 501    else
 502    {
 503  14 addInterceptor(first, cacheStoreInterceptor);
 504    }
 505    }
 506   
 507    // cache loader interceptor is only invoked if we are ready to write to the actual tree cache
 508  424 if (activationInterceptor != null)
 509    {
 510  16 if (first == null)
 511    {
 512  0 first = activationInterceptor;
 513    }
 514    else
 515    {
 516  16 addInterceptor(first, activationInterceptor);
 517    }
 518   
 519  16 if (cacheLoaderManager.isFetchPersistentState())
 520    {
 521  0 if (first == null)
 522    {
 523  0 first = passivationInterceptor;
 524    }
 525    else
 526    {
 527  0 addInterceptor(first, passivationInterceptor);
 528    }
 529    }
 530    }
 531   
 532  424 if (cacheLoaderInterceptor != null)
 533    {
 534  20 if (first == null)
 535    {
 536  0 first = cacheLoaderInterceptor;
 537    }
 538    else
 539    {
 540  20 addInterceptor(first, cacheLoaderInterceptor);
 541    }
 542   
 543  20 if (cacheLoaderManager.isFetchPersistentState())
 544    {
 545  6 if (first == null)
 546    {
 547  0 first = cacheStoreInterceptor;
 548    }
 549    else
 550    {
 551  6 addInterceptor(first, cacheStoreInterceptor);
 552    }
 553    }
 554    }
 555   
 556  424 if (dataGravitatorInterceptor != null)
 557    {
 558  14 if (first == null)
 559    {
 560  0 first = dataGravitatorInterceptor;
 561    }
 562    else
 563    {
 564  14 addInterceptor(first, dataGravitatorInterceptor);
 565    }
 566    }
 567   
 568   
 569  424 if (first == null)
 570    {
 571  0 first = lockInterceptor;
 572    }
 573    else
 574    {
 575  424 addInterceptor(first, lockInterceptor);
 576    }
 577   
 578  424 if (first == null)
 579    {
 580  0 first = validationInterceptor;
 581    }
 582    else
 583    {
 584  424 addInterceptor(first, validationInterceptor);
 585    }
 586   
 587  424 if (first == null)
 588    {
 589  0 first = createIfNotExistsInterceptor;
 590    }
 591    else
 592    {
 593  424 addInterceptor(first, createIfNotExistsInterceptor);
 594    }
 595   
 596    // eviction interceptor to come before the optimistic node interceptor
 597  424 if (first == null)
 598    {
 599  0 first = evictionInterceptor;
 600    }
 601    else
 602    {
 603  424 addInterceptor(first, evictionInterceptor);
 604    }
 605   
 606  424 if (first == null)
 607    {
 608  0 first = nodeInterceptor;
 609    }
 610    else
 611    {
 612  424 addInterceptor(first, nodeInterceptor);
 613    }
 614   
 615   
 616  424 if (first == null)
 617    {
 618  0 first = invokerInterceptor;
 619    }
 620    else
 621    {
 622  424 addInterceptor(first, invokerInterceptor);
 623    }
 624   
 625  424 if (log.isInfoEnabled())
 626    {
 627  424 log.info("interceptor chain is:\n" + printInterceptorChain(first));
 628    }
 629   
 630  424 return setLastInterceptorPointer(first, invokerInterceptor);
 631    }
 632   
 633  24498 public String printInterceptorChain(Interceptor i)
 634    {
 635  24498 StringBuffer sb = new StringBuffer();
 636  24498 if (i != null)
 637    {
 638  24498 if (i.getNext() != null)
 639    {
 640  21651 sb.append(printInterceptorChain(i.getNext())).append("\n");
 641    }
 642  24498 sb.append(i.getClass());
 643    }
 644  24498 return sb.toString();
 645    }
 646   
 647  6404 public List<Interceptor> asList(Interceptor interceptor)
 648    {
 649  6404 if (interceptor == null)
 650    {
 651  0 return null;
 652    }
 653  6404 int num = 1;
 654  6404 Interceptor tmp = interceptor;
 655  ? while ((tmp = tmp.getNext()) != null)
 656    {
 657  52395 num++;
 658    }
 659  6404 List<Interceptor> retval = new ArrayList<Interceptor>(num);
 660  6404 tmp = interceptor;
 661  6404 num = 0;
 662  6404 do
 663    {
 664  58799 retval.add(tmp);
 665  58799 tmp = tmp.getNext();
 666    }
 667  58799 while (tmp != null);
 668  6404 return retval;
 669    }
 670   
 671    /**
 672    * "Fixes" the next() and last() pointers for each interceptor, based on the order presented in the list passed in
 673    *
 674    * @param interceptors
 675    * @return the first interceptor in the chain.
 676    */
 677  6 public Interceptor correctInterceptorChaining(List<Interceptor> interceptors)
 678    {
 679  6 Interceptor first = null, last = null;
 680   
 681  6 for (Interceptor next : interceptors)
 682    {
 683  42 if (first == null)
 684    {
 685  6 first = last = next;
 686  6 continue;
 687    }
 688  36 last.setNext(next);
 689  36 last = next;
 690    }
 691   
 692  6 if (last != null) last.setNext(null);
 693   
 694    // now set the 'last' pointer.
 695  6 return setLastInterceptorPointer(first, last);
 696    }
 697   
 698    /**
 699    * Initialises the interceptors with a CacheSPI instance. Essentially calls setCache(). This is done AFTER the interceptor chain
 700    * is created, and when Cache.start() is called, so the interceptors get a fully initialised cache.
 701    *
 702    * @param chain interceptor chain
 703    * @param cache cache instance
 704    */
 705  2824 public void initialiseInterceptors(Interceptor firstInterceptor, CacheSPI cache)
 706    {
 707  24296 for (Interceptor i : asList(firstInterceptor)) i.setCache(cache);
 708    }
 709    }