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 java.util.Collections;
029: import java.util.Enumeration;
030: import java.util.HashSet;
031: import java.util.Set;
032:
033: import org.cougaar.core.blackboard.IncrementalSubscription;
034: import org.cougaar.glm.ldm.Constants;
035: import org.cougaar.glm.ldm.asset.Inventory;
036: import org.cougaar.glm.ldm.asset.Organization;
037: import org.cougaar.glm.ldm.asset.ScheduledContentPG;
038: import org.cougaar.glm.plugins.MaintainedItem;
039: import org.cougaar.glm.plugins.TaskUtils;
040: import org.cougaar.planning.ldm.plan.Allocation;
041: import org.cougaar.planning.ldm.plan.PlanElement;
042: import org.cougaar.planning.ldm.plan.Task;
043: import org.cougaar.planning.ldm.plan.Verb;
044: import org.cougaar.util.UnaryPredicate;
045: import org.cougaar.util.log.Logging;
046: import org.cougaar.util.log.Logger;
047:
048: /** Allocate SUPPLY tasks to local inventory (if there is any) or to
049: * the closest supplier.
050: */
051: public class GeneralInventoryManager extends InventoryManager {
052: private static Logger logger = Logging
053: .getLogger(GeneralInventoryManager.class);
054: private IncrementalSubscription refillAllocs_ = null;
055:
056: /** Constructor */
057: public GeneralInventoryManager(InventoryPlugin plugin,
058: Organization org, String type) {
059: super (plugin, org, type);
060: if (logger.isDebugEnabled()) {
061: logger.debug("Constructor type:" + type);
062: }
063: initialize();
064:
065: }
066:
067: // ********************************************************
068: // *
069: // Point Of Entry to GeneralInventoryManager *
070: // *
071: // ********************************************************
072:
073: // Uses update() from superclass (Template Method pattern) (learned at JavaOne)
074: // It should not be overridden.
075: // This method is called everytime a subscription has changed.
076:
077: // ********************************************************
078: // *
079: // Need Update / Reset Section *
080: // *
081: // ********************************************************
082:
083: // RJB changed
084: protected Set needUpdate(Set invSet) {
085: if (invSet == null)
086: invSet = new HashSet();
087: // Determine if this inventory processor needs to run
088: // return a set of changed inventories to re-process
089: boolean refill_changed = checkRefills(refillAllocs_, invSet);
090: boolean inventory_changed = checkInventories(
091: modifiedInventorySubscription_.getChangedList(), invSet);
092: boolean inventory_policy_changed = checkInventoryPolicies(
093: inventoryPolicySubscription_,
094: modifiedInventorySubscription_.elements(), invSet);
095:
096: // Allocations of tasks with quantity > 0 to Inventory objects
097: // inventoryAllocSubscription_ only used to determine when to run processor.
098: // Inventory objects held in the plugin.
099: boolean allocatedInventories = checkInventoryAllocations(
100: inventoryAllocSubscription_, invSet);
101:
102: if (refill_changed || allocatedInventories || inventory_changed
103: || inventory_policy_changed) {
104: String prefix = "<" + supplyType_
105: + "> UPDATING INVENTORIES: ";
106: if (refill_changed) {
107: if (logger.isDebugEnabled()) {
108: logger.debug(prefix + "refill changed.");
109: }
110: }
111: if (allocatedInventories) {
112: if (logger.isDebugEnabled()) {
113: logger.debug(prefix + "allocations added/removed.");
114: }
115:
116: }
117: if (inventory_changed) {
118: if (logger.isDebugEnabled()) {
119: logger.debug(prefix + "inventory changed.");
120: }
121: }
122: if (inventory_policy_changed) {
123: if (logger.isDebugEnabled()) {
124: logger.debug(prefix + "inventory policy changed.");
125: }
126: }
127: }
128: return invSet;
129: }
130:
131: private boolean checkRefills(IncrementalSubscription refillAllocs,
132: Set invSet) {
133: Enumeration refills = refillAllocs.getChangedList();
134: boolean changed = false;
135: while (refills.hasMoreElements()) {
136: Allocation alloc = (Allocation) refills.nextElement();
137: Set changes = refillAllocs.getChangeReports(alloc);
138: if (TaskUtils.checkChangeReports(changes,
139: PlanElement.EstimatedResultChangeReport.class)) {
140: Task refill = alloc.getTask();
141: MaintainedItem inventoryID = (MaintainedItem) refill
142: .getPrepositionalPhrase(
143: Constants.Preposition.MAINTAINING)
144: .getIndirectObject();
145: Inventory inv = inventoryPlugin_.findOrMakeInventory(
146: supplyType_, inventoryID
147: .getTypeIdentification());
148: if (inv != null) {
149: invSet.add(inv);
150: changed = true;
151: }
152: }
153: }
154: return changed;
155: }
156:
157: private boolean checkInventories(Enumeration changedInventories,
158: Set invSet) {
159: boolean changed = changedInventories.hasMoreElements();
160: while (changedInventories.hasMoreElements()) {
161: invSet.add((Inventory) changedInventories.nextElement());
162: }
163: return changed;
164: }
165:
166: private boolean checkInventoryPolicies(
167: IncrementalSubscription policySubscription,
168: Enumeration inventories, Set invSet) {
169: boolean changed = updateInventoryPolicy(policySubscription
170: .getAddedList())
171: || updateInventoryPolicy(policySubscription
172: .getChangedList());
173: if (changed) {
174: while (inventories.hasMoreElements()) {
175: invSet.add((Inventory) inventories.nextElement());
176: }
177: }
178: return changed;
179: }
180:
181: private boolean checkInventoryAllocations(
182: IncrementalSubscription invAllocSubscription, Set invSet) {
183: boolean changed = false;
184: if (invAllocSubscription.hasChanged()) {
185: Enumeration allocs = invAllocSubscription.getAddedList();
186: while (allocs.hasMoreElements()) {
187: Allocation alloc = (Allocation) allocs.nextElement();
188: if (!inventoryPlugin_.hasSeenAllConsumers()) {
189: inventoryPlugin_.recordCustomerForTask(alloc
190: .getTask());
191: }
192: invSet.add(alloc.getAsset());
193: changed = true;
194: }
195: allocs = invAllocSubscription.getRemovedList();
196: while (allocs.hasMoreElements()) {
197: invSet.add(((Allocation) allocs.nextElement())
198: .getAsset());
199: changed = true;
200: }
201: }
202: return changed;
203: }
204:
205: // ********************************************************
206: // *
207: // Utilities Section *
208: // *
209: // ********************************************************
210:
211: // Public
212:
213: private Enumeration getAllScheduleElements(Inventory inventory) {
214: ScheduledContentPG scp = inventory.getScheduledContentPG();
215: return scp.getSchedule().getAllScheduleElements();
216: }
217:
218: // this should be over-ridden for specialized inventory managers
219: protected double getMinRefillQuantity(Inventory inventory) {
220: return inventory.getVolumetricStockagePG()
221: .getMinReorderVolume().getGallons();
222: }
223:
224: // ********************************************************
225: // *
226: // Initialization Section *
227: // *
228: // ********************************************************
229:
230: //Allocation of refill tasks
231: static class RefillAllocPredicate implements UnaryPredicate {
232: String type_;
233: String orgName_;
234:
235: public RefillAllocPredicate(String type, String orgName) {
236: type_ = type;
237: orgName_ = orgName;
238: }
239:
240: public boolean execute(Object o) {
241: if (o instanceof Allocation) {
242: Task task = ((Allocation) o).getTask();
243: Verb verb = task.getVerb();
244: if (verb.equals(Constants.Verb.SUPPLY)
245: || verb.equals(Constants.Verb.PROJECTSUPPLY)) {
246: if (TaskUtils.isDirectObjectOfType(task, type_)) {
247: // need to check if externally allocated
248: if (((Allocation) o).getAsset() instanceof Organization) {
249: if (TaskUtils
250: .isMyRefillTask(task, orgName_)) {
251: return true;
252: }
253: }
254: }
255: }
256: }
257: return false;
258: }
259: }
260:
261: /** Initialize this instance. */
262: protected void initialize() {
263: setupSubscriptions();
264: }
265:
266: /** Initialize my subscriptions. */
267: protected void setupSubscriptions() {
268:
269: refillAllocs_ = subscribe(new RefillAllocPredicate(supplyType_,
270: myOrgName_));
271:
272: if (plugin_.didRehydrate()) {
273: updateInventoryPolicy(Collections
274: .enumeration(inventoryPolicySubscription_
275: .getCollection()));
276: }
277:
278: }
279: }
|