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.Iterator;
031: import java.util.Vector;
032:
033: import org.cougaar.core.blackboard.IncrementalSubscription;
034: import org.cougaar.core.mts.MessageAddress;
035: import org.cougaar.glm.ldm.Constants;
036: import org.cougaar.glm.ldm.asset.Organization;
037: import org.cougaar.glm.ldm.plan.GeolocLocationImpl;
038: import org.cougaar.glm.ldm.plan.NewGeolocLocation;
039: import org.cougaar.planning.ldm.PlanningFactory;
040: import org.cougaar.planning.ldm.asset.AbstractAsset;
041: import org.cougaar.planning.ldm.asset.Asset;
042: import org.cougaar.planning.ldm.plan.AllocationResult;
043: import org.cougaar.planning.ldm.plan.AspectType;
044: import org.cougaar.planning.ldm.plan.AspectValue;
045: import org.cougaar.planning.ldm.plan.Expansion;
046: import org.cougaar.planning.ldm.plan.NewExpansion;
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.Preference;
052: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
053: import org.cougaar.planning.ldm.plan.PrepositionalPhraseImpl;
054: import org.cougaar.planning.ldm.plan.ScoringFunction;
055: import org.cougaar.planning.ldm.plan.SubTaskResult;
056: import org.cougaar.planning.ldm.plan.Task;
057: import org.cougaar.planning.ldm.plan.Verb;
058: import org.cougaar.planning.ldm.plan.Workflow;
059: import org.cougaar.planning.plugin.legacy.SimplePlugin;
060: import org.cougaar.planning.plugin.util.ExpanderHelper;
061: import org.cougaar.planning.plugin.util.PluginHelper;
062: import org.cougaar.util.UnaryPredicate;
063:
064: public class StrategicTransportProjectionExpanderPlugin extends
065: SimplePlugin {
066:
067: private IncrementalSubscription myExpansions;
068: private IncrementalSubscription incomingTasks;
069: private IncrementalSubscription nonorgassets;
070: // Look for Failed Dispositions
071: private IncrementalSubscription allocs;
072: private int count = 0;
073: long startTime, endTime;
074:
075: private long now;
076:
077: private final static long ONE_DAY = 24L * 60L * 60L * 1000L;
078: private final static long ONE_WEEK = 7L * ONE_DAY;
079:
080: protected void setupSubscriptions() {
081: now = currentTimeMillis(); // start of run (scenario time)
082: //subscribe to incoming tasks
083: incomingTasks = (IncrementalSubscription) subscribe(taskPred);
084: myExpansions = (IncrementalSubscription) subscribe(expansionPred);
085: nonorgassets = (IncrementalSubscription) subscribe(noassetPred);
086: }
087:
088: protected void execute() {
089: if (incomingTasks.hasChanged()) {
090: for (Enumeration newtasks = incomingTasks.getAddedList(); newtasks
091: .hasMoreElements();) {
092: expand((Task) newtasks.nextElement());
093: }
094: }
095:
096: if (myExpansions.hasChanged()) {
097: watchExpansions(myExpansions.getAddedList());
098: watchExpansions(myExpansions.getChangedList());
099: PluginHelper.updateAllocationResult(myExpansions);
100: }
101: }
102:
103: private void watchExpansions(Enumeration changedExpansions) {
104: while (changedExpansions.hasMoreElements()) {
105: NewExpansion exp = (NewExpansion) changedExpansions
106: .nextElement();
107: for (Iterator iter = exp.getSubTaskResults().iterator(); iter
108: .hasNext();) {
109: SubTaskResult str = (SubTaskResult) iter.next();
110: if (str.hasChanged()) {
111: Task task = str.getTask();
112: AllocationResult repAR = str.getAllocationResult();
113: if (repAR != null && !repAR.isSuccess()) {
114: updatePreferences((NewTask) task);
115: }
116: }
117: }
118: }
119: }
120:
121: private void expand(Task task) {
122: // System.out.println("&&&&&&&&&&&&&&&&& DRtoST Starting to expand");
123: Asset mystuff = null;
124: // System.out.println("&&&&&&&&&&&&&&&&&&&&& DRtoST myComponent is: " + myComponent);
125: MessageAddress me = getMessageAddress();
126: Verb newverb = Verb.get(Constants.Verb.TRANSPORT);
127: startTime = now;
128: // increment date by 5 DAYS
129: now += 5 * ONE_DAY;
130: endTime = now;
131: Vector mypreferences = new Vector();
132: Enumeration e = nonorgassets.elements();
133: NewWorkflow wf = theLDMF.newWorkflow();
134: wf.setIsPropagatingToSubtasks(true);
135: wf.setParentTask(task);
136: AllocationResult estAR = null;
137: if (!e.hasMoreElements()) { // No non-org assets
138: estAR = PluginHelper.createEstimatedAllocationResult(task,
139: theLDMF, 1.0, true);
140: }
141: while (e.hasMoreElements()) {
142: if (++count > 10) {
143: resettime(); // after every 10 tasks, change the date
144: }
145: NewTask subtask = theLDMF.newTask();
146:
147: mystuff = (Asset) e.nextElement();
148: //}
149: if (mystuff != null) {
150: //System.out.println("&&&&&&&&&&&&&&&&&&&&& DRtoST solenoid myasset: " + mystuff);
151: } else {
152: System.err
153: .println("&&&&&&&&&&&&&&&&&&&&&& DRtoST solenoid myasset is NULL!!!");
154: }
155:
156: // Look for prepositionalphrase in parent task, FOR <clusterasset>
157: // and copy it into the new TRANSPORT subtask
158: Vector prepphrases = new Vector();
159: Enumeration origpp = task.getPrepositionalPhrases();
160: while (origpp.hasMoreElements()) {
161: PrepositionalPhrase app = (PrepositionalPhrase) origpp
162: .nextElement();
163: if ((app.getPreposition()
164: .equals(Constants.Preposition.FOR))
165: && (app.getIndirectObject() instanceof Asset)) {
166: prepphrases.addElement(app);
167: }
168: }
169:
170: // create prepositionalphrase oftype strategictransportation
171: NewPrepositionalPhrase pp = theLDMF
172: .newPrepositionalPhrase();
173: pp.setPreposition(Constants.Preposition.OFTYPE);
174: AbstractAsset strans = null;
175: try {
176: PlanningFactory ldmfactory = getFactory();
177: Asset strans_proto = ldmfactory
178: .createPrototype(
179: Class
180: .forName("org.cougaar.planning.ldm.asset.AbstractAsset"),
181: "StrategicTransportation");
182: strans = (AbstractAsset) ldmfactory
183: .createInstance(strans_proto);
184: } catch (Exception exc) {
185: System.out
186: .println("DRtoSTExp - problem creating the abstract strategictransport asset");
187: exc.printStackTrace();
188: }
189: pp.setIndirectObject(strans);
190: prepphrases.addElement(pp);
191:
192: NewPrepositionalPhrase from = new PrepositionalPhraseImpl();
193: from.setPreposition(Constants.Preposition.FROM);
194: NewGeolocLocation fromgl = new GeolocLocationImpl();
195: fromgl.setName("FT STEWART");
196: fromgl.setGeolocCode("HKUZ");
197: fromgl.setCountryStateName("GEORGIA");
198: from.setIndirectObject(fromgl);
199: prepphrases.addElement(from);
200:
201: NewPrepositionalPhrase to = new PrepositionalPhraseImpl();
202: to.setPreposition(Constants.Preposition.TO);
203: NewGeolocLocation togl = new GeolocLocationImpl();
204: togl.setName("FT IRWIN");
205: togl.setGeolocCode("HFXZ");
206: togl.setCountryStateName("CALIFORNIA");
207: to.setIndirectObject(togl);
208: prepphrases.addElement(to);
209:
210: // Create transport task
211: subtask.setParentTask(task);
212: subtask.setDirectObject(mystuff);
213: subtask.setPrepositionalPhrases(prepphrases.elements());
214: subtask.setVerb(newverb);
215: subtask.setPlan(task.getPlan());
216: // create some start and end time preferences
217: mypreferences.removeAllElements();
218: AspectValue startAV = AspectValue.newAspectValue(
219: AspectType.START_TIME, startTime);
220: ScoringFunction startSF = ScoringFunction
221: .createPreferredAtValue(startAV, 2);
222: Preference startPref = theLDMF.newPreference(
223: AspectType.START_TIME, startSF);
224: mypreferences.addElement(startPref);
225: AspectValue endAV = AspectValue.newAspectValue(
226: AspectType.END_TIME, endTime);
227: ScoringFunction endSF = ScoringFunction
228: .createPreferredAtValue(endAV, 2);
229: Preference endPref = theLDMF.newPreference(
230: AspectType.END_TIME, endSF);
231: mypreferences.addElement(endPref);
232: subtask.setPreferences(mypreferences.elements());
233: subtask.setSource(me);
234: wf.addTask(subtask);
235: subtask.setWorkflow(wf);
236: publishAdd(subtask);
237: }
238: publishAdd(wf);
239: createTheExpansion(wf, task, estAR);
240: }
241:
242: // change the start & end time of the tasks
243: private void resettime() {
244: // increment date by 2 DAYS
245: now += 2 * ONE_DAY;
246: startTime = now;
247: // increment date by 5 DAYS
248: now += 5 * ONE_DAY;
249: endTime = now;
250: //reset counter
251: count = 0;
252: }
253:
254: private void createTheExpansion(Workflow wf, Task parent,
255: AllocationResult estAR) {
256: // make the expansion
257: PlanElement pe = theLDMF.createExpansion(theLDMF
258: .getRealityPlan(), parent, wf, estAR);
259: publishAdd(pe);
260: }
261:
262: //If the reported allocation result has been successfully calculated
263: //for the workflow set the estimated equal to the reported to send a
264: //notification back up. This is currently not used. The
265: //NotificationLP is handling propagation of AllocationResults.
266:
267: private void updateAllocationResult(PlanElement cpe) {
268: if (cpe.getReportedResult() != null) {
269: // compare allocationresult objects.
270: // if they are not equal, re-set the estimated result
271: // for now ignore whether the composition of the results are the same.
272: AllocationResult reportedresult = cpe.getReportedResult();
273: AllocationResult estimatedresult = cpe.getEstimatedResult();
274: if ((estimatedresult == null)
275: || (!(estimatedresult.equals(reportedresult)))) {
276: cpe.setEstimatedResult(reportedresult);
277: publishChange(cpe);
278: }
279: }
280: }
281:
282: // If we get a Failed Disposition (AllocationResult.isSuccess() == false),
283: // then we want to change our Preferences a bit and try again...
284: // N.B. if this Plugin was running in a more complex society, we may want to
285: // incorporate some thread-safe code here...
286: private void updatePreferences(NewTask t) {
287: Preference endTimePreference = t
288: .getPreference(AspectType.END_TIME);
289: long old_end = endTimePreference.getScoringFunction().getBest()
290: .getAspectValue().longValue();
291: long new_end = old_end + ONE_WEEK;
292: // // This is what we did until AspectValues were immutable.
293: // endTimePreference.getScoringFunction().getBest().getAspectValue().setValue(new_end);
294:
295: AspectValue endAV = AspectValue.newAspectValue(
296: AspectType.END_TIME, new_end);
297: ScoringFunction endSF = ScoringFunction.createPreferredAtValue(
298: endAV, 2);
299: Preference endPref = theLDMF.newPreference(AspectType.END_TIME,
300: endSF);
301: t.setPreference(endPref);
302:
303: publishChange((Task) t);
304: }
305:
306: /**
307: * Test if this object is an expansion of one of our tasks. We use
308: * taskPred for the latter.
309: **/
310: private static UnaryPredicate expansionPred = new UnaryPredicate() {
311: public boolean execute(Object o) {
312: if (o instanceof Expansion) {
313: return taskPred.execute(((Expansion) o).getTask());
314: }
315: return false;
316: }
317: };
318:
319: /**
320: * The predicate for our incoming tasks. We are looking for
321: * DETERMINEREQUIREMENT tasks of type Asset where the asset type is
322: * StrategicTransportation.
323: **/
324: private static UnaryPredicate taskPred = new UnaryPredicate() {
325: public boolean execute(Object o) {
326: if (o instanceof Task) {
327: Task t = (Task) o;
328: if (t.getVerb().equals(
329: Constants.Verb.DETERMINEREQUIREMENTS)) {
330: return (ExpanderHelper.isOfType(t,
331: Constants.Preposition.OFTYPE,
332: "StrategicTransportation"));
333: }
334: }
335: return false;
336: }
337: };
338:
339: /**
340: * This predicate selects our organic assets. These are the assets
341: * we need to transport if we move.
342: **/
343: private static UnaryPredicate noassetPred = new UnaryPredicate() {
344: public boolean execute(Object o) {
345: return ((o instanceof Asset) && !(o instanceof Organization));
346: }
347: };
348: }
|