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.ldm.asset;
028:
029: import org.cougaar.core.service.LoggingService;
030: import org.cougaar.planning.ldm.asset.PGDelegate;
031: import org.cougaar.planning.ldm.asset.AggregateAsset;
032: import org.cougaar.planning.ldm.asset.Asset;
033: import org.cougaar.planning.ldm.asset.PGDelegate;
034: import org.cougaar.planning.ldm.asset.PropertyGroup;
035: import org.cougaar.planning.ldm.measure.Rate;
036: import org.cougaar.planning.ldm.measure.CountRate;
037: import org.cougaar.planning.ldm.plan.Schedule;
038: import org.cougaar.glm.ldm.plan.Service;
039: import org.cougaar.glm.ldm.oplan.OpTempo;
040: import org.cougaar.glm.ldm.oplan.OrgActivity;
041: import org.cougaar.util.TimeSpan;
042: import org.cougaar.util.UnaryPredicate;
043:
044: import org.cougaar.logistics.plugin.utils.*;
045: import org.cougaar.logistics.ldm.MEIPrototypeProvider;
046:
047: import java.math.BigDecimal;
048:
049: import java.util.*;
050:
051: public class RepairPartConsumerBG extends ConsumerBG {
052:
053: public static HashMap cachedDBValues = new HashMap();
054: protected RepairPartConsumerPG myPG;
055: transient MEIPrototypeProvider parentPlugin;
056: final static String supplyType = "Consumable";
057: final static int MAX_PARTS = 20;
058: final static double ZERO_X = 0.0;
059: final static double RESERVE_X = 0.2;
060: final static double LOW_X = 0.4;
061: final static double MEDIUM_X = 0.6;
062: final static double HIGH_X = 1.0;
063: final static String LOW_OPTEMPO = OpTempo.LOW.toUpperCase();
064: final static String MEDIUM_OPTEMPO = OpTempo.MEDIUM.toUpperCase();
065: final static String HIGH_OPTEMPO = OpTempo.HIGH.toUpperCase();
066: final static String PARTS = "PARTS";
067: final static String RATES = "RATES";
068: ArrayList consumptionRates = null;
069: ArrayList parts = null;
070: private transient LoggingService logger;
071:
072: public RepairPartConsumerBG(RepairPartConsumerPG pg) {
073: myPG = pg;
074: }
075:
076: public void initialize(MEIPrototypeProvider plugin) {
077: parentPlugin = plugin;
078: logger = parentPlugin.getLoggingService(this );
079: }
080:
081: public List getPredicates() {
082: // Add limit resources policy
083: ArrayList predList = new ArrayList();
084: String typeId = myPG.getMei().getTypeIdentificationPG()
085: .getTypeIdentification();
086: predList.add(new OrgActivityPred());
087: return predList;
088: }
089:
090: public Schedule getParameterSchedule(Collection col, TimeSpan span) {
091: Schedule paramSchedule = null;
092: Vector params = new Vector();
093: Iterator predList = col.iterator();
094: UnaryPredicate predicate;
095: // DEBUG
096: // String myOrgName = parentPlugin.getMyOrg().getItemIdentificationPG().getItemIdentification();
097: // if (myOrgName.indexOf("35-ARBN") >= 0) {
098: // System.out.println("getParamSched() Asset is "+
099: // myPG.getMei().getTypeIdentificationPG().getTypeIdentification());
100: // }
101: ArrayList consumerlist = new ArrayList();
102: consumerlist.add(myPG.getMei());
103: Schedule consumerSched = parentPlugin.getScheduleUtils()
104: .createConsumerSchedule(consumerlist);
105: consumerSched = parentPlugin.getScheduleUtils()
106: .convertQuantitySchedule(consumerSched);
107: params.add(parentPlugin.getScheduleUtils().trimObjectSchedule(
108: consumerSched, span));
109: while (predList.hasNext()) {
110: Iterator list = ((Collection) predList.next()).iterator();
111: predicate = (UnaryPredicate) list.next();
112: if (predicate instanceof OrgActivityPred) {
113: Collection orgColl = (Collection) list.next();
114: if ((orgColl == null) || (orgColl.isEmpty())) {
115: return null;
116: }
117: Schedule orgActSched = parentPlugin.getScheduleUtils()
118: .createOrgActivitySchedule(orgColl);
119: params.add(parentPlugin.getScheduleUtils()
120: .trimObjectSchedule(orgActSched, span));
121: } else {
122: if (logger.isErrorEnabled()) {
123: logger
124: .error("getParameterSchedule: unknown predicate");
125: }
126: }
127: }
128: paramSchedule = parentPlugin.getScheduleUtils()
129: .getMergedSchedule(params);
130: return paramSchedule;
131: }
132:
133: public Rate getRate(Asset asset, List params) {
134: Rate r = null;
135: // DEBUG
136: // String myOrgName = parentPlugin.getMyOrg().getItemIdentificationPG().getItemIdentification();
137: if (consumptionRates == null) {
138: return r;
139: }
140: if (params == null) {
141: if (logger.isErrorEnabled()) {
142: logger.error("getRate() params null");
143: }
144: // if (myOrgName.indexOf("35-ARBN") >= 0) {
145: // System.out.println("getRate() params null for "+
146: // asset.getTypeIdentificationPG().getNomenclature());
147: // }
148: return r;
149: }
150: Double qty = (Double) params.get(0);
151: OrgActivity orgAct = (OrgActivity) params.get(1);
152: if (orgAct == null) {
153: if (logger.isDebugEnabled()) {
154: logger.debug("getRate() orgAct null for "
155: + asset.getTypeIdentificationPG()
156: .getNomenclature());
157: }
158:
159: return r;
160: }
161: int idx = parts.indexOf(asset);
162: Double d = (Double) consumptionRates.get(idx);
163: if (d == null) {
164: if (logger.isErrorEnabled()) {
165: logger.error("getRate() consumption rate null for "
166: + asset.getTypeIdentificationPG()
167: .getNomenclature());
168: }
169:
170: return r;
171: }
172:
173: double dailyRate = d.doubleValue();
174: if (orgAct.getOpTempo().toUpperCase().equals(HIGH_OPTEMPO)) {
175: dailyRate = dailyRate * HIGH_X;
176: } else if (orgAct.getOpTempo().toUpperCase().equals(
177: MEDIUM_OPTEMPO)) {
178: dailyRate = dailyRate * MEDIUM_X;
179: } else if (orgAct.getOpTempo().toUpperCase()
180: .equals(LOW_OPTEMPO)) {
181: dailyRate = dailyRate * LOW_X;
182: } else {
183: dailyRate = dailyRate * ZERO_X;
184: }
185:
186: r = CountRate.newEachesPerDay(dailyRate * qty.doubleValue());
187:
188: return r;
189: }
190:
191: public Collection getConsumed() {
192: if (parts == null) {
193: synchronized (cachedDBValues) {
194: Asset asset = myPG.getMei();
195: if (asset instanceof AggregateAsset) {
196: asset = ((AggregateAsset) asset).getAsset();
197: }
198: String typeId = asset.getTypeIdentificationPG()
199: .getTypeIdentification();
200: HashMap partsNrates = (HashMap) cachedDBValues
201: .get(typeId);
202: if (partsNrates == null) {
203: Vector result = parentPlugin
204: .lookupAssetConsumptionRate(asset,
205: supplyType, myPG.getService(), myPG
206: .getTheater());
207: if (result == null) {
208: if (logger.isDebugEnabled()) {
209: logger
210: .debug("getConsumed(): Database query returned EMPTY result set for "
211: + myPG.getMei()
212: + ", "
213: + supplyType);
214: }
215: } else {
216: partsNrates = parseResults(result);
217: cachedDBValues.put(typeId, partsNrates);
218: parts = (ArrayList) partsNrates.get(PARTS);
219: consumptionRates = (ArrayList) partsNrates
220: .get(RATES);
221: }
222: } else {
223: parts = (ArrayList) partsNrates.get(PARTS);
224: consumptionRates = (ArrayList) partsNrates
225: .get(RATES);
226: }
227: }
228: }
229: if (parts == null) {
230: if (logger.isDebugEnabled()) {
231: logger.debug("No consumption rates for "
232: + myPG.getMei()
233: + " at "
234: + parentPlugin.getMyOrg()
235: .getItemIdentificationPG()
236: .getItemIdentification());
237: }
238: parts = new ArrayList();
239: }
240: return parts;
241: }
242:
243: public Collection getConsumed(int x) {
244: return getConsumed();
245: }
246:
247: public Collection getConsumed(int x, int y) {
248: return getConsumed();
249: }
250:
251: protected HashMap parseResults(Vector result) {
252: String mei_nsn, typeid, optempo;
253: double dcr;
254: Asset newAsset;
255: ArrayList spareParts = new ArrayList();
256: ArrayList rates = new ArrayList();
257: Enumeration results = result.elements();
258: Object row[];
259:
260: for (int i = 0; results.hasMoreElements() && (i < MAX_PARTS); i++) {
261: row = (Object[]) results.nextElement();
262: mei_nsn = (String) row[0];
263: if (logger.isDebugEnabled()) {
264: logger
265: .debug("RepairParts: parsing results for MEI nsn: "
266: + mei_nsn);
267: }
268: typeid = "NSN/" + (String) row[1];
269: newAsset = parentPlugin.getPrototype(typeid);
270: if (newAsset != null) {
271: optempo = (String) row[2]; // Query only retrieves HIGH optempo, ignore
272: dcr = ((BigDecimal) row[3]).doubleValue();
273: spareParts.add(newAsset);
274: rates.add(new Double(dcr));
275: if (logger.isDebugEnabled()) {
276: logger.debug("parseResult() for part " + i + " "
277: + newAsset + ", MEI " + mei_nsn + ", DCR "
278: + dcr + ", Optempo " + optempo);
279: }
280: } else {
281: if (logger.isDebugEnabled()) {
282: logger
283: .debug("parseResult() could not getPrototype for "
284: + typeid + ", " + supplyType);
285: }
286: }
287: }
288: HashMap ratesMap = new HashMap();
289: ratesMap.put(PARTS, spareParts);
290: ratesMap.put(RATES, rates);
291: return ratesMap;
292: } // parseResults
293:
294: public PGDelegate copy(PropertyGroup pg) {
295: return null;
296: }
297:
298: }
|