001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.blackboard;
028:
029: /**
030: * A callback for {@link
031: * org.cougaar.core.service.BlackboardService#registerInterest}
032: * subscription or alarm activity.
033: * <p>
034: * On the {@link #signalNotify} callback, the watcher should schedule
035: * itself to run in a separate thread, e.g. by using the {@link
036: * org.cougaar.core.service.ThreadService}.
037: * <p>
038: * Most of this could likely be removed and replaced with a simple
039: * {@link org.cougaar.core.thread.Schedulable#start}, since most
040: * clients don't check the {@link #signalNotify} "event" and the
041: * {@link Subscriber} has a {@link Subscriber#wasClientActivity}
042: * method that's equivalent to {@link #clearSignal}.
043: */
044: public class SubscriptionWatcher {
045:
046: // this class supports a wait/notify semaphore, but clients
047: // are encouraged to rely on the "signalNotify" callback instead
048: // of blocking.
049:
050: public final static int EXTERNAL = 1;
051: public final static int INTERNAL = 2;
052: public final static int CLIENT = 3;
053:
054: /** have the collections changed since we last looked? */
055: protected boolean externalFlag = false;
056: protected boolean internalFlag = false;
057: protected boolean clientFlag = false;
058:
059: /**
060: * Some blackboard activity has occured, so the watcher should
061: * schedule a separate thread, open a transaction, check if its
062: * subscriptions have changed, and finish the transaction.
063: */
064: public synchronized void signalNotify(int event) {
065: switch (event) {
066: case EXTERNAL:
067: externalFlag = true;
068: break;
069: case INTERNAL:
070: internalFlag = true;
071: break;
072: case CLIENT:
073: clientFlag = true;
074: break;
075: default:
076: break;
077: }
078: notifyAll();
079: }
080:
081: /**
082: * Wait for a signal to continue.
083: * @return true iff the wake signal is unconditional.
084: */
085: public synchronized boolean waitForSignal() {
086: while (!test()) {
087: try {
088: wait();
089: } catch (InterruptedException ie) {
090: }
091: }
092: return clearSignal();
093: }
094:
095: public synchronized boolean clearSignal() {
096: boolean retval = clientFlag || internalFlag;
097:
098: externalFlag = false;
099: internalFlag = false;
100: clientFlag = false;
101:
102: return retval;
103: }
104:
105: /**
106: * @return true IFF it is time to wake up.
107: * by default, this will return true when any of
108: * externalFlag, internalFlag and clientFlag are true.
109: */
110: protected boolean test() {
111: return (externalFlag || internalFlag || clientFlag);
112: //return (externalFlag || clientFlag);
113: }
114:
115: }
|