001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.cache.invalidation;
023:
024: import java.io.Serializable;
025: import java.util.HashSet;
026:
027: import javax.management.MBeanParameterInfo;
028: import javax.management.MBeanOperationInfo;
029:
030: import org.jboss.cache.invalidation.InvalidationManager.BridgeInvalidationSubscriptionImpl;
031:
032: /**
033: * Implementation of InvalidationManagerMBean
034: *
035: * @see org.jboss.cache.invalidation.InvalidationManagerMBean
036: *
037: * @author <a href="mailto:sacha.labourey@cogito-info.ch">Sacha Labourey</a>.
038: * @version $Revision: 59578 $
039: */
040: public class InvalidationManager extends
041: org.jboss.system.ServiceMBeanSupport implements
042: InvalidationManagerMBean {
043:
044: // Constants -----------------------------------------------------
045:
046: public static final String DEFAULT_JMX_SERVICE_NAME = "jboss.cache:service=InvalidationManager";
047: public static final String DEFAULT_INVALIDERS_JMX_NAME = "jboss.cache:service=InvalidationGroup";
048:
049: // Attributes ----------------------------------------------------
050:
051: protected java.util.Hashtable groups = new java.util.Hashtable();
052: protected java.util.Vector bridgeSubscribers = new java.util.Vector();
053: protected int hashcode = 0;
054:
055: protected boolean DEFAULT_TO_ASYNCHRONOUS_MODE = false;
056:
057: // Static --------------------------------------------------------
058:
059: // Constructors --------------------------------------------------
060:
061: public InvalidationManager() {
062: super ();
063: }
064:
065: public void startService() throws Exception {
066: // bind us in system registry
067: //
068: log.debug("Starting Invalidation Manager "
069: + this .getServiceName().toString());
070: org.jboss.system.Registry.bind(
071: this .getServiceName().toString(), this );
072: this .hashcode = this .getServiceName().hashCode();
073: }
074:
075: public void stopService() {
076: log.debug("Stoping Invalidation Manager "
077: + this .getServiceName().toString());
078: org.jboss.system.Registry.unbind(this .getServiceName()
079: .toString());
080: }
081:
082: public boolean getIsAsynchByDefault() {
083: return DEFAULT_TO_ASYNCHRONOUS_MODE;
084: }
085:
086: public void setIsAsynchByDefault(boolean flag) {
087: this .DEFAULT_TO_ASYNCHRONOUS_MODE = flag;
088: }
089:
090: public java.util.Collection getInvalidationGroups() {
091: return this .groups.values();
092: }
093:
094: public InvalidationGroup getInvalidationGroup(String groupName) {
095: synchronized (this .groups) {
096: InvalidationGroup group = (InvalidationGroup) this .groups
097: .get(groupName);
098: if (group == null) {
099: group = createGroup(groupName);
100: }
101:
102: group.addReference();
103:
104: return group;
105: }
106: }
107:
108: public synchronized BridgeInvalidationSubscription registerBridgeListener(
109: InvalidationBridgeListener listener) {
110: log.debug("Subscribing a new cache-invalidation bridge");
111: BridgeInvalidationSubscription subs = new BridgeInvalidationSubscriptionImpl(
112: listener);
113:
114: java.util.Vector newVector = new java.util.Vector(
115: this .bridgeSubscribers);
116: newVector.add(subs);
117: this .bridgeSubscribers = newVector;
118:
119: return subs;
120: }
121:
122: public void batchInvalidate(BatchInvalidation[] invalidations) {
123: this .batchInvalidate(invalidations,
124: this .DEFAULT_TO_ASYNCHRONOUS_MODE);
125: }
126:
127: public void batchInvalidate(BatchInvalidation[] invalidations,
128: boolean asynchronous) {
129: if (log.isTraceEnabled())
130: log.trace("Batch cache invalidation. Caches concerned: "
131: + invalidations.length);
132:
133: this .crossDomainBatchInvalidate(null, invalidations,
134: asynchronous);
135: }
136:
137: public void invalidateAll(String groupName) {
138: invalidateAll(groupName, DEFAULT_TO_ASYNCHRONOUS_MODE);
139: }
140:
141: public void invalidateAll(String groupName, boolean async) {
142: if (log.isTraceEnabled())
143: log.trace("Invalidate all for group: " + groupName);
144:
145: crossDomainInvalidateAll(null, groupName, async);
146: }
147:
148: // Public --------------------------------------------------------
149:
150: // Z implementation ----------------------------------------------
151:
152: // Object overrides ---------------------------------------------------
153:
154: public int hashCode() {
155: return hashcode;
156: }
157:
158: // Package protected ---------------------------------------------
159:
160: // Protected -----------------------------------------------------
161:
162: protected InvalidationGroup createGroup(String groupName) {
163: InvalidationGroup group = new org.jboss.cache.invalidation.InvalidationManager.InvalidationGroupImpl(
164: groupName);
165: this .groups.put(groupName, group);
166:
167: // register the group with JMX so it can be easyly remotly
168: // reached (and thus cache can be invalidated)
169: //
170: try {
171: log
172: .debug("Creating and registering a new InvalidationGroup: "
173: + groupName);
174: javax.management.ObjectName groupObjectName = new javax.management.ObjectName(
175: DEFAULT_INVALIDERS_JMX_NAME + ",GroupName="
176: + groupName);
177: this .getServer().registerMBean(group, groupObjectName);
178: } catch (Exception e) {
179: log
180: .debug(
181: "Problem while trying to register a new invalidation group in JMX",
182: e);
183: }
184:
185: // warn bridges
186: //
187: log.debug("Informing bridges about new group creation ...");
188: for (int i = 0; i < bridgeSubscribers.size(); i++)
189: ((BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
190: .elementAt(i))).groupCreated(groupName);
191:
192: return group;
193: }
194:
195: protected void removeGroup(String groupName) {
196: synchronized (this .groups) {
197: this .groups.remove(groupName);
198:
199: // Remove group from JMX
200: //
201: try {
202: log
203: .debug("Removing and JMX-unregistering an InvalidationGroup: "
204: + groupName);
205: javax.management.ObjectName groupObjectName = new javax.management.ObjectName(
206: DEFAULT_INVALIDERS_JMX_NAME + ",GroupName="
207: + groupName);
208: this .getServer().unregisterMBean(groupObjectName);
209: } catch (Exception e) {
210: log
211: .debug(
212: "Problem while trying to un-register a new invalidation group in JMX",
213: e);
214: }
215:
216: // warn bridges
217: //
218: for (int i = 0; i < bridgeSubscribers.size(); i++)
219: ((BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
220: .elementAt(i))).groupDropped(groupName);
221: }
222:
223: }
224:
225: protected synchronized void unregisterBridgeListener(
226: BridgeInvalidationSubscription bridgeSubscriber) {
227: // safe remove to avoid problems with iterators
228: //
229: log.debug("Unsubscription of a cache-invalidation bridge");
230:
231: java.util.Vector newVector = new java.util.Vector(
232: this .bridgeSubscribers);
233: newVector.remove(bridgeSubscriber);
234: this .bridgeSubscribers = newVector;
235: }
236:
237: protected void doLocalOnlyInvalidation(String groupName,
238: Serializable key, boolean asynchronous) {
239: InvalidationGroupImpl group = (InvalidationGroupImpl) this .groups
240: .get(groupName);
241: if (group != null)
242: group.localOnlyInvalidate(key, asynchronous);
243: }
244:
245: protected void doLocalOnlyInvalidations(String groupName,
246: Serializable[] keys, boolean asynchronous) {
247: InvalidationGroupImpl group = (InvalidationGroupImpl) this .groups
248: .get(groupName);
249: if (group != null)
250: group.localOnlyInvalidate(keys, asynchronous);
251: }
252:
253: protected void doLocalOnlyInvalidateAll(String groupName,
254: boolean asynchronous) {
255: InvalidationGroupImpl group = (InvalidationGroupImpl) this .groups
256: .get(groupName);
257: if (group != null)
258: group.localOnlyInvalidateAll();
259: }
260:
261: protected void doBridgedOnlyInvalidation(
262: BridgeInvalidationSubscriptionImpl exceptSource,
263: String groupName, Serializable key) {
264: for (int i = 0; i < bridgeSubscribers.size(); i++) {
265: BridgeInvalidationSubscriptionImpl bridge = (BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
266: .elementAt(i));
267: if (bridge != exceptSource)
268: bridge.bridgedInvalidate(groupName, key,
269: this .DEFAULT_TO_ASYNCHRONOUS_MODE);
270: }
271: }
272:
273: protected void doBridgedOnlyInvalidation(
274: BridgeInvalidationSubscriptionImpl exceptSource,
275: String groupName, Serializable[] keys) {
276: for (int i = 0; i < bridgeSubscribers.size(); i++) {
277: BridgeInvalidationSubscriptionImpl bridge = (BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
278: .elementAt(i));
279: if (bridge != exceptSource)
280: bridge.bridgedInvalidate(groupName, keys,
281: this .DEFAULT_TO_ASYNCHRONOUS_MODE);
282: }
283: }
284:
285: protected void doBridgedOnlyInvalidateAll(
286: BridgeInvalidationSubscriptionImpl exceptSource,
287: String groupName) {
288: for (int i = 0; i < bridgeSubscribers.size(); i++) {
289: BridgeInvalidationSubscriptionImpl bridge = (BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
290: .elementAt(i));
291: if (bridge != exceptSource)
292: bridge.bridgedInvalidateAll(groupName,
293: this .DEFAULT_TO_ASYNCHRONOUS_MODE);
294: }
295: }
296:
297: // this is called when an invalidation occurs in one of the group. Common behaviour
298: // can be groupped here. By default, we simply forward the invalidations to the
299: // available bridges.
300: //
301: protected void localGroupInvalidationEvent(String groupName,
302: Serializable key, boolean asynchronous) {
303: for (int i = 0; i < bridgeSubscribers.size(); i++)
304: ((BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
305: .elementAt(i))).bridgedInvalidate(groupName, key,
306: asynchronous);
307: }
308:
309: protected void localGroupInvalidationsEvent(String groupName,
310: Serializable[] keys, boolean asynchronous) {
311: for (int i = 0; i < bridgeSubscribers.size(); i++)
312: ((BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
313: .elementAt(i))).bridgedInvalidate(groupName, keys,
314: asynchronous);
315: }
316:
317: protected void localGroupInvalidateAllEvent(String groupName,
318: boolean asynchronous) {
319: for (int i = 0; i < bridgeSubscribers.size(); i++)
320: ((BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
321: .elementAt(i))).bridgedInvalidateAll(groupName,
322: asynchronous);
323: }
324:
325: // We warn other groups and the local group (if available)
326: //
327: protected void bridgeGroupInvalidationEvent(
328: BridgeInvalidationSubscriptionImpl source,
329: String groupName, Serializable key) {
330: doBridgedOnlyInvalidation(source, groupName, key);
331: doLocalOnlyInvalidation(groupName, key,
332: this .DEFAULT_TO_ASYNCHRONOUS_MODE);
333: }
334:
335: protected void bridgeGroupInvalidationEvent(
336: BridgeInvalidationSubscriptionImpl source,
337: String groupName, Serializable[] keys) {
338: doBridgedOnlyInvalidation(source, groupName, keys);
339: doLocalOnlyInvalidation(groupName, keys,
340: this .DEFAULT_TO_ASYNCHRONOUS_MODE);
341: }
342:
343: protected void bridgeGroupInvalidateAllEvent(
344: BridgeInvalidationSubscriptionImpl source, String groupName) {
345: doBridgedOnlyInvalidateAll(source, groupName);
346: doLocalOnlyInvalidateAll(groupName,
347: this .DEFAULT_TO_ASYNCHRONOUS_MODE);
348: }
349:
350: protected void crossDomainBatchInvalidate(
351: BridgeInvalidationSubscriptionImpl source,
352: BatchInvalidation[] invalidations, boolean asynchronous) {
353: if (invalidations == null)
354: return;
355:
356: // local invalidation first
357: //
358: for (int i = 0; i < invalidations.length; i++) {
359: BatchInvalidation currInvalid = invalidations[i];
360:
361: doLocalOnlyInvalidations(currInvalid
362: .getInvalidationGroupName(), currInvalid.getIds(),
363: asynchronous);
364: }
365:
366: // bridged invalidation next
367: //
368: for (int i = 0; i < bridgeSubscribers.size(); i++) {
369: BridgeInvalidationSubscriptionImpl bridge = (BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
370: .elementAt(i));
371: if (bridge != source)
372: bridge.bridgedBatchInvalidations(invalidations,
373: asynchronous);
374: }
375: }
376:
377: protected void crossDomainInvalidateAll(
378: BridgeInvalidationSubscriptionImpl source,
379: String groupName, boolean asynchronous) {
380: // local invalidation first
381: //
382: doLocalOnlyInvalidateAll(groupName, asynchronous);
383:
384: // bridged invalidation next
385: //
386: for (int i = 0; i < bridgeSubscribers.size(); i++) {
387: BridgeInvalidationSubscriptionImpl bridge = (BridgeInvalidationSubscriptionImpl) (bridgeSubscribers
388: .elementAt(i));
389: if (bridge != source)
390: bridge.bridgedInvalidateAll(groupName, asynchronous);
391: }
392: }
393:
394: // Private -------------------------------------------------------
395:
396: // Inner classes -------------------------------------------------
397:
398: /**
399: * This class implements the InvalidationGroup interface. It represent the
400: * meeting point of caches and invaliders for a same group.
401: */
402: class InvalidationGroupImpl implements InvalidationGroup,
403: javax.management.DynamicMBean {
404: protected org.jboss.logging.Logger igLog = null;
405: protected String groupName = null;
406: protected boolean asynchronous = DEFAULT_TO_ASYNCHRONOUS_MODE;
407: protected HashSet registered = new HashSet();
408: protected int counter = 0;
409:
410: public int hashCode() {
411: return groupName.hashCode();
412: }
413:
414: public String getGroupName() {
415: return this .groupName;
416: }
417:
418: public InvalidationGroupImpl(String groupName) {
419: this .groupName = groupName;
420: String escapedClass = getClass().getName()
421: .replace('$', '.');
422: this .igLog = org.jboss.logging.Logger
423: .getLogger(escapedClass + "." + groupName);
424: }
425:
426: public InvalidationManagerMBean getInvalidationManager() {
427: return InvalidationManager.this ;
428: }
429:
430: public void invalidate(Serializable key) {
431: this .invalidate(key, this .asynchronous);
432: }
433:
434: public void invalidate(Serializable key, boolean asynchronous) {
435: localOnlyInvalidate(key, asynchronous);
436:
437: localGroupInvalidationEvent(this .groupName, key,
438: asynchronous);
439: }
440:
441: public void invalidate(Serializable[] keys) {
442: this .invalidate(keys, this .asynchronous);
443: }
444:
445: public void invalidate(Serializable[] keys, boolean asynchronous) {
446: localOnlyInvalidate(keys, asynchronous);
447:
448: localGroupInvalidationsEvent(this .groupName, keys,
449: asynchronous);
450: }
451:
452: public void invalidateAll() {
453: invalidateAll(asynchronous);
454: }
455:
456: public void invalidateAll(boolean asynchronous) {
457: localOnlyInvalidateAll();
458: localGroupInvalidateAllEvent(groupName, asynchronous);
459: }
460:
461: public synchronized void register(Invalidatable newRegistered) {
462: // we make a temp copy to avoid concurrency issues with the invalidate method
463: //
464: HashSet newlyRegistered = new HashSet(this .registered);
465: newlyRegistered.add(newRegistered);
466:
467: this .registered = newlyRegistered;
468: }
469:
470: public synchronized void unregister(Invalidatable oldRegistered) {
471: // we make a temp copy to avoid concurrency issues with the invalidate method
472: //
473: HashSet newlyRegistered = new HashSet(this .registered);
474: newlyRegistered.remove(oldRegistered);
475:
476: this .registered = newlyRegistered;
477:
478: this .removeReference();
479: }
480:
481: public void setAsynchronousInvalidation(boolean async) {
482: this .asynchronous = async;
483: }
484:
485: public boolean getAsynchronousInvalidation() {
486: return this .asynchronous;
487: }
488:
489: public void addReference() {
490: counter++;
491: igLog.debug("Counter reference value (++): " + counter);
492: }
493:
494: public int getReferenceCount() {
495: return this .counter;
496: }
497:
498: public void removeReference() {
499: counter--;
500: igLog.debug("Counter reference value (--): " + counter);
501:
502: if (counter <= 0) {
503: removeGroup(this .groupName);
504:
505: //Iterator iter = this.registered.iterator ();
506: //while (iter.hasNext ())
507: // ((Invalidatable)iter.next ()).groupIsDropped () ;
508: }
509: }
510:
511: // DynamicMBean implementation ----------------------------------------------
512:
513: public Object getAttribute(String attribute)
514: throws javax.management.AttributeNotFoundException,
515: javax.management.MBeanException,
516: javax.management.ReflectionException {
517: if (attribute == null || attribute.equals(""))
518: throw new IllegalArgumentException(
519: "null or empty attribute name");
520:
521: if (attribute.equals("AsynchronousInvalidation"))
522: return new Boolean(this .asynchronous);
523: else
524: throw new javax.management.AttributeNotFoundException(
525: attribute + " is not a known attribute");
526: }
527:
528: public javax.management.AttributeList getAttributes(
529: java.lang.String[] attributes) {
530: return null;
531: }
532:
533: public javax.management.MBeanInfo getMBeanInfo() {
534:
535: MBeanParameterInfo serSimpleParam = new MBeanParameterInfo(
536: "key", Serializable.class.getName(),
537: "Primary key to be invalidated");
538:
539: MBeanParameterInfo serArrayParam = new MBeanParameterInfo(
540: "keys", Serializable[].class.getName(),
541: "Primary keys to be invalidated");
542:
543: MBeanParameterInfo asynchParam = new MBeanParameterInfo(
544: "asynchronous", Boolean.class.getName(),
545: "Indicates if the invalidation should be asynchronous or must be synchronous");
546:
547: javax.management.MBeanAttributeInfo[] attrInfo = new javax.management.MBeanAttributeInfo[] { new javax.management.MBeanAttributeInfo(
548: "AsynchronousInvalidation",
549: Boolean.class.getName(),
550: "Indicates if invalidation, by default, should be done asynchronously",
551: true, true, false) };
552:
553: MBeanOperationInfo[] opInfo = {
554: new MBeanOperationInfo(
555: "invalidate",
556: "invalidate a single key using default (a)synchronous behaviour",
557: new MBeanParameterInfo[] { serSimpleParam },
558: void.class.getName(),
559: MBeanOperationInfo.ACTION),
560:
561: new MBeanOperationInfo(
562: "invalidate",
563: "invalidate a single key indicating the (a)synchronous behaviour",
564: new MBeanParameterInfo[] { serSimpleParam,
565: asynchParam },
566: void.class.getName(),
567: MBeanOperationInfo.ACTION),
568:
569: new MBeanOperationInfo(
570: "invalidate",
571: "invalidate multiple keys using default (a)synchronous behaviour",
572: new MBeanParameterInfo[] { serArrayParam },
573: void.class.getName(),
574: MBeanOperationInfo.ACTION),
575:
576: new MBeanOperationInfo(
577: "invalidate",
578: "invalidate multiple keys indicating the (a)synchronous behaviour",
579: new MBeanParameterInfo[] { serArrayParam,
580: asynchParam },
581: void.class.getName(),
582: MBeanOperationInfo.ACTION),
583:
584: new MBeanOperationInfo(
585: "invalidateAll",
586: "invalidate all keys using default (a)synchronous behaviour",
587: new MBeanParameterInfo[] {}, void.class
588: .getName(),
589: MBeanOperationInfo.ACTION),
590:
591: new MBeanOperationInfo(
592: "invalidateAll",
593: "invalidate all keys with specified (a)synchronous behaviour",
594: new MBeanParameterInfo[] { asynchParam },
595: void.class.getName(),
596: MBeanOperationInfo.ACTION) };
597:
598: javax.management.MBeanNotificationInfo[] notifyInfo = null;
599: javax.management.MBeanConstructorInfo[] ctorInfo = new javax.management.MBeanConstructorInfo[] {};
600:
601: return new javax.management.MBeanInfo(getClass().getName(),
602: "Cache invalidation for group named "
603: + this .groupName, attrInfo, ctorInfo,
604: opInfo, notifyInfo);
605: }
606:
607: public java.lang.Object invoke(java.lang.String actionName,
608: java.lang.Object[] params, java.lang.String[] signature)
609: throws javax.management.MBeanException,
610: javax.management.ReflectionException {
611: if ("invalidate".equals(actionName)) {
612: if (params.length == 1) {
613: if (params[0] instanceof Serializable[])
614: this .invalidate((Serializable[]) params[0]);
615: else if (params[0] instanceof Serializable)
616: this .invalidate((Serializable) params[0]);
617: else
618: throw new IllegalArgumentException(
619: "First argument must be Serializable (or array of)");
620: } else if (params.length == 2) {
621: if (params[0] instanceof Serializable[])
622: this .invalidate((Serializable[]) params[0],
623: ((Boolean) params[1]).booleanValue());
624: else if (params[0] instanceof Serializable)
625: this .invalidate((Serializable) params[0],
626: ((Boolean) params[1]).booleanValue());
627: else
628: throw new IllegalArgumentException(
629: "First argument must be Serializable (or array of)");
630: } else {
631: throw new IllegalArgumentException(
632: "Unknown operation with these parameters: "
633: + actionName);
634: }
635: } else if ("invalidateAll".equals(actionName)) {
636: if (params == null || params.length == 0) {
637: this .invalidateAll();
638: } else if (params.length == 1) {
639: this .invalidateAll(((Boolean) params[1])
640: .booleanValue());
641: } else {
642: throw new IllegalArgumentException(
643: "invalidateAll can take zero or one parameter but got "
644: + params.length);
645: }
646: } else {
647: throw new IllegalArgumentException(
648: "Unknown operation: " + actionName);
649: }
650: return null;
651: }
652:
653: public void setAttribute(javax.management.Attribute attribute)
654: throws javax.management.AttributeNotFoundException,
655: javax.management.InvalidAttributeValueException,
656: javax.management.MBeanException,
657: javax.management.ReflectionException {
658: String attrName = attribute.getName();
659: if (attrName == null || attrName.equals(""))
660: throw new IllegalArgumentException(
661: "null or empty attribute name");
662:
663: if (attrName.equals("AsynchronousInvalidation")) {
664: Object value = attribute.getValue();
665: if (value instanceof Boolean)
666: this .asynchronous = ((Boolean) value)
667: .booleanValue();
668: else
669: throw new javax.management.InvalidAttributeValueException(
670: "Attribute is of boolean type");
671: } else
672: throw new javax.management.AttributeNotFoundException(
673: attrName + " is not a known attribute");
674: }
675:
676: public javax.management.AttributeList setAttributes(
677: javax.management.AttributeList attributes) {
678: return null;
679: }
680:
681: // Protected ------------------------------------------------------------------------
682:
683: protected void localOnlyInvalidate(Serializable[] keys,
684: boolean asynchronous) {
685: java.util.Iterator iter = this .registered.iterator();
686: while (iter.hasNext()) {
687: Invalidatable inv = (Invalidatable) iter.next();
688: inv.areInvalid(keys);
689: }
690: }
691:
692: protected void localOnlyInvalidate(Serializable key,
693: boolean asynchronous) {
694: java.util.Iterator iter = this .registered.iterator();
695: while (iter.hasNext()) {
696: Invalidatable inv = (Invalidatable) iter.next();
697: inv.isInvalid(key);
698: }
699:
700: }
701:
702: protected void localOnlyInvalidateAll() {
703: java.util.Iterator iter = this .registered.iterator();
704: while (iter.hasNext()) {
705: Invalidatable inv = (Invalidatable) iter.next();
706: inv.invalidateAll();
707: }
708: }
709: }
710:
711: // *******************************************************************************************33
712: // *******************************************************************************************33
713: // *******************************************************************************************33
714:
715: class BridgeInvalidationSubscriptionImpl implements
716: BridgeInvalidationSubscription {
717:
718: protected InvalidationBridgeListener listener = null;
719:
720: public BridgeInvalidationSubscriptionImpl(
721: InvalidationBridgeListener listener) {
722: this .listener = listener;
723: }
724:
725: public void invalidate(String invalidationGroupName,
726: Serializable key) {
727: bridgeGroupInvalidationEvent(this , invalidationGroupName,
728: key);
729: }
730:
731: public void invalidate(String invalidationGroupName,
732: Serializable[] keys) {
733: bridgeGroupInvalidationEvent(this , invalidationGroupName,
734: keys);
735: }
736:
737: public void invalidateAll(String groupName) {
738: bridgeGroupInvalidateAllEvent(this , groupName);
739: }
740:
741: public void batchInvalidate(BatchInvalidation[] invalidations) {
742: crossDomainBatchInvalidate(this , invalidations,
743: DEFAULT_TO_ASYNCHRONOUS_MODE);
744:
745: }
746:
747: public void unregister() {
748: unregisterBridgeListener(this );
749: }
750:
751: // Internal callbacks
752: //
753:
754: protected void bridgedInvalidate(String invalidationGroupName,
755: Serializable key, boolean asynchronous) {
756: this .listener.invalidate(invalidationGroupName, key,
757: asynchronous);
758: }
759:
760: protected void bridgedInvalidate(String invalidationGroupName,
761: Serializable[] keys, boolean asynchronous) {
762: this .listener.invalidate(invalidationGroupName, keys,
763: asynchronous);
764: }
765:
766: protected void bridgedInvalidateAll(
767: String invalidationGroupName, boolean asynchronous) {
768: this .listener.invalidateAll(invalidationGroupName,
769: asynchronous);
770: }
771:
772: protected void bridgedBatchInvalidations(
773: BatchInvalidation[] invalidations, boolean asynchronous) {
774: this .listener.batchInvalidate(invalidations, asynchronous);
775: }
776:
777: protected void groupCreated(String invalidationGroupName) {
778: this .listener.newGroupCreated(invalidationGroupName);
779: }
780:
781: protected void groupDropped(String invalidationGroupName) {
782: this.listener.groupIsDropped(invalidationGroupName);
783: }
784:
785: }
786: }
|