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.mlm.plugin.sample;
028:
029: import java.util.Enumeration;
030: import java.util.Vector;
031:
032: import org.cougaar.core.blackboard.IncrementalSubscription;
033: import org.cougaar.glm.ldm.Constants;
034: import org.cougaar.glm.ldm.plan.GeolocLocation;
035: import org.cougaar.planning.ldm.asset.AssetGroup;
036: import org.cougaar.planning.ldm.plan.Aggregation;
037: import org.cougaar.planning.ldm.plan.AllocationResult;
038: import org.cougaar.planning.ldm.plan.AspectType;
039: import org.cougaar.planning.ldm.plan.AuxiliaryQueryType;
040: import org.cougaar.planning.ldm.plan.NewComposition;
041: import org.cougaar.planning.ldm.plan.NewMPTask;
042: import org.cougaar.planning.ldm.plan.Plan;
043: import org.cougaar.planning.ldm.plan.PlanElement;
044: import org.cougaar.planning.ldm.plan.Preference;
045: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
046: import org.cougaar.planning.ldm.plan.Task;
047: import org.cougaar.planning.ldm.plan.Verb;
048: import org.cougaar.planning.plugin.legacy.SimplePlugin;
049: import org.cougaar.util.UnaryPredicate;
050:
051: public class MCCAggregatorPlugin extends SimplePlugin {
052:
053: private IncrementalSubscription myTasks;
054: private IncrementalSubscription myAggs;
055: private Vector tasks_to_aggregate = new Vector();
056: private static long ONE_DAY = 86400000L;
057:
058: // Predicate for _ALL_ TRANSPORT Tasks
059: private static UnaryPredicate taskPred() {
060: return new UnaryPredicate() {
061: public boolean execute(Object o) {
062: if (o instanceof Task) {
063: Task t = (Task) o;
064: if (t.getVerb().equals(Constants.Verb.TRANSPORT))
065: return true;
066: }
067: return false;
068: }
069: };
070: }
071:
072: // Predicate for my Aggregations
073: private static UnaryPredicate aggPred() {
074: return new UnaryPredicate() {
075: public boolean execute(Object o) {
076: return (o instanceof Aggregation);
077: }
078: };
079: }
080:
081: public void setupSubscriptions() {
082: // Setup Subscription to all incoming Transport Tasks
083: myTasks = (IncrementalSubscription) subscribe(taskPred());
084: myAggs = (IncrementalSubscription) subscribe(aggPred());
085: }
086:
087: public void execute() {
088: if (myTasks.hasChanged()) {
089: //System.err.println( "\n" + this + ":myTasks.hasChanged!" );
090: Enumeration newTasks = myTasks.getAddedList();
091: while (newTasks.hasMoreElements()) {
092: Task newTask = (Task) newTasks.nextElement();
093: if (newTask.getPlanElement() == null) {
094: aggregate(newTask);
095: }
096: }
097: Enumeration changedTasks = myTasks.getChangedList();
098: while (changedTasks.hasMoreElements()) {
099: Task changedTask = (Task) changedTasks.nextElement();
100: PlanElement oldPE = changedTask.getPlanElement();
101: if (oldPE != null) {
102: publishRemove(oldPE);
103: }
104: aggregate(changedTask);
105: }
106: }
107:
108: if (myAggs.hasChanged()) {
109: Enumeration changedAggs = myAggs.getChangedList();
110: while (changedAggs.hasMoreElements()) {
111: Aggregation agg = (Aggregation) changedAggs
112: .nextElement();
113: updateAllocationResult(agg);
114: }
115: }
116:
117: //} else {
118: // This 'auto-purging' on every execute() call is not the right
119: // thing here; but until it is discovered why the myTasks collection shows
120: // up as hasChanged() == true (always), this will take its place...
121: // Purge the waiting list...
122: if (!(tasks_to_aggregate.isEmpty())) {
123: //System.err.println( "\n" + this + ": Purging..." );
124: Enumeration tasks = tasks_to_aggregate.elements();
125: while (tasks.hasMoreElements()) {
126: Task failedTask = (Task) tasks.nextElement();
127: Vector tmp_tasks = new Vector(1);
128: tmp_tasks.addElement(failedTask);
129: private_createAggregation(tmp_tasks);
130: }
131: tasks_to_aggregate.removeAllElements();
132: }
133: wakeAfter(15000L);
134: }
135:
136: private void aggregate(Task task) {
137: /*
138: * We want to group like Tasks together here; by "like" we mean:
139: * - Same Verb (Transport)
140: * - Make Aggregations of two Tanks/HET
141: * - Tasks have same locations
142: * - Tasks have same Dates (allow some fuzziness here)
143: *
144: * Initially, this is going to use a simple approach, using
145: * the DefaultARDistributer.
146: */
147: Enumeration waitingTasks = tasks_to_aggregate.elements();
148: while (waitingTasks.hasMoreElements()) {
149: Task waitingTask = (Task) waitingTasks.nextElement();
150: if (compare(waitingTask, task)) {
151: tasks_to_aggregate.remove(waitingTask);
152: Vector tmp_tasks = new Vector(2);
153: tmp_tasks.addElement(waitingTask);
154: tmp_tasks.addElement(task);
155: private_createAggregation(tmp_tasks);
156: return;
157: }
158: }
159: tasks_to_aggregate.addElement(task);
160: }
161:
162: private boolean compare(Task task1, Task task2) {
163: if ((task1.getVerb().equals(Constants.Verb.TRANSPORT))
164: && (task2.getVerb().equals(Constants.Verb.TRANSPORT))) {
165: Enumeration task1PPs = task1.getPrepositionalPhrases();
166: Enumeration task2PPs = task2.getPrepositionalPhrases();
167: PrepositionalPhrase task1From = null;
168: PrepositionalPhrase task2From = null;
169: PrepositionalPhrase task1To = null;
170: PrepositionalPhrase task2To = null;
171: while (task1PPs.hasMoreElements()) {
172: PrepositionalPhrase pp = (PrepositionalPhrase) task1PPs
173: .nextElement();
174: if (pp.getPreposition().equals(
175: Constants.Preposition.FROM))
176: task1From = pp;
177: if (pp.getPreposition()
178: .equals(Constants.Preposition.TO))
179: task1To = pp;
180: }
181: while (task2PPs.hasMoreElements()) {
182: PrepositionalPhrase pp = (PrepositionalPhrase) task2PPs
183: .nextElement();
184: if (pp.getPreposition().equals(
185: Constants.Preposition.FROM))
186: task2From = pp;
187: if (pp.getPreposition()
188: .equals(Constants.Preposition.TO))
189: task2To = pp;
190: }
191: if ((task1From != null) && (task2From != null)
192: && (task1To != null) && (task2To != null)) {
193: GeolocLocation t1FromWhere = (GeolocLocation) task1From
194: .getIndirectObject();
195: GeolocLocation t2FromWhere = (GeolocLocation) task2From
196: .getIndirectObject();
197: GeolocLocation t1ToWhere = (GeolocLocation) task1To
198: .getIndirectObject();
199: GeolocLocation t2ToWhere = (GeolocLocation) task2To
200: .getIndirectObject();
201: if ((t1FromWhere.getGeolocCode().equals(t2FromWhere
202: .getGeolocCode()))
203: && (t1ToWhere.getGeolocCode().equals(t2ToWhere
204: .getGeolocCode()))) {
205: Enumeration t1Prefs = task1.getPreferences();
206: Enumeration t2Prefs = task2.getPreferences();
207: // We're really only concerned with the END_TIMEs here...
208: Preference t1EndPref = null;
209: Preference t2EndPref = null;
210: while (t1Prefs.hasMoreElements()) {
211: Preference pref = (Preference) t1Prefs
212: .nextElement();
213: if (pref.getAspectType() == AspectType.END_TIME)
214: t1EndPref = pref;
215: }
216: while (t2Prefs.hasMoreElements()) {
217: Preference pref = (Preference) t2Prefs
218: .nextElement();
219: if (pref.getAspectType() == AspectType.END_TIME)
220: t2EndPref = pref;
221: }
222: if ((t1EndPref != null) && (t2EndPref != null)) {
223: long diff = t1EndPref.getScoringFunction()
224: .getBest().getAspectValue().longValue()
225: - t2EndPref.getScoringFunction()
226: .getBest().getAspectValue()
227: .longValue();
228:
229: if (Math.abs(diff) < ONE_DAY)
230:
231: return true;
232: }
233: }
234: }
235: }
236: return false;
237: }
238:
239: //private void createAggregation( Task task1, Task task2 ) {
240: private void private_createAggregation(Vector tasks) {
241: //Vector tasks = new Vector();
242: //tasks.addElement( task1 );
243: //tasks.addElement( task2 );
244: if (!(tasks.isEmpty())) {
245: Vector assets = getAssets(tasks);
246: //assets.addElement( task1.getDirectObject() );
247: //assets.addElement( task2.getDirectObject() );
248:
249: NewMPTask combTask = theLDMF.newMPTask();
250: combTask.setParentTasks(tasks.elements());
251: combTask.setVerb(Verb
252: .get(Constants.Verb.TRANSPORTATIONMISSION));
253: AssetGroup ag = new AssetGroup();
254: ag.setAssets(assets);
255: combTask.setDirectObject(ag);
256: combTask.setPlan(private_getPlan(tasks));
257: combTask
258: .setPrepositionalPhrases(private_getPrepositionalPhrases(tasks));
259: combTask.setPreferences(private_getPreferences(tasks));
260: // set a request for AuxiliaryQueryType FAILED_REASON
261: int[] aqts = { AuxiliaryQueryType.FAILURE_REASON };
262: combTask.setAuxiliaryQueryTypes(aqts);
263:
264: NewComposition comp = theLDMF.newComposition();
265: Vector aggregations = new Vector();
266: for (Enumeration e = tasks.elements(); e.hasMoreElements();) {
267: Task tmp_task = (Task) e.nextElement();
268: //comp.addParentTask( tmp_task );
269: Aggregation agg = theLDMF.createAggregation(theLDMF
270: .getRealityPlan(), tmp_task, comp, null);
271: aggregations.addElement(agg);
272: }
273: combTask.setComposition(comp);
274: comp.setCombinedTask(combTask);
275: comp.setAggregations(aggregations);
276:
277: for (Enumeration agg_enum = aggregations.elements(); agg_enum
278: .hasMoreElements();) {
279: Aggregation agg = (Aggregation) agg_enum.nextElement();
280: publishAdd(agg);
281: //System.err.println( "\n" + this + ": publishadd( " + agg + " )" );
282: }
283: publishAdd(combTask);
284: //System.err.println( "\n" + this + ": publishadd( " + combTask + " )" );
285: }
286: }
287:
288: //
289: // All of the following will only work under the conditions
290: // where the Tasks belonging to this Vector are from the same Plan,
291: // have the same (limited) PrepositionalPhrases (basically TO and FROMs)
292: // match, and have the same Preferences (or at least the END_TIME Aspects
293: // are the same).
294: //
295: private Plan private_getPlan(Vector tasks) {
296: return ((Task) tasks.firstElement()).getPlan();
297: }
298:
299: private Enumeration private_getPrepositionalPhrases(Vector tasks) {
300: return ((Task) tasks.firstElement()).getPrepositionalPhrases();
301: }
302:
303: private Enumeration private_getPreferences(Vector tasks) {
304: return ((Task) tasks.firstElement()).getPreferences();
305: }
306:
307: private Vector getAssets(Vector tasks) {
308: Vector assets = new Vector();
309: Enumeration task_enum = tasks.elements();
310: while (task_enum.hasMoreElements()) {
311: Task tmp_task = (Task) task_enum.nextElement();
312: assets.addElement(tmp_task.getDirectObject());
313: }
314: return assets;
315: }
316:
317: private void updateAllocationResult(Aggregation agg) {
318: if (agg.getReportedResult() != null) {
319: //System.err.println( "\n" + this + ": updateAllocationResult(" + agg + ")" );
320: // for now just compare the allocation result instances
321: // if they are different objects pass them back up regardless
322: // of their content equalness.
323: AllocationResult reportedresult = agg.getReportedResult();
324: AllocationResult estimatedresult = agg.getEstimatedResult();
325: if ((estimatedresult == null)
326: || (!(estimatedresult == reportedresult))) {
327: agg.setEstimatedResult(reportedresult);
328: // Publish the change (let superclass handle transactions)
329: publishChange(agg);
330: }
331: }
332: }
333:
334: }
|