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.logistics.plugin.demand;
028:
029: import java.util.Collection;
030: import java.util.ArrayList;
031: import java.util.Vector;
032: import java.util.Iterator;
033: import java.util.Enumeration;
034: import java.util.HashSet;
035:
036: import org.cougaar.planning.ldm.asset.Asset;
037: import org.cougaar.planning.ldm.plan.*;
038: import org.cougaar.planning.ldm.asset.AggregateAsset;
039: import org.cougaar.planning.ldm.measure.CountRate;
040: import org.cougaar.planning.plugin.util.PluginHelper;
041: import org.cougaar.logistics.ldm.Constants;
042: import org.cougaar.glm.ldm.plan.AlpineAspectType;
043:
044: /**
045: * <pre>
046: * The default RequirementsExpander for the DemandForecastPlugin.
047: *
048: * This class expands a determine requirements task into generateProjections tasks for each
049: * MEI that has the passed in supply class PG on it.
050: *
051: *
052: **/
053:
054: public class DetermineRequirementsExpander extends DemandForecastModule
055: implements DetReqExpanderIfc {
056:
057: public DetermineRequirementsExpander(DemandForecastPlugin dfPlugin) {
058: super (dfPlugin);
059: }
060:
061: /**
062: * Expand DetermineRequirements tasks into GenerateProjections tasks.
063: **/
064: public void expandDetermineRequirements(Task detReqTask,
065: Collection assets) {
066: if ((assets == null) || (assets.isEmpty())) {
067: disposeOfTask(detReqTask);
068: return;
069: }
070: ArrayList gpTasks = new ArrayList();
071: Iterator assetIT = assets.iterator();
072: while (assetIT.hasNext()) {
073: Asset consumer = (Asset) assetIT.next();
074: if (getAssetUtils().getQuantity(consumer) > 0) {
075: NewTask gpTask = createGPTask(detReqTask, consumer);
076: gpTasks.add(gpTask);
077: } else {
078: if (logger.isWarnEnabled()) {
079: Asset asset;
080: if (consumer instanceof AggregateAsset) {
081: asset = ((AggregateAsset) consumer).getAsset();
082: } else {
083: // Not expecting this case, only AggregateAssets can have a zero quantity
084: asset = consumer.getPrototype();
085: }
086: logger
087: .warn("Ignoring Asset: "
088: + getAssetUtils()
089: .getAssetIdentifier(asset)
090: + " at "
091: + dfPlugin.getMyOrganization()
092: + " - Asset has a quantity of zero. Bug #3467");
093: }
094: }
095: }
096: if (gpTasks.isEmpty()) {
097: if (logger.isWarnEnabled()) {
098: logger
099: .warn("Cannot expand - no subtasks for determine requirements task "
100: + getTaskUtils().taskDesc(detReqTask));
101: }
102: } else {
103: PlanElement pe = detReqTask.getPlanElement();
104: if ((pe != null) && (pe instanceof Disposition)) {
105: dfPlugin.publishRemove(pe);
106: pe = null;
107: }
108: // First time through build a fresh expansion
109: if (pe == null) {
110: createAndPublishExpansion(detReqTask, gpTasks);
111: }
112: // There are new assets to add to the expansion
113: else if (pe instanceof Expansion) {
114: addToAndPublishExpansion(detReqTask, gpTasks);
115: } else {
116: if (logger.isErrorEnabled()) {
117: logger
118: .error("Unhandled plan element type on DetermineRequirementsTask :"
119: + pe.getClass().getName());
120: }
121: }
122: }
123: }
124:
125: public void removeSubtasksFromDetermineRequirements(
126: Task detReqTask, Collection removedAssets) {
127: Expansion expansion = (Expansion) detReqTask.getPlanElement();
128: NewWorkflow wf = (NewWorkflow) expansion.getWorkflow();
129: HashSet remTaskHash = new HashSet(removedAssets);
130: Enumeration subtasks = wf.getTasks();
131: while (subtasks.hasMoreElements()) {
132: Task task = (Task) subtasks.nextElement();
133: Asset consumer = task.getDirectObject();
134: if (remTaskHash.contains(consumer)) {
135: wf.removeTask(task);
136: dfPlugin.publishRemove(task);
137: }
138: }
139: dfPlugin.publishChange(expansion);
140: }
141:
142: protected void createAndPublishExpansion(Task parent,
143: Collection subtasks) {
144: Iterator subtasksIT = subtasks.iterator();
145: while (subtasksIT.hasNext()) {
146: dfPlugin.publishAdd(subtasksIT.next());
147: }
148: Workflow wf = buildWorkflow(parent, subtasks);
149: Expansion expansion = getPlanningFactory().createExpansion(
150: parent.getPlan(), parent, wf, null);
151: dfPlugin.publishAdd(expansion);
152: if (logger.isDebugEnabled()) {
153: logger.debug("Agent: " + dfPlugin.getClusterId().toString()
154: + "DetReqExp type[" + dfPlugin.getSupplyType()
155: + "] " + " Expanding DetReq: " + parent.getUID()
156: + " Expansion is: " + expansion.getUID());
157: }
158: }
159:
160: protected void addToAndPublishExpansion(Task parent,
161: Collection subtasks) {
162: Expansion expansion = (Expansion) parent.getPlanElement();
163: NewWorkflow wf = (NewWorkflow) expansion.getWorkflow();
164: Iterator subtasksIT = subtasks.iterator();
165: while (subtasksIT.hasNext()) {
166: Task task = (Task) subtasksIT.next();
167: wf.addTask(task);
168: ((NewTask) task).setWorkflow(wf);
169: dfPlugin.publishAdd(task);
170: }
171: dfPlugin.publishChange(expansion);
172: }
173:
174: protected NewTask createGPTask(Task parentTask, Asset consumer) {
175: Vector prefs = new Vector();
176:
177: PrepositionalPhrase prepPhrase = newPrepositionalPhrase(
178: Constants.Preposition.OFTYPE, dfPlugin.getSupplyType());
179:
180: prefs.addElement(createStartTimePref(parentTask));
181:
182: NewTask newTask = getPlanningFactory().newTask();
183:
184: newTask.setParentTask(parentTask);
185: newTask.setPlan(parentTask.getPlan());
186:
187: //MWD Remove
188: //newTask.setPrepositionalPhrases(parentTask.getPrepositionalPhrases());
189: //newTask = addPrepositionalPhrase(newTask, prepPhrase);
190:
191: newTask.setPrepositionalPhrases(prepPhrase);
192:
193: newTask.setDirectObject(consumer);
194: newTask.setVerb(Verb.get(Constants.Verb.GENERATEPROJECTIONS));
195:
196: newTask.setPreferences(prefs.elements());
197:
198: return newTask;
199: }
200:
201: /**
202: * Build a workflow from a vector of tasks.
203: * @param parent parent task of workflow
204: * @param subtasks workflow tasks
205: * @return Workflow
206: **/
207: public Workflow buildWorkflow(Task parent, Collection subtasks) {
208: NewWorkflow wf = getPlanningFactory().newWorkflow();
209: wf.setParentTask(parent);
210: wf.setIsPropagatingToSubtasks(true);
211: NewTask t;
212: Iterator subtasksIT = subtasks.iterator();
213: while (subtasksIT.hasNext()) {
214: t = (NewTask) subtasksIT.next();
215: t.setWorkflow(wf);
216: wf.addTask(t);
217: }
218: return wf;
219: }
220:
221: protected void disposeOfTask(Task task) {
222: AspectValue avs[] = new AspectValue[1];
223: avs[0] = AspectValue.newAspectValue(
224: AlpineAspectType.DEMANDRATE, CountRate
225: .newEachesPerDay(0.0));
226: AllocationResult dispAR = getPlanningFactory()
227: .newAllocationResult(Constants.Confidence.OBSERVED,
228: true, avs);
229: Disposition disposition = getPlanningFactory()
230: .createDisposition(task.getPlan(), task, dispAR);
231: dfPlugin.publishAdd(disposition);
232: }
233:
234: protected long getStartTimePref(Task task) {
235: synchronized (task) {
236: Enumeration taskPrefs = task.getPreferences();
237: while (taskPrefs.hasMoreElements()) {
238: Preference aPref = (Preference) taskPrefs.nextElement();
239: if (aPref.getAspectType() == AspectType.START_TIME) {
240: ScoringFunction sf = aPref.getScoringFunction();
241: return (long) sf.getBest().getValue();
242: }
243: }
244: }
245: return 0L;
246: }
247:
248: protected Preference createStartTimePref(Task parentTask) {
249: long startTime = getStartTimePref(parentTask);
250: AspectValue av = AspectValue.newAspectValue(
251: AspectType.START_TIME, startTime);
252: ScoringFunction score = ScoringFunction
253: .createNearOrAbove(av, 0);
254: return getPlanningFactory().newPreference(
255: AspectType.START_TIME, score);
256: }
257:
258: public PrepositionalPhrase newPrepositionalPhrase(
259: String preposition, Object io) {
260: NewPrepositionalPhrase pp = getPlanningFactory()
261: .newPrepositionalPhrase();
262: pp.setPreposition(preposition);
263: pp.setIndirectObject(io);
264: return pp;
265: }
266:
267: public void updateAllocationResults(Collection planElements) {
268: Iterator peIt = planElements.iterator();
269: while (peIt.hasNext()) {
270: PlanElement pe = (PlanElement) peIt.next();
271: if (PluginHelper.updatePlanElement(pe)) {
272: dfPlugin.publishChange(pe);
273: }
274: }
275: }
276:
277: /**
278: *
279: * MWD remove
280: *
281: public static NewTask addPrepositionalPhrase(NewTask task, PrepositionalPhrase pp) {
282: Enumeration enum = task.getPrepositionalPhrases();
283: Vector phrases = new Vector();
284: while (enum.hasMoreElements()) {
285: phrases.addElement(enum.nextElement());
286: }
287: phrases.addElement(pp);
288: task.setPrepositionalPhrases(phrases.elements());
289: return task;
290: }
291:
292: **/
293: }
|