001: /*--------------------------------------------------------------------------
002: * <copyright>
003: *
004: * Copyright 2000-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: package org.cougaar.glm.plugins.inventory;
027:
028: import org.cougaar.core.blackboard.IncrementalSubscription;
029: import org.cougaar.glm.ldm.Constants;
030: import org.cougaar.glm.ldm.asset.Inventory;
031: import org.cougaar.glm.ldm.asset.Organization;
032: import org.cougaar.glm.plugins.AssetUtils;
033: import org.cougaar.glm.plugins.TaskUtils;
034: import org.cougaar.glm.plugins.TimeUtils;
035: import org.cougaar.planning.ldm.asset.Asset;
036: import org.cougaar.planning.ldm.plan.Allocation;
037: import org.cougaar.planning.ldm.plan.AllocationResult;
038: import org.cougaar.planning.ldm.plan.Role;
039: import org.cougaar.planning.ldm.plan.Task;
040: import org.cougaar.planning.ldm.plan.Verb;
041: import org.cougaar.planning.plugin.util.AllocationResultHelper;
042: import org.cougaar.planning.plugin.util.PluginHelper;
043: import org.cougaar.util.UnaryPredicate;
044: import org.cougaar.util.log.Logger;
045: import org.cougaar.util.log.Logging;
046:
047: import java.util.Enumeration;
048: import java.util.Vector;
049:
050: public class ExternalAllocator extends InventoryProcessor {
051:
052: protected IncrementalSubscription refillAllocs_ = null;
053: protected IncrementalSubscription providerOrgs_ = null;
054: /** Organizations with the right type of role */
055: public Vector providers_ = new Vector();
056: protected Role providerRole_;
057: /** list of nsn's with no resupply point */
058: protected Vector notified_ = new Vector();
059: private Logger logger = Logging.getLogger(ExternalAllocator.class);
060:
061: public ExternalAllocator(InventoryPlugin plugin, Organization org,
062: String type, org.cougaar.planning.ldm.plan.Role role) {
063: super (plugin, org, type);
064: providerRole_ = role;
065: providerOrgs_ = subscribe(new ItemProviderPredicate(org,
066: providerRole_));
067: refillAllocs_ = subscribe(new RefillAllocPredicate(supplyType_,
068: myOrgName_));
069: }
070:
071: //Allocation of refill tasks
072: static class RefillAllocPredicate implements UnaryPredicate {
073: String type_;
074: String orgName_;
075:
076: public RefillAllocPredicate(String type, String orgName) {
077: type_ = type;
078: orgName_ = orgName;
079: }
080:
081: public boolean execute(Object o) {
082: if (o instanceof Allocation) {
083: Task task = ((Allocation) o).getTask();
084: Verb verb = task.getVerb();
085: if (verb.equals(Constants.Verb.SUPPLY)
086: || verb.equals(Constants.Verb.PROJECTSUPPLY)) {
087: if (TaskUtils.isDirectObjectOfType(task, type_)) {
088: // need to check if externally allocated
089: if (((Allocation) o).getAsset() instanceof Organization) {
090: if (TaskUtils
091: .isMyRefillTask(task, orgName_)) {
092: return true;
093: }
094: }
095: }
096: }
097: }
098: return false;
099: }
100: }
101:
102: /** Test if we have an Organization that is a provider_. */
103: public static class ItemProviderPredicate implements UnaryPredicate {
104: Role provider_;
105: Organization org_;
106:
107: public ItemProviderPredicate(Organization org, Role prov) {
108: org_ = org;
109: provider_ = prov;
110: }
111:
112: public boolean execute(Object o) {
113: if (o instanceof Organization) {
114: Organization org = (Organization) o;
115: return AssetUtils.isOrgSupporting(org_, org, provider_);
116: }
117: return false;
118: }
119: }
120:
121: /** This method is called everytime a subscription has changed. */
122: public void update() {
123: super .update(); // set up dates
124: if (inventoryPlugin_.getDetermineRequirementsTask() != null) {
125: notified_.clear();
126: rememberProviders();
127: // Supply tasks that are not handled in this cluster are allocated to
128: // an external cluster
129: allocateSupplyTasks(supplyTasks_.getAddedList());
130: // Allocate projection tasks for this cluster to an external cluster
131: allocateSupplyTasks(projectionTasks_.getAddedList());
132: // Allocate refill tasks for this cluster to external cluster
133: allocateRefillTasks(refillTasks_.getAddedList());
134: // Allocate inventory projections
135: allocateRefillTasks(myProjectionTasks_.getAddedList());
136: PluginHelper.updateAllocationResult(refillAllocs_);
137: }
138: }
139:
140: /** reset providers table */
141: public void rememberProviders() {
142: Enumeration orgs = providerOrgs_.elements();
143: providers_.clear();
144: while (orgs.hasMoreElements()) {
145: Organization org = (Organization) orgs.nextElement();
146: // guess can only put one type of thing one place...
147: // can't send spark plug requests to one place and
148: // tires to another.
149: providers_.addElement(org);
150: }
151: }
152:
153: public void allocateSupplyTasks(Enumeration tasks) {
154: Task supplyTask;
155: Inventory inv = null;
156: Asset proto;
157: int allocatedTasks = 0;
158: while (tasks.hasMoreElements()) {
159: supplyTask = (Task) tasks.nextElement();
160: proto = (Asset) supplyTask.getDirectObject();
161: // If inventory exists for this item then ignore task
162: // Let the Supply Expander handle it.
163: inv = inventoryPlugin_.findOrMakeInventory(supplyType_,
164: proto);
165: if (inv == null) {
166: allocateTask(supplyTask);
167: // printDebug("allocateSupplyTasks(), allocated "+TaskUtils.taskDesc(supplyTask)+
168: // " tasks to external sources.");
169: allocatedTasks++;
170: }
171: }
172: // printDebug("allocateSupplyTasks(), allocated "+allocatedTasks+
173: // " tasks to external sources.");
174: }
175:
176: public void allocateRefillTasks(Enumeration tasks) {
177: Task refillTask;
178: while (tasks.hasMoreElements()) {
179: refillTask = (Task) tasks.nextElement();
180: allocateTask(refillTask);
181: }
182: }
183:
184: /** Figure out which organization supplying item is best for us. */
185: public Organization findBestSource(Task task) {
186: // PAS FILL THIS IN
187: Enumeration en = providers_.elements();
188: Enumeration support_orgs;
189: if (TaskUtils.isProjection(task)) {
190: /* For a projection, should be time-phased as support
191: changes over time. We ignore that, for now */
192: support_orgs = AssetUtils.getSupportingOrgs(
193: myOrganization_, providerRole_, TaskUtils
194: .getStartTime(task), TaskUtils
195: .getEndTime(task));
196: } else {
197: support_orgs = AssetUtils.getSupportingOrgs(
198: myOrganization_, providerRole_, TaskUtils
199: .getEndTime(task));
200: }
201: if (support_orgs.hasMoreElements()) {
202: // For now, returning the first supporting org during the time span
203: return (Organization) support_orgs.nextElement();
204: } else {
205: if (TaskUtils.isProjection(task)) {
206: if (logger.isErrorEnabled()) {
207: logger.error("No "
208: + providerRole_
209: + ", during "
210: + TimeUtils.dateString(TaskUtils
211: .getStartTime(task))
212: + TimeUtils.dateString(TaskUtils
213: .getEndTime(task)));
214: }
215: } else {
216: if (logger.isErrorEnabled()) {
217: logger.error("No "
218: + providerRole_
219: + ", during "
220: + TimeUtils.dateString(TaskUtils
221: .getEndTime(task)));
222: }
223: }
224: }
225: return null;
226: }
227:
228: protected void allocateTask(Task task) {
229: String itemId = task.getDirectObject()
230: .getTypeIdentificationPG().getTypeIdentification();
231: Organization provider = findBestSource(task);
232: if (provider == null) {
233: // prevents same error message from being printed many times.
234: if (!notified_.contains(itemId)) {
235: if (logger.isDebugEnabled()) {
236: logger
237: .debug("allocateTask() <"
238: + supplyType_
239: + "> allocateRefillTask no best source for "
240: + itemId);
241: }
242: notified_.addElement(itemId);
243: }
244: } else {
245: // printDebug("allocateRefillTask "+task+" to "+provider);
246: AllocationResult ar = new AllocationResultHelper(task, null)
247: .getAllocationResult(1.0);
248: publishAllocation(task, provider, providerRole_, ar);
249: }
250: }
251: }
|