0001: /*
0002: * <copyright>
0003: *
0004: * Copyright 1997-2004 BBNT Solutions, LLC
0005: * under sponsorship of the Defense Advanced Research Projects
0006: * Agency (DARPA).
0007: *
0008: * You can redistribute this software and/or modify it under the
0009: * terms of the Cougaar Open Source License as published on the
0010: * Cougaar Open Source Website (www.cougaar.org).
0011: *
0012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023: *
0024: * </copyright>
0025: */
0026:
0027: package org.cougaar.logistics.ldm;
0028:
0029: import org.cougaar.core.blackboard.IncrementalSubscription;
0030: import org.cougaar.core.component.ServiceBroker;
0031: import org.cougaar.core.service.BlackboardQueryService;
0032: import org.cougaar.core.service.LoggingService;
0033: import org.cougaar.glm.ldm.QueryLDMPlugin;
0034: import org.cougaar.glm.ldm.asset.ClassVIIMajorEndItem;
0035: import org.cougaar.glm.ldm.asset.Organization;
0036: import org.cougaar.glm.ldm.asset.NewMovabilityPG;
0037: import org.cougaar.glm.ldm.asset.MovabilityPG;
0038: import org.cougaar.glm.ldm.plan.Service;
0039: import org.cougaar.logistics.ldm.asset.*;
0040: import org.cougaar.logistics.plugin.inventory.AssetUtils;
0041: import org.cougaar.logistics.plugin.inventory.TaskUtils;
0042: import org.cougaar.logistics.plugin.inventory.TimeUtils;
0043: import org.cougaar.logistics.plugin.inventory.UtilsProvider;
0044: import org.cougaar.logistics.plugin.utils.ScheduleUtils;
0045: import org.cougaar.planning.ldm.plan.NewSchedule;
0046: import org.cougaar.planning.ldm.plan.NewRoleSchedule;
0047: import org.cougaar.planning.ldm.asset.AggregateAsset;
0048: import org.cougaar.planning.ldm.asset.Asset;
0049: import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
0050: import org.cougaar.planning.ldm.PlanningFactory;
0051: import org.cougaar.util.UnaryPredicate;
0052:
0053: import java.text.StringCharacterIterator;
0054: import java.util.Collection;
0055: import java.util.Calendar;
0056: import java.util.Date;
0057: import java.util.Enumeration;
0058: import java.util.Iterator;
0059: import java.util.List;
0060: import java.util.Vector;
0061:
0062: public class MEIPrototypeProvider extends QueryLDMPlugin implements
0063: UtilsProvider {
0064:
0065: private boolean configured;
0066:
0067: public static final String MEI_STRING = "ClassVIIMajorEndItem";
0068: public static final String THEATER = "SWA";
0069: public static final String LEVEL2 = "Level2";
0070:
0071: private String service = null;
0072: private String echelon = null;
0073: private static final String LEVEL2TOGGLE = "-Level2";
0074: // By default, do level 2
0075: private boolean level2Off = false;
0076: // Subscription to policies
0077: private IncrementalSubscription meiSubscription;
0078:
0079: // MEI Consumption
0080: public static final int AMMO = 0;
0081: public static final int FUEL = 1;
0082: public static final int PKG_POL = 2;
0083: public static final int SPARES = 3;
0084:
0085: // private IncrementalSubscription myOrganizations;
0086: protected Organization myOrg;
0087:
0088: private ServiceBroker serviceBroker;
0089: private LoggingService logger;
0090: private TaskUtils taskUtils;
0091: private TimeUtils timeUtils;
0092: private AssetUtils assetUtils;
0093: private ScheduleUtils scheduleUtils;
0094: private BlackboardQueryService queryService;
0095: private PlanningFactory factory;
0096: private boolean publishedLevel2MeiAsset = false;
0097:
0098: private static UnaryPredicate orgsPredicate = new UnaryPredicate() {
0099: public boolean execute(Object o) {
0100: if (o instanceof Organization) {
0101: return ((Organization) o).isSelf();
0102: }
0103: return false;
0104: }
0105: };
0106:
0107: private static class ClassVIIPredicate implements UnaryPredicate {
0108: // Predicate defining MEIs, in theory all of the MEIs we created
0109: // prototypes for
0110: public boolean execute(Object o) {
0111: if (o instanceof ClassVIIMajorEndItem) {
0112: return true;
0113: }
0114:
0115: if (o instanceof AggregateAsset) {
0116: if (((AggregateAsset) o).getAsset() instanceof ClassVIIMajorEndItem) {
0117: return true;
0118: }
0119: }
0120: return false;
0121: }
0122: };
0123:
0124: private static UnaryPredicate level2MeiPredicate = new UnaryPredicate() {
0125: public boolean execute(Object o) {
0126: return (o instanceof Level2MEIAsset);
0127: }
0128: };
0129:
0130: public TaskUtils getTaskUtils() {
0131: return taskUtils;
0132: }
0133:
0134: public TimeUtils getTimeUtils() {
0135: return timeUtils;
0136: }
0137:
0138: public AssetUtils getAssetUtils() {
0139: return assetUtils;
0140: }
0141:
0142: public ScheduleUtils getScheduleUtils() {
0143: return scheduleUtils;
0144: }
0145:
0146: public LoggingService getLoggingService(Object requestor) {
0147: return (LoggingService) serviceBroker.getService(requestor,
0148: LoggingService.class, null);
0149: }
0150:
0151: public BlackboardQueryService getBlackboardQueryService(
0152: Object requestor) {
0153: return (BlackboardQueryService) serviceBroker.getService(
0154: requestor, BlackboardQueryService.class, null);
0155: }
0156:
0157: private PlanningFactory getPlanningFactory() {
0158: PlanningFactory rootFactory = null;
0159: rootFactory = (PlanningFactory) getFactory("planning");
0160: return rootFactory;
0161: }
0162:
0163: public void load() {
0164: super .load();
0165: serviceBroker = getBindingSite().getServiceBroker();
0166: if (serviceBroker != null) {
0167: logger = getLoggingService(this );
0168: timeUtils = new TimeUtils(this );
0169: assetUtils = new AssetUtils(this );
0170: taskUtils = new TaskUtils(this );
0171: scheduleUtils = new ScheduleUtils(this );
0172: queryService = getBlackboardQueryService(this );
0173: factory = getPlanningFactory();
0174: if (queryService == null) {
0175: if (logger.isErrorEnabled()) {
0176: logger.error("Unable to get query service");
0177: }
0178: }
0179: }
0180: Vector params = getParameters();
0181: if (params != null) {
0182: level2Off = params.contains(LEVEL2TOGGLE);
0183: }
0184: }
0185:
0186: protected void setupSubscriptions() {
0187: super .setupSubscriptions();
0188: meiSubscription = (IncrementalSubscription) subscribe(new ClassVIIPredicate());
0189: if (didRehydrate()) {
0190: if (logger.isInfoEnabled())
0191: logger
0192: .info("Did Rehydrate -- will do rehydrate() method");
0193: rehydrate();
0194: } else if (logger.isInfoEnabled())
0195: logger.info("Did not rehydrate.");
0196: } // setupSubscriptions
0197:
0198: protected void rehydrate() {
0199: configure();
0200: if (configured) {
0201: // rehook handlers
0202: Enumeration meis = meiSubscription.elements();
0203: Asset asset, proto;
0204: Vector good_prototypes = new Vector();
0205: while (meis.hasMoreElements()) {
0206: asset = (Asset) meis.nextElement();
0207: if (asset instanceof AggregateAsset) {
0208: proto = ((AggregateAsset) asset).getAsset();
0209: } else {
0210: proto = asset.getPrototype();
0211: } // if
0212: if (proto == null) {
0213: if (logger.isErrorEnabled()) {
0214: logger.error("no prototype for " + asset);
0215: }
0216: } // if
0217: if ((proto != null)
0218: && (!good_prototypes.contains(proto))) {
0219: TypeIdentificationPG tip = asset
0220: .getTypeIdentificationPG();
0221: if (tip != null) {
0222: String type_id = tip.getTypeIdentification();
0223: if (type_id != null) {
0224: getLDM().cachePrototype(type_id, proto);
0225: good_prototypes.add(proto);
0226: } else {
0227: if (logger.isErrorEnabled()) {
0228: logger.error("cannot rehydrate "
0229: + proto + " no typeId");
0230: }
0231: }
0232: } else {
0233: if (logger.isErrorEnabled()) {
0234: logger.error("cannot rehydrate " + proto
0235: + " no typeIdPG");
0236: }
0237: }
0238: }
0239: }
0240: addConsumerPGs(meiSubscription);
0241: } else if (logger.isInfoEnabled())
0242: logger
0243: .info("in rehydrate still not configured after call to configure - so not doing addConsumerPGs");
0244: }
0245:
0246: public void execute() {
0247: // System.out.println("Execute called for "+getAgentIdentifier());
0248: if (!configured) {
0249: configure();
0250: }
0251: if (!meiSubscription.isEmpty()) {
0252: // System.out.println("Calling addConsumerPGs() for "+getAgentIdentifier());
0253: addConsumerPGs(meiSubscription);
0254: } else if (logger.isInfoEnabled())
0255: logger.info("execute had empty meiSubscription");
0256: }
0257:
0258: protected void configure() {
0259: // System.out.println(" configuring MEIPrototypeProvider for "+getAgentIdentifier());
0260: Iterator new_orgs = queryService.query(orgsPredicate)
0261: .iterator();
0262: if (new_orgs.hasNext()) {
0263: myOrg = (Organization) new_orgs.next();
0264: Service srvc = myOrg.getOrganizationPG().getService();
0265: if (srvc != null) {
0266: service = srvc.toString();
0267: // System.out.println("MEIPrototypeProvider configured for "+getAgentIdentifier());
0268: if (!level2Off) {
0269: if (!publishedLevel2MeiAsset && !queryLevel2Mei()) {
0270: publishLevel2Mei();
0271: }
0272: }
0273: configured = true;
0274: } else {
0275: if (logger.isErrorEnabled()) {
0276: logger.error("Organization has no Service :"
0277: + myOrg.getItemIdentificationPG()
0278: .getItemIdentification());
0279: }
0280: }
0281: echelon = myOrg.getMilitaryOrgPG().getEchelon();
0282: if (echelon == null) {
0283: if (logger.isErrorEnabled()) {
0284: logger
0285: .error("Organization has no echelon, will not produce Ammunition demand:"
0286: + myOrg.getItemIdentificationPG()
0287: .getItemIdentification());
0288: }
0289: }
0290: } else if (logger.isInfoEnabled())
0291: logger.info("No self orgs from query service?");
0292: }
0293:
0294: private void publishLevel2Mei() {
0295: boolean[] consumed = checkLevel2MeiConsumption();
0296: /*
0297: * Sorry for the confusion, the requirements have evolved, only create and publish
0298: * level 2 MEIs if there is consumption.
0299: */
0300: if (consumesAnything(consumed)) {
0301: Asset asset = factory.createPrototype(Level2MEIAsset.class,
0302: "Level2MEI");
0303: Asset a = factory.createInstance(asset);
0304: setupAvailableSchedule(a);
0305: if (logger.isDebugEnabled())
0306: logger
0307: .debug("MEIPrototypeProvider publishing Level2MEI asset in agent: "
0308: + getAgentIdentifier());
0309: publishAdd(a);
0310: }
0311: publishedLevel2MeiAsset = true;
0312: }
0313:
0314: // In case we rehydrate, query the blackboard
0315: private boolean queryLevel2Mei() {
0316: Collection container = queryService.query(level2MeiPredicate);
0317: Object o = null;
0318: if (!container.isEmpty()) {
0319: o = container.iterator().next();
0320: if (o instanceof Level2MEIAsset) {
0321: // set this so that we don't keep querying
0322: publishedLevel2MeiAsset = true;
0323: return true;
0324: }
0325: }
0326: return false;
0327: }
0328:
0329: protected boolean[] checkLevel2MeiConsumption() {
0330: // by default, assume false
0331: boolean result[] = { false, false, false, false };
0332: // not implemented yet
0333: result[PKG_POL] = false;
0334: result[SPARES] = false;
0335:
0336: String query = (String) fileParameters_.get("UnitConsumption");
0337: if (query == null) {
0338: if (logger.isErrorEnabled()) {
0339: logger
0340: .error("checkLevel2MEIConsumption() query is null ");
0341: }
0342: return result;
0343: }
0344: query = substituteOrgName(query, getAgentIdentifier()
0345: .toString());
0346: Vector qresult = null;
0347: try {
0348: qresult = executeQuery(query);
0349: if (logger.isDebugEnabled())
0350: logger
0351: .debug("checkLevel2MEIConsumption() execute query: "
0352: + query);
0353: if (qresult.isEmpty()) {
0354: // TODO: this should be a warn, but we are currently getting one and
0355: // I have asked Gary to look into it. After that, we should switch back.
0356: if (logger.isDebugEnabled())
0357: logger
0358: .debug("No results returned for Level2MEIConsumption query: "
0359: + query);
0360: } else {
0361: Object row[] = (Object[]) qresult.firstElement();
0362: result[AMMO] = convertConsumptionElement(row[AMMO]);
0363: // not implemented yet
0364: //result[PKG_POL]=convertConsumptionElement(row[PKG_POL]);
0365: //result[SPARES]=convertConsumptionElement(row[SPARES]);
0366: result[FUEL] = convertConsumptionElement(row[FUEL]);
0367: }
0368: } catch (Exception ee) {
0369: if (logger.isErrorEnabled()) {
0370: logger
0371: .error("in checkLevel2MeiConsumption(), DB query failed.Query= "
0372: + query);
0373: }
0374: }
0375: return result;
0376: }
0377:
0378: protected boolean[] checkMeiConsumption(Asset asset) {
0379: // The default is that the MEI consumes all 4 classes.
0380: // This prevents problems if the table hasn't been updated for
0381: // a new MEI.
0382: boolean result[] = { true, true, true, true };
0383:
0384: if (asset instanceof Level2MEIAsset) {
0385: return checkLevel2MeiConsumption();
0386: }
0387:
0388: String type_id = asset.getTypeIdentificationPG()
0389: .getTypeIdentification();
0390: String query = (String) fileParameters_.get("MeiConsumption");
0391: String consumer_id = type_id
0392: .substring(type_id.indexOf("/") + 1);
0393: query = substituteNSN(query, consumer_id);
0394:
0395: Vector qresult;
0396:
0397: try {
0398: qresult = executeQuery(query);
0399: if (logger.isDebugEnabled())
0400: logger
0401: .debug("in checkMeiConsumption() query complete for asset "
0402: + asset.getTypeIdentificationPG()
0403: .getNomenclature()
0404: + "\nquery= " + query);
0405: if (qresult.isEmpty()) {
0406: if (logger.isDebugEnabled())
0407: logger.debug("no result for asset "
0408: + asset.getTypeIdentificationPG()
0409: .getNomenclature());
0410: } else {
0411: Object row[] = (Object[]) qresult.firstElement();
0412: result[AMMO] = convertConsumptionElement(row[AMMO]);
0413: result[PKG_POL] = convertConsumptionElement(row[PKG_POL]);
0414: result[SPARES] = convertConsumptionElement(row[SPARES]);
0415: result[FUEL] = convertConsumptionElement(row[FUEL]);
0416: } // if else
0417: } catch (Exception ee) {
0418: if (logger.isErrorEnabled()) {
0419: logger
0420: .error("in checkMeiConsumption(), DB query failed.Query= "
0421: + query);
0422: }
0423: } // try
0424:
0425: return result;
0426: }
0427:
0428: private boolean convertConsumptionElement(Object ele) {
0429: boolean res = true;
0430: try {
0431: if (ele.toString().equals("0")) {
0432: res = false;
0433: }
0434: } catch (Exception e) {
0435: if (logger.isErrorEnabled()) {
0436: logger
0437: .error("in convertConsumptionElement(), convert failed; ele= "
0438: + ele);
0439: }
0440: }
0441: return res;
0442: }
0443:
0444: private boolean consumes(boolean[] consumed, int type) {
0445: boolean res = true;
0446: try {
0447: res = consumed[type];
0448: } catch (Exception e) {
0449: if (logger.isErrorEnabled()) {
0450: logger.error("in consumes(), array access failed");
0451: }
0452: }
0453: return res;
0454: }
0455:
0456: private boolean consumesAnything(boolean[] consumed) {
0457: for (int i = 0; i < consumed.length; i++) {
0458: boolean b = consumed[i];
0459: if (b == true) {
0460: return true;
0461: }
0462: }
0463: return false;
0464: }
0465:
0466: // On rehydration, this should just re-initialize the PGs
0467: // Otherwise, it should create the various consumer PGs for the MEIs as necessary,
0468: // putting the appropriate BG on them as well
0469: // It only creates PGs for the MEIs that consume that supply class
0470: protected void addConsumerPGs(Collection meiConsumers) {
0471: if (logger.isDebugEnabled())
0472: logger.debug(getAgentIdentifier()
0473: + " in addConsumerPGs with " + meiConsumers.size()
0474: + " meis");
0475: Iterator meis = meiConsumers.iterator();
0476: Asset a, anAsset;
0477:
0478: // Loop over all the MEIs, adding PGs as necessary
0479: while (meis.hasNext()) {
0480: // Reset this boolean for each Asset so decision to publishChange is accurate
0481: boolean addedPG = false; // Did we add any PGs to this Asset?
0482:
0483: a = (Asset) meis.next();
0484: if (a instanceof AggregateAsset) {
0485: anAsset = ((AggregateAsset) a).getAsset();
0486: } else {
0487: anAsset = a;
0488: }
0489:
0490: if (anAsset instanceof ClassVIIMajorEndItem) {
0491: if (logger.isDebugEnabled())
0492: logger.debug(getAgentIdentifier()
0493: + ".addConsumerPGs for Class7MEI: "
0494: + anAsset);
0495:
0496: if (anAsset instanceof Level2MEIAsset) {
0497: //This cargo category code means, "do not transport me."
0498: setNoTransportCargoCode(anAsset);
0499: }
0500:
0501: boolean[] consumed = checkMeiConsumption(anAsset);
0502:
0503: // For each class of supply, add the appropriate consumer PG as necessary
0504: if (consumes(consumed, FUEL)) {
0505: NewFuelConsumerPG fuelpg = (NewFuelConsumerPG) anAsset
0506: .searchForPropertyGroup(FuelConsumerPG.class);
0507: if (fuelpg == null) {
0508: if (logger.isDebugEnabled())
0509: logger
0510: .debug("addConsumerPGs() CREATING FuelConsumerPG for "
0511: + anAsset
0512: + " in "
0513: + getAgentIdentifier());
0514:
0515: fuelpg = (NewFuelConsumerPG) getLDM()
0516: .getFactory().createPropertyGroup(
0517: FuelConsumerPG.class);
0518: fuelpg.setMei(a);
0519: fuelpg.setService(service);
0520: fuelpg.setTheater(THEATER);
0521: if (anAsset instanceof Level2MEIAsset) {
0522: fuelpg.setFuelBG(new Level2FuelConsumerBG(
0523: fuelpg));
0524: } else {
0525: fuelpg
0526: .setFuelBG(new FuelConsumerBG(
0527: fuelpg));
0528: }
0529: fuelpg.initialize(this );
0530: anAsset.setPropertyGroup(fuelpg);
0531: addedPG = true;
0532: } else {
0533: if (logger.isDebugEnabled())
0534: logger
0535: .debug(getAgentIdentifier()
0536: + ".addConsPGs Re-BGing FuelConsumerPG for "
0537: + anAsset);
0538: if (didRehydrate()) {
0539: if (logger.isInfoEnabled())
0540: logger
0541: .info(" Due to rehydrate. Will re-initialize BG only.");
0542: fuelpg.initialize(this );
0543: } else {
0544: if (logger.isDebugEnabled())
0545: logger
0546: .debug(" DidRehydrate is false. Blindly assume the PG is ok and avoid doing excess work.");
0547:
0548: // Note that we could check the Mei, Service, Theater, and BG. But there's
0549: // no situation where they should not be OK.
0550: }
0551: }
0552: } else {
0553: if (logger.isDebugEnabled())
0554: logger
0555: .debug(getAgentIdentifier()
0556: + ".addConsPGs not putting FuelPG on asset that does not consume it: "
0557: + anAsset);
0558: }
0559:
0560: if (consumes(consumed, AMMO)) {
0561: NewAmmoConsumerPG ammopg = (NewAmmoConsumerPG) anAsset
0562: .searchForPropertyGroup(AmmoConsumerPG.class);
0563: if (ammopg == null) {
0564: if (logger.isDebugEnabled())
0565: logger
0566: .debug("addConsumerPGs() CREATING AmmoConsumerPG for "
0567: + anAsset
0568: + " in "
0569: + getAgentIdentifier());
0570: ammopg = (NewAmmoConsumerPG) getLDM()
0571: .getFactory().createPropertyGroup(
0572: AmmoConsumerPG.class);
0573: ammopg.setMei(a);
0574: ammopg.setService(service);
0575: ammopg.setTheater(THEATER);
0576: if (anAsset instanceof Level2MEIAsset) {
0577: ammopg.setAmmoBG(new Level2AmmoConsumerBG(
0578: ammopg));
0579: } else {
0580: ammopg
0581: .setAmmoBG(new AmmoConsumerBG(
0582: ammopg));
0583: }
0584: ammopg.initialize(this );
0585: anAsset.setPropertyGroup(ammopg);
0586: addedPG = true;
0587: } else {
0588: if (logger.isDebugEnabled())
0589: logger
0590: .debug(getAgentIdentifier()
0591: + ".addConsPGs Re-BGing AmmoConsumerPG for "
0592: + anAsset);
0593: if (didRehydrate()) {
0594: if (logger.isInfoEnabled())
0595: logger
0596: .info(" Due to rehydrate. Will re-initialize BG only.");
0597: ammopg.initialize(this );
0598: } else {
0599: if (logger.isDebugEnabled())
0600: logger
0601: .debug(" DidRehydrate is false. Blindly assume the PG is ok and avoid doing excess work.");
0602:
0603: // Note that we could check the Mei, Service, Theater, and BG. But there's
0604: // no situation where they should not be OK.
0605: } // end of block to handle re-BG not rehydrate
0606: } // end of block to handle existing PG
0607: } else {
0608: if (logger.isDebugEnabled())
0609: logger
0610: .debug(getAgentIdentifier()
0611: + ".addConsPGs not putting AmmopG on asset that does not consume it: "
0612: + anAsset);
0613: }
0614:
0615: if (consumes(consumed, PKG_POL)) {
0616: NewPackagedPOLConsumerPG packagedpg = (NewPackagedPOLConsumerPG) anAsset
0617: .searchForPropertyGroup(PackagedPOLConsumerPG.class);
0618: if (packagedpg == null) {
0619: if (logger.isDebugEnabled())
0620: logger
0621: .debug("addConsumerPGs() CREATING PackagedPOLConsumerPG for "
0622: + anAsset
0623: + " in "
0624: + getAgentIdentifier());
0625:
0626: packagedpg = (NewPackagedPOLConsumerPG) getLDM()
0627: .getFactory().createPropertyGroup(
0628: PackagedPOLConsumerPG.class);
0629: packagedpg.setMei(a);
0630: packagedpg.setService(service);
0631: packagedpg.setTheater(THEATER);
0632: packagedpg
0633: .setPackagedPOLBG(new PackagedPOLConsumerBG(
0634: packagedpg));
0635: packagedpg.initialize(this );
0636: anAsset.setPropertyGroup(packagedpg);
0637: addedPG = true;
0638: } else {
0639: // Already had this PG
0640: if (logger.isDebugEnabled())
0641: logger
0642: .debug(getAgentIdentifier()
0643: + ".addConsPGs Re-BGing PackagedPOLConsumerPG for "
0644: + anAsset);
0645: if (didRehydrate()) {
0646: if (logger.isInfoEnabled())
0647: logger
0648: .info(" Due to rehydrate. Will re-initialize BG only.");
0649: packagedpg.initialize(this );
0650: } else {
0651: if (logger.isDebugEnabled())
0652: logger
0653: .debug(" DidRehydrate is false. Blindly assume the PG is ok and avoid doing excess work.");
0654:
0655: // Note that we could check the Mei, Service, Theater, and BG. But there's
0656: // no situation where they should not be OK.
0657: } // end of block to handle non-rehydrate existing PG
0658:
0659: } // end of block to handle existing PG
0660: } else {
0661: if (logger.isDebugEnabled())
0662: logger
0663: .debug(getAgentIdentifier()
0664: + ".addConsPGs not putting PackagedPOLPG on asset that does not consume it: "
0665: + anAsset);
0666: }
0667:
0668: if (consumes(consumed, SPARES)) {
0669: NewRepairPartConsumerPG partpg = (NewRepairPartConsumerPG) anAsset
0670: .searchForPropertyGroup(RepairPartConsumerPG.class);
0671: if (partpg == null) {
0672: if (logger.isDebugEnabled())
0673: logger
0674: .debug("addConsumerPGs() CREATING RepairPartConsumerPG for "
0675: + anAsset
0676: + " in "
0677: + getAgentIdentifier());
0678:
0679: partpg = (NewRepairPartConsumerPG) getLDM()
0680: .getFactory().createPropertyGroup(
0681: RepairPartConsumerPG.class);
0682: partpg.setMei(a);
0683: partpg.setService(service);
0684: partpg.setTheater(THEATER);
0685: partpg
0686: .setRepairPartBG(new RepairPartConsumerBG(
0687: partpg));
0688: partpg.initialize(this );
0689: anAsset.setPropertyGroup(partpg);
0690: addedPG = true;
0691: } else {
0692: // Already had this PG
0693: if (logger.isDebugEnabled())
0694: logger
0695: .debug(getAgentIdentifier()
0696: + ".addConsPGs Re-BGing RepairPartConsumerPG for "
0697: + anAsset);
0698: if (didRehydrate()) {
0699: if (logger.isInfoEnabled())
0700: logger
0701: .info(" Due to rehydrate. Will re-initialize BG only.");
0702: partpg.initialize(this );
0703: } else {
0704: if (logger.isDebugEnabled())
0705: logger
0706: .debug(" DidRehydrate is false. Blindly assume the PG is ok and avoid doing excess work.");
0707:
0708: // Note that we could check the Mei, Service, Theater, and BG. But there's
0709: // no situation where they should not be OK.
0710: } // end of block to handle non-rehydrate existing PG
0711:
0712: } // end of block to handle existing PG
0713: } else {
0714: if (logger.isDebugEnabled())
0715: logger
0716: .debug(getAgentIdentifier()
0717: + ".addConsPGs not putting RepairPartPG on asset that does not consume it: "
0718: + anAsset);
0719: } // end of block to handle RepairPartPG at all
0720:
0721: // Only publishChange the Asset if we really changed it
0722: if (addedPG) {
0723: publishChange(a);
0724: } else if (logger.isDebugEnabled()) {
0725: logger.debug(getAgentIdentifier()
0726: + ".addConsumerPGs did not add any PGs to "
0727: + a);
0728: }
0729: } else {
0730: // Not a Class7MEI
0731: if (logger.isInfoEnabled())
0732: logger
0733: .info(getAgentIdentifier()
0734: + ".addConsumerPGs had non Class7MEI: "
0735: + a);
0736: }
0737: } // while loop over MEIs
0738: } // addConsumerBGs method
0739:
0740: private void setNoTransportCargoCode(Asset anAsset) {
0741: MovabilityPG pg = (MovabilityPG) anAsset
0742: .searchForPropertyGroup(MovabilityPG.class);
0743: if (pg.getCargoCategoryCode() == null) {
0744: NewMovabilityPG newpg = (NewMovabilityPG) getLDM()
0745: .getFactory().createPropertyGroup(
0746: MovabilityPG.class);
0747: newpg.setMoveable(false);
0748: newpg.setCargoCategoryCode("000");
0749: anAsset.setPropertyGroup(newpg);
0750: }
0751: }
0752:
0753: public void setServiceBroker(ServiceBroker serviceBroker) {
0754: this .serviceBroker = serviceBroker;
0755: }
0756:
0757: public Organization getMyOrg() {
0758: return myOrg;
0759: }
0760:
0761: public boolean canHandle(String typeid, Class class_hint) {
0762: Boolean protoProvider = (Boolean) myParams_
0763: .get("PrototypeProvider");
0764: if (logger.isDebugEnabled())
0765: logger.debug("canHandle (typeid:" + typeid + ")");
0766: if ((protoProvider == null) || (protoProvider.booleanValue())) {
0767: if ((class_hint == null)
0768: || class_hint.getName().equals(MEI_STRING)) {
0769: String[] handlesList = { "NSN/", "MDS/", "TAMCN/",
0770: "MEI/", "DODIC/" };
0771: for (int i = 0; i < handlesList.length; i++) {
0772: if (typeid.startsWith(handlesList[i])) {
0773: return true;
0774: }
0775: }
0776: }
0777: }
0778: if (logger.isDebugEnabled())
0779: logger.debug("canHandle(), Unable to provider Prototype."
0780: + " ProtoProvider = " + protoProvider
0781: + ", typeid= " + typeid);
0782: return false;
0783: }
0784:
0785: public Asset makePrototype(String type_name, Class class_hint) {
0786: // Demand Rate Queries are based upon service
0787: if (!configured) {
0788: configure();
0789: if (!configured) {
0790: if (logger.isErrorEnabled()) {
0791: logger
0792: .error("makePrototype() plugin missing myOrganization");
0793: }
0794: return null;
0795: }
0796: }
0797: if ((class_hint != null)
0798: && !class_hint.getName().equals(MEI_STRING)) {
0799: if (logger.isErrorEnabled()) {
0800: logger
0801: .error("make prototype How did we get this far?? "
0802: + class_hint);
0803: }
0804: return null;
0805: }
0806:
0807: if (!configured) {
0808: if (logger.isErrorEnabled()) {
0809: logger.error("makePrototype(" + type_name + ","
0810: + class_hint + ") PlugIn not configured yet");
0811: }
0812: return null;
0813: }
0814:
0815: // create initial asset
0816: String nomen = getMEINomenclature(type_name, service);
0817: if (nomen == null) {
0818: return null;
0819: } // if
0820: if (logger.isDebugEnabled())
0821: logger.debug("is dodic:"
0822: + (type_name.indexOf("DODIC") > -1));
0823: return newAsset(type_name, MEI_STRING, nomen);
0824: } // makePrototype
0825:
0826: // getNormalizedName():
0827: // Normalizes the wide range of Airforce MDSs inorder to find the MDS in the
0828: // database.
0829: private String getNormalizedName(String name) {
0830:
0831: StringBuffer mission = new StringBuffer();
0832: StringBuffer design = new StringBuffer();
0833: StringBuffer series = new StringBuffer();
0834: if (logger.isDebugEnabled())
0835: logger.debug("getNormalizedName, Original MDS: " + name);
0836: StringCharacterIterator sci = new StringCharacterIterator(name);
0837: int state = 0;
0838: //0 = mission
0839: //1 = design
0840: //2 = series
0841:
0842: //Character Ch;
0843: char ch;
0844: while ((ch = sci.current()) != StringCharacterIterator.DONE) {
0845:
0846: if (!Character.isLetterOrDigit(ch)) {
0847: sci.next();
0848: continue;
0849: } // if
0850: ch = Character.toUpperCase(ch);
0851:
0852: if (state == 0) {
0853: //looking for mission
0854: if (Character.isLetter(ch)) {
0855: mission.append(ch);
0856: sci.next();
0857: } else {
0858: state = 1;
0859: } // if
0860: } else if (state == 1) { //looking for design
0861: if (Character.isDigit(ch)) {
0862: design.append(ch);
0863: sci.next();
0864: } else {
0865: state = 2;
0866: } // if
0867:
0868: } else { //looking for series
0869: series.append(ch);
0870: sci.next();
0871: }
0872: } // while
0873:
0874: //Converting design to Integer
0875:
0876: while (design.length() < 3) {
0877: design.insert(0, (int) 0);
0878: } // while
0879: while (series.length() > 1) {
0880: series.deleteCharAt(series.length() - 1);
0881: } // while
0882:
0883: return (mission.toString() + design.toString() + series
0884: .toString());
0885: } // getNormalizedName
0886:
0887: protected String getMEINomenclature(String type_id, String service) {
0888: String query = (String) fileParameters_.get("meiQuery");
0889: String consumer_id = type_id
0890: .substring(type_id.indexOf("/") + 1);
0891: if (type_id.startsWith("MDS/")
0892: && service.equals(Service.AIRFORCE)) {
0893: consumer_id = getNormalizedName(consumer_id);
0894: } // if
0895: Vector result = null;
0896: String nomen = null;
0897: if (query != null) {
0898: int i = query.indexOf(":nsn");
0899: String q1 = query.substring(0, i) + "'" + consumer_id + "'";
0900: String q2 = query.substring(i + 4, query
0901: .indexOf(":service"))
0902: + "'" + service + "'";
0903: query = q1 + q2;
0904: try {
0905: result = executeQuery(query);
0906: if (result.isEmpty()) {
0907: // this is fine - means the type_id is not an MEI
0908: return null;
0909: } else {
0910: Object row[] = (Object[]) result.firstElement();
0911: nomen = (String) row[0];
0912: }
0913: } catch (Exception ee) {
0914: if (logger.isErrorEnabled()) {
0915: logger
0916: .error("retrieveFromDB(), DB query failed. query= "
0917: + query + "\n ERROR " + ee);
0918: }
0919: return null;
0920: }
0921: }
0922: return nomen;
0923: } // getMEINomenclature
0924:
0925: public void fillProperties(Asset anAsset) {
0926: }
0927:
0928: public Asset getPrototype(String typeid) {
0929: return getLDM().getFactory().getPrototype(typeid);
0930: }
0931:
0932: // Queries the DB to retrieve the parts for an MEI and the consumption rates for each
0933: // part in order to create and AssetConsumptionRate object.
0934: // public AssetConsumptionRate lookupAssetConsumptionRate
0935: public Vector lookupAssetConsumptionRate(Asset asset,
0936: String asset_type, String service, String theater) {
0937: if (logger.isDebugEnabled())
0938: logger.debug("lookupAssetConsumptionRate()");
0939:
0940: String query = createACRQuery(asset, asset_type, service,
0941: theater);
0942: if (query == null) {
0943: if (logger.isErrorEnabled()) {
0944: logger
0945: .error("lookupAssetConsumptionRate() Invalid ACR query for "
0946: + asset_type + service);
0947: }
0948: return null;
0949: } // if
0950: if (logger.isDebugEnabled())
0951: logger.debug("lookupAssetConsumptionRate() ACR query for "
0952: + asset_type + service + " = " + query);
0953: Vector result;
0954: try {
0955: Date beforeQuery = new Date();
0956: result = executeQuery(query);
0957: Date afterQuery = new Date();
0958: long duration = afterQuery.getTime()
0959: - beforeQuery.getTime();
0960: if (logger.isInfoEnabled())
0961: logger.info(duration
0962: + " consumptionRate query duration for "
0963: + getAgentIdentifier());
0964: if (logger.isDebugEnabled())
0965: logger
0966: .debug("in lookupAssetConsumptionRate() query complete for asset "
0967: + asset.getTypeIdentificationPG()
0968: .getNomenclature()
0969: + "\nquery= " + query);
0970: if (result.isEmpty()) {
0971: if (logger.isDebugEnabled())
0972: logger.debug("no result for asset "
0973: + asset.getTypeIdentificationPG()
0974: .getNomenclature());
0975: return null;
0976: } // if
0977: } catch (Exception ee) {
0978: if (logger.isErrorEnabled()) {
0979: logger
0980: .error("in lookupAssetConsumptionRate(), DB query failed.Query= "
0981: + query);
0982: }
0983: return null;
0984: } // try
0985: // return parseACRResults (result, asset_type);
0986: return result;
0987: } // lookupAssetConsumptionRate
0988:
0989: public Vector lookupLevel2AssetConsumptionRate(String agent,
0990: Asset asset, String supply_type) {
0991: Vector result = null;
0992: String query = (String) fileParameters_.get(LEVEL2
0993: + supply_type + "Rate");
0994: if (query == null) {
0995: if (logger.isErrorEnabled()) {
0996: logger
0997: .error("lookupLevel2AssetConsumptionRate() ACR query is null for "
0998: + LEVEL2 + supply_type);
0999: }
1000: return null;
1001: }
1002: query = substituteOrgName(query, agent);
1003: if (logger.isDebugEnabled())
1004: logger
1005: .debug("lookupLevel2AssetConsumptionRate() ACR query for "
1006: + LEVEL2 + supply_type + " = " + query);
1007: try {
1008: result = executeQuery(query);
1009: if (logger.isDebugEnabled())
1010: logger
1011: .debug("in lookupLevel2AssetConsumptionRate() query complete for asset "
1012: + asset.getTypeIdentificationPG()
1013: .getNomenclature()
1014: + "\nquery= " + query);
1015: if (result.isEmpty()) {
1016: if (logger.isDebugEnabled())
1017: logger.debug("no result for asset "
1018: + asset.getTypeIdentificationPG()
1019: .getNomenclature());
1020: return null;
1021: }
1022: } catch (Exception ee) {
1023: if (logger.isErrorEnabled()) {
1024: logger
1025: .error("in lookupLevel2AssetConsumptionRate(), DB query failed.Query= "
1026: + query);
1027: }
1028: return null;
1029: }
1030: return result;
1031: }
1032:
1033: public String generateMEIQueryParameter(Asset asset,
1034: String asset_type, Service service) {
1035: String typeID = asset.getTypeIdentificationPG()
1036: .getTypeIdentification();
1037: int indx = typeID.indexOf('/');
1038: String division = typeID.substring(0, indx);
1039: return asset_type + service.getName() + division;
1040: } // generateMEIQueryParameter
1041:
1042: public String createACRQuery(Asset asset, String asset_type,
1043: String service, String theater) {
1044: String typeID = asset.getTypeIdentificationPG()
1045: .getTypeIdentification();
1046: int indx = typeID.indexOf('/');
1047: String division;
1048: try {
1049: division = typeID.substring(0, indx);
1050: } catch (Exception exc) {
1051: if (logger.isErrorEnabled()) {
1052: logger.error(" ########### " + typeID + " "
1053: + exc.getMessage());
1054: }
1055: exc.printStackTrace();
1056: return null;
1057: }
1058: String query = (String) fileParameters_.get(asset_type
1059: + service + division);
1060: String consumer_id = typeID.substring(indx + 1);
1061: if (logger.isDebugEnabled())
1062: logger.debug("createACRQuery(), typeID:" + typeID
1063: + ", query:" + query + ", consumer_Id:"
1064: + consumer_id);
1065: if (asset_type.equals("Ammunition")) {
1066: String tmpQuery = substituteNSN(query, consumer_id);
1067: return substituteEchelon(tmpQuery);
1068: } else {
1069: return substituteNSN(query, consumer_id);
1070: }
1071: } // createACRQuery
1072:
1073: /** Replaces the ":nsn" in the query with the actual NSN.
1074: * @param q query string
1075: * @param nsn actual NSN
1076: * @return new query
1077: **/
1078: public String substituteNSN(String q, String nsn) {
1079: String query = null;
1080: if (q != null) {
1081: int indx = q.indexOf(":nsn");
1082: if (indx != -1) {
1083: query = q.substring(0, indx) + "'" + nsn + "'";
1084: if (q.length() > indx + 4) {
1085: query += q.substring(indx + 4);
1086: } // if
1087: } // if
1088: } // if
1089: //System.JTEST.out.println ("The string AFTER the substitution was " + query);
1090: return query;
1091: } // substituteNSN
1092:
1093: /** Replaces the ":echelon" in the ammunition query with the actual value.
1094: * @param q query string
1095: * @return new query
1096: **/
1097: public String substituteEchelon(String q) {
1098: String query = null;
1099: if ((q != null) && (echelon != null)) {
1100: int idx = q.indexOf(":echelon");
1101: if (idx != -1) {
1102: query = q.substring(0, idx) + "'" + echelon + "'";
1103: if (q.length() > idx + 8) {
1104: query += q.substring(idx + 8);
1105: }
1106: }
1107: }
1108: return query;
1109: }
1110:
1111: //#002
1112: public String substituteSupplyType(String q, String supplyType) {
1113: String query = null;
1114: if (q != null) {
1115: int indx = q.indexOf(":type");
1116: if (indx != -1) {
1117: query = q.substring(0, indx) + "'" + supplyType + "'";
1118: if (q.length() > indx + 4) {
1119: query += q.substring(indx + 4);
1120: } // if
1121: } // if
1122: } // if
1123: return query;
1124: } // substituteSupplyType
1125:
1126: public String substituteOrgName(String q, String agent_name) {
1127: StringBuffer query = new StringBuffer();
1128: q = q.trim();
1129: agent_name = "'" + agent_name + "'";
1130: if (q != null) {
1131: int indx = q.indexOf(":org");
1132: if (indx != -1) {
1133: query.append(q.substring(0, indx) + agent_name);
1134: if (q.length() > indx) {
1135: query.append(q.substring(indx + 4));
1136: }
1137: }
1138: }
1139: return query.toString();
1140: }
1141:
1142: /**
1143: * Replaces the ":nsns" in the query for the actual list of NSNs.
1144: * @param q query string
1145: * @param list actual list of NSNs
1146: * @return new query or null if unsuccessful
1147: **/
1148: public String substituteNSNList(String q, List list) {
1149: StringBuffer query = new StringBuffer(220);
1150: if ((q != null) && !list.isEmpty()) {
1151: int indx = q.indexOf(":nsns");
1152: if (indx != -1) {
1153: boolean comma = false;
1154: query.append(q.substring(0, indx));
1155: Iterator i = list.iterator();
1156: while (i.hasNext()) {
1157: if (comma) {
1158: query.append(',');
1159: } // if
1160: query.append("'" + (String) i.next() + "'");
1161: comma = true;
1162: } // while
1163: if (q.length() > indx + 5) {
1164: query.append(q.substring(indx + 5));
1165: } // if
1166: return query.toString();
1167: } // if
1168: } // if
1169: return null;
1170: } // substituteNSNList
1171:
1172: private void setupAvailableSchedule(Asset asset) {
1173: Calendar mycalendar = Calendar.getInstance();
1174: // set the start date of the available schedule to 01/01/1990
1175: mycalendar.set(1990, 0, 1, 0, 0, 0);
1176: Date start = mycalendar.getTime();
1177: // set the end date of the available schedule to 01/01/2010
1178: mycalendar.set(2010, 0, 1, 0, 0, 0);
1179: Date end = mycalendar.getTime();
1180: NewSchedule availsched = factory.newSimpleSchedule(start, end);
1181: // set the available schedule
1182: ((NewRoleSchedule) asset.getRoleSchedule())
1183: .setAvailableSchedule(availsched);
1184: }
1185: } // MEIPrototypeProvider
|