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.Enumeration;
031: import java.util.HashSet;
032: import java.util.Iterator;
033: import java.util.List;
034: import java.util.Map;
035: import java.util.Vector;
036:
037: import org.cougaar.core.mts.MessageAddress;
038: import org.cougaar.lib.filter.UTILPlugin;
039: import org.cougaar.planning.ldm.PlanningFactory;
040: import org.cougaar.planning.ldm.asset.Asset;
041: import org.cougaar.planning.ldm.plan.Aggregation;
042: import org.cougaar.planning.ldm.plan.AllocationResult;
043: import org.cougaar.planning.ldm.plan.AllocationResultDistributor;
044: import org.cougaar.planning.ldm.plan.AspectValue;
045: import org.cougaar.planning.ldm.plan.ContextOfOplanIds;
046: import org.cougaar.planning.ldm.plan.NewComposition;
047: import org.cougaar.planning.ldm.plan.NewMPTask;
048: import org.cougaar.planning.ldm.plan.Plan;
049: import org.cougaar.planning.ldm.plan.Priority;
050: import org.cougaar.planning.ldm.plan.Task;
051: import org.cougaar.planning.ldm.plan.Verb;
052: import org.cougaar.util.log.Logger;
053:
054: /**
055: * This class contains utility functions for creating
056: * Aggregations.
057: */
058:
059: public class UTILAggregate {
060: private static String myName = "UTILAggregate";
061: protected Logger logger;
062:
063: /**
064: * Set the logger -- may be misleading though
065: *
066: * @param log logger to use
067: */
068: public UTILAggregate(Logger log) {
069: logger = log;
070: alloc = new UTILAllocate(log);
071: expand = new UTILExpand(log);
072: assetHelper = new UTILAsset(log);
073: }
074:
075: /**
076: * Creates an Aggregation for every parent task.
077: *
078: * @param ldmf the PlanningFactory
079: * @param parentTasks parent tasks
080: * @return MPTask representing composition
081: */
082:
083: public List makeAggregation(UTILPlugin creator,
084: PlanningFactory ldmf, Plan realityPlan, Vector parentTasks,
085: Verb whatVerb, Vector prepPhrases, Vector directObjects,
086: Vector preferences, MessageAddress sourceClusterID,
087: AspectValue[] aspectValues, double confidence) {
088: List stuffToPublish = new ArrayList();
089:
090: NewMPTask mptask = makeMPSubTask(ldmf, realityPlan, parentTasks
091: .elements(), whatVerb, prepPhrases.elements(),
092: assetHelper.makeAssetGroup(ldmf, directObjects),
093: preferences.elements(), Priority.UNDEFINED,
094: sourceClusterID);
095:
096: // create the new composition
097: NewComposition comp = ldmf.newComposition();
098: comp.setCombinedTask(mptask);
099: comp.setDistributor(AllocationResultDistributor.DEFAULT);
100: // comp.setIsPropagating();
101:
102: // create the new MP task that represents all subtasks
103: mptask.setComposition(comp);
104: mptask.setParentTasks(parentTasks.elements());
105: stuffToPublish.add(mptask);
106: stuffToPublish.add(comp);
107:
108: // create aggregations for each parent task
109: for (Iterator i = parentTasks.iterator(); i.hasNext();) {
110: Task parentTask = (Task) i.next();
111: // if (logger.isDebugEnabled())
112: // alloc.setLogger (logger);
113: boolean isSuccess = !alloc.exceedsPreferences(parentTask,
114: aspectValues);
115:
116: if (!isSuccess) {
117: logger
118: .warn("UTILAggregate.makeAggregation - making failed aggregation for "
119: + parentTask);
120: expand.showPreferences(parentTask, aspectValues);
121: }
122:
123: // if (logger.isDebugEnabled())
124: // UTILAllocate.setLogger (logger);
125: AllocationResult estAR = ldmf.newAVAllocationResult(
126: confidence, isSuccess, aspectValues);
127: Aggregation agg = ldmf.createAggregation(parentTask
128: .getPlan(), parentTask, comp, estAR);
129: if (logger.isDebugEnabled())
130: logger
131: .debug("UTILAggregate.makeAggregation - Making aggregation for task "
132: + parentTask.getUID()
133: + " agg "
134: + agg.getUID());
135:
136: stuffToPublish.add(agg);
137: comp.addAggregation(agg);
138: }
139:
140: return stuffToPublish;
141: }
142:
143: /**
144: * Creates an Aggregation for every parent task.
145: * <p>
146: * Note that the direct object of the MPTask will usually contain an asset group
147: * whose members are the direct objects of the parents. <br>
148: * If one wishes to rescind a parent task, both the list of parents on the MPTask<br>
149: * and the direct object should be repaired.
150: * <p>
151: * By default does not propagate rescinds past an aggregation.
152: * <p>
153: * @param creator the plugin that created the aggregations, told when there is
154: * a failure
155: * @param ldmf the PlanningFactory
156: * @param realityPlan the plan the plan elements are part of
157: * @param parentTasks parent tasks
158: * @param whatVerb the verb to give the MPTask
159: * @param prepPhrases preps to attach to the MPTask
160: * @param directObjects the direct objects of the parent tasks (usually) that will
161: * be put into an asset group, which will be the direct object of the MPTask
162: * @param preferences the preferences for the MPTask
163: * @param sourceClusterID which cluster is creating these things
164: * @param taskToAspectValues maps task to an array of AspectValues
165: * @param confidence what confidence to set the on the allocation results of the aggregations
166: * @return List of items to publish, which will include the MPTask
167: * representing composition, all the compositions, and the aggregation plan elements
168: */
169:
170: public List makeAggregation(UTILPlugin creator,
171: PlanningFactory ldmf, Plan realityPlan, Vector parentTasks,
172: Verb whatVerb, Vector prepPhrases, Vector directObjects,
173: Vector preferences, MessageAddress sourceClusterID,
174: Map taskToAspectValues, double confidence) {
175: List stuffToPublish = new ArrayList();
176:
177: NewMPTask mptask = makeMPSubTask(ldmf, realityPlan, parentTasks
178: .elements(), whatVerb, prepPhrases.elements(),
179: assetHelper.makeAssetGroup(ldmf, directObjects),
180: preferences.elements(), Priority.UNDEFINED,
181: sourceClusterID);
182: // create the new composition
183: NewComposition comp = ldmf.newComposition();
184: comp.setCombinedTask(mptask);
185: comp.setDistributor(AllocationResultDistributor.DEFAULT);
186: // comp.setIsPropagating();
187:
188: HashSet set = new HashSet();
189: Iterator taskIt = parentTasks.iterator();
190: Task parent;
191: while (taskIt.hasNext()) {
192: parent = (Task) taskIt.next();
193: if (parent.getContext() != null) {
194: set.addAll((ContextOfOplanIds) parent.getContext());
195: }
196: }
197: mptask.setContext(new ContextOfOplanIds(set));
198:
199: // create the new MP task that represents all subtasks
200: mptask.setComposition(comp);
201: mptask.setParentTasks(parentTasks.elements());
202: stuffToPublish.add(mptask);
203: stuffToPublish.add(comp);
204:
205: AllocationResult lastAR = null;
206: AspectValue[] lastAV = null;
207: // create aggregations for each parent task
208: for (Iterator i = parentTasks.iterator(); i.hasNext();) {
209: Task parentTask = (Task) i.next();
210: // get the aspect values specific to this task
211: AspectValue[] aspectValues = (AspectValue[]) taskToAspectValues
212: .get(parentTask);
213:
214: // if (logger.isDebugEnabled())
215: // UTILAllocate.setLogger (logger); // will show comparison of prefs to aspect value
216: boolean isSuccess = !alloc.exceedsPreferences(parentTask,
217: aspectValues);
218:
219: if (!isSuccess) {
220: logger
221: .warn("UTILAggregate.makeAggregation - making failed aggregation for "
222: + parentTask);
223: expand.showPlanElement(parentTask);
224: }
225:
226: // if (logger.isDebugEnabled())
227: // UTILAllocate.setLogger (logger);
228:
229: AllocationResult estAR;
230:
231: if (aspectValues == lastAV)
232: estAR = lastAR; // avoid creating a new allocation result if we have the same aspect value array
233: else
234: estAR = ldmf.newAVAllocationResult(confidence,
235: isSuccess, aspectValues);
236:
237: Aggregation agg = ldmf.createAggregation(parentTask
238: .getPlan(), parentTask, comp, estAR);
239: if (logger.isDebugEnabled())
240: logger
241: .debug("UTILAggregate.makeAggregation - Making aggregation for task "
242: + parentTask.getUID()
243: + " agg "
244: + agg.getUID());
245:
246: stuffToPublish.add(agg);
247: comp.addAggregation(agg);
248:
249: lastAV = aspectValues;
250: lastAR = estAR;
251: }
252:
253: return stuffToPublish;
254: }
255:
256: /**
257: * Creates a failed Aggregation.
258: *
259: * Sets the estimated allocation result of the plan element to an
260: * empty failed alloc result.
261: *
262: * @param ldmf PlanningFactory
263: * @param t task
264: * @return Aggregation
265: */
266: public Aggregation makeFailedAggregation(UTILPlugin creator,
267: PlanningFactory ldmf, Task t) {
268: AllocationResult failedAR = ldmf.newAllocationResult(1.0,
269: false, new int[1], new double[1]);
270:
271: Aggregation agg = ldmf.createAggregation(t.getPlan(), t, ldmf
272: .newComposition(), failedAR);
273: return agg;
274: }
275:
276: /**
277: * Create an MPTask with an enumeration of parent tasks.
278: * @param ldmf the PlanningFactory
279: * @param source the cluster originating the task
280: * @param plan the log plan
281: * @param parentTasks parent tasks
282: * @param verb the verb
283: * @param prepphrases PrepositionalPhrases
284: * @param obj the direct object
285: * @return NewMPTask
286: */
287: public NewMPTask makeMPSubTask(PlanningFactory ldmf, Plan plan,
288: Enumeration parentTasks, Verb verb,
289: Enumeration prepphrases, Asset obj,
290: Enumeration preferences, byte priority,
291: MessageAddress source) {
292:
293: NewMPTask mpt = ldmf.newMPTask();
294: mpt.setPlan(plan);
295: mpt.setParentTasks(parentTasks);
296: mpt.setVerb(verb);
297: if (prepphrases != null)
298: mpt.setPrepositionalPhrases(prepphrases);
299: mpt.setDirectObject(obj);
300: mpt.setPreferences(preferences);
301: mpt.setPriority(priority);
302: mpt.setSource(source);
303: return mpt;
304: }
305:
306: protected UTILAllocate alloc;
307: protected UTILExpand expand;
308: protected UTILAsset assetHelper;
309: }
|