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.planning.ldm.lps;
028:
029: import java.util.Collection;
030: import java.util.Enumeration;
031:
032: import org.cougaar.core.blackboard.EnvelopeTuple;
033: import org.cougaar.core.domain.EnvelopeLogicProvider;
034: import org.cougaar.core.domain.LogicProvider;
035: import org.cougaar.core.domain.RestartLogicProvider;
036: import org.cougaar.core.domain.RestartLogicProviderHelper;
037: import org.cougaar.core.domain.RootPlan;
038: import org.cougaar.core.mts.MessageAddress;
039: import org.cougaar.core.util.UID;
040: import org.cougaar.planning.ldm.LogPlan;
041: import org.cougaar.planning.ldm.PlanningFactory;
042: import org.cougaar.planning.ldm.plan.AllocationResult;
043: import org.cougaar.planning.ldm.plan.MPTask;
044: import org.cougaar.planning.ldm.plan.NewNotification;
045: import org.cougaar.planning.ldm.plan.PEforCollections;
046: import org.cougaar.planning.ldm.plan.PlanElement;
047: import org.cougaar.planning.ldm.plan.Task;
048: import org.cougaar.planning.ldm.plan.TaskScoreTable;
049: import org.cougaar.util.UnaryPredicate;
050: import org.cougaar.util.log.Logger;
051: import org.cougaar.util.log.Logging;
052:
053: /** RescindLogicProvider class provides the logic to capture
054: * rescinded PlanElements (removed from collection)
055: *
056: **/
057: public class NotificationLP implements LogicProvider,
058: EnvelopeLogicProvider, RestartLogicProvider {
059: private static Logger logger = Logging
060: .getLogger(NotificationLP.class);
061:
062: private final RootPlan rootplan;
063: private final LogPlan logplan;
064: private final PlanningFactory ldmf;
065: private final MessageAddress self;
066:
067: public NotificationLP(RootPlan rootplan, LogPlan logplan,
068: PlanningFactory ldmf, MessageAddress self) {
069: this .rootplan = rootplan;
070: this .logplan = logplan;
071: this .ldmf = ldmf;
072: this .self = self;
073: }
074:
075: public void init() {
076: }
077:
078: /**
079: * @param o an Envelope.Tuple.object is an ADDED
080: * PlanElement which contains an Allocation to an Organization.
081: * Do something if the test returned true i.e. it was an Allocation
082: **/
083: public void execute(EnvelopeTuple o, Collection changes) {
084: Object obj = o.getObject();
085: if ((o.isAdd() && (obj instanceof PlanElement))
086: || (o.isChange() && (obj instanceof PlanElement) && ((PEforCollections) obj)
087: .shouldDoNotification())) {
088: PlanElement pe = (PlanElement) obj;
089: if (logger.isDebugEnabled())
090: logger.debug("Got a PE to do checkValues on: "
091: + pe.getUID());
092: checkValues(pe, changes);
093: }
094: }
095:
096: public void restart(final MessageAddress cid) {
097: UnaryPredicate pred = new UnaryPredicate() {
098: public boolean execute(Object o) {
099: if (o instanceof PlanElement) {
100: PlanElement pe = (PlanElement) o;
101: MessageAddress source = pe.getTask().getSource();
102: return RestartLogicProviderHelper.matchesRestart(
103: self, cid, source);
104: }
105: return false;
106: }
107: };
108: Enumeration en = rootplan.searchBlackboard(pred);
109: while (en.hasMoreElements()) {
110: PlanElement pe = (PlanElement) en.nextElement();
111: checkValues(pe, null);
112: }
113: }
114:
115: private void checkValues(PlanElement pe, Collection changes) {
116: checkValues(pe, changes, rootplan, logplan, ldmf, self);
117: }
118:
119: static final void checkValues(PlanElement pe, Collection changes,
120: RootPlan rootplan, LogPlan logplan, PlanningFactory ldmf,
121: MessageAddress self) {
122: Task task = pe.getTask();
123:
124: if (logger.isDebugEnabled()) {
125: logger.debug("\n" + self + ": task = " + task);
126: }
127:
128: ((PEforCollections) pe).setNotification(false);
129: if (task instanceof MPTask) {
130: TaskScoreTable resultsbytask = ((MPTask) task)
131: .getComposition().calculateDistribution();
132: if (resultsbytask != null) {
133: Enumeration etasks = ((MPTask) task).getParentTasks();
134: while (etasks.hasMoreElements()) {
135: Task pt = (Task) etasks.nextElement();
136: if (pt != null) {
137: AllocationResult result = resultsbytask
138: .getAllocationResult(pt);
139: createNotification(pt.getUID(), task, result,
140: changes, rootplan, logplan, ldmf, self);
141: } // else no notification need be generated
142: }
143: }
144: } else {
145: UID ptuid = task.getParentTaskUID();
146: if (ptuid != null) {
147: AllocationResult ar = pe.getEstimatedResult();
148: createNotification(ptuid, task, ar, changes, rootplan,
149: logplan, ldmf, self);
150: } // else no notification need be generated
151: }
152: }
153:
154: static final void createNotification(UID ptuid, Task t,
155: AllocationResult ar, Collection changes, RootPlan rootplan,
156: LogPlan logplan, PlanningFactory ldmf, MessageAddress self) {
157:
158: if (logger.isDebugEnabled()) {
159: PlanElement pe = null;
160: if (t != null) {
161: pe = t.getPlanElement();
162: if (pe != null) {
163: logger.debug("Doing checkNotification for PE: "
164: + pe);
165: }
166: } else {
167: logger.warn("Got null Task in createNotification?!");
168: }
169: }
170:
171: MessageAddress dest = t.getSource();
172: if (self == dest || self.equals(dest.getPrimary())) {
173: // deliver intra-agent notifications directly
174: ReceiveNotificationLP.propagateNotification(rootplan,
175: logplan, ptuid, ar, t.getUID(), changes);
176: } else {
177: // need to send an actual notification
178: NewNotification nn = ldmf.newNotification();
179: nn.setTaskUID(ptuid);
180: nn.setPlan(t.getPlan());
181: nn.setAllocationResult(ar);
182: // set the UID of the child task for Expansion aggregation change purposes
183: nn.setChildTaskUID(t.getUID());
184: if (ptuid == null) {
185: logger
186: .error("createNotification: parent task UID is null for task "
187: + t);
188: }
189:
190: MessageAddress newDest = t.getSource();
191: //MessageAddress newDest = pt.getDestination();
192: MessageAddress newSource = self;
193:
194: nn.setSource(newSource);
195: nn.setDestination(newDest);
196: rootplan.sendDirective(nn, changes);
197: }
198: }
199: }
|