KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > factories > InterceptorChainFactory


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 JavaDoc;
18 import java.util.List JavaDoc;
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 static Log log = LogFactory.getLog(InterceptorChainFactory.class);
28
29    public Interceptor buildInterceptorChain(CacheImpl cache) throws IllegalAccessException JavaDoc, ClassNotFoundException JavaDoc, InstantiationException JavaDoc
30    {
31       if (cache.getConfiguration().isNodeLockingOptimistic())
32       {
33          return createOptimisticInterceptorChain(cache);
34       }
35       else
36       {
37          return createPessimisticInterceptorChain(cache);
38       }
39    }
40
41    public static Interceptor setLastInterceptorPointer(Interceptor first, Interceptor last)
42    {
43       Interceptor i = first;
44       while (i != null)
45       {
46          i.setLast(last);
47          i = i.getNext();
48       }
49       return first;
50    }
51
52
53    private Interceptor createInterceptor(String JavaDoc classname, CacheSPI cache) throws ClassNotFoundException JavaDoc, IllegalAccessException JavaDoc, InstantiationException JavaDoc
54    {
55       Class JavaDoc<Interceptor> clazz = Util.loadClass(classname);
56       return createInterceptor(clazz, cache);
57    }
58
59    private Interceptor createInterceptor(Class JavaDoc<? extends Interceptor> clazz, CacheSPI cache) throws IllegalAccessException JavaDoc, InstantiationException JavaDoc
60    {
61       Interceptor i = clazz.newInstance();
62       i.setCache(cache);
63       i.setStatisticsEnabled(cache.getConfiguration().getExposeManagementStatistics());
64       return i;
65    }
66
67
68    /**
69     * Adds an interceptor at the end of the chain
70     */

71    private void addInterceptor(Interceptor first, Interceptor i)
72    {
73       if (first == null) return;
74       while (first.getNext() != null) first = first.getNext();
75       first.setNext(i);
76    }
77
78    private Interceptor createPessimisticInterceptorChain(CacheImpl cache) throws IllegalAccessException JavaDoc, InstantiationException JavaDoc, ClassNotFoundException JavaDoc
79    {
80       Interceptor call_interceptor;
81       Interceptor lock_interceptor;
82       Interceptor repl_interceptor = null;
83       Interceptor cache_loader_interceptor = null;
84       Interceptor cache_store_interceptor = null;
85       Interceptor unlock_interceptor;
86       Interceptor passivation_interceptor = null;
87       Interceptor activation_interceptor = null;
88       Interceptor cacheMgmtInterceptor;
89       Interceptor txInterceptor;
90       Interceptor eviction_interceptor;
91       Interceptor dataGravitatorInterceptor = null;
92       Interceptor invocationCtxInterceptor = createInterceptor(InvocationContextInterceptor.class, cache);
93       Interceptor notificationInterceptor = createInterceptor(NotificationInterceptor.class, cache);
94       Interceptor first = null;
95
96
97       call_interceptor = createInterceptor(CallInterceptor.class, cache);
98       ((CallInterceptor) call_interceptor).setTreeCacheInstance(cache);
99
100       if (cache.getBuddyManager() != null)
101       {
102          dataGravitatorInterceptor = createInterceptor(DataGravitatorInterceptor.class, cache);
103       }
104
105       lock_interceptor = createInterceptor(PessimisticLockInterceptor.class, cache);
106
107       unlock_interceptor = createInterceptor(UnlockInterceptor.class, cache);
108
109       cacheMgmtInterceptor = createInterceptor(CacheMgmtInterceptor.class, cache);
110
111       txInterceptor = createInterceptor(TxInterceptor.class, cache);
112
113       switch (cache.getConfiguration().getCacheMode())
114       {
115          case REPL_SYNC:
116          case REPL_ASYNC:
117             repl_interceptor = createInterceptor(ReplicationInterceptor.class, cache);
118             break;
119          case INVALIDATION_SYNC:
120          case INVALIDATION_ASYNC:
121             repl_interceptor = createInterceptor(InvalidationInterceptor.class, cache);
122             break;
123          case LOCAL:
124             //Nothing...
125
}
126
127       CacheLoaderManager cacheLoaderMgr = cache.getCacheLoaderManager();
128
129       if (cacheLoaderMgr != null && cacheLoaderMgr.getCacheLoader() != null)
130       {
131          if (cacheLoaderMgr.isPassivation())
132          {
133             activation_interceptor = createInterceptor(ActivationInterceptor.class, cache);
134             passivation_interceptor = createInterceptor(PassivationInterceptor.class, cache);
135          }
136          else
137          {
138             cache_loader_interceptor = createInterceptor(CacheLoaderInterceptor.class, cache);
139             cache_store_interceptor = createInterceptor(CacheStoreInterceptor.class, cache);
140          }
141       }
142
143       // load the icInterceptor first
144
if (first == null) first = invocationCtxInterceptor;
145
146       // load the cache management interceptor next
147
if (cache.getConfiguration().getExposeManagementStatistics())
148       {
149          if (first == null)
150          {
151             first = cacheMgmtInterceptor;
152          }
153          else
154          {
155             addInterceptor(first, cacheMgmtInterceptor);
156          }
157       }
158
159       // load the tx interceptor
160
if (first == null)
161       {
162          first = txInterceptor;
163       }
164       else
165       {
166          addInterceptor(first, txInterceptor);
167       }
168
169       if (first == null)
170          first = notificationInterceptor;
171       else
172          addInterceptor(first, notificationInterceptor);
173
174       // create the stack from the bottom up
175
if (activation_interceptor != null)
176       {
177          if (!cacheLoaderMgr.isFetchPersistentState())
178          {
179             if (first == null)
180             {
181                first = passivation_interceptor;
182             }
183             else
184             {
185                addInterceptor(first, passivation_interceptor);
186             }
187          }
188       }
189
190       if (cache_loader_interceptor != null)
191       {
192          if (!cacheLoaderMgr.isFetchPersistentState())
193          {
194             if (first == null)
195             {
196                first = cache_store_interceptor;
197             }
198             else
199             {
200                addInterceptor(first, cache_store_interceptor);
201             }
202          }
203       }
204
205       if (repl_interceptor != null)
206       {
207          if (first == null)
208          {
209             first = repl_interceptor;
210          }
211          else
212          {
213             addInterceptor(first, repl_interceptor);
214          }
215       }
216
217       if (unlock_interceptor != null)
218       {
219          if (first == null)
220          {
221             first = unlock_interceptor;
222          }
223          else
224          {
225             addInterceptor(first, unlock_interceptor);
226          }
227       }
228
229       if (activation_interceptor != null)
230       {
231          if (!cacheLoaderMgr.isFetchPersistentState())
232          {
233             if (first == null)
234             {
235                first = activation_interceptor;
236             }
237             else
238             {
239                addInterceptor(first, activation_interceptor);
240             }
241          }
242          else
243          {
244             if (first == null)
245             {
246                first = activation_interceptor;
247             }
248             else
249             {
250                addInterceptor(first, activation_interceptor);
251             }
252             if (first == null)
253             {
254                first = passivation_interceptor;
255             }
256             else
257             {
258                addInterceptor(first, passivation_interceptor);
259             }
260          }
261       }
262
263       if (cache_loader_interceptor != null)
264       {
265          if (!cacheLoaderMgr.isFetchPersistentState())
266          {
267             if (first == null)
268             {
269                first = cache_loader_interceptor;
270             }
271             else
272             {
273                addInterceptor(first, cache_loader_interceptor);
274             }
275          }
276          else
277          {
278             if (first == null)
279             {
280                first = cache_loader_interceptor;
281             }
282             else
283             {
284                addInterceptor(first, cache_loader_interceptor);
285             }
286             if (first == null)
287             {
288                first = cache_store_interceptor;
289             }
290             else
291             {
292                addInterceptor(first, cache_store_interceptor);
293             }
294          }
295       }
296
297       if (dataGravitatorInterceptor != null)
298       {
299          if (first == null)
300          {
301             first = dataGravitatorInterceptor;
302          }
303          else
304          {
305             addInterceptor(first, dataGravitatorInterceptor);
306          }
307       }
308
309       if (first == null)
310       {
311          first = lock_interceptor;
312       }
313       else
314       {
315          addInterceptor(first, lock_interceptor);
316       }
317
318       if (cache.getConfiguration().getEvictionConfig() != null && cache.getConfiguration().getEvictionConfig().isValidConfig())
319       {
320          eviction_interceptor = createInterceptor(cache.getEvictionInterceptorClass(), cache);
321          if (first == null)
322          {
323             first = eviction_interceptor;
324          }
325          else
326          {
327             addInterceptor(first, eviction_interceptor);
328          }
329       }
330
331       if (first == null)
332       {
333          first = call_interceptor;
334       }
335       else
336       {
337          addInterceptor(first, call_interceptor);
338       }
339
340       if (log.isInfoEnabled())
341       {
342          log.info("interceptor chain is:\n" + printInterceptorChain(first));
343       }
344
345       return setLastInterceptorPointer(first, call_interceptor);
346    }
347
348    private Interceptor createOptimisticInterceptorChain(CacheImpl cache) throws IllegalAccessException JavaDoc, InstantiationException JavaDoc, ClassNotFoundException JavaDoc
349    {
350       Interceptor txInterceptor, replicationInterceptor = null, lockInterceptor, validationInterceptor;
351       Interceptor createIfNotExistsInterceptor, nodeInterceptor, invokerInterceptor, activationInterceptor = null;
352       Interceptor passivationInterceptor = null, cacheLoaderInterceptor = null, cacheStoreInterceptor = null, first = null;
353       Interceptor cacheMgmtInterceptor, evictionInterceptor = null, dataGravitatorInterceptor = null;
354       Interceptor invocationCtxInterceptor = createInterceptor(InvocationContextInterceptor.class, cache);
355       Interceptor notificationInterceptor = createInterceptor(NotificationInterceptor.class, cache);
356
357       CacheLoaderManager cacheLoaderManager = cache.getCacheLoaderManager();
358       if (cacheLoaderManager != null && cacheLoaderManager.getCacheLoader() != null)
359       {
360          if (cacheLoaderManager.isPassivation())
361          {
362             activationInterceptor = createInterceptor(ActivationInterceptor.class, cache);
363             passivationInterceptor = createInterceptor(PassivationInterceptor.class, cache);
364          }
365          else
366          {
367             cacheLoaderInterceptor = createInterceptor(CacheLoaderInterceptor.class, cache);
368             cacheStoreInterceptor = createInterceptor(CacheStoreInterceptor.class, cache);
369          }
370       }
371
372       txInterceptor = createInterceptor(TxInterceptor.class, cache);
373
374       if (cache.getBuddyManager() != null)
375       {
376          dataGravitatorInterceptor = createInterceptor(DataGravitatorInterceptor.class, cache);
377       }
378
379       switch (cache.getConfiguration().getCacheMode())
380       {
381          case REPL_SYNC:
382          case REPL_ASYNC:
383             replicationInterceptor = createInterceptor(OptimisticReplicationInterceptor.class, cache);
384             break;
385          case INVALIDATION_SYNC:
386          case INVALIDATION_ASYNC:
387             replicationInterceptor = createInterceptor(InvalidationInterceptor.class, cache);
388             break;
389          case LOCAL:
390             //Nothing...
391
}
392
393       lockInterceptor = createInterceptor(OptimisticLockingInterceptor.class, cache);
394
395       validationInterceptor = createInterceptor(OptimisticValidatorInterceptor.class, cache);
396
397       createIfNotExistsInterceptor = createInterceptor(OptimisticCreateIfNotExistsInterceptor.class, cache);
398
399       nodeInterceptor = createInterceptor(OptimisticNodeInterceptor.class, cache);
400
401       invokerInterceptor = createInterceptor(CallInterceptor.class, cache);
402       ((CallInterceptor) invokerInterceptor).setTreeCacheInstance(cache);
403
404       if (cache.getConfiguration().getEvictionConfig() != null && cache.getConfiguration().getEvictionConfig().isValidConfig())
405       {
406          evictionInterceptor = createInterceptor(cache.getEvictionInterceptorClass(), cache);
407       }
408
409       if (first == null) first = invocationCtxInterceptor;
410
411       if (cache.getConfiguration().getExposeManagementStatistics())
412       {
413          cacheMgmtInterceptor = createInterceptor(CacheMgmtInterceptor.class, cache);
414          if (first == null)
415          {
416             first = cacheMgmtInterceptor;
417          }
418          else
419          {
420             addInterceptor(first, cacheMgmtInterceptor);
421          }
422       }
423
424       if (txInterceptor != null)
425       {
426          if (first == null)
427          {
428             first = txInterceptor;
429          }
430          else
431          {
432             addInterceptor(first, txInterceptor);
433          }
434       }
435
436       if (first == null)
437          first = notificationInterceptor;
438       else
439          addInterceptor(first, notificationInterceptor);
440
441       if (first == null)
442       {
443          first = replicationInterceptor;
444       }
445       else
446       {
447          addInterceptor(first, replicationInterceptor);
448       }
449
450       if (passivationInterceptor != null && !cacheLoaderManager.isFetchPersistentState())
451       {
452          if (first == null)
453          {
454             first = passivationInterceptor;
455          }
456          else
457          {
458             addInterceptor(first, passivationInterceptor);
459          }
460       }
461
462       // add the cache store interceptor here
463
if (cacheStoreInterceptor != null && !cacheLoaderManager.isFetchPersistentState())
464       {
465          if (first == null)
466          {
467             first = cacheStoreInterceptor;
468          }
469          else
470          {
471             addInterceptor(first, cacheStoreInterceptor);
472          }
473       }
474
475       // cache loader interceptor is only invoked if we are ready to write to the actual tree cache
476
if (activationInterceptor != null)
477       {
478          if (first == null)
479          {
480             first = activationInterceptor;
481          }
482          else
483          {
484             addInterceptor(first, activationInterceptor);
485          }
486
487          if (cacheLoaderManager.isFetchPersistentState())
488          {
489             if (first == null)
490             {
491                first = passivationInterceptor;
492             }
493             else
494             {
495                addInterceptor(first, passivationInterceptor);
496             }
497          }
498       }
499
500       if (cacheLoaderInterceptor != null)
501       {
502          if (first == null)
503          {
504             first = cacheLoaderInterceptor;
505          }
506          else
507          {
508             addInterceptor(first, cacheLoaderInterceptor);
509          }
510
511          if (cacheLoaderManager.isFetchPersistentState())
512          {
513             if (first == null)
514             {
515                first = cacheStoreInterceptor;
516             }
517             else
518             {
519                addInterceptor(first, cacheStoreInterceptor);
520             }
521          }
522       }
523
524       if (dataGravitatorInterceptor != null)
525       {
526          if (first == null)
527          {
528             first = dataGravitatorInterceptor;
529          }
530          else
531          {
532             addInterceptor(first, dataGravitatorInterceptor);
533          }
534       }
535
536
537       if (first == null)
538       {
539          first = lockInterceptor;
540       }
541       else
542       {
543          addInterceptor(first, lockInterceptor);
544       }
545
546       if (first == null)
547       {
548          first = validationInterceptor;
549       }
550       else
551       {
552          addInterceptor(first, validationInterceptor);
553       }
554
555       if (first == null)
556       {
557          first = createIfNotExistsInterceptor;
558       }
559       else
560       {
561          addInterceptor(first, createIfNotExistsInterceptor);
562       }
563
564       // eviction interceptor to come before the optimistic node interceptor
565
if (first == null)
566       {
567          first = evictionInterceptor;
568       }
569       else
570       {
571          addInterceptor(first, evictionInterceptor);
572       }
573
574       if (first == null)
575       {
576          first = nodeInterceptor;
577       }
578       else
579       {
580          addInterceptor(first, nodeInterceptor);
581       }
582
583
584       if (first == null)
585       {
586          first = invokerInterceptor;
587       }
588       else
589       {
590          addInterceptor(first, invokerInterceptor);
591       }
592
593       if (log.isInfoEnabled())
594       {
595          log.info("interceptor chain is:\n" + printInterceptorChain(first));
596       }
597
598       return setLastInterceptorPointer(first, invokerInterceptor);
599    }
600
601    public static String JavaDoc printInterceptorChain(Interceptor i)
602    {
603       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
604       if (i != null)
605       {
606          if (i.getNext() != null)
607          {
608             sb.append(printInterceptorChain(i.getNext())).append("\n");
609          }
610          sb.append(i.getClass());
611       }
612       return sb.toString();
613    }
614
615    public static List JavaDoc<Interceptor> asList(Interceptor interceptor)
616    {
617       if (interceptor == null)
618       {
619          return null;
620       }
621       int num = 1;
622       Interceptor tmp = interceptor;
623       while ((tmp = tmp.getNext()) != null)
624       {
625          num++;
626       }
627       List JavaDoc<Interceptor> retval = new ArrayList JavaDoc<Interceptor>(num);
628       tmp = interceptor;
629       num = 0;
630       do
631       {
632          retval.add(tmp);
633          tmp = tmp.getNext();
634       }
635       while (tmp != null);
636       return retval;
637    }
638
639    /**
640     * "Fixes" the next() and last() pointers for each interceptor, based on the order presented in the list passed in
641     *
642     * @param interceptors
643     * @return the first interceptor in the chain.
644     */

645    public static Interceptor correctInterceptorChaining(List JavaDoc<Interceptor> interceptors)
646    {
647       Interceptor first = null, last = null;
648
649       for (Interceptor next : interceptors)
650       {
651          if (first == null)
652          {
653             first = last = next;
654             continue;
655          }
656          last.setNext(next);
657          last = next;
658       }
659
660       if (last != null) last.setNext(null);
661
662       // now set the 'last' pointer.
663
return setLastInterceptorPointer(first, last);
664    }
665 }
666
Popular Tags