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.lib.util;
028:
029:import java.util.ArrayList;
030:import java.util.Collections;
031:import java.util.Date;
032:import java.util.Enumeration;
033:import java.util.HashMap;
034:import java.util.Iterator;
035:import java.util.List;
036:import java.util.Map;
037:import java.util.Vector;
038:
039:import org.cougaar.core.mts.MessageAddress;
040:import org.cougaar.core.service.BlackboardService;
041:import org.cougaar.core.util.UID;
042:import org.cougaar.lib.filter.UTILPlugin;
043:import org.cougaar.planning.ldm.PlanningFactory;
044:import org.cougaar.planning.ldm.asset.Asset;
045:import org.cougaar.planning.ldm.plan.AllocationResult;
046:import org.cougaar.planning.ldm.plan.AllocationResultAggregator;
047:import org.cougaar.planning.ldm.plan.AspectType;
048:import org.cougaar.planning.ldm.plan.AspectValue;
049:import org.cougaar.planning.ldm.plan.Expansion;
050:import org.cougaar.planning.ldm.plan.MPTask;
051:import org.cougaar.planning.ldm.plan.NewTask;
052:import org.cougaar.planning.ldm.plan.NewWorkflow;
053:import org.cougaar.planning.ldm.plan.Plan;
054:import org.cougaar.planning.ldm.plan.PlanElement;
055:import org.cougaar.planning.ldm.plan.Preference;
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.PluginDelegate;
060:import org.cougaar.util.log.Logger;
061:
062:/**
063: * This class contains utility functions related to
064: * subtasks and expansions.
065: */
066:
067:public class UTILExpand {
068: public UTILExpand (Logger logger) {
069: this .logger = logger;
070: pref = new UTILPreference (logger);
071: prepHelper = new UTILPrepPhrase (logger);
072: }
073:
074: public void setAlloc (UTILAllocate alloc) {
075: this .alloc = alloc;
076: }
077:
078: public void setPropagateRescinds (boolean p) {
079: shouldPropagateRescinds = p;
080: }
081:
082: /**
083: * Create a subtask.
084: *
085: * For when you want to be able to set all the fields of the
086: * new task.
087: *
088: * If you just want to set a new direct object for the task,
089: * see the other makeSubTask.
090: *
091: * @param ldmf the PlanningFactory
092: * @param plan the log plan
093: * @param parent the parent task
094: * @param verb the verb
095: * @param prepphrases PrepositionalPhrases
096: * @param obj the direct object
097: * @param preferences for sub task
098: * @param priority of task
099: * @param source the cluster originating the task
100: * @return NewTask
101: */
102: public NewTask makeSubTask(PlanningFactory ldmf,
103: Plan plan,
104: Task parent,
105: Verb verb,
106: Enumeration prepphrases,
107: Asset obj,
108: Enumeration preferences,
109: byte priority,
110: MessageAddress source) {
111: return makeSubTask(ldmf, plan, (parent != null) ? parent.getUID() : null, verb, prepphrases,
112: obj, preferences, priority, source);
113: }
114:
115: /**
116: * Create a subtask.
117: *
118: * For when you want to be able to set all the fields of the
119: * new task.
120: *
121: * If you just want to set a new direct object for the task,
122: * see the other makeSubTask.
123: *
124: * @param ldmf the LdmFactory
125: * @param plan the log plan
126: * @param parent_uid the parent task UID
127: * @param verb the verb
128: * @param prepphrases the PrepositionalPhrases
129: * @param obj the direct object
130: * @param preferences for sub task
131: * @param priority of task
132: * @param source the cluster originating the task
133: * @return NewTask
134: */
135: public NewTask makeSubTask(PlanningFactory ldmf,
136: Plan plan,
137: UID parent_uid,
138: Verb verb,
139: Enumeration prepphrases,
140: Asset obj,
141: Enumeration preferences,
142: byte priority,
143: MessageAddress source) {
144: NewTask task = ldmf.newTask();
145:
146: if(parent_uid != null)
147: task.setParentTaskUID(parent_uid);
148: task.setDirectObject(obj);
149: task.setPrepositionalPhrases(prepphrases);
150: task.setVerb(verb);
151: task.setPlan(plan);
152: task.setPreferences(preferences);
153: task.setPriority(priority);
154: task.setSource(source);
155: return task;
156: }
157:
158: /**
159: * Checks the parentTask for AuxiliaryQuery. If a query exists,
160: * then propagate the query to the subtask. Since not all subtasks
161: * need to propagate the query, this is not automatically part of
162: * the makeSubTask. Only call this when needed.
163: *
164: * @param parentTask
165: * @param subTask
166: */
167:
168: public void addAuxiliaryQuery (Task parentTask, NewTask subTask) {
169: if (parentTask.getAuxiliaryQueryTypes()[0] != -1) {
170: subTask.setAuxiliaryQueryTypes(parentTask.getAuxiliaryQueryTypes());
171: }
172: }
173:
174: /**
175: * Clone a task.
176: *
177: * Used in handling rescinds.
178: *
179: * @param ldmf the PlanningFactory
180: * @param taskToClone the task to be cloned
181: * @return cloned copy of the original task
182: * @see org.cougaar.lib.filter.UTILAllocatorPluginAdapter
183: */
184: public NewTask cloneTask(PlanningFactory ldmf,
185: Task taskToClone) {
186: // Warning, this assumes that the task is part of a workflow!
187:
188: Workflow flow = taskToClone.getWorkflow();
189:
190: logger.debug ("ldmf is " + ldmf + " taskToClone " + taskToClone);
191:
192: NewTask t;
193: synchronized (taskToClone) { // bug #2125
194: t = makeSubTask (ldmf,
195: taskToClone.getPlan(),
196:
197: (flow != null) ? flow.getParentTask () : null,
198: taskToClone.getVerb(),
199: taskToClone.getPrepositionalPhrases(),
200: taskToClone.getDirectObject (),
201: taskToClone.getPreferences(),
202: taskToClone.getPriority(),
203: taskToClone.getSource ());
204: }
205: addAuxiliaryQuery(taskToClone, t);
206: return t;
207: }
208:
209: /**
210: * Create a subtask, using fields from parent task
211: * For when you just want a copy of the parent task with
212: * a different direct object.
213: *
214: * @param ldmf the PlanningFactory
215: * @param parent the parent task
216: * @param obj the direct object
217: * @param source the cluster originating the task
218: * @return NewTask
219: */
220: public NewTask makeSubTask(PlanningFactory ldmf,
221: Task parent,
222: Asset obj,
223: MessageAddress source) {
224: NewTask task = ldmf.newTask();
225:
226: if(parent != null) {
227: task.setParentTaskUID(parent.getUID());
228: task.setContext(parent.getContext());
229: }
230: task.setDirectObject(obj);
231: task.setPrepositionalPhrases(parent.getPrepositionalPhrases());
232: task.setVerb(parent.getVerb ());
233: task.setPlan(parent.getPlan ());
234: synchronized(parent) { task.setPreferences(parent.getPreferences ()); } // bug #2125
235: task.setPriority(parent.getPriority ());
236: task.setSource(source);
237: return task;
238: }
239:
240:
241: /**
242: * Create a new Workflow from the subtask(s)
243:
244: * @param ldmf the PlanningFactory
245: * @param subtasks a vector of subtasks
246: * @return Workflow a workflow containing the subtasks
247: */
248: /* public Workflow makeWorkflow(LdmFactory ldmf, List subtasks) {
249: return makeWorkflow (ldmf, subtasks, myARA);//AllocationResultAggregator.DEFAULT);
250: }*/
251:
252: /**
253: * Create a new Workflow from the subtask(s)
254: * @param ldmf the LdmFactory
255: * @param subtasks a vector of subtasks
256: * @param parent task of this workflow expansion
257: * @return Workflow a workflow containing the subtasks
258: */
259: public Workflow makeWorkflow(PlanningFactory ldmf, List subtasks,
260: Task parent) {
261: return makeWorkflow (ldmf, subtasks, myARA,//AllocationResultAggregator.DEFAULT,
262: parent);
263: }
264:
265: /**
266: * Create a new Workflow from the subtask(s)
267: * @param ldmf the PlanningFactory
268: * @param subtasks a vector of subtasks
269: * @param ara subclass of AllocationResultAggregator, which allows clients to
270: * redefine how the allocation results of subtasks are rolled up
271: * into an aggregate result.
272: * @param parent task of this workflow expansion
273: * @return Workflow a workflow containing the subtasks
274: * @see org.cougaar.planning.ldm.plan.AllocationResultAggregator
275: */
276: public Workflow makeWorkflow(PlanningFactory ldmf, List subtasks,
277: AllocationResultAggregator ara,
278: Task parent) {
279: NewWorkflow wf = ldmf.newWorkflow();
280:
281: if (shouldPropagateRescinds)
282: wf.setIsPropagatingToSubtasks (true);
283:
284: wf.setParentTask(parent);
285:
286: for (Iterator iter = subtasks.iterator (); iter.hasNext ();)
287: ((NewTask)iter.next()).setWorkflow(wf);
288:
289: wf.setTasks(Collections.enumeration(subtasks));
290:
291: wf.setAllocationResultAggregator (ara);
292:
293: return wf;
294: }
295:
296: public void showExpansion(Expansion exp) {
297: logger.info("--------------- exp " + exp.getUID () + " ----------------");
298: Workflow wf = exp.getWorkflow ();
299: if (wf == null)
300: return;
301: int i = 0;
302: for (Enumeration en = wf.getTasks (); en.hasMoreElements (); ) {
303: showPlanElement((Task) en.nextElement (), i++);
304: }
305: }
306:
307: public void showPlanElement (Task subTask) {
308: showPlanElement (subTask, -1);
309: }
310:
311: protected void showPlanElement (Task subTask, int taskNum) {
312: PlanElement pe = subTask.getPlanElement ();
313:// String extra = "";
314: if (prepHelper.hasPrepNamed (subTask, "TASKEDTO"))
315:// extra = " TASKEDTO " + prepHelper.getIndirectObject (subTask, "TASKEDTO");
316:
317: // logger.debug ("\t" + ((taskNum != -1) ? "#" + taskNum : "") +
318: // " FROM " + prepHelper.getFromLocation (subTask) +
319: // " TO " + prepHelper.getToLocation (subTask) + extra);
320: if (pe == null) {
321: logger.warn ("\t no PE yet.");
322: showPreferences (subTask);
323: }
324: else {
325: if (pe.getEstimatedResult () == null)
326: logger.warn ("\t" + " NULL EST AR");
327: else
328: showPreferences (subTask,
329: pe.getEstimatedResult().getAspectValueResults());
330: }
331: }
332:
333: public void showPreferences (Task t,
334: AspectValue[] aspects) {
335: Enumeration prefs;
336: synchronized (t) { prefs = t.getPreferences ();} // bug #2125
337: Map map = new HashMap ();
338:
339: for (; prefs.hasMoreElements (); ) {
340: Preference pref = (Preference) prefs.nextElement ();
341: map.put (new Integer (pref.getAspectType ()), pref);
342: }
343:
344: for (int i = 0; i < aspects.length; i++) {
345: AspectValue av = aspects[i];
346: int aspectType = av.getType();
347: Integer aspectTypeInt = new Integer (aspectType);
348: Preference pref = (Preference) map.remove (aspectTypeInt);
349: if (pref != null) {
350: if (aspectType == AspectType.END_TIME)
351: logger.warn(printEndTime (t, av));
352: else
353: logger.warn(print (av, pref));
354: }
355: }
356: }
357:
358: public void showPreferences (Task t) {
359: Enumeration prefs;
360: synchronized (t) { prefs = t.getPreferences ();} // bug #2125
361:
362: for (; prefs.hasMoreElements (); ) {
363: Preference pref = (Preference) prefs.nextElement ();
364: if (pref != null) {
365: if (pref.getAspectType () == AspectType.END_TIME)
366: logger.warn(printEndTime (t));
367: else
368: logger.warn(print (pref));
369: }
370: }
371: }
372:
373: protected String print (AspectValue av, Preference pref) {
374: String type = null;
375: String value = null;
376: String prefstr = null;
377: String intermediate = "";
378:
379: try {
380: AspectValue prefav =
381: pref.getScoringFunction().getBest().getAspectValue();
382: switch (av.getAspectType ()) {
383: case AspectType.START_TIME:
384: type = "START";
385: value = "" + new Date ((long) av.getValue ());
386: prefstr = "" + new Date ((long) prefav.getValue());
387: intermediate = (av.getValue () < prefav.getValue()) ? " >" : "";
388: break;
389: case AspectType.END_TIME:
390: type = "END ";
391: value = "" + new Date ((long) av.getValue ());
392: prefstr = "" + new Date ((long) prefav.getValue());
393: break;
394: default:
395: type = "<" + av.getAspectType () + ">";
396: value = "" + av;
397: prefstr = "" + prefav;
398: break;
399: }
400: } catch (Exception e) {
401: return "Excep";
402: }
403:
404: return (type + ":p " + prefstr + intermediate + "-a " + value);
405: }
406:
407: protected String print (Preference pref) {
408: String type = null;
409: String prefstr = null;
410: try {
411: AspectValue prefav =
412: pref.getScoringFunction().getBest().getAspectValue();
413: switch (pref.getAspectType ()) {
414: case AspectType.START_TIME:
415: type = "START";
416: prefstr = "" + new Date ((long) prefav.getValue());
417: break;
418: case AspectType.END_TIME:
419: type = "END ";
420: prefstr = "" + new Date ((long) prefav.getValue());
421: break;
422: default:
423: type = "<" + pref.getAspectType () + ">";
424: prefstr = "" + prefav;
425: break;
426: }
427: } catch (Exception e) {
428: return "Excep";
429: }
430:
431: return (type + ":p " + prefstr);
432: }
433:
434: protected String printEndTime (Task t, AspectValue av) {
435: String type = null;
436: String value = null;
437: // String prefstr = null;
438:
439: type = "END ";
440: Date avDate = new Date ((long) av.getValue ());
441: value = "" + avDate;
442: Date early = pref.getEarlyDate(t);
443: Date best = pref.getBestDate(t);
444: Date late = pref.getLateDate(t);
445: String earlyMark = (avDate.before (early)) ? " <" : "";
446: String lateMark = (avDate.after (late )) ? " >" : "";
447:
448: return
449: (type + ":p-e " + early + earlyMark + " a " + value) + "\n" +
450: (type + ":p-b " + best + " a " + value) + "\n" +
451: (type + ":p-l " + late + lateMark + " a " + value);
452: }
453:
454: protected String printEndTime (Task t) {
455: String type = null;
456:
457: type = "END ";
458:
459: Date early = pref.getEarlyDate(t);
460: Date best = pref.getBestDate(t);
461: Date late = pref.getLateDate(t);
462:
463: return
464: (type + ":p-e " + early + "\n") +
465: (type + ":p-b " + best + "\n") +
466: (type + ":p-l " + late);
467: }
468:
469: /**
470: * Creates the Expansion.
471: *
472: * Sets the estimated allocation result of the plan element to NULL.
473: *
474: * @param ldmf PlanningFactory
475: * @param wf a workflow
476: * @return Expansion
477: */
478: public Expansion makeExpansion(PlanningFactory ldmf, Workflow wf) {
479: Task t = wf.getParentTask();
480: Expansion exp = ldmf.createExpansion(t.getPlan(), t, wf, null);
481: return exp;
482: }
483:
484: /**
485: * Creates the Expansion.
486: *
487: * Estimated allocation result of the expansion is set to the values of the
488: * best values of the task, with a confidence of MEDIUM_CONFIDENCE (0.5).
489: *
490: * @param ldmf PlanningFactory
491: * @param wf a workflow
492: * @return Expansion
493: * @see UTILAllocate#MEDIUM_CONFIDENCE
494: */
495: public Expansion makeExpansionWithConfidence(PlanningFactory ldmf, Workflow wf) {
496: Task t = wf.getParentTask();
497: Enumeration prefs;
498: synchronized (t) { prefs = t.getPreferences(); } // bug #2125 (MIK: this is SO unlikely to help!)
499: List aspect_values = new ArrayList();
500:
501: while(prefs.hasMoreElements()){
502: Preference p = (Preference)prefs.nextElement();
503: aspect_values.add(pref.getPreferenceBestAspectValue(p));
504: }
505:
506: AllocationResult ar =
507: ldmf.newAVAllocationResult(UTILAllocate.MEDIUM_CONFIDENCE,
508: true, (AspectValue[])aspect_values.toArray(new AspectValue[0]));
509:
510: Expansion exp = ldmf.createExpansion(t.getPlan(), t, wf, ar);
511: return exp;
512: }
513:
514: /**
515: * Creates a failed Expansion.
516: *
517: * Sets the estimated allocation result of the plan element to an
518: * empty failed alloc result.
519: *
520: * @param ldmf PlanningFactory
521: * @param t task to make a failed expansion for
522: * @return Expansion
523: */
524: public Expansion makeFailedExpansion(UTILPlugin creator,
525: PlanningFactory ldmf, Task t) {
526: AllocationResult failedAR =
527: ldmf.newAllocationResult(1.0, false,
528: new int[1], new double[1]);
529:
530: Expansion exp = ldmf.createExpansion(t.getPlan(), t, ldmf.newWorkflow(), failedAR);
531:
532: return exp;
533: }
534:
535: /**
536: * This method Expands the given Task.
537: * @param ldmf the LDMFactory
538: * @param plugin the PluginDelegate
539: * @param pluginName string representation of the plugin's name
540: * @param t the task to be expanded.
541: * @param subtasks the expanded subtasks
542: */
543:
544: public void handleTask(PlanningFactory ldmf, PluginDelegate plugin, String pluginName,
545: boolean wantConfidence, Task t, List subtasks) {
546: handleTask (ldmf, plugin.getBlackboardService (), pluginName, wantConfidence, t, subtasks);
547: }
548:
549: public void handleTask(PlanningFactory ldmf, BlackboardService blackboard, String pluginName,
550: boolean wantConfidence, Task t, List subtasks) {
551: if (subtasks.isEmpty ()) {
552: throw new UTILPluginException(pluginName+".handleTask - WARNING : getSubtasks returned empty vector!");
553: }
554:
555: // WARNING: The following MPTask code is somewhat GlobalSea specific.
556: // However, in general if we try to create expansions containing
557: // MPTasks, we crash, so this is a slightly better solution for now.
558: if (logger.isDebugEnabled()){
559: logger.debug(pluginName +
560: ".handleTask: Subtask(s) created for " +
561: ((t instanceof MPTask)?"MPT":"t") + "ask :" +
562: t.getUID());
563: }
564:
565: Workflow wf = null;
566:
567: if (t instanceof MPTask) {
568: // Handling for the special case in which the subtasks of
569: // an expanded MPTask are ALL also MPTasks.
570: Iterator sub_t_i = subtasks.iterator();
571: boolean contains_mptasks = false;
572: while (sub_t_i.hasNext()) {
573: if (sub_t_i.next() instanceof MPTask)
574: contains_mptasks = true;
575: else if (contains_mptasks == true)
576: throw new UTILPluginException(pluginName +
577: ".handleTask : ERROR: Found expansion with mixed Task and MPTask children.");
578: } // while
579:
580: if (contains_mptasks)
581: wf = makeWorkflow(ldmf, subtasks, t /*parent*/);
582: }
583:
584: // General case
585: // If we haven't created a workflow yet, we want the "normal" case
586:
587: if (wf == null) {
588: wf = makeWorkflow (ldmf, subtasks, t);
589: }
590:
591: Expansion exp = null;
592: if(wantConfidence){
593: exp = makeExpansionWithConfidence (ldmf, wf);
594: }
595: else{
596: exp = makeExpansion (ldmf, wf);
597: }
598:
599: if (logger.isDebugEnabled()){
600: logger.debug(pluginName + ".handleTask: Expansion created. (" +
601: exp.getUID() + ")");
602: }
603:
604: for (Iterator i = subtasks.iterator (); i.hasNext ();) {
605: blackboard.publishAdd (i.next());
606: }
607: // plugin.publishAdd(wf); // Mike Thome says never publish the workflow
608: blackboard.publishAdd(exp);
609:
610: if (logger.isDebugEnabled()){
611: logger.debug(pluginName + ".handleTask: Expansion published. Workflow has " +
612: alloc.enumToList(exp.getWorkflow ().getTasks()).size () + " subtasks." );
613: }
614:
615: }
616:
617: /**
618: * who uses this anymore anyway? TOPS?
619: */
620: public Expansion handleTaskPrime(PlanningFactory ldmf, PluginDelegate plugin, String pluginName,
621: boolean wantConfidence, boolean myExtraOutput,
622: Task t, List subtasks) {
623: return handleTaskPrime (ldmf, plugin.getBlackboardService(), pluginName, wantConfidence, myExtraOutput, t, subtasks);
624: }
625:
626: /**
627: * who uses this anymore anyway? TOPS?
628: */
629: public Expansion handleTaskPrime(PlanningFactory ldmf, BlackboardService blackboard, String pluginName,
630: boolean wantConfidence, boolean myExtraOutput,
631: Task t, List subtasks) {
632: if (subtasks.isEmpty ()) {
633: throw new UTILPluginException(pluginName+".handleTask - WARNING : getSubtasks returned empty vector!");
634: }
635:
636: // WARNING: The following MPTask code is somewhat GlobalSea specific.
637: // However, in general if we try to create expansions containing
638: // MPTasks, we crash, so this is a slightly better solution for now.
639: if (logger.isDebugEnabled()){
640: logger.debug(pluginName +
641: ".handleTask: Subtask(s) created for " +
642: ((t instanceof MPTask)?"MPT":"t") + "ask :" +
643: t.getUID());
644: }
645:
646: Workflow wf = null;
647:
648: if (t instanceof MPTask) {
649: // Handling for the special case in which the subtasks of
650: // an expanded MPTask are ALL also MPTasks.
651: Iterator sub_t_i = subtasks.iterator();
652: boolean contains_mptasks = false;
653: while (sub_t_i.hasNext()) {
654: if (sub_t_i.next() instanceof MPTask)
655: contains_mptasks = true;
656: else if (contains_mptasks == true)
657: throw new UTILPluginException(pluginName +
658: ".handleTask : ERROR: Found expansion with mixed Task and MPTask children.");
659: } // while
660:
661: if (contains_mptasks)
662: wf = makeWorkflow(ldmf, subtasks, t /*parent*/);
663: }
664:
665: // General case
666: // If we haven't created a workflow yet, we want the "normal" case
667:
668: if (wf == null) {
669: wf = makeWorkflow (ldmf, subtasks, t);
670: }
671:
672: /*
673: if (myExtraOutput){
674: logger.debug(pluginName + ".handleTask: Workflow created.");
675: }
676: */
677:
678: Expansion exp = null;
679: if(wantConfidence){
680: exp = makeExpansionWithConfidence (ldmf, wf);
681: }
682: else{
683: exp = makeExpansion (ldmf, wf);
684: }
685:
686: if (logger.isDebugEnabled()){
687: logger.debug(pluginName + ".handleTask: Expansion created. (" +
688: exp.getUID() + ")");
689: }
690:
691: for (Iterator i = subtasks.iterator (); i.hasNext ();) {
692: blackboard.publishAdd (i.next());
693: }
694: blackboard.publishAdd(exp);
695:
696: if (logger.isDebugEnabled()){
697: logger.debug(pluginName + ".handleTask: Expansion published. Workflow has " +
698: alloc.enumToList(exp.getWorkflow ().getTasks()).size () + " subtasks." );
699: }
700:
701: return exp;
702: }
703:
704: public Enumeration createDividedPreferences(PlanningFactory ldmf, Task t, Date begin, Date end, Logger logger) {
705: Enumeration taskPrefs;
706: synchronized (t) { taskPrefs = t.getPreferences(); } // bug #2125
707: Vector newPrefs = new Vector();
708: Date start = null;
709: Date early = null;
710: Date best = null;
711: Date late = null;
712: while (taskPrefs.hasMoreElements()) {
713: Preference this Pref = (Preference) taskPrefs.nextElement();
714: if (this Pref.getAspectType() == AspectType.START_TIME) {
715: start = pref.getReadyAt(t);
716: } else if (this Pref.getAspectType() == AspectType.END_TIME) {
717: early = pref.getEarlyDate(t);
718: best = pref.getBestDate(t);
719: late = pref.getLateDate(t);
720: } else {
721: newPrefs.addElement(this Pref);
722: }
723: }
724: if (start == null || early == null || best == null || late == null ||
725: early.before(start) || best.before(early) || late.before(best) ||
726: begin.before(start) || end.after(late)) {
727: throw new UTILRuntimeException ("UTILExpand.createDividedPreferences : task\n\t" + t +
728: "\n\thas bad time preferences.");
729: }
730:
731: long whole_duration = late.getTime() - start.getTime();
732: long partial_duration = end.getTime() - begin.getTime();
733: double time_fragment = (double)partial_duration / (double)whole_duration;
734:
735: long early_to_best = (long) (((double) (best.getTime() - early.getTime())) * time_fragment);
736: long best_to_late = (long) (((double) (late.getTime() - best.getTime ())) * time_fragment);
737:
738: Date newEarly = new Date(end.getTime() - (early_to_best + best_to_late));
739: Date newBest = new Date(end.getTime() - best_to_late);
740:
741: if (logger.isDebugEnabled()) {
742: logger.debug("createDivided - begin " + begin +
743: " e " + newEarly +
744: " b " + newBest +
745: " l " + end);
746: logger.debug("createDivided - task's start " + start +
747: " e " + early +
748: " b " + best +
749: " l " + late);
750: }
751:
752: newPrefs.addElement(pref.makeStartDatePreference(ldmf, begin));
753: newPrefs.addElement(pref.makeEndDatePreference(ldmf,
754: newEarly,
755: newBest,
756: end));
757: return newPrefs.elements();
758: }
759:
760: // private static AllocationResultAggregator myARA = new UTILAllocationResultAggregator ();
761: private AllocationResultAggregator myARA = AllocationResultAggregator.DEFAULT;
762:
763: private boolean shouldPropagateRescinds = true;
764: protected Logger logger;
765: protected UTILPreference pref;
766: protected UTILPrepPhrase prepHelper;
767: protected UTILAllocate alloc;
768:}
|