001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.mlm.plugin.strategictransport;
028:
029: import java.util.Collection;
030: import java.util.Enumeration;
031: import java.util.Iterator;
032: import java.util.Vector;
033:
034: import org.cougaar.core.blackboard.IncrementalSubscription;
035: import org.cougaar.core.blackboard.Subscription;
036: import org.cougaar.glm.ldm.Constants;
037: import org.cougaar.glm.ldm.asset.Organization;
038: import org.cougaar.planning.ldm.PlanningFactory;
039: import org.cougaar.planning.ldm.asset.Asset;
040: import org.cougaar.planning.ldm.plan.Allocation;
041: import org.cougaar.planning.ldm.plan.AllocationResult;
042: import org.cougaar.planning.ldm.plan.AspectScorePoint;
043: import org.cougaar.planning.ldm.plan.Expansion;
044: import org.cougaar.planning.ldm.plan.PlanElement;
045: import org.cougaar.planning.ldm.plan.Preference;
046: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
047: import org.cougaar.planning.ldm.plan.Relationship;
048: import org.cougaar.planning.ldm.plan.Role;
049: import org.cougaar.planning.ldm.plan.ScoringFunction;
050: import org.cougaar.planning.ldm.plan.Task;
051: import org.cougaar.planning.ldm.plan.Workflow;
052: import org.cougaar.planning.plugin.legacy.SimplePlugin;
053: import org.cougaar.util.UnaryPredicate;
054:
055: public class StrategicTransportAllocatorPlugin extends SimplePlugin {
056:
057: private Subscription allocatableWorkflows;
058: private IncrementalSubscription orgAssets;
059: private Subscription myAllocations;
060: private PlanningFactory ldmf;
061: private Vector waitingTasks = new Vector();
062:
063: protected void setupSubscriptions() {
064: ldmf = theLDMF;
065:
066: // subscribe for PlanElements with Workflows to allocate
067: allocatableWorkflows = subscribe(allocWFPred());
068:
069: // subscribe for assets to allocate against
070: orgAssets = (IncrementalSubscription) subscribe(orgPred());
071:
072: // subscribe to my allocations in order to catch changes in the penalties and schedules
073: // from the notification process
074: myAllocations = subscribe(myAllocsPred());
075:
076: }
077:
078: protected void execute() {
079: if (allocatableWorkflows.hasChanged()) {
080: Enumeration newwfs = ((IncrementalSubscription) allocatableWorkflows)
081: .getAddedList();
082: while (newwfs.hasMoreElements()) {
083: Expansion exp = (Expansion) newwfs.nextElement();
084: allocate(exp.getWorkflow());
085: }
086: }
087:
088: // check the asset container for new StrategicTransportProviders
089: // if you find any and there are tasks in waitingTasks, allocate them now.
090: if (orgAssets.hasChanged()) {
091: checkNewOrgs(orgAssets.getCollection());
092: }
093:
094: if (myAllocations.hasChanged()) {
095: Enumeration changedallocs = ((IncrementalSubscription) myAllocations)
096: .getChangedList();
097: while (changedallocs.hasMoreElements()) {
098: PlanElement cpe = (PlanElement) changedallocs
099: .nextElement();
100: updateAllocationResult(cpe);
101: }
102: }
103:
104: } // end of execute
105:
106: private void allocate(Workflow wf) {
107: Enumeration tasks = wf.getTasks();
108:
109: Organization stratTransProvider = findOrganization(Constants.Role.STRATEGICTRANSPORTATIONPROVIDER);
110:
111: while (tasks.hasMoreElements()) {
112: Task t = (Task) tasks.nextElement();
113: if (stratTransProvider != null) {
114: createTheAllocation(t, stratTransProvider);
115: } else {
116: // if you don't have a transport organization asset - wait for one
117: waitingTasks.addElement(t);
118: }
119: }
120: }
121:
122: private Organization findOrganization(Role role) {
123: for (Iterator iterator = orgAssets.getCollection().iterator(); iterator
124: .hasNext();) {
125: Organization org = (Organization) iterator.next();
126: if (org.isSelf()) {
127: Collection transportCollection = org
128: .getRelationshipSchedule()
129: .getMatchingRelationships(role);
130:
131: if (transportCollection.size() != 0) {
132: Relationship relationship = (Relationship) transportCollection
133: .iterator().next();
134: return (Organization) org.getRelationshipSchedule()
135: .getOther(relationship);
136: }
137: }
138: }
139:
140: return null;
141: }
142:
143: private void createTheAllocation(Task t, Asset a) {
144: // make the allocation
145: Allocation alloc = ldmf.createAllocation(ldmf.getRealityPlan(),
146: t, a, createEstimatedAllocationResult(t),
147: Constants.Role.TRANSPORTER);
148: publishAdd(alloc);
149: }
150:
151: private void checkNewOrgs(Collection orgAssets) {
152: if (waitingTasks.isEmpty()) {
153: return;
154: }
155:
156: Organization stratTransProvider = findOrganization(Constants.Role.STRATEGICTRANSPORTATIONPROVIDER);
157:
158: if (stratTransProvider != null) {
159: // we only need (and expect) one asset to meet our predicate
160: Vector newv = new Vector();
161: Vector tmp = waitingTasks;
162: waitingTasks = newv;
163: Enumeration e = tmp.elements();
164: while (e.hasMoreElements()) {
165: Task t = (Task) e.nextElement();
166: createTheAllocation(t, stratTransProvider);
167: }
168: }
169: }
170:
171: private void updateAllocationResult(PlanElement cpe) {
172: if (cpe.getReportedResult() != null) {
173: // for now just compare the allocation result instances
174: // if they are different objects pass them back up regardless
175: // of their content equalness.
176: AllocationResult reportedresult = cpe.getReportedResult();
177: AllocationResult estimatedresult = cpe.getEstimatedResult();
178: if ((estimatedresult == null)
179: || (!(estimatedresult == reportedresult))) {
180: cpe.setEstimatedResult(reportedresult);
181: // Publish the change (let superclass handle transactions)
182: publishChange(cpe);
183: }
184: }
185: }
186:
187: private AllocationResult createEstimatedAllocationResult(Task t) {
188: Enumeration preferences = t.getPreferences();
189: if (preferences != null && preferences.hasMoreElements()) {
190: // do something really simple for now.
191: Vector aspects = new Vector();
192: Vector results = new Vector();
193: while (preferences.hasMoreElements()) {
194: Preference pref = (Preference) preferences
195: .nextElement();
196: int at = pref.getAspectType();
197: aspects.addElement(new Integer(at));
198: ScoringFunction sf = pref.getScoringFunction();
199: // allocate as if you can do it at the "Best" point
200: double myresult = ((AspectScorePoint) sf.getBest())
201: .getValue();
202: results.addElement(new Double(myresult));
203: }
204: int[] aspectarray = new int[aspects.size()];
205: double[] resultsarray = new double[results.size()];
206: for (int i = 0; i < aspectarray.length; i++)
207: aspectarray[i] = (int) ((Integer) aspects.elementAt(i))
208: .intValue();
209: for (int j = 0; j < resultsarray.length; j++)
210: resultsarray[j] = (double) ((Double) results
211: .elementAt(j)).doubleValue();
212:
213: AllocationResult myestimate = ldmf.newAllocationResult(0.0,
214: true, aspectarray, resultsarray);
215: return myestimate;
216: }
217: // if there were no preferences...return a null estimate for the allocation result (for now)
218: return null;
219: }
220:
221: private static UnaryPredicate allocWFPred() {
222: return new UnaryPredicate() {
223: public boolean execute(Object o) {
224: if (o instanceof Expansion) {
225: Workflow wf = ((Expansion) o).getWorkflow();
226: Enumeration e = wf.getTasks();
227: Task t = (Task) e.nextElement();
228: if (t.getVerb().toString().equals(
229: Constants.Verb.TRANSPORT)) {
230: Enumeration epp = t.getPrepositionalPhrases();
231: while (epp.hasMoreElements()) {
232: PrepositionalPhrase pp = (PrepositionalPhrase) epp
233: .nextElement();
234: if ((pp.getPreposition()
235: .equals(Constants.Preposition.OFTYPE))
236: && (pp.getIndirectObject() instanceof Asset)) {
237: String io = ((Asset) pp
238: .getIndirectObject())
239: .getTypeIdentificationPG()
240: .getTypeIdentification();
241: if (io
242: .equals("StrategicTransportation")) {
243: return true;
244: }
245: }
246: }
247: }
248: }
249: return false;
250: }
251: };
252: }
253:
254: private static UnaryPredicate orgPred() {
255: return new UnaryPredicate() {
256: public boolean execute(Object o) {
257: if (o instanceof Organization) {
258: return true;
259: } else {
260: return false;
261: }
262: }
263: };
264: }
265:
266: private static UnaryPredicate myAllocsPred() {
267: return new UnaryPredicate() {
268: public boolean execute(Object o) {
269: if (o instanceof PlanElement) {
270: Task t = ((PlanElement) o).getTask();
271: if (t.getVerb().toString().equals(
272: Constants.Verb.TRANSPORT)) {
273: Enumeration epp = t.getPrepositionalPhrases();
274: while (epp.hasMoreElements()) {
275: PrepositionalPhrase pp = (PrepositionalPhrase) epp
276: .nextElement();
277: if ((pp.getPreposition()
278: .equals(Constants.Preposition.OFTYPE))
279: && (pp.getIndirectObject() instanceof Asset)) {
280: String io = null;
281: io = ((Asset) pp.getIndirectObject())
282: .getTypeIdentificationPG()
283: .getTypeIdentification();
284: if (io
285: .equals("StrategicTransportation")) {
286: // if the PlanElement is for the correct kind of task - make sure its an allocation
287: if (o instanceof Allocation) {
288: return true;
289: }
290: }
291: }
292: }
293: }
294: }
295: return false;
296: }
297: };
298: }
299: }
|