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.Collection;
030: import java.util.Date;
031: import java.util.Enumeration;
032: import java.util.Iterator;
033: import java.util.Vector;
034:
035: import org.cougaar.core.blackboard.IncrementalSubscription;
036: import org.cougaar.glm.ldm.Constants;
037: import org.cougaar.glm.ldm.asset.Organization;
038: import org.cougaar.glm.ldm.plan.GeolocLocation;
039: import org.cougaar.glm.ldm.plan.GeolocLocationImpl;
040: import org.cougaar.glm.ldm.plan.NewGeolocLocation;
041: import org.cougaar.planning.ldm.asset.AbstractAsset;
042: import org.cougaar.planning.ldm.asset.Asset;
043: import org.cougaar.planning.ldm.plan.AllocationResult;
044: import org.cougaar.planning.ldm.plan.AspectType;
045: import org.cougaar.planning.ldm.plan.AspectValue;
046: import org.cougaar.planning.ldm.plan.Expansion;
047: import org.cougaar.planning.ldm.plan.NewPrepositionalPhrase;
048: import org.cougaar.planning.ldm.plan.NewTask;
049: import org.cougaar.planning.ldm.plan.NewWorkflow;
050: import org.cougaar.planning.ldm.plan.PlanElement;
051: import org.cougaar.planning.ldm.plan.Predictor;
052: import org.cougaar.planning.ldm.plan.Preference;
053: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
054: import org.cougaar.planning.ldm.plan.Relationship;
055: import org.cougaar.planning.ldm.plan.ScoringFunction;
056: import org.cougaar.planning.ldm.plan.Task;
057: import org.cougaar.planning.ldm.plan.Workflow;
058: import org.cougaar.planning.plugin.legacy.SimplePlugin;
059: import org.cougaar.util.UnaryPredicate;
060:
061: /**
062: * This class implements a Plugin that uses a Predictor (if available) to
063: * generate new subtasks from an incoming parent Task.
064: */
065: public class PredictorExpanderPlugin extends SimplePlugin {
066:
067: //
068: // Begin inner class TransportTuple
069: //
070: private class TransportTuple {
071: private GeolocLocation from;
072: private GeolocLocation to;
073: private Date start_time;
074: private Date end_time;
075:
076: public TransportTuple(GeolocLocation from, GeolocLocation to,
077: Date start_time, Date end_time) {
078: this .from = from;
079: this .to = to;
080: this .start_time = start_time;
081: this .end_time = end_time;
082: }
083:
084: public TransportTuple(Date start_time, Date end_time) {
085: from = to = null;
086: this .start_time = start_time;
087: this .end_time = end_time;
088: }
089:
090: public GeolocLocation getFrom() {
091: return from;
092: }
093:
094: public GeolocLocation getTo() {
095: return to;
096: }
097:
098: public Date getStartTime() {
099: return start_time;
100: }
101:
102: public Date getEndTime() {
103: return end_time;
104: }
105:
106: public void setFrom(GeolocLocation from) {
107: this .from = from;
108: }
109:
110: public void setTo(GeolocLocation to) {
111: this .to = to;
112: }
113: }
114:
115: //
116: // End inner class TransportTuple
117: //
118:
119: private IncrementalSubscription expandableTasks;
120: private IncrementalSubscription myExpansions;
121: private IncrementalSubscription orgAssets;
122:
123: public void setupSubscriptions() {
124: expandableTasks = (IncrementalSubscription) subscribe(candidateTasksPred());
125: myExpansions = (IncrementalSubscription) subscribe(myExpPred());
126: orgAssets = (IncrementalSubscription) subscribe(orgPred());
127: }
128:
129: public void execute() {
130: if (expandableTasks.hasChanged()) {
131: Enumeration newTasks = ((IncrementalSubscription) expandableTasks)
132: .getAddedList();
133: while (newTasks.hasMoreElements()) {
134: Task myTask = (Task) newTasks.nextElement();
135: expand(myTask);
136: }
137: Enumeration changedTasks = ((IncrementalSubscription) expandableTasks)
138: .getChangedList();
139: while (changedTasks.hasMoreElements()) {
140: Task task = (Task) changedTasks.nextElement();
141: PlanElement oldPE = task.getPlanElement();
142: if (oldPE != null) {
143: publishRemove(oldPE);
144: }
145: expand(task);
146: }
147: }
148:
149: if (myExpansions.hasChanged()) {
150: Enumeration changedexps = ((IncrementalSubscription) myExpansions)
151: .getChangedList();
152: while (changedexps.hasMoreElements()) {
153: PlanElement cpe = (PlanElement) changedexps
154: .nextElement();
155: updateAllocationResult(cpe);
156: }
157: }
158: }
159:
160: private void expand(Task task) {
161: NewWorkflow wf = theLDMF.newWorkflow();
162: wf.setParentTask(task);
163: wf.setIsPropagatingToSubtasks(true);
164: TransportTuple tt_0 = new TransportTuple(createGeoloc(
165: "FT STEWART", "HKUZ", "GEORGIA"), createGeoloc(
166: "FT HOOD", "HFTZ", "TEXAS"), new Date((long) task
167: .getPreferredValue(AspectType.START_TIME)), new Date(
168: (long) task.getPreferredValue(AspectType.END_TIME)));
169: Task subtask0 = createTransportLeg(task, wf, tt_0);
170: TransportTuple tt_1 = new TransportTuple(createGeoloc(
171: "FT HOOD", "HFTZ", "TEXAS"), createGeoloc("FT IRWIN",
172: "HFXZ", "CALIFORNIA"), getPrediction(
173: AspectType.END_TIME, subtask0), new Date((long) task
174: .getPreferredValue(AspectType.END_TIME)));
175: Task subtask1 = createTransportLeg(task, wf, tt_1);
176: createTheExpansion(wf, task);
177: }
178:
179: private Date getPrediction(int at, Task task) {
180: Date date = null;
181: for (Iterator iterator = orgAssets.getCollection().iterator(); iterator
182: .hasNext();) {
183: Organization org = (Organization) iterator.next();
184: if (org.isSelf()) {
185: Collection stratTransRelationships = org
186: .getRelationshipSchedule()
187: .getMatchingRelationships(
188: Constants.Role.STRATEGICTRANSPORTATIONPROVIDER);
189:
190: if (stratTransRelationships.size() != 0) {
191: // we only expect one
192: Relationship relationship = (Relationship) stratTransRelationships
193: .iterator().next();
194: Organization transporter = (Organization) org
195: .getRelationshipSchedule().getOther(
196: relationship);
197: AllocationResult ar = createEstimatedAllocationResult(
198: task, transporter);
199: date = new Date((long) ar.getValue(at));
200: break;
201: }
202: }
203: }
204: return date;
205: }
206:
207: private NewGeolocLocation createGeoloc(String name, String geoloc,
208: String statename) {
209: NewGeolocLocation gl = new GeolocLocationImpl();
210: gl.setName(name);
211: gl.setGeolocCode(geoloc);
212: gl.setCountryStateName(statename);
213: return gl;
214: }
215:
216: private Task createTransportLeg(Task task, NewWorkflow wf,
217: TransportTuple tt) {
218: //Verb newverb = Verb.get(Constants.Verb.TRANSPORT);
219: NewTask subtask = theLDMF.newTask();
220: Vector prepphrases = new Vector();
221: //Enumeration origpp = task.getPrepositionalPhrases();
222: //while (origpp.hasMoreElements()) {
223: // PrepositionalPhrase pp = (PrepositionalPhrase)origpp.nextElement();
224: // if ((pp.getPreposition().equals(Constants.Preposition.FOR)) &&
225: // (pp.getIndirectObject() instanceof Asset) ) {
226: // prepphrases.addElement(pp);
227: // }
228: // }
229: NewPrepositionalPhrase newpp = theLDMF.newPrepositionalPhrase();
230: newpp.setPreposition(Constants.Preposition.OFTYPE);
231: AbstractAsset transasset = null;
232: try {
233: Asset trans_proto = theLDMF
234: .createPrototype(
235: Class
236: .forName("org.cougaar.planning.ldm.asset.AbstractAsset"),
237: "StrategicTransportation");
238: transasset = (AbstractAsset) theLDMF
239: .createInstance(trans_proto);
240: } catch (Exception e) {
241: e.printStackTrace();
242: }
243: newpp.setIndirectObject(transasset);
244: prepphrases.addElement(newpp);
245:
246: NewPrepositionalPhrase frompp = theLDMF
247: .newPrepositionalPhrase();
248: frompp.setPreposition(Constants.Preposition.FROM);
249: frompp.setIndirectObject(tt.getFrom());
250: prepphrases.addElement(frompp);
251:
252: NewPrepositionalPhrase topp = theLDMF.newPrepositionalPhrase();
253: topp.setPreposition(Constants.Preposition.TO);
254: topp.setIndirectObject(tt.getTo());
255: prepphrases.addElement(topp);
256:
257: subtask.setParentTask(task);
258: subtask.setDirectObject(task.getDirectObject());
259: subtask.setPrepositionalPhrases(prepphrases.elements());
260: subtask.setVerb(task.getVerb());
261: subtask.setPlan(task.getPlan());
262:
263: Vector prefs = new Vector();
264: AspectValue startAV = AspectValue.newAspectValue(
265: AspectType.START_TIME, tt.getStartTime().getTime());
266: ScoringFunction startSF = ScoringFunction
267: .createPreferredAtValue(startAV, 2);
268: Preference startPref = theLDMF.newPreference(
269: AspectType.START_TIME, startSF);
270: prefs.addElement(startPref);
271:
272: AspectValue endAV = AspectValue.newAspectValue(
273: AspectType.END_TIME, tt.getEndTime().getTime());
274: ScoringFunction endSF = ScoringFunction.createPreferredAtValue(
275: endAV, 2);
276: Preference endPref = theLDMF.newPreference(AspectType.END_TIME,
277: endSF);
278: prefs.addElement(endPref);
279:
280: subtask.setPreferences(prefs.elements());
281: subtask.setSource(getMessageAddress());
282: wf.addTask(subtask);
283: subtask.setWorkflow(wf);
284: publishAdd(subtask);
285:
286: return subtask;
287: }
288:
289: private void createTheExpansion(Workflow wf, Task parent) {
290: PlanElement pe = theLDMF.createExpansion(theLDMF
291: .getRealityPlan(), parent, wf, null);
292: Enumeration e = wf.getTasks();
293: while (e.hasMoreElements()) {
294: publishAdd(e.nextElement());
295: }
296: publishAdd(pe);
297: }
298:
299: private AllocationResult createEstimatedAllocationResult(Task t,
300: Organization org) {
301: Predictor predictor = org.getClusterPG().getPredictor();
302: //AllocationResult est_ar = null;
303: if (predictor != null)
304: return predictor.Predict(t, getDelegate());
305: else
306: return null;
307: }
308:
309: private void updateAllocationResult(PlanElement cpe) {
310: if (cpe.getReportedResult() != null) {
311: // compare the allocationresult objects.
312: // If they are not ==, re-set the estimated result.
313: // For now, ignore whether their composition is equal.
314: AllocationResult reportedresult = cpe.getReportedResult();
315: AllocationResult estimatedresult = cpe.getEstimatedResult();
316: if ((estimatedresult == null)
317: || (!(estimatedresult == reportedresult))) {
318: cpe.setEstimatedResult(reportedresult);
319: // Publish the change (let superclass handle transactions)
320: publishChange(cpe);
321: }
322: }
323: }
324:
325: private static UnaryPredicate destPred() {
326: return new UnaryPredicate() {
327: public boolean execute(Object o) {
328: Task t = (Task) o;
329: PrepositionalPhrase from_tmp = t
330: .getPrepositionalPhrase(Constants.Preposition.FROM);
331: PrepositionalPhrase to_tmp = t
332: .getPrepositionalPhrase(Constants.Preposition.TO);
333: if (from_tmp.getIndirectObject() instanceof GeolocLocation
334: && to_tmp.getIndirectObject() instanceof GeolocLocation) {
335: GeolocLocation from_geo = (GeolocLocation) from_tmp
336: .getIndirectObject();
337: GeolocLocation to_geo = (GeolocLocation) to_tmp
338: .getIndirectObject();
339: if (from_geo.getGeolocCode().equals("HKUZ")
340: && to_geo.getGeolocCode().equals("HFXZ")) {
341: return true;
342: }
343: }
344: return false;
345: }
346: };
347: }
348:
349: private static UnaryPredicate candidateTasksPred() {
350: return new UnaryPredicate() {
351: private UnaryPredicate destPred = destPred();
352:
353: public boolean execute(Object o) {
354: if (o instanceof Task) {
355: Task t = (Task) o;
356: if (t.getVerb().equals(Constants.Verb.TRANSPORT)) {
357: PrepositionalPhrase pp = t
358: .getPrepositionalPhrase(Constants.Preposition.OFTYPE);
359: if (pp != null) {
360: Object indObject = pp.getIndirectObject();
361: if (indObject instanceof Asset) {
362: Asset asset = (Asset) indObject;
363: String io = asset
364: .getTypeIdentificationPG()
365: .getTypeIdentification();
366: if (io
367: .equals("StrategicTransportation")) {
368: return destPred.execute(o);
369: }
370: }
371: }
372: }
373: }
374: return false;
375: }
376: };
377: }
378:
379: private static UnaryPredicate expTasksPred() {
380: return new UnaryPredicate() {
381: private UnaryPredicate candidateTasksPred = candidateTasksPred();
382:
383: public boolean execute(Object o) {
384: if (candidateTasksPred.execute(o)) {
385: Task t = (Task) o;
386: if (t.getPlanElement() == null) {
387: return true;
388: }
389: }
390: return false;
391: }
392: };
393: }
394:
395: private static UnaryPredicate myExpPred() {
396: return new UnaryPredicate() {
397: private UnaryPredicate myTaskPred = candidateTasksPred();
398:
399: public boolean execute(Object o) {
400: if (o instanceof Expansion) {
401: return myTaskPred
402: .execute(((Expansion) o).getTask());
403: }
404: return false;
405: }
406: };
407: }
408:
409: private static UnaryPredicate orgPred() {
410: return new UnaryPredicate() {
411: public boolean execute(Object o) {
412: if (o instanceof Organization) {
413: return true;
414: } else {
415: return false;
416: }
417: }
418: };
419: }
420: }
|