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.lib.callback;
028:
029: import java.util.Collection;
030: import java.util.HashSet;
031: import java.util.Iterator;
032:
033: import org.cougaar.lib.filter.UTILListeningBufferingThread;
034: import org.cougaar.planning.ldm.plan.Task;
035: import org.cougaar.util.log.Logger;
036:
037: /**
038: * For use with (threaded?) expanders.
039: *
040: * Filters for tasks without workflows or plan elements.
041: */
042:
043: public class UTILBufferingCallback extends UTILFilterCallbackAdapter {
044: public UTILBufferingCallback(UTILGenericListener listener,
045: Logger logger) {
046: super (listener, logger);
047:
048: listenerIsBuffering = myListener instanceof UTILListeningBufferingThread;
049: }
050:
051: /**
052: * Called when new, changed, or removed tasks fall into or out of container.
053: *
054: * Tells listener about new tasks that are fit to be handled. Checks each
055: * to see if well formed. Only tells listener of well formed tasks.
056: *
057: * Has debug logger.info to tell how many new tasks have arrived. Also to tell
058: * how many expandable tasks have been removed from container.
059: *
060: * @see #isWellFormed
061: */
062:
063: public void reactToChangedFilter() {
064: int i = 0;
065:
066: Collection removedCollection = mySub.getRemovedCollection();
067:
068: Collection tasksForListener = new HashSet();
069:
070: for (Iterator iter = mySub.getAddedCollection().iterator(); iter
071: .hasNext();) {
072: Task t = (Task) iter.next();
073: if (removedCollection.contains(t))
074: continue;
075:
076: if (isWellFormed(t)) {
077:
078: if (!listenerIsBuffering)
079: ((UTILGenericListener) myListener).handleTask(t);
080: else
081: tasksForListener.add(t);
082:
083: if (logger.isDebugEnabled())
084: logger.debug("UTILBufferingCallback : Notifying "
085: + myListener + " about " + t.getUID());
086: i++;
087: }
088: }
089:
090: for (Iterator iter = mySub.getChangedCollection().iterator(); iter
091: .hasNext();) {
092: Task changedT = (Task) iter.next();
093: if (removedCollection.contains(changedT))
094: continue;
095: if (isWellFormed(changedT)) {
096:
097: if (!listenerIsBuffering)
098: ((UTILGenericListener) myListener)
099: .handleTask(changedT);
100: else
101: tasksForListener.add(changedT);
102:
103: if (logger.isDebugEnabled())
104: logger.debug("UTILBufferingCallback : Notifying "
105: + myListener + " about changed task "
106: + changedT.getUID());
107: i++;
108: }
109: }
110:
111: if (listenerIsBuffering)
112: ((UTILListeningBufferingThread) myListener)
113: .handleAll(tasksForListener);
114:
115: if (!mySub.getAddedCollection().isEmpty()
116: || !mySub.getChangedCollection().isEmpty()) {
117: // synchronize ????????
118: if (logger.isInfoEnabled())
119: logger.info("UTILBufferingCallback : Notifying "
120: + myListener + " about " + i + " tasks");
121: if (logger.isInfoEnabled())
122: logger
123: .info("mySub had added or changed tasks - regardless of whether they are wellformed, we are waking up the listener");
124: ((UTILGenericListener) myListener).wakeUp();
125: }
126:
127: if (!mySub.getRemovedCollection().isEmpty()) {
128: for (Iterator iter = mySub.getRemovedCollection()
129: .iterator(); iter.hasNext();) {
130: Task t = (Task) iter.next();
131: if (logger.isDebugEnabled())
132: logger
133: .debug("UTILBufferingCallback : Telling listener that task "
134: + t.getUID() + " was removed.");
135: ((UTILGenericListener) myListener).handleRemovedTask(t);
136: }
137: }
138: }
139:
140: /**
141: * Place where you can react to rehydration event.
142: *
143: * If the blackboard says "didRehydrate" then each callback
144: * that is a RehydrateReactor will be called here.
145: * This can happen on an agent move too.
146: *
147: * NOTE : The plugin will only look at *unplanned* tasks on rehydration.
148: * I don't think this will cause problems.
149: * Fix for bug #3356: http://bugs.cougaar.org/show_bug.cgi?id=3356
150: *
151: * @see org.cougaar.lib.filter.UTILPluginAdapter#execute
152: */
153: public void reactToRehydrate() {
154: Collection contents = mySub.getCollection();
155:
156: if (logger.isInfoEnabled())
157: logger
158: .info("UTILBufferingCallback.reactToRehydrate - Notifying "
159: + myListener
160: + " about "
161: + contents.size()
162: + " previously buffered tasks.");
163:
164: // Only want to call wakeUp if some tasks still match
165: boolean workToBeDone = false;
166: for (Iterator iter = contents.iterator(); iter.hasNext();) {
167: Task t = (Task) iter.next();
168:
169: if (isWellFormed(t)) {
170: if (t.getPlanElement() == null) { // fix for bug #3356 - only look at unplanned tasks on rehydration
171: workToBeDone = true; // Will need to have plugin wake up later
172: ((UTILGenericListener) myListener).handleTask(t);
173: if (logger.isDebugEnabled())
174: logger
175: .debug("UTILBufferingCallback.reactToRehydrate - Notifying "
176: + myListener
177: + " about "
178: + t.getUID());
179: }
180: }
181: }
182:
183: if (workToBeDone) {
184: if (logger.isDebugEnabled())
185: logger
186: .debug("UTILBufCal.react: asking listener to wake up?");
187: ((UTILGenericListener) myListener).wakeUp();
188: }
189: }
190:
191: protected boolean isWellFormed(Task task) {
192: return true;
193: }
194:
195: boolean listenerIsBuffering = myListener instanceof UTILListeningBufferingThread;
196: }
|