001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 TASC
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: package org.cougaar.glm.plugins.multiplesuppliers;
027:
028: import java.util.Enumeration;
029:
030: import org.cougaar.core.blackboard.IncrementalSubscription;
031: import org.cougaar.core.service.LoggingService;
032: import org.cougaar.glm.ldm.asset.Organization;
033: import org.cougaar.lib.util.UTILPrepPhrase;
034: import org.cougaar.planning.ldm.plan.Allocation;
035: import org.cougaar.planning.ldm.plan.AllocationResult;
036: import org.cougaar.planning.ldm.plan.PlanElement;
037: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
038: import org.cougaar.planning.ldm.plan.Task;
039: import org.cougaar.planning.plugin.legacy.SimplePlugin;
040: import org.cougaar.util.UnaryPredicate;
041:
042: /**
043: * The Base SourceAllocator class.
044: */
045: public class SourceAllocator extends SimplePlugin {
046: // The implemented approach for SOURCE logic requires all suppliers to have the SOURCE plugins.
047: // An alternate approach sends SUPPLY tasks to clusters that don't have MultipleSupplierCapable role.
048: // The downside of this approach is that all SUPPLY plugins must ignore SUPPLY tasks whose parent task
049: // is a SOURCE task. In this alternate approach, SOURCE-capable clusters must have a role of MultipleSupplierCapable.
050:
051: private String clusterName = null;
052:
053: private IncrementalSubscription sourceSubtasks = null;
054: private IncrementalSubscription allocations = null;
055:
056: static class SourceSubtasksP implements UnaryPredicate {
057: public boolean execute(Object o) {
058: if (o instanceof Task) {
059: Task task = (Task) o;
060: if (task.getVerb().toString().equals(Grammar.SOURCE)
061: && task.getWorkflow() != null) {
062: return true;
063: }
064: }
065: return false;
066: }
067: }
068:
069: static class AllocationsP implements UnaryPredicate {
070: public boolean execute(Object o) {
071: if (o instanceof Allocation) {
072: return true;
073: }
074: return false;
075: }
076: }
077:
078: /**
079: * rely upon load-time introspection to set these services -
080: * don't worry about revokation.
081: */
082: public final void setLoggingService(LoggingService bs) {
083: logger = bs;
084:
085: prepHelper = new UTILPrepPhrase(logger);
086: }
087:
088: /**
089: * Get the logging service, for subclass use.
090: */
091: protected LoggingService getLoggingService() {
092: return logger;
093: }
094:
095: /**
096: * This method is meant to be overridden by subclasses for those instances where
097: * the subclass needs to do any initialization at the beginning of each execute() loop.
098: * The defualt implementation of this method does nothing.
099: */
100: protected void transactInit() {
101: }
102:
103: /**
104: * This method is meant to be overridden by subclasses for those instances where
105: * the sublass needs to do processing when a task change is detected.
106: * The defualt implementation of this method does nothing.
107: * @param task a Task that has marked as changed.
108: */
109: protected void handleChangedTask(Task task) {
110: }
111:
112: /**
113: * This method is meant to be overridden by subclasses for those instances where
114: * the sublass needs to do processing when a task removal is detected.
115: * The defualt implementation of this method does nothing.
116: * @param task a Task that has marked as removed.
117: */
118: protected void handleRemovedTask(Task task) {
119: }
120:
121: /**
122: * This method is meant to be overridden by subclasses for those instances where
123: * the sublass needs to do processing when an allocation removal is detected.
124: * The defuat implementation of this method does nothing.
125: * @param allocation an Allocation that has marked as removed.
126: */
127: protected void handleRemovedAllocation(Allocation allocation) {
128: }
129:
130: public String getClusterName() {
131: return clusterName;
132: }
133:
134: /**
135: * Standard SimplePlugin method.
136: * Store cluster name and setup subscriptions for SOURCE subtasks and for Allocations.
137: */
138: protected void setupSubscriptions() {
139: clusterName = getMessageAddress().getAddress();
140: sourceSubtasks = (IncrementalSubscription) subscribe(new SourceSubtasksP());
141: allocations = (IncrementalSubscription) subscribe(new AllocationsP());
142: }
143:
144: public void execute() {
145: // Call transactionInit() first.
146: // This way subclasses can do initialization at the beginning of each execute() loop.
147: transactInit();
148:
149: if (allocations != null && allocations.hasChanged()) {
150: Enumeration removedAllocationsEnum = allocations
151: .getRemovedList();
152: while (removedAllocationsEnum.hasMoreElements()) {
153: Allocation allocation = (Allocation) removedAllocationsEnum
154: .nextElement();
155: handleRemovedAllocation(allocation);
156: }
157:
158: Enumeration changedAllocationsEnum = allocations
159: .getChangedList();
160: while (changedAllocationsEnum.hasMoreElements()) {
161: Allocation allocation = (Allocation) changedAllocationsEnum
162: .nextElement();
163: allocatorRollup(allocation);
164: }
165: }
166:
167: if (sourceSubtasks != null && sourceSubtasks.hasChanged()) {
168: Enumeration addedSubtasks = sourceSubtasks.getAddedList();
169: while (addedSubtasks.hasMoreElements()) {
170: Task subtask = (Task) addedSubtasks.nextElement();
171: allocateTask(subtask);
172: }
173: Enumeration changedSubtasks = sourceSubtasks
174: .getChangedList();
175: while (changedSubtasks.hasMoreElements()) {
176: Task subtask = (Task) changedSubtasks.nextElement();
177: handleChangedTask(subtask);
178: }
179: Enumeration removedSubtasks = sourceSubtasks
180: .getRemovedList();
181: while (removedSubtasks.hasMoreElements()) {
182: Task subtask = (Task) removedSubtasks.nextElement();
183: handleRemovedTask(subtask);
184: }
185: }
186: }
187:
188: /**
189: * This plugin's execute() method calls this method when allocations are marked as changed
190: * in order to rollup AllocationResults.
191: * @param pe the changed PlanElement
192: */
193: private void allocatorRollup(PlanElement pe) {
194: if (pe.getReportedResult() != null) {
195: Task task = pe.getTask();
196: String verb = task.getVerb().toString();
197: if (verb.equals(Grammar.SOURCE)) {
198: AllocationResult reportedResult = pe
199: .getReportedResult();
200: AllocationResult estimatedResult = pe
201: .getEstimatedResult();
202: if (estimatedResult == null
203: || estimatedResult != reportedResult) {
204: pe.setEstimatedResult(reportedResult);
205: publishChange(pe);
206: }
207: }
208: }
209: }
210:
211: /**
212: * This plugin's execute method calls this method when new SOURCE tasks are detected.
213: */
214: private boolean allocateTask(Task task) {
215: boolean retval = true;
216:
217: String verbStr = task.getVerb().toString();
218: if (verbStr.equals(Grammar.SOURCE)) {
219: PrepositionalPhrase pPhrase = prepHelper.getPrepNamed(task,
220: Grammar.USESUPPLIER);
221: if (pPhrase == null) {
222: System.out
223: .println("SourceAllocator.allocateTask: SOURCE task missing USESUPPLIER phrase");
224: return false;
225: } else {
226: Organization supplier = (Organization) pPhrase
227: .getIndirectObject();
228: if (supplier != null) {
229: publishAdd(Utility.createAllocation(getFactory(),
230: task, supplier, 0.0, 0.0));
231: } else {
232: publishAdd(Utility.makeFailedDisposition(theLDMF,
233: task));
234: }
235: }
236: } else {
237: retval = false;
238: }
239: return retval;
240: }
241:
242: protected LoggingService logger;
243: protected UTILPrepPhrase prepHelper;
244: }
|