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.Iterator;
031:
032: import org.cougaar.planning.ldm.plan.Allocation;
033: import org.cougaar.planning.ldm.plan.Disposition;
034: import org.cougaar.planning.ldm.plan.PlanElement;
035: import org.cougaar.planning.ldm.plan.Task;
036: import org.cougaar.util.UnaryPredicate;
037: import org.cougaar.util.log.Logger;
038:
039: /**
040: * <pre>
041: * Filters for tasks with workflows, where the tasks
042: * meet the test of isInteresting.
043: *
044: * The reaction to a new workflow is simpler than
045: * UTILSingleTaskWorkflowCallback. This is better
046: * for threaded allocators, where we can't make assumptions
047: * about how the tasks will be handled, like we can with
048: * a one-at-a-time model.
049: * </pre>
050: */
051:
052: public class UTILWorkflowCallback extends UTILBufferingCallback
053: implements UTILRehydrateReactor {
054: public UTILWorkflowCallback(UTILGenericListener listener,
055: Logger logger) {
056: super (listener, logger);
057: }
058:
059: /**
060: * <pre>
061: * Filters for tasks that have workflows.
062: * They are then tested
063: * against the plugin-specific interestingTask test.
064: *
065: * set logger.isDebugEnabled() to true if you want to see logger.info on every
066: * handled task. That is, which tasks have been
067: * allocated and which failed to allocate.
068: * (Previously handled tasks will not be given to the listener.)
069: *
070: * </pre>
071: * @return anonymous UnaryPredicate inner class
072: */
073: protected UnaryPredicate getPredicate() {
074: return new UnaryPredicate() {
075: public boolean execute(Object o) {
076: if (o instanceof Task) {
077: Task subtask = (Task) o;
078:
079: if (subtask.getWorkflow() == null) {
080: return false;
081: }
082:
083: boolean hasBeenAllocated = (subtask
084: .getPlanElement() != null);
085:
086: if (logger.isDebugEnabled())
087: debugInfo(subtask, hasBeenAllocated);
088:
089: UTILGenericListener genericListener = (UTILGenericListener) myListener;
090:
091: boolean interesting = (!hasBeenAllocated && genericListener
092: .interestingTask(subtask));
093:
094: if (logger.isDebugEnabled())
095: logger.debug("UTILWorkflowCallback : For "
096: + myListener + " found task "
097: + subtask.getUID() + " interesting");
098:
099: return interesting;
100: }
101: return false;
102: }
103: };
104: }
105:
106: protected void debugInfo(Task subtask, boolean hasBeenAllocated) {
107: if (hasBeenAllocated) {
108: PlanElement pe = subtask.getPlanElement();
109: if (pe instanceof Allocation)
110: logger.debug("UTILWorkflowCallback - Task "
111: + subtask.getUID() + " has allocation.");
112: else if (pe instanceof Disposition)
113: logger.debug("UTILWorkflowCallback - Task " + subtask
114: + " has failed allocation.");
115: else
116: logger.debug("UTILWorkflowCallback - Task "
117: + subtask.getUID() + " has " + pe);
118: } else {
119: logger.debug("UTILWorkflowCallback - Task "
120: + subtask.getUID() + " has NOT been allocated.");
121: }
122: }
123:
124: /** place where you can react to rehydration event */
125: public void reactToRehydrate() {
126: Collection contents = mySub.getCollection();
127:
128: if (logger.isInfoEnabled())
129: logger
130: .info("UTILWorkflowCallback.reactToRehydrate - Notifying "
131: + myListener
132: + " about "
133: + contents.size()
134: + " previously buffered tasks.");
135:
136: // Only want to call wakeUp if some tasks still match
137: boolean workToBeDone = false;
138: for (Iterator iter = contents.iterator(); iter.hasNext();) {
139: Task t = (Task) iter.next();
140:
141: if (isWellFormed(t)) {
142: workToBeDone = true; // Will need to have plugin wake up later
143: ((UTILGenericListener) myListener).handleTask(t);
144: if (logger.isDebugEnabled())
145: logger
146: .debug("UTILWorkflowCallback.reactToRehydrate - Notifying "
147: + myListener
148: + " about "
149: + t.getUID());
150: }
151: }
152:
153: if (workToBeDone) {
154: if (logger.isDebugEnabled())
155: logger.debug("UTILWorkflwCallback.react asking "
156: + myListener + " to wakeUp");
157: ((UTILGenericListener) myListener).wakeUp();
158: }
159: }
160:
161: /**
162: * Examines an incoming task to see if it is well formed.
163: * Looks at timing information, and asks listener to examine
164: * task as well. If task is ill formed, asks listener to handle
165: * it (probably publish as a failed plan element).
166: */
167: protected boolean isWellFormed(Task task) {
168: UTILGenericListener genericListener = (UTILGenericListener) myListener;
169: if (verify.isTaskTimingCorrect(task)
170: && verify.hasRequiredFields(task)
171: && genericListener.isTaskWellFormed(task))
172: return true;
173: else
174: genericListener.handleIllFormedTask(task);
175:
176: return false;
177: }
178: }
|