0001: /*--------------------------------------------------------------------------
0002: * <copyright>
0003: *
0004: * Copyright 1999-2004 BBNT Solutions, LLC
0005: * under sponsorship of the Defense Advanced Research Projects
0006: * Agency (DARPA).
0007: *
0008: * You can redistribute this software and/or modify it under the
0009: * terms of the Cougaar Open Source License as published on the
0010: * Cougaar Open Source Website (www.cougaar.org).
0011: *
0012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023: *
0024: * </copyright>
0025: * --------------------------------------------------------------------------*/
0026: package org.cougaar.glm.plugins;
0027:
0028: import java.text.NumberFormat;
0029: import java.util.Calendar;
0030: import java.util.Collection;
0031: import java.util.Date;
0032: import java.util.Enumeration;
0033: import java.util.Hashtable;
0034: import java.util.Iterator;
0035: import java.util.Vector;
0036:
0037: import org.cougaar.core.blackboard.IncrementalSubscription;
0038: import org.cougaar.core.mts.MessageAddress;
0039: import org.cougaar.glm.ldm.asset.Organization;
0040: import org.cougaar.glm.ldm.plan.ObjectScheduleElement;
0041: import org.cougaar.glm.ldm.plan.PlanScheduleElementType;
0042: import org.cougaar.glm.ldm.plan.QuantityScheduleElement;
0043: import org.cougaar.planning.ldm.PlanningFactory;
0044: import org.cougaar.planning.ldm.asset.Asset;
0045: import org.cougaar.planning.ldm.measure.Rate;
0046: import org.cougaar.planning.ldm.plan.Allocation;
0047: import org.cougaar.planning.ldm.plan.AllocationResult;
0048: import org.cougaar.planning.ldm.plan.AllocationResultAggregator;
0049: import org.cougaar.planning.ldm.plan.AspectType;
0050: import org.cougaar.planning.ldm.plan.AspectValue;
0051: import org.cougaar.planning.ldm.plan.AuxiliaryQueryType;
0052: import org.cougaar.planning.ldm.plan.Context;
0053: import org.cougaar.planning.ldm.plan.Disposition;
0054: import org.cougaar.planning.ldm.plan.Expansion;
0055: import org.cougaar.planning.ldm.plan.NewPrepositionalPhrase;
0056: import org.cougaar.planning.ldm.plan.NewSchedule;
0057: import org.cougaar.planning.ldm.plan.NewTask;
0058: import org.cougaar.planning.ldm.plan.NewWorkflow;
0059: import org.cougaar.planning.ldm.plan.PlanElement;
0060: import org.cougaar.planning.ldm.plan.Preference;
0061: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
0062: import org.cougaar.planning.ldm.plan.Role;
0063: import org.cougaar.planning.ldm.plan.Schedule;
0064: import org.cougaar.planning.ldm.plan.ScheduleImpl;
0065: import org.cougaar.planning.ldm.plan.ScheduleType;
0066: import org.cougaar.planning.ldm.plan.ScoringFunction;
0067: import org.cougaar.planning.ldm.plan.Task;
0068: import org.cougaar.planning.ldm.plan.TaskScoreTable;
0069: import org.cougaar.planning.ldm.plan.TimeAspectValue;
0070: import org.cougaar.planning.ldm.plan.Verb;
0071: import org.cougaar.planning.ldm.plan.Workflow;
0072: import org.cougaar.planning.plugin.legacy.PluginDelegate;
0073: import org.cougaar.planning.plugin.util.AllocationResultHelper;
0074: import org.cougaar.util.TimeSpan;
0075: import org.cougaar.util.UnaryPredicate;
0076: import org.cougaar.util.log.Logger;
0077: import org.cougaar.util.log.Logging;
0078:
0079: /**
0080: * BasicProcessor supplies generic methods for connecting to the 'owner'
0081: * plugin and to record objects as they are published by this processor
0082: * to the logplan.
0083: * @see DecorationPlugin
0084: * @see PluginDecorator
0085: */
0086: public abstract class BasicProcessor {
0087:
0088: protected PlanningFactory ldmFactory_;
0089: /**
0090: * 'hook' to plugin's methods
0091: */
0092: protected PluginDelegate delegate_;
0093: /**
0094: * organization cluster identifier
0095: */
0096: protected MessageAddress clusterId_;
0097: protected Organization myOrganization_ = null;
0098: // The name of my organization -- used for UsingGLMSource
0099: protected String myOrgName_ = null;
0100: protected String className_;
0101: protected DecorationPlugin plugin_;
0102: public AllocationResultAggregator UnlikeTaskARA_ = new UnlikeTaskARA();
0103:
0104: public static NumberFormat demandFormat = NumberFormat
0105: .getInstance();
0106: /**
0107: * number of msec per day
0108: */
0109: // 86400000 msec/day = 1000msec/sec * 60sec/min *60min/hr * 24 hr/day
0110: protected static final long MSEC_PER_DAY = TaskUtils.MSEC_PER_DAY;
0111: protected static final long MSEC_PER_MIN = 60 * 1000;
0112: protected static final long MSEC_PER_HOUR = MSEC_PER_MIN * 60;
0113: protected Calendar calendar_ = Calendar.getInstance();
0114: private static Logger logger = Logging
0115: .getLogger(BasicProcessor.class);
0116:
0117: // like execute - called whenever a subscription has changed
0118: public abstract void update();
0119:
0120: public BasicProcessor(DecorationPlugin pi, Organization org) {
0121: // set constants
0122: className_ = this .getClass().getName();
0123: int indx = className_.lastIndexOf(".");
0124: if (indx > -1) {
0125: className_ = className_.substring(indx + 1);
0126: }
0127: plugin_ = pi;
0128: myOrganization_ = org;
0129: myOrgName_ = myOrganization_.getItemIdentificationPG()
0130: .getItemIdentification();
0131: delegate_ = plugin_.getMyDelegate();
0132: clusterId_ = delegate_.getMessageAddress();
0133: ldmFactory_ = delegate_.getLDM().getFactory();
0134:
0135: // initialize quantity formater
0136: demandFormat.setMaximumIntegerDigits(10);
0137: demandFormat.setMinimumIntegerDigits(2);
0138: demandFormat.setMinimumFractionDigits(2);
0139: demandFormat.setMaximumFractionDigits(2);
0140: demandFormat.setGroupingUsed(false);
0141: }
0142:
0143: public boolean isSubscriptionChanged(IncrementalSubscription sub) {
0144: return plugin_.isSubscriptionChanged(sub);
0145: }
0146:
0147: protected IncrementalSubscription subscribe(UnaryPredicate predicate) {
0148: IncrementalSubscription subscript = (IncrementalSubscription) delegate_
0149: .subscribe(predicate);
0150: plugin_.monitorSubscription(this , subscript);
0151: return subscript;
0152: }
0153:
0154: /**
0155: * Create String defining task identity.
0156: * @param t task
0157: * @return String defining task identity.
0158: */
0159: protected String taskKey(Task t) {
0160: return PublicationKey.getTaskKey(t);
0161: }
0162:
0163: /**
0164: * Create String defining task identity. Defaults to comparing preferences.
0165: * @param prev_task previously published task.
0166: * @param new_task already defined to have the same taskKey as task a.
0167: * @return null if the two tasks are the same,
0168: * or returns task a modified for a publishChange.
0169: * @see #taskKey(Task t)
0170: */
0171: protected Task changeTask(Task prev_task, Task new_task) {
0172: // Checks for changed preferences.
0173: if (prev_task == new_task) {
0174: // happens in GLMSourcing when updating an expansion where some part of it has failed.
0175: // printError("changeTask SAME TASK! \nelement:"+TaskUtils.taskDesc(prev_task)+"\n parent: "+prev_task.getParentTask());
0176: // not sure when this happens
0177: return new_task;
0178: }
0179: if (!TaskUtils.comparePreferences(new_task, prev_task)) {
0180: Enumeration ntPrefs = new_task.getPreferences();
0181: ((NewTask) prev_task).setPreferences(ntPrefs);
0182: return prev_task;
0183: }
0184: return null;
0185: }
0186:
0187: private String getQuantitySF(Task task) {
0188: Preference task_pref = task.getPreference(AspectType.QUANTITY);
0189: if (task_pref != null) {
0190: return task_pref.getScoringFunction() + " ";
0191: } else {
0192: return " !!no QUANTITY preference!! ";
0193: }
0194: }
0195:
0196: public long getAlpTime() {
0197: return delegate_.currentTimeMillis();
0198: }
0199:
0200: /**
0201: * build Allocation with an estimated alloc result
0202: */
0203: private Allocation buildAllocation(Task t, Asset a, Role r) {
0204: return ldmFactory_.createAllocation(t.getPlan(), t, a, null, r);
0205: }
0206:
0207: /**
0208: * Create workflow from subtasks, create new Expansion with Workflow.
0209: */
0210: private Expansion buildExpansion(Task parent, Vector subtasks) {
0211: Workflow wf = buildWorkflow(parent, subtasks);
0212: Expansion expansion = ldmFactory_.createExpansion(parent
0213: .getPlan(), parent, wf, null);
0214:
0215: return expansion;
0216: }
0217:
0218: /**
0219: * Initialize workflow parent task and sets propagating
0220: * @param parent parent task of workflow
0221: * @return NewWorkflow with parent task an propagating set
0222: */
0223: public NewWorkflow newWorkflow(Task parent) {
0224: NewWorkflow wf = ldmFactory_.newWorkflow();
0225: wf.setParentTask(parent);
0226: wf.setIsPropagatingToSubtasks(true);
0227: return wf;
0228: }
0229:
0230: /**
0231: * Build a workflow from a vector of tasks.
0232: * @param parent parent task of workflow
0233: * @param subtasks workflow tasks
0234: * @return Workflow
0235: */
0236: public Workflow buildWorkflow(Task parent, Vector subtasks) {
0237: NewWorkflow wf = newWorkflow(parent);
0238: NewTask t;
0239: int i, length = subtasks.size();
0240: for (i = 0; i < length; i++) {
0241: t = (NewTask) subtasks.elementAt(i);
0242: t.setWorkflow(wf);
0243: wf.addTask(t);
0244: }
0245: return wf;
0246: }
0247:
0248: /**
0249: * Build a workflow with a single task.
0250: * @param parent parent task of workflow
0251: * @param task single workflow task
0252: * @return Workflow
0253: */
0254: public Workflow buildWorkflow(Task parent, Task task) {
0255: NewWorkflow wf = newWorkflow(parent);
0256: NewTask t = (NewTask) task;
0257: t.setWorkflow(wf);
0258: wf.addTask(t);
0259: return wf;
0260: }
0261:
0262: /**
0263: * The goal of this code is to replace any existing expansion of
0264: * the parent into the new set of subtasks, but to do so in a way
0265: * that maximizes the reuse of existing subtasks of the parent.
0266: * This is done by putting all the existing subtasks into a
0267: * hashtable using a key characterizing the ways that the subtask
0268: * cannot be changed (verb, etc.). Then the new tasks are matched
0269: * against the old. Where matches are found the existing task is
0270: * adjusted to match. IF a new task cannot be matched, it is added
0271: * to the expansion. After matching is completed, any old tasks
0272: * that were not matched are removed from the expansion.
0273: */
0274: protected void publishExpansion(Task parent, Vector tasks) {
0275: if (tasks.isEmpty()) {
0276: if (logger.isErrorEnabled()) {
0277: logger.error("publishExpansion - no tasks"
0278: + TaskUtils.taskDesc(parent));
0279: }
0280: return;
0281: }
0282: Enumeration elements = tasks.elements();
0283: Task task = (Task) elements.nextElement();
0284: PlanElement pe = parent.getPlanElement();
0285: Expansion expansion;
0286: if (pe == null) {
0287: // In MB5.2 no longer automatically publishes tasks in a workflow.
0288: Enumeration en = tasks.elements();
0289: while (en.hasMoreElements()) {
0290: publishAddTask((Task) en.nextElement());
0291: }
0292: // create new expansion
0293: expansion = buildExpansion(parent, tasks);
0294: delegate_.publishAdd(expansion);
0295: return;
0296: }
0297: if (!(pe instanceof Expansion)) {
0298: if (logger.isErrorEnabled()) {
0299: logger
0300: .error("publishExpansion: problem pe not Expansion?"
0301: + pe
0302: + "\n Task:"
0303: + PublicationKey.getTotalTaskKey(task)
0304: + "\n Parent Task:"
0305: + PublicationKey
0306: .getTotalTaskKey(parent));
0307: }
0308: return;
0309: }
0310:
0311: expansion = (Expansion) pe;
0312: // Expansion previously published - need to change.
0313: Hashtable published_tasks = createPublishedTable(expansion
0314: .getWorkflow().getTasks());
0315:
0316: boolean change_expansion = false;
0317: NewTask new_task;
0318: Task prev_task;
0319: String key;
0320: PublishedTask published_task;
0321: Context context = parent.getContext();
0322: // publish
0323: elements = tasks.elements();
0324: while (elements.hasMoreElements()) {
0325: new_task = (NewTask) elements.nextElement();
0326: if (new_task.getContext() == null)
0327: new_task.setContext(context);
0328: key = taskKey(new_task);
0329: // isElementPublished
0330: // check if already published
0331: published_task = (PublishedTask) published_tasks.get(key);
0332: if (published_task != null) {
0333: if (published_task.getPublished()) {
0334: if (logger.isErrorEnabled()) {
0335: logger
0336: .error("WARNING: publishExpansion() Change() Ack! Two PublishedElements with the same key! <"
0337: + key
0338: + ">\n TASK1:"
0339: + published_task.getTask()
0340: + "\nTASK2:" + new_task);
0341: }
0342: } else {
0343: prev_task = published_task.getTask();
0344: // Check unnecessary because alpTime is always before Commitment time
0345: if (prev_task.beforeCommitment(new Date(
0346: getAlpTime()))) {
0347: // check if changed...
0348: Task t = changeTask(prev_task, new_task);
0349: if (t != null) {
0350: // printDebug( "publishExpansion() Change CHANGE key <"+key+">");
0351: delegate_.publishChange(t);
0352: change_expansion = true;
0353: // add new task to hash table for later publishing
0354: published_task.setTask(t);
0355:
0356: }
0357: } else {
0358: if (logger.isDebugEnabled()) {
0359: logger
0360: .debug("publishExpansion() After commitment:"
0361: + prev_task
0362: .getCommitmentDate()
0363: + " task:" + key);
0364: }
0365: }
0366: }
0367: published_task.setPublished(true);
0368: } else {
0369: // printDebug( "publishExpansion() Change() ADD key <"+key+">");
0370: publishAddTask(new_task);
0371: change_expansion = true;
0372: published_tasks.put(key, new PublishedTask(new_task,
0373: true));
0374: }
0375: }
0376: boolean remove_from_wf = rescindUnpublishedTasks(published_tasks);
0377: if (change_expansion || remove_from_wf) {
0378: // Tasks w/i workflow have been added and/or removed need to
0379: // publish change the workflow.
0380: // If tasks are only changed, then don't need to change workflow.
0381:
0382: // RJB -- comment this out for now -- may not need to look at it
0383: // printDebug("PublishExpansion CHANGE expansion:"+expansion+" w/ TASK:"+expansion.getTask());
0384: NewWorkflow nwf = (NewWorkflow) expansion.getWorkflow();
0385: // Enumeration oldTasks = ((Workflow)nwf).getTasks();
0386: // while (oldTasks.hasMoreElements()) {
0387: // printDebug("old task: " + TaskUtils.taskDesc((Task)oldTasks.nextElement()));
0388: // }
0389: Vector newTasks = new Vector();
0390: Enumeration key_list = published_tasks.keys();
0391: while (key_list.hasMoreElements()) {
0392: key = (String) key_list.nextElement();
0393: PublishedTask ipo = (PublishedTask) published_tasks
0394: .get(key);
0395: NewTask newTask = (NewTask) ipo.getTask();
0396: // printDebug("ipo.getTask(): " + TaskUtils.taskDesc(task));
0397: if (ipo.getPublished()) {
0398: newTasks.addElement(newTask);
0399: newTask.setWorkflow(nwf);
0400: }
0401: }
0402: nwf.setTasks(newTasks.elements());
0403: if (expansion.getEstimatedResult() != null) {
0404: expansion
0405: .setEstimatedResult(buildExpansionResult(expansion));
0406: }
0407: delegate_.publishChange(expansion);
0408: }
0409: }
0410:
0411: /**
0412: * Reconcile an intended schedule of projections with the
0413: * currently published schedule of projections so as to reuse as
0414: * many of the existing projection tasks as possible.
0415: * Generally as elements from the published schedule are used they
0416: * are removed from the schedule. Tasks remaining in the schedule
0417: * are rescinded.
0418: * There are three regions of interest: before now, around now and
0419: * after now. These are each handled separately. In the region
0420: * before now, already published tasks are unconditionally
0421: * retained and new tasks are unconditionally ignored.
0422: * In the region around now, tasks may start before now and end
0423: * after. If both a published task and a new task spanning now
0424: * exist, then there are two cases: If the demand rates are the
0425: * same, then the published task is changed to look like the new
0426: * task (by changing its end time preference). The start time of
0427: * the published task is unchanged. Think of the existing task
0428: * ending now and the new task starting now and then splicing the
0429: * two together into one task. If the rates are different, then
0430: * the existing task must end when the new task starts. The
0431: * current code accomplishes this by setting the end time
0432: * preference of the existing task to the start time of the new.
0433: * This is not exactly correct since we shouldn't change the past.
0434: * The times of the tasks should be no less than now.
0435: * In the region after now, we try to match up the tasks. When a
0436: * match is possible, the existing task is changed if necessary
0437: * (and republished) otherwise it is rescinded and the new task
0438: * added.
0439: */
0440: protected Enumeration diffProjections(Schedule published_schedule,
0441: Schedule newtask_schedule) {
0442: // Chedk for an empty schedule
0443: if (newtask_schedule.isEmpty()) {
0444: if (logger.isErrorEnabled()) {
0445: logger
0446: .error("publishChangeProjection(), New Task Schedule empty: "
0447: + newtask_schedule);
0448: }
0449: return null;
0450: }
0451:
0452: Vector add_tasks = new Vector();
0453: // Remove from the published schedule of tasks all tasks that occur BEFORE now but not overlapping now
0454: // These historical tasks should not be changed
0455: long now = getAlpTime();
0456: ObjectScheduleElement ose;
0457: Iterator historical_tasks = published_schedule
0458: .getEncapsulatedScheduleElements(TimeSpan.MIN_VALUE,
0459: now).iterator();
0460: while (historical_tasks.hasNext()) {
0461: ose = (ObjectScheduleElement) historical_tasks.next();
0462: ((NewSchedule) published_schedule)
0463: .removeScheduleElement(ose);
0464: }
0465:
0466: // Examine the new task and published task that straddle NOW
0467: Task published_task = null;
0468: Task new_task = null;
0469: Collection c = newtask_schedule
0470: .getScheduleElementsWithTime(now);
0471: if (!c.isEmpty()) {
0472: ose = (ObjectScheduleElement) c.iterator().next();
0473: new_task = (Task) ose.getObject();
0474: ((NewSchedule) newtask_schedule).removeScheduleElement(ose);
0475: }
0476: c = published_schedule.getScheduleElementsWithTime(now);
0477: if (!c.isEmpty()) {
0478: ose = (ObjectScheduleElement) c.iterator().next();
0479: published_task = (Task) ose.getObject();
0480: ((NewSchedule) published_schedule)
0481: .removeScheduleElement(ose);
0482: }
0483: if (published_task != null && new_task != null) {
0484: // Depending upon whether the rate is equal set the end time of the published task to the start or
0485: // end time of the new task
0486: Rate new_rate = TaskUtils.getRate(new_task);
0487: if (new_rate.equals(TaskUtils.getRate(published_task))) {
0488: // check end times not the same
0489: ((NewTask) published_task).setPreference(new_task
0490: .getPreference(AspectType.END_TIME));
0491: if (logger.isDebugEnabled()) {
0492: logger.debug(printProjection("extend old end",
0493: published_task));
0494: }
0495: publishChangeTask(published_task);
0496: } else {
0497: // check to make sure start_time is not before now
0498: // long that is the maximum of now and the start_time
0499: long when = Math.max(now, TaskUtils
0500: .getStartTime(new_task));
0501: setEndTimePreference((NewTask) published_task, when);
0502: if (logger.isDebugEnabled()) {
0503: logger.debug(printProjection("truncate old end 1",
0504: published_task));
0505: }
0506: publishChangeTask(published_task);
0507: setStartTimePreference((NewTask) new_task, when);
0508: if (logger.isDebugEnabled()) {
0509: logger.debug(printProjection(
0510: "truncate new start 1", new_task));
0511: }
0512: add_tasks.add(new_task);
0513: }
0514: } else if (new_task != null) {
0515: setStartTimePreference((NewTask) new_task, now);
0516: if (logger.isDebugEnabled()) {
0517: logger.debug(printProjection("truncate new start 2",
0518: new_task));
0519: }
0520: add_tasks.add(new_task);
0521: } else if (published_task != null) {
0522: setEndTimePreference((NewTask) published_task, now);
0523: publishChangeTask(published_task);
0524: if (logger.isDebugEnabled()) {
0525: logger.debug(printProjection("truncate old end 2",
0526: published_task));
0527: }
0528: }
0529:
0530: // Compare new tasks to previously scheduled tasks, if a published task is found that
0531: // spans the new task's start time then adjust the published task (if needed) and publish
0532: // the change. If no task is found than add new_task to list of tasks to be published.
0533: // When start time of schedule is equal to TimeSpan.MIN_VALUE, schedule is empty
0534: long start;
0535: while (!newtask_schedule.isEmpty()) {
0536: start = newtask_schedule.getStartTime();
0537: ose = (ObjectScheduleElement) ScheduleUtils
0538: .getElementWithTime(newtask_schedule, start);
0539: if (ose != null) {
0540: new_task = (Task) ose.getObject();
0541: ((NewSchedule) newtask_schedule)
0542: .removeScheduleElement(ose);
0543: } else {
0544: if (logger.isErrorEnabled()) {
0545: logger
0546: .error("publishChangeProjection(), Bad Schedule: "
0547: + newtask_schedule);
0548: }
0549: return null;
0550: }
0551: // Get overlapping schedule elements from start to end of new task
0552: c = published_schedule.getScheduleElementsWithTime(start);
0553: if (!c.isEmpty()) {
0554: // change the task to look like new task
0555: ose = (ObjectScheduleElement) c.iterator().next();
0556: published_task = (Task) ose.getObject();
0557: ((NewSchedule) published_schedule)
0558: .removeScheduleElement(ose);
0559:
0560: published_task = changeTask(published_task, new_task);
0561: if (published_task != null) {
0562: if (logger.isDebugEnabled()) {
0563: logger.debug(printProjection("replace with",
0564: published_task));
0565: }
0566: publishChangeTask(published_task);
0567: // printDebug("publishChangeProjection(), Publishing changed Projections: "+
0568: // TaskUtils.projectionDesc(new_task));
0569: }
0570: } else {
0571: // no task exists that covers this timespan, publish it
0572: add_tasks.add(new_task);
0573: }
0574: }
0575: // Rescind any tasks that were not accounted for
0576: Enumeration e = published_schedule.getAllScheduleElements();
0577: while (e.hasMoreElements()) {
0578: Task task = (Task) ((ObjectScheduleElement) e.nextElement())
0579: .getObject();
0580: if (logger.isDebugEnabled()) {
0581: logger.debug(printProjection("remove", task));
0582: }
0583: plugin_.publishRemoveFromExpansion(task);
0584: }
0585: if (logger.isDebugEnabled()) {
0586: for (Enumeration en = add_tasks.elements(); en
0587: .hasMoreElements();) {
0588: Task task = (Task) en.nextElement();
0589: logger.debug(printProjection("add", task));
0590: }
0591: }
0592: return add_tasks.elements();
0593: }
0594:
0595: protected void setEndTimePreference(NewTask task, long end) {
0596: AspectValue av = TimeAspectValue.create(AspectType.END_TIME,
0597: end);
0598: ScoringFunction score = ScoringFunction
0599: .createStrictlyAtValue(av);
0600: task.setPreference(ldmFactory_.newPreference(
0601: AspectType.END_TIME, score));
0602: }
0603:
0604: protected void setStartTimePreference(NewTask task, long start) {
0605: AspectValue av = TimeAspectValue.create(AspectType.START_TIME,
0606: start);
0607: ScoringFunction score = ScoringFunction
0608: .createStrictlyAtValue(av);
0609: task.setPreference(ldmFactory_.newPreference(
0610: AspectType.START_TIME, score));
0611: }
0612:
0613: protected String printProjection(String msg, Task task) {
0614: return ("diffProjections() " + task.getUID() + " " + msg + " "
0615: + TaskUtils.getDailyQuantity(task) + " "
0616: + TimeUtils.dateString(TaskUtils.getStartTime(task))
0617: + " to " + TimeUtils.dateString(TaskUtils
0618: .getEndTime(task)));
0619: }
0620:
0621: public static Schedule newObjectSchedule(Enumeration tasks) {
0622: Vector os_elements = new Vector();
0623: ScheduleImpl s = new ScheduleImpl();
0624: s.setScheduleElementType(PlanScheduleElementType.OBJECT);
0625: s.setScheduleType(ScheduleType.OTHER);
0626: Task task;
0627: while (tasks.hasMoreElements()) {
0628: task = (Task) tasks.nextElement();
0629: os_elements.add(new ObjectScheduleElement(TaskUtils
0630: .getStartTime(task), TaskUtils.getEndTime(task),
0631: task));
0632: }
0633: s.setScheduleElements(os_elements.elements());
0634: return s;
0635: }
0636:
0637: private Hashtable createPublishedTable(Enumeration tasks) {
0638: Hashtable task_table = new Hashtable();
0639: while (tasks.hasMoreElements()) {
0640: Task task = (Task) tasks.nextElement();
0641: // create new key for each part of the workflow
0642: task_table.put(taskKey(task),
0643: new PublishedTask(task, false));
0644: }
0645: return task_table;
0646: }
0647:
0648: /**
0649: * Rescinds all elements in the given hashtable that
0650: * have not been republished since the last call to
0651: */
0652: private boolean rescindUnpublishedTasks(Hashtable tasks) {
0653: PublishedTask ipo;
0654: Task task;
0655: String key;
0656: Object obj;
0657: boolean removed_task = false;
0658:
0659: Enumeration key_list = tasks.keys();
0660: while (key_list.hasMoreElements()) {
0661: key = (String) key_list.nextElement();
0662: ipo = (PublishedTask) tasks.get(key);
0663: task = ipo.getTask();
0664: // Taking out commitment check temporarily until it is decided
0665: // how this field is to be used
0666: if (!(ipo.getPublished())
0667: && task.beforeCommitment(new Date(getAlpTime()))) {
0668: // if (!(ipo.getPublished())) {
0669: // printDebug("rescindUnpublishedTasks() removing key <"+key+">");
0670: delegate_.publishRemove(ipo.getTask());
0671: removed_task = true;
0672: }
0673: }
0674: return removed_task;
0675: }
0676:
0677: protected void publishAddTask(Task task) {
0678: // delegate_.publishAdd(task);
0679: if (!plugin_.publishAddObject(task)) {
0680:
0681: if (logger.isErrorEnabled()) {
0682: logger.error("publishAddTask fail to publish task "
0683: + TaskUtils.taskDesc(task));
0684: }
0685: }
0686: }
0687:
0688: protected void publishRemoveTask(Task task) {
0689: delegate_.publishRemove(task);
0690: }
0691:
0692: protected void publishAsset(Asset asset) {
0693: delegate_.publishAdd(asset);
0694: }
0695:
0696: protected void publishRemoveAsset(Asset asset) {
0697: delegate_.publishRemove(asset);
0698: }
0699:
0700: protected void publishChangeAsset(Asset asset) {
0701: delegate_.publishChange(asset);
0702: }
0703:
0704: protected void publishChangeTask(Task task) {
0705: delegate_.publishChange(task);
0706: }
0707:
0708: protected void publishRemoveAllocation(Allocation alloc) {
0709: delegate_.publishRemove(alloc);
0710: }
0711:
0712: protected void publishRemoveExpansion(Expansion exp) {
0713: delegate_.publishRemove(exp);
0714: }
0715:
0716: protected boolean publishAllocation(Task task, Asset asset,
0717: org.cougaar.planning.ldm.plan.Role role) {
0718: return publishAllocation(task, asset, role, null, false);
0719: }
0720:
0721: protected boolean publishAllocation(Task task, Asset asset,
0722: Role role, AllocationResult ar) {
0723: return publishAllocation(task, asset, role, ar, true);
0724: }
0725:
0726: protected boolean publishAllocation(Task task, Asset asset,
0727: Role role, AllocationResult ar, boolean needAR) {
0728: // Commitment Date is an important piece of replanning but will not be part of Demo99
0729: if (!(task.beforeCommitment(new Date(getAlpTime())))) {
0730: if (logger.isDebugEnabled()) {
0731: logger
0732: .debug("publishAllocation: return ... after commitment"
0733: + task.getCommitmentDate()
0734: + " task:"
0735: + task + " to Asset " + asset);
0736: }
0737: // too late to change
0738: return false;
0739: }
0740: // printDebug(2,"publishAllocation: "+TaskUtils.taskDesc(task)+" with plan element: "+task.getPlanElement());
0741:
0742: if (asset == null) {
0743: if (logger.isErrorEnabled()) {
0744: logger.error("publishAllocation null asset! for task "
0745: + task);
0746: }
0747: return false;
0748: }
0749:
0750: PlanElement pe = task.getPlanElement();
0751: Allocation alloc;
0752: if (pe == null) {
0753: // new allocation
0754: alloc = buildAllocation(task, asset, role);
0755: if (ar != null) {
0756: alloc.setEstimatedResult(ar);
0757: } else if (needAR) {
0758: if (logger.isDebugEnabled()) {
0759: logger
0760: .debug("publishing allocation without estimated result: "
0761: + alloc.getUID());
0762: }
0763: }
0764: if (!plugin_.publishAddObject(alloc)) {
0765: if (logger.isErrorEnabled()) {
0766: logger.error("publishAalloc fail to publish alloc "
0767: + alloc);
0768: }
0769: }
0770: return true;
0771: }
0772: if (!(pe instanceof Allocation)) {
0773: if (logger.isDebugEnabled()) {
0774: logger
0775: .debug("publishAllocation: plan element not allocation:"
0776: + pe);
0777: }
0778: if (logger.isDebugEnabled()) {
0779: logger.debug("publishAllocation: task:" + task);
0780: }
0781: return false;
0782: }
0783:
0784: boolean change_alloc = false;
0785: boolean add_alloc = false;
0786:
0787: alloc = (Allocation) pe;
0788:
0789: // check task
0790: Task published_task = alloc.getTask();
0791: if (published_task != task) {
0792: if (taskKey(published_task).equals(taskKey(task))) {
0793: // Commitment Date is an important part of replanning but is not part of Demo99
0794: if (published_task.beforeCommitment(new Date(
0795: getAlpTime()))) {
0796: // check if changed...
0797: if (changeTask(published_task, task) != null) {
0798: // printDebug(2,"publishAllocation CHANGED task"+ task.getUID());
0799: change_alloc = true;
0800: }
0801: // printDebug("after changeTask: " + TaskUtils.taskDesc(published_task));
0802: task = published_task;
0803: }
0804: } else {
0805: if (logger.isErrorEnabled()) {
0806: logger.error("new task? publishAllocation old:"
0807: + published_task + " \n new:" + task);
0808: }
0809: }
0810: }
0811:
0812: // check asset
0813: if (alloc.getAsset() != asset) {
0814: delegate_.publishRemove(alloc);
0815: if (logger.isDebugEnabled()) {
0816: logger
0817: .debug("publishAlloc removing and adding in same transaction for ASSET:"
0818: + alloc.getAsset()
0819: + " vs. "
0820: + asset
0821: + " task:" + TaskUtils.taskDesc(task));
0822: }
0823: // PAS this will probably cause an error.
0824: alloc = buildAllocation(task, asset, role);
0825: add_alloc = true;
0826: }
0827:
0828: // check role
0829: if (!add_alloc && !alloc.getRole().equals(role)) {
0830: if (logger.isDebugEnabled()) {
0831: logger.debug("publishAllocation CHANGE role " + task);
0832: }
0833: delegate_.publishRemove(alloc);
0834: if (logger.isDebugEnabled()) {
0835: logger
0836: .debug("publishAlloc removing and adding in same transaction for ROLE: "
0837: + alloc.getRole()
0838: + " not equal to "
0839: + role
0840: + " task:"
0841: + TaskUtils.taskDesc(task));
0842: }
0843: // PAS this will probably cause an error.
0844: alloc = buildAllocation(task, asset, role);
0845: add_alloc = true;
0846: }
0847:
0848: // check allocation result
0849: AllocationResult alloc_ar = alloc.getEstimatedResult();
0850: if ((ar != null)
0851: && ((alloc_ar == null) || !ar.isEqual(alloc_ar))) {
0852: alloc.setEstimatedResult(ar);
0853: // printDebug("publishAllocation CHANGE result" +task);
0854: change_alloc = true;
0855: // need to publish change
0856: } else {
0857: if ((ar == null) && (alloc_ar != null)) {
0858: alloc
0859: .setEstimatedResult(createEstimatedAllocationResult(task));
0860: // printDebug("publishAllocation CHANGE result (new)" +task);
0861: change_alloc = true;
0862: }
0863: }
0864:
0865: if (add_alloc) {
0866: if (!plugin_.publishAddObject(alloc)) {
0867: if (logger.isErrorEnabled()) {
0868: logger.error("publishAalloc fail to publish alloc "
0869: + alloc);
0870: }
0871: }
0872: return true;
0873: } else if (change_alloc) {
0874: // printDebug("publishAlloc publishChange "+pe);
0875: delegate_.publishChange(pe);
0876: return true;
0877: }
0878: return false;
0879: }
0880:
0881: public AllocationResult buildExpansionResult(Expansion expansion) {
0882: return buildExpansionResult(expansion, true);
0883: }
0884:
0885: public AllocationResult buildExpansionResult(Expansion expansion,
0886: boolean like_tasks) {
0887: Hashtable table = new Hashtable();
0888:
0889: Task task;
0890: PlanElement sub_pe;
0891: Workflow wf = expansion.getWorkflow();
0892: Enumeration tasks = wf.getTasks();
0893: while (tasks.hasMoreElements()) {
0894: task = (Task) tasks.nextElement();
0895: sub_pe = task.getPlanElement();
0896: if (sub_pe != null) {
0897: AllocationResult ar = sub_pe.getReportedResult();
0898: if (ar == null) {
0899: // task has been expanded or allocated...
0900: // but no results returned.
0901: // Or allocated to final asset, in which case
0902: // only the estimated gets set...
0903: ar = sub_pe.getEstimatedResult();
0904: if (ar == null) {
0905: // printDebug("buildExpansionResult() No reported or estimated Result pe:"+sub_pe+" .\nparent:"+task);
0906: return null;
0907: }
0908: }
0909: table.put(task, ar);
0910: }
0911: // else hasn't been allocated or expanded yet.
0912: }
0913: if (like_tasks) {
0914: return AllocationResultAggregator.DEFAULT.calculate(wf,
0915: new TaskScoreTable(table), expansion
0916: .getEstimatedResult());
0917: } else {
0918: return UnlikeTaskARA_.calculate(wf, new TaskScoreTable(
0919: table), expansion.getEstimatedResult());
0920: }
0921: }
0922:
0923: /**
0924: * Does the right computation for workflows which are made up of
0925: * equally important tasks with no inter-task constraints.
0926: * START_TIME is minimized.
0927: * END_TIME is maximized.
0928: * DURATION is overall END_TIME - overall START_TIME.
0929: * COST is summed.
0930: * DANGER is maximized.
0931: * RISK is maximized.
0932: * QUANTITY is maximized.
0933: * INTERVAL is summed.
0934: * TOTAL_QUANTITY is maximized.
0935: * TOTAL_SHIPMENTS is summed.
0936: * CUSTOMER_SATISFACTION is averaged.
0937: * Any extended aspect types are ignored.
0938: * For AuxiliaryQuery information, if all the query values are the same
0939: * across subtasks or one subtask has query info it will be place in the
0940: * aggregate result. However, if there are conflicting query values, no
0941: * information will be put in the aggregated result.
0942: * returns null when there are no subtasks or any task has no result.
0943: */
0944: public class UnlikeTaskARA implements AllocationResultAggregator {
0945: public AllocationResult calculate(Workflow wf,
0946: TaskScoreTable tst, AllocationResult currentar) {
0947: double acc[] = new double[AspectType._ASPECT_COUNT];
0948: acc[START_TIME] = Double.MAX_VALUE;
0949: acc[END_TIME] = 0.0;
0950: // duration is computed from end values of start and end
0951: acc[COST] = 0.0;
0952: acc[DANGER] = 0.0;
0953: acc[RISK] = 0.0;
0954: acc[QUANTITY] = 0.0;
0955: acc[INTERVAL] = 0.0;
0956: acc[TOTAL_QUANTITY] = 0.0;
0957: acc[TOTAL_SHIPMENTS] = 0.0;
0958: acc[CUSTOMER_SATISFACTION] = 1.0; // start at best
0959:
0960: int count = 0;
0961: boolean suc = true;
0962: double rating = 0.0;
0963:
0964: Enumeration tasks = wf.getTasks();
0965: if (tasks == null || (!tasks.hasMoreElements()))
0966: return null;
0967:
0968: String auxqsummary[] = new String[AuxiliaryQueryType.AQTYPE_COUNT];
0969: // initialize all values to UNDEFINED for comparison purposes below.
0970: final String UNDEFINED = "UNDEFINED";
0971: for (int aqs = 0; aqs < auxqsummary.length; aqs++) {
0972: auxqsummary[aqs] = UNDEFINED;
0973: }
0974:
0975: while (tasks.hasMoreElements()) {
0976: Task t = (Task) tasks.nextElement();
0977: count++;
0978: AllocationResult ar = tst.getAllocationResult(t);
0979: if (ar == null) {
0980: return null; // bail if undefined
0981: }
0982:
0983: suc = suc && ar.isSuccess();
0984: rating += ar.getConfidenceRating();
0985:
0986: int[] definedaspects = ar.getAspectTypes();
0987: for (int b = 0; b < definedaspects.length; b++) {
0988: // accumulate the values for the defined aspects
0989: switch (definedaspects[b]) {
0990: case START_TIME:
0991: acc[START_TIME] = Math.min(acc[START_TIME], ar
0992: .getValue(START_TIME));
0993: break;
0994: case END_TIME:
0995: acc[END_TIME] = Math.max(acc[END_TIME], ar
0996: .getValue(END_TIME));
0997: break;
0998: // compute duration later
0999: case COST:
1000: acc[COST] += ar.getValue(COST);
1001: break;
1002: case DANGER:
1003: acc[DANGER] = Math.max(acc[DANGER], ar
1004: .getValue(DANGER));
1005: break;
1006: case RISK:
1007: acc[RISK] = Math.max(acc[RISK], ar
1008: .getValue(RISK));
1009: break;
1010: case QUANTITY:
1011: acc[QUANTITY] = Math.max(acc[QUANTITY], ar
1012: .getValue(QUANTITY));
1013: break;
1014: // for now simply add the repetitve task values
1015: case INTERVAL:
1016: acc[INTERVAL] += ar.getValue(INTERVAL);
1017: break;
1018: case TOTAL_QUANTITY:
1019: acc[TOTAL_QUANTITY] = Math.max(
1020: acc[TOTAL_QUANTITY], ar
1021: .getValue(TOTAL_QUANTITY));
1022: break;
1023: case TOTAL_SHIPMENTS:
1024: acc[TOTAL_SHIPMENTS] += ar
1025: .getValue(TOTAL_SHIPMENTS);
1026: break;
1027: //end of repetitive task specific aspects
1028: case CUSTOMER_SATISFACTION:
1029: acc[CUSTOMER_SATISFACTION] += ar
1030: .getValue(CUSTOMER_SATISFACTION);
1031: break;
1032: }
1033: }
1034:
1035: // Sum up the auxiliaryquery data. If there are conflicting data
1036: // values, send back nothing for that type. If only one subtask
1037: // has information about a querytype, send it back in the
1038: // aggregated result.
1039: for (int aq = 0; aq < AuxiliaryQueryType.AQTYPE_COUNT; aq++) {
1040: String data = ar.auxiliaryQuery(aq);
1041: if (data != null) {
1042: String sumdata = auxqsummary[aq];
1043: // if sumdata = null, there has already been a conflict.
1044: if (sumdata != null) {
1045: if (sumdata.equals(UNDEFINED)) {
1046: // there's not a value yet, so use this one.
1047: auxqsummary[aq] = data;
1048: } else if (!data.equals(sumdata)) {
1049: // there's a conflict, pass back null
1050: auxqsummary[aq] = null;
1051: }
1052: }
1053: }
1054: }
1055:
1056: } // end of looping through all subtasks
1057:
1058: acc[DURATION] = acc[END_TIME] - acc[START_TIME];
1059: acc[CUSTOMER_SATISFACTION] /= count;
1060:
1061: rating /= count;
1062:
1063: boolean delta = false;
1064: //for (int i = 0; i <= _LAST_ASPECT; i++) {
1065: //if (acc[i] != currentar.getValue(i)) {
1066: //delta = true;
1067: //break;
1068: //}
1069: //}
1070:
1071: // only check the defined aspects and make sure that the currentar is not null
1072: if (currentar == null) {
1073: delta = true; // if the current ar == null then set delta true
1074: } else {
1075: int[] caraspects = currentar.getAspectTypes();
1076: if (caraspects.length != acc.length) {
1077: //if the current ar length is different than the length of the new
1078: // calculations (acc) there's been a change
1079: delta = true;
1080: } else {
1081: for (int i = 0; i < caraspects.length; i++) {
1082: int da = caraspects[i];
1083: if (acc[da] != currentar.getValue(da)) {
1084: delta = true;
1085: break;
1086: }
1087: }
1088: }
1089:
1090: if (!delta) {
1091: if (currentar.isSuccess() != suc) {
1092: delta = true;
1093: } else if (Math.abs(currentar.getConfidenceRating()
1094: - rating) > SIGNIFICANT_CONFIDENCE_RATING_DELTA) {
1095: delta = true;
1096: }
1097: }
1098: }
1099:
1100: if (delta) {
1101: AllocationResult artoreturn = new AllocationResult(
1102: rating, suc, _STANDARD_ASPECTS, acc);
1103: for (int aqt = 0; aqt < auxqsummary.length; aqt++) {
1104: String aqdata = auxqsummary[aqt];
1105: if ((aqdata != null) && (aqdata != UNDEFINED)) {
1106: artoreturn.addAuxiliaryQueryInfo(aqt, aqdata);
1107: }
1108: }
1109: return artoreturn;
1110: } else {
1111: return currentar;
1112: }
1113: }
1114: }
1115:
1116: // If estimated result != reported result,
1117: // copy reported to estimated.
1118: public void updateAllocationResult(PlanElement pe) {
1119: if (TaskUtils.updatePlanElement(pe))
1120: delegate_.publishChange(pe);
1121: }
1122:
1123: /**
1124: * When the published sub-tasks of an expansion get the allocation result updated,
1125: * try to update the allocation result on the whole expansion.
1126: * Do not update the allocation result until all subtasks have been updated.
1127: */
1128: protected void updateExpansionResult(Enumeration planelements) {
1129: while (planelements.hasMoreElements()) {
1130: updateAllocationResult((PlanElement) planelements
1131: .nextElement());
1132: }
1133: }
1134:
1135: protected void publishFailedDisposition(Task task,
1136: AllocationResult ar) {
1137: PlanElement pe = task.getPlanElement();
1138: Disposition fa;
1139: if (pe == null) {
1140: fa = ldmFactory_.createFailedDisposition(task.getPlan(),
1141: task, ar);
1142: if (fa == null) {
1143: if (logger.isErrorEnabled()) {
1144: logger.error("publishFailedDisposition... no fa?: "
1145: + task);
1146: }
1147: }
1148: delegate_.publishAdd(fa);
1149: } else {
1150: if (!(pe instanceof Disposition)) {
1151: if (logger.isErrorEnabled()) {
1152: logger
1153: .error("publishFailedDisposition: plan element not Failed allocation:"
1154: + pe);
1155: }
1156: if (logger.isErrorEnabled()) {
1157: logger.error("publishFailedDisposition: task:"
1158: + task);
1159: }
1160: return;
1161: }
1162: fa = (Disposition) pe;
1163: // check difference between last fa and this ar.
1164: if (!ar.isEqual(fa.getEstimatedResult())) {
1165: fa.setEstimatedResult(ar);
1166: delegate_.publishChange(fa);
1167: }
1168: }
1169: }
1170:
1171: public String arDesc(AllocationResult ar) {
1172: try {
1173: return "(AR: "
1174: + (long) ar.getValue(AspectType.QUANTITY)
1175: + "; "
1176: + TimeUtils.dateString((long) ar
1177: .getValue(AspectType.START_TIME))
1178: + ","
1179: + TimeUtils.dateString((long) ar
1180: .getValue(AspectType.END_TIME)) + ")";
1181: } catch (Exception e) {
1182: return "(AR: "
1183: + ar
1184: + TimeUtils.dateString((long) ar
1185: .getValue(AspectType.START_TIME))
1186: + ","
1187: + TimeUtils.dateString((long) ar
1188: .getValue(AspectType.END_TIME)) + ")";
1189: }
1190: }
1191:
1192: public String qseString(QuantityScheduleElement qse) {
1193: return " qty: " + demandFormat.format(qse.getQuantity())
1194: + " " + TimeUtils.dateString(qse.getStartTime())
1195: + " to " + TimeUtils.dateString(qse.getEndTime());
1196: }
1197:
1198: /**
1199: * create an AllocationResult that assumes the 'best' possible result
1200: * (taken from GLSAllocatorPlugin)
1201: */
1202: public AllocationResult createEstimatedAllocationResult(Task t) {
1203: AllocationResultHelper helper = new AllocationResultHelper(t,
1204: null);
1205: return helper.getAllocationResult(0.0, true);
1206: }
1207:
1208: public PrepositionalPhrase newPrepositionalPhrase(
1209: String preposition, Object io) {
1210: NewPrepositionalPhrase pp = ldmFactory_
1211: .newPrepositionalPhrase();
1212: pp.setPreposition(preposition);
1213: pp.setIndirectObject(io);
1214: return pp;
1215: }
1216:
1217: public PrepositionalPhrase newPrepositionalPhrase(String preposition) {
1218: NewPrepositionalPhrase pp = ldmFactory_
1219: .newPrepositionalPhrase();
1220: pp.setPreposition(preposition);
1221: return pp;
1222: }
1223:
1224: public NewTask buildNewTask(Task input_task, String output_verb,
1225: Asset direct_object) {
1226: NewTask newtask = ldmFactory_.newTask();
1227: if (input_task == null) {
1228: newtask.setPlan(ldmFactory_.getRealityPlan());
1229: } else {
1230: newtask.setParentTask(input_task);
1231: newtask.setPlan(input_task.getPlan());
1232: newtask.setPrepositionalPhrases(input_task
1233: .getPrepositionalPhrases());
1234: }
1235: newtask.setDirectObject(direct_object);
1236: newtask.setVerb(Verb.get(output_verb));
1237: return newtask;
1238: }
1239:
1240: public Task buildTask(Task input_task, String output_verb,
1241: Asset direct_object, PrepositionalPhrase pp) {
1242: NewTask newtask = buildNewTask(input_task, output_verb,
1243: direct_object);
1244: newtask = TaskUtils.addPrepositionalPhrase(newtask, pp);
1245: return newtask;
1246: }
1247:
1248: public Task buildTask(Task input_task, String output_verb,
1249: Asset direct_object, Vector preposition_phrases) {
1250: NewTask newtask = buildNewTask(input_task, output_verb,
1251: direct_object);
1252: newtask.setPrepositionalPhrases(preposition_phrases.elements());
1253: return newtask;
1254: }
1255:
1256: public Task buildTask(Task input_task, String output_verb,
1257: Asset direct_object, Vector preposition_phrases,
1258: Preference pref) {
1259: NewTask newtask = buildNewTask(input_task, output_verb,
1260: direct_object);
1261: newtask.setPrepositionalPhrases(preposition_phrases.elements());
1262: newtask.addPreference(pref);
1263: return newtask;
1264: }
1265:
1266: public Task buildTask(Task input_task, String output_verb,
1267: Asset direct_object, Vector preposition_phrases,
1268: Enumeration prefs) {
1269: NewTask newtask = buildNewTask(input_task, output_verb,
1270: direct_object);
1271: newtask.setPrepositionalPhrases(preposition_phrases.elements());
1272: newtask.setPreferences(prefs);
1273: return newtask;
1274: }
1275:
1276: public Task buildTask(Task input_task, String output_verb,
1277: Asset direct_object, Enumeration prefs) {
1278: NewTask newtask = buildNewTask(input_task, output_verb,
1279: direct_object);
1280: newtask.setPreferences(prefs);
1281: return newtask;
1282: }
1283:
1284: /**
1285: * Create a preference with the Strict scoring function at 'value' for the
1286: * given aspect type
1287: */
1288: public Preference createPreference(int aspect, double value) {
1289: AspectValue av = AspectValue.newAspectValue(aspect, value);
1290: // ScoringFunction score = ScoringFunction.createPreferredAtValue(av, 2);
1291: ScoringFunction score = ScoringFunction
1292: .createStrictlyAtValue(av);
1293: return ldmFactory_.newPreference(aspect, score);
1294: }
1295:
1296: /**
1297: * Create a preference with the scoring NearOrAbove function at 'value' for the
1298: * given aspect type
1299: */
1300: public Preference createQuantityPreference(int aspect, double value) {
1301: AspectValue av = AspectValue.newAspectValue(aspect, value);
1302: ScoringFunction score = ScoringFunction
1303: .createNearOrAbove(av, 0);
1304: return ldmFactory_.newPreference(aspect, score);
1305: }
1306:
1307: public Preference createDateBeforePreference(int aspect, long value) {
1308: AspectValue av = AspectValue.newAspectValue(aspect, value);
1309: ScoringFunction score = ScoringFunction
1310: .createNearOrBelow(av, 0);
1311: return ldmFactory_.newPreference(aspect, score);
1312: }
1313:
1314: public Preference createDateAfterPreference(int aspect, long value) {
1315: AspectValue av = AspectValue.newAspectValue(aspect, value);
1316: ScoringFunction score = ScoringFunction
1317: .createNearOrAbove(av, 0);
1318: return ldmFactory_.newPreference(aspect, score);
1319: }
1320:
1321: }
1322:
1323: /* An object containing the
1324: * published plan element and a flag set if the plan element is
1325: * published after the current replan. */
1326: class PublishedTask {
1327:
1328: private Task task_;
1329: private boolean publishFlag_;
1330:
1331: /**
1332: * Constructer
1333: * @param t Task plan element to be published
1334: * @param b boolean is plan element published
1335: */
1336: public PublishedTask(Task t, boolean b) {
1337: task_ = t;
1338: publishFlag_ = b;
1339: }
1340:
1341: /**
1342: * Constructer (defaults to pe not published)
1343: * @param t Task plan element to be published
1344: */
1345: protected PublishedTask(Task t) {
1346: task_ = t;
1347: publishFlag_ = true;
1348: }
1349:
1350: /**
1351: * @return Task plan element
1352: */
1353: protected Task getTask() {
1354: return task_;
1355: }
1356:
1357: protected void setTask(Task task) {
1358: task_ = task;
1359: }
1360:
1361: /**
1362: * @param b boolean sets published flag to b.
1363: */
1364: protected void setPublished(boolean b) {
1365: publishFlag_ = b;
1366: }
1367:
1368: /**
1369: * @return boolean - is plan element published.
1370: */
1371: protected boolean getPublished() {
1372: return publishFlag_;
1373: }
1374: }
|