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.mlm.ui.data;
0028:
0029: import java.text.DateFormat;
0030: import java.util.Collection;
0031: import java.util.Date;
0032: import java.util.Enumeration;
0033: import java.util.Iterator;
0034: import java.util.Vector;
0035:
0036: import org.cougaar.glm.ldm.Constants;
0037: import org.cougaar.glm.ldm.GLMFactory;
0038: import org.cougaar.glm.ldm.asset.Capacity;
0039: import org.cougaar.glm.ldm.asset.GLMAsset;
0040: import org.cougaar.glm.ldm.asset.Inventory;
0041: import org.cougaar.glm.ldm.asset.InventoryLevelsPG;
0042: import org.cougaar.glm.ldm.asset.InventoryPG;
0043: import org.cougaar.glm.ldm.asset.Person;
0044: import org.cougaar.glm.ldm.plan.AlpineAspectType;
0045: import org.cougaar.glm.ldm.plan.LaborSchedule;
0046: import org.cougaar.glm.ldm.plan.NewQuantityScheduleElement;
0047: import org.cougaar.glm.ldm.plan.PlanScheduleType;
0048: import org.cougaar.glm.ldm.plan.QuantityScheduleElement;
0049: import org.cougaar.glm.plugins.ScheduleUtils;
0050: import org.cougaar.glm.plugins.TaskUtils;
0051: import org.cougaar.glm.plugins.TimeUtils;
0052: import org.cougaar.planning.ldm.asset.Asset;
0053: import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
0054: import org.cougaar.planning.ldm.measure.CountRate;
0055: import org.cougaar.planning.ldm.measure.FlowRate;
0056: import org.cougaar.planning.ldm.measure.MassTransferRate;
0057: import org.cougaar.planning.ldm.measure.Rate;
0058: import org.cougaar.planning.ldm.plan.Allocation;
0059: import org.cougaar.planning.ldm.plan.AllocationResult;
0060: import org.cougaar.planning.ldm.plan.AspectRate;
0061: import org.cougaar.planning.ldm.plan.AspectScorePoint;
0062: import org.cougaar.planning.ldm.plan.AspectType;
0063: import org.cougaar.planning.ldm.plan.AspectValue;
0064: import org.cougaar.planning.ldm.plan.Preference;
0065: import org.cougaar.planning.ldm.plan.RoleSchedule;
0066: import org.cougaar.planning.ldm.plan.Schedule;
0067: import org.cougaar.planning.ldm.plan.ScheduleElement;
0068: import org.cougaar.planning.ldm.plan.ScheduleImpl;
0069: import org.cougaar.planning.ldm.plan.ScheduleUtilities;
0070: import org.cougaar.planning.ldm.plan.ScoringFunction;
0071: import org.cougaar.planning.ldm.plan.Task;
0072: import org.cougaar.planning.ldm.plan.TimeAspectValue;
0073: import org.cougaar.planning.ldm.plan.Verb;
0074: import org.cougaar.planning.plugin.util.AllocationResultHelper;
0075: import org.cougaar.util.TimeSpan;
0076: import org.cougaar.util.TimeSpanSet;
0077:
0078: /** Composes inventory and capacity schedules from COUGAAR log plan objects.
0079: Note that the getters return null if the schedule requested is null
0080: or empty.
0081: */
0082: // PAS does anyone use TotalSchedule - no
0083: // PSP REQUESTED_DUE_OUT_SHORTFALL not use ie getDueOutShortfallSchedule not used
0084: public class UIInventoryImpl {
0085: static final String[][] capacityInfo = {
0086: { "AmmunitionTransportation", "Tons" },
0087: { "AmmunitionHandling", "Tons/Day" },
0088: { "AmmunitionStorage", "Tons" },
0089: { "FuelTransportation", "Gallons" },
0090: { "FuelHandling", "Gallons/Day" },
0091: { "FuelStorage", "Gallons" },
0092: { "WaterTransportation", "Gallons" },
0093: { "WaterHandling", "Gallons/Day" },
0094: { "WaterStorage", "Gallons" },
0095: { "ContainerTransportation", "Count" },
0096: { "NonContainerTransportation", "Tons" },
0097: { "MaterielHandling", "Tons/Day" },
0098: { "MaterielStorage", "Tons" },
0099: { "PassengerTransportation", "Count" },
0100: { "HETTransportation", "Tons" }, };
0101: static final String[] fuelTypes = { "DF2", "DFM", "JP5", "JP8",
0102: "MUG" };
0103:
0104: public final static String NO_INVENTORY_SCHEDULE_JUST_CONSUME = "NO INVENTORY SCHEDULE(DEMAND)";
0105:
0106: Asset asset;
0107: TimeSpanSet dueInSchedule = new TimeSpanSet();
0108: TimeSpanSet unconfirmedDueInSchedule = new TimeSpanSet();
0109: TimeSpanSet requestedDueInSchedule = new TimeSpanSet();
0110: TimeSpanSet projectedDueInSchedule = new TimeSpanSet();
0111: TimeSpanSet projectedRequestedDueInSchedule = new TimeSpanSet();
0112: TimeSpanSet inactiveDueInSchedule = new TimeSpanSet();
0113: TimeSpanSet inactiveUnconfirmedDueInSchedule = new TimeSpanSet();
0114: TimeSpanSet inactiveRequestedDueInSchedule = new TimeSpanSet();
0115: TimeSpanSet inactiveProjectedDueInSchedule = new TimeSpanSet();
0116: TimeSpanSet inactiveProjectedRequestedDueInSchedule = new TimeSpanSet();
0117:
0118: Vector dueOutLaborSchedule = null;
0119: Vector laborSchedule = null;
0120:
0121: Vector onHandDailySchedule = null;
0122: Vector onHandDetailedSchedule = null;
0123:
0124: Vector dueOutSchedule = null;
0125: Vector projectedDueOutSchedule = null;
0126: Vector projectedDueOutLaborSchedule = null;
0127: Vector requestedDueOutSchedule = null;
0128: Vector projectedRequestedDueOutSchedule = null;
0129:
0130: Vector inactiveDueOutSchedule = null;
0131: Vector inactiveProjectedDueOutSchedule = null;
0132: Vector inactiveRequestedDueOutSchedule = null;
0133: Vector inactiveProjectedRequestedDueOutSchedule = null;
0134:
0135: Schedule averageDemandSchedule = null;
0136: Schedule reorderLevelSchedule = null;
0137: Schedule goalLevelSchedule = null;
0138: Vector projectedMockDueInSchedule = null;
0139: Vector projectedRequestedMockDueInSchedule = null;
0140: Schedule onHandMockSchedule = null;
0141: Vector projectedRequestedMockDueOutSchedule = null;
0142: Vector projectedMockDueOutSchedule = null;
0143:
0144: // Vector dueOutShortfallSchedule = null;
0145: // Vector totalSchedule = null;
0146: final static long MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
0147: static boolean debug;
0148:
0149: public UIInventoryImpl() {
0150: // print debug messages if inventory_debug set to true
0151: debug = false;
0152: String val = System.getProperty("inventory_debug");
0153: if (val != null) {
0154: if (val.equals("true")) {
0155: debug = true;
0156: }
0157: }
0158: }
0159:
0160: public Asset getAsset() {
0161: return this .asset;
0162: }
0163:
0164: protected Asset getInsideAsset() {
0165: if ((asset instanceof GLMAsset)
0166: && (((GLMAsset) asset).getScheduledContentPG() != null))
0167: return ((GLMAsset) asset).getScheduledContentPG()
0168: .getAsset();
0169: else
0170: return this .asset;
0171: }
0172:
0173: /** Set asset for this inventory object.
0174: * Handle Labor assets differently from non-labor.
0175: */
0176:
0177: public void setAsset(Asset asset) {
0178: this .asset = asset;
0179:
0180: if (asset instanceof GLMAsset) {
0181: Schedule s = null;
0182: if ((asset instanceof Inventory)
0183: && (((Inventory) asset)
0184: .getDetailedScheduledContentPG() != null)) {
0185: s = ((Inventory) asset).getDetailedScheduledContentPG()
0186: .getSchedule();
0187: onHandDetailedSchedule = scheduleToNonOverlapVector(s);
0188: System.out
0189: .println("Got a detailed Inventory schedule!!!");
0190: s = null;
0191: }
0192: if (((GLMAsset) asset).getScheduledContentPG() != null) {
0193: s = ((GLMAsset) asset).getScheduledContentPG()
0194: .getSchedule();
0195: }
0196: if (s != null) {
0197: if (s.getScheduleType().equals(
0198: PlanScheduleType.TOTAL_CAPACITY)) {
0199: if (s instanceof LaborSchedule)
0200: s = ((LaborSchedule) s).getQuantitySchedule();
0201: else
0202: System.out
0203: .println("UIInventoryImpl WARNING: Expected labor schedule");
0204: laborSchedule = scheduleToNonOverlapVector(s);
0205: } else
0206: onHandDailySchedule = scheduleToNonOverlapVector(s);
0207: }
0208: if (isLaborAsset(asset)) {
0209: dueOutLaborSchedule = computeDueOutVector(false); // All non-inventory assets are active
0210: projectedDueOutLaborSchedule = computeProjectedDueOutVector(false);
0211: // setDueOutLaborSchedule();
0212: } else {
0213: dueOutSchedule = computeDueOutVector(false);
0214: inactiveDueOutSchedule = computeDueOutVector(true);
0215: projectedDueOutSchedule = computeProjectedDueOutVector(false);
0216: inactiveProjectedDueOutSchedule = computeProjectedDueOutVector(true);
0217: requestedDueOutSchedule = computeRequestedDueOutVector(false);
0218: inactiveRequestedDueOutSchedule = computeRequestedDueOutVector(true);
0219: projectedRequestedDueOutSchedule = computeProjectedRequestedDueOutVector(false);
0220: inactiveProjectedRequestedDueOutSchedule = computeProjectedRequestedDueOutVector(true);
0221:
0222: if (asset instanceof Inventory)
0223: setInventoryLevelsSchedules((Inventory) asset);
0224:
0225: // setRequestedDueOutSchedule();
0226: // setProjectedRequestedDueOutSchedule();
0227: // setDueOutShortfallSchedule();
0228: }
0229: }
0230: }
0231:
0232: /** It's a labor asset if the class of the asset is Capacity or
0233: if the class of the inner asset is Person.
0234: */
0235:
0236: private boolean isLaborAsset(Asset asset) {
0237: if (asset instanceof Capacity)
0238: return true;
0239: if (getInsideAsset() instanceof Person)
0240: return true;
0241: return false;
0242: }
0243:
0244: // /** total = onHand + dueOut
0245: // private void setTotalSchedule() {
0246: // Schedule onHandCSchedule = getCSchedule(onHandDailySchedule);
0247: // Schedule dueOutCSchedule = getCSchedule(dueOutSchedule);
0248: // Schedule total = ScheduleUtilities.addSchedules(onHandCSchedule,
0249: // dueOutCSchedule);
0250: // if (debug) {
0251: // System.out.println("Available Schedule");
0252: // printSchedule(onHandCSchedule);
0253: // System.out.println("Allocated COUGAAR Schedule");
0254: // printSchedule(dueOutCSchedule);
0255: // System.out.println("Total Schedule");
0256: // printSchedule(total);
0257: // }
0258: // totalSchedule = scheduleToVector(total);
0259: // }
0260:
0261: // public Vector getTotalSchedule() {
0262: // setTotalSchedule(); // only compute this if needed
0263: // return getSchedule(totalSchedule);
0264: // }
0265:
0266: // checks if empty schedule, return null
0267: protected Vector getSchedule(Vector sched) {
0268: if (sched == null)
0269: return null;
0270: if (sched.size() == 0)
0271: return null;
0272: return sched;
0273: }
0274:
0275: // checks if empty schedule, return null
0276: protected TimeSpanSet checkTimeSpanSet(TimeSpanSet set) {
0277: if (set == null) {
0278: System.out.println("Null timespanset");
0279: return null;
0280: }
0281: if (set.size() == 0) {
0282: System.out.println("Empty timespanset");
0283: return null;
0284: }
0285: return set;
0286: }
0287:
0288: /** Get human readable form of the TypeIdentificationPG.
0289: @return String - the nomenclature from the TypeIdentificationPG
0290: */
0291: public String getAssetName() {
0292: TypeIdentificationPG typeIdPG = this .getInsideAsset()
0293: .getTypeIdentificationPG();
0294: return typeIdPG.getNomenclature() + ":"
0295: + typeIdPG.getTypeIdentification();
0296: }
0297:
0298: /**
0299: Returns a schedule as defined in ScheduleType
0300: */
0301:
0302: public String getScheduleType() {
0303: if ((asset instanceof GLMAsset)
0304: && (((GLMAsset) asset).getScheduledContentPG() != null)) {
0305: Schedule s = ((GLMAsset) asset).getScheduledContentPG()
0306: .getSchedule();
0307: if (s != null)
0308: return s.getScheduleType();
0309: } else {
0310: return NO_INVENTORY_SCHEDULE_JUST_CONSUME;
0311: }
0312:
0313: return "";
0314: }
0315:
0316: /**
0317: Returns the unit type -- i.e. gallons, man hours, tons, etc.
0318: */
0319:
0320: public String getUnitType() {
0321: Asset insideAsset = this .getInsideAsset();
0322: String typeId = insideAsset.getTypeIdentificationPG()
0323: .getTypeIdentification();
0324: String nomenclature = insideAsset.getTypeIdentificationPG()
0325: .getNomenclature();
0326:
0327: String scheduleType = getScheduleType();
0328:
0329: // capacity
0330: if (scheduleType.equals(PlanScheduleType.TOTAL_CAPACITY)
0331: || scheduleType
0332: .equals(PlanScheduleType.AVAILABLE_CAPACITY)
0333: || scheduleType
0334: .equals(PlanScheduleType.ACTUAL_CAPACITY)
0335: || scheduleType.equals(PlanScheduleType.LABOR)) {
0336: if (typeId.startsWith("MOS"))
0337: return "Hours/Day";
0338: else {
0339: for (int i = 0; i < capacityInfo.length; i++)
0340: if (capacityInfo[i][0].equals(typeId))
0341: return capacityInfo[i][1];
0342: }
0343: return "";
0344: }
0345:
0346: // inventory
0347: if (typeId.startsWith("NSN")) {
0348: for (int i = 0; i < fuelTypes.length; i++)
0349: if (fuelTypes[i].equals(nomenclature))
0350: return "Gallons"; // fuel
0351: return "Items"; // consumables
0352: } else
0353: return "STons"; // ammunition
0354: }
0355:
0356: /**
0357: Get the schedule that indicates the on hand inventory for this asset.
0358: @return Vector - vector of UIQuantityScheduleElement
0359: */
0360: public Vector getOnHandDailySchedule() {
0361: return getSchedule(onHandDailySchedule);
0362: }
0363:
0364: /**
0365: Get the schedule that indicates the on hand inventory for this asset.
0366: @return Vector - vector of UIQuantityScheduleElement
0367: */
0368: public Vector getOnHandDetailedSchedule() {
0369: return getSchedule(onHandDetailedSchedule);
0370: }
0371:
0372: /**
0373: Get the schedule that indicates the on hand inventory with jaggy ness
0374: in the projection phase for this asset.
0375: @return Vector - vector of UIQuantityScheduleElement
0376: */
0377: public Vector getOnHandMockSchedule() {
0378: return getSchedule(scheduleToNonOverlapVector(onHandMockSchedule));
0379: }
0380:
0381: /** Take a COUGAAR schedule and make it into a vector of UIQuantityScheduleElement
0382: for serialization.
0383: */
0384: static private Vector scheduleToVector(Schedule CSchedule) {
0385: Vector s = new Vector();
0386: if (CSchedule != null) {
0387: Enumeration elements = CSchedule.getAllScheduleElements();
0388: while (elements.hasMoreElements()) {
0389: QuantityScheduleElement scheduleElement = (QuantityScheduleElement) elements
0390: .nextElement();
0391: s.addElement(new UIQuantityScheduleElement(
0392: scheduleElement));
0393: }
0394: }
0395: return s;
0396: }
0397:
0398: private UIQuantityScheduleElement getScheduleElementFromTask(
0399: Task task) {
0400: if (task == null) {
0401: System.out
0402: .println("UIInventoryImpl WARNING: Allocation result is null");
0403: return null;
0404: }
0405:
0406: double quantity;
0407:
0408: if (TaskUtils.isProjection(task)) {
0409: Rate r = getProjectionRate(task);
0410: if (r == null)
0411: quantity = -1;
0412: else
0413: quantity = getDailyQty(r);
0414:
0415: } else {
0416: quantity = getPreferenceValue(task, AspectType.QUANTITY);
0417: }
0418: if (quantity < 0) {
0419: System.out
0420: .println("UIInventoryImpl WARNING: EXPECTED QUANTITY IN ALLOCATION RESULT WHEN DERIVING SCHEDULE ELEMENT FROM TASK");
0421: return null; // ignore if no quantity
0422: }
0423:
0424: long end_time = getPreferredTime(task, AspectType.END_TIME);
0425: if (end_time < 0) {
0426: System.out
0427: .println("UIInventoryImpl WARNING: NO END_TIME IN ALLOCATION RESULT WHEN DERIVING SCHEDULE ELEMENT FROM TASK");
0428: return null;
0429: }
0430:
0431: return new UIQuantityScheduleElement(end_time - 1, end_time,
0432: quantity);
0433: }
0434:
0435: /**
0436: * create a Vector of schedule elements for the given task. If pe is
0437: * not null, use the allocation result from it else use the tasks
0438: * preferences. An AllocationResultHelper does a lot of the work.
0439: **/
0440: private Vector getScheduleFromProjectionTask(Task projectTask,
0441: boolean isInactive, Allocation pe) {
0442: if (projectTask == null) {
0443: System.out
0444: .println("UIInventoryImpl WARNING: Project Task is null");
0445: return null;
0446: }
0447: if (!TaskUtils.isProjection(projectTask)) {
0448: System.out
0449: .println("UIInventoryImpl WARNING: Expected Project Task.");
0450: return null;
0451: }
0452: Vector schedule = new Vector();
0453: AllocationResultHelper helper = new AllocationResultHelper(
0454: projectTask, pe);
0455: for (int i = 0, n = helper.getPhaseCount(); i < n; i++) {
0456: AllocationResultHelper.Phase phase = helper.getPhase(i);
0457: long startTime = phase.getStartTime();
0458: long endTime = phase.getEndTime();
0459: AspectRate arate = (AspectRate) phase
0460: .getAspectValue(AlpineAspectType.DEMANDRATE);
0461: double quantity = getDailyQty(arate.getRateValue());
0462: while (startTime < endTime) {
0463: UIQuantityScheduleElement el = new UIQuantityScheduleElement(
0464: startTime, startTime + 1, quantity);
0465: if (isInactive(projectTask, el) == isInactive) {
0466: schedule.add(el);
0467: if (debug) {
0468: System.out
0469: .println("UIInventoryImpl::getScheduleFromProjectionTask: add "
0470: + el
0471: + " inactive is "
0472: + isInactive
0473: + " for task: "
0474: + TaskUtils
0475: .taskDesc(projectTask));
0476: }
0477: }
0478: startTime += TimeUtils.MSEC_PER_DAY;
0479: }
0480: }
0481: return schedule;
0482: }
0483:
0484: public static Rate getProjectionRate(Task task) {
0485: Rate r = TaskUtils.getRate(task);
0486: return r;
0487: }
0488:
0489: public static double getDailyQty(Rate aRate) {
0490: if (aRate instanceof FlowRate) {
0491: return ((FlowRate) aRate).getGallonsPerDay();
0492: }
0493: if (aRate instanceof CountRate) {
0494: return ((CountRate) aRate).getEachesPerDay();
0495: }
0496: if (aRate instanceof MassTransferRate) {
0497: return ((MassTransferRate) aRate).getShortTonsPerDay();
0498: }
0499: System.out
0500: .println("UIInventoryImpl::getDailyQty - unknown type of rate - "
0501: + aRate.getClass().getName());
0502: return -1;
0503: }
0504:
0505: public static double getPreferenceValue(Task task, int aspect_type) {
0506: Preference task_pref = task.getPreference(aspect_type);
0507: if (task_pref == null) {
0508: return -1;
0509: } else if (task_pref.getScoringFunction() == null) {
0510: return -1;
0511: } else if (task_pref.getScoringFunction().getBest() == null) {
0512: return -1;
0513: } else {
0514: return task_pref.getScoringFunction().getBest().getValue();
0515: }
0516: }
0517:
0518: private UIQuantityScheduleElement getScheduleFromAllocation(
0519: AllocationResult allocationResult) {
0520: long endTime = -1;
0521: double quantity = 0;
0522:
0523: if (allocationResult == null) {
0524: System.out
0525: .println("UIInventoryImpl WARNING: Allocation result is null");
0526: return null;
0527: }
0528:
0529: if (allocationResult.isDefined(AspectType.QUANTITY))
0530: quantity = allocationResult.getValue(AspectType.QUANTITY);
0531: else {
0532: System.out
0533: .println("UIInventoryImpl WARNING: EXPECTED QUANTITY IN ALLOCATION RESULT FOR DUE OUT");
0534: return null; // ignore if no quantity
0535: }
0536:
0537: if (allocationResult.isDefined(AspectType.END_TIME)) {
0538: endTime = (long) allocationResult
0539: .getValue(AspectType.END_TIME);
0540: } else {
0541: return null; // ignore if no end time
0542: }
0543:
0544: // if (debug) System.out.println("Creating schedule: " + quantity +
0545: // " start time: " + startTime +
0546: // " end time: " + endTime);
0547:
0548: return new UIQuantityScheduleElement(endTime - 1, endTime,
0549: quantity);
0550: }
0551:
0552: protected void setInventoryLevelsSchedules(Inventory inventory) {
0553: InventoryLevelsPG invLevPG = inventory.getInventoryLevelsPG();
0554:
0555: averageDemandSchedule = invLevPG.getAverageDemandSchedule();
0556: goalLevelSchedule = invLevPG.getGoalLevelSchedule();
0557: reorderLevelSchedule = invLevPG.getReorderLevelSchedule();
0558: }
0559:
0560: protected int getProjectedDueOutPeriodDays() {
0561: return 1;
0562: }
0563:
0564: protected long getProjectedDueOutPeriodMSecs() {
0565: return TimeUtils.MSEC_PER_DAY * getProjectedDueOutPeriodDays();
0566: }
0567:
0568: protected static Vector extractElementsInTimePeriod(
0569: Vector schedule, long startTime, long endTime) {
0570: Vector extracted = new Vector(schedule.size());
0571: for (int i = 0; i < schedule.size(); i++) {
0572: UIQuantityScheduleElement el = (UIQuantityScheduleElement) schedule
0573: .elementAt(i);
0574:
0575: if ((el.getStartTime() >= startTime)
0576: && (el.getEndTime() <= endTime)) {
0577: extracted.addElement(el.clone());
0578: }
0579: }
0580: return extracted;
0581: }
0582:
0583: protected static double deriveMockDueInQty(Schedule s,
0584: long startTime, long endTime, double invQty,
0585: double reorderLevel, double goalLevel) {
0586: if (invQty < reorderLevel) {
0587: //System.out.println("UIInventoryImpl::deriveMockDueInQty reordering: InvQty is " + invQty + " Reorder is " + reorderLevel + " diff is " + (invQty - reorderLevel));
0588: return goalLevel - invQty;
0589: } else
0590: return 0.0;
0591: }
0592:
0593: protected static double extractFirstQtyInDay(Schedule s, long time) {
0594: Collection col = s.getOverlappingScheduleElements(time, time
0595: + TimeUtils.MSEC_PER_DAY);
0596: // Collection col = s.getOverlappingScheduleElements(time,s.getEndTime());
0597: if (col.size() >= 1) {
0598: return ((QuantityScheduleElement) (col.toArray())[0])
0599: .getQuantity();
0600: } else {
0601: throw new RuntimeException(
0602: "Should be at least one Schedule element in schedule for "
0603: + new Date(time) + " but there are "
0604: + col.size());
0605: }
0606: }
0607:
0608: protected static double extractSingleQtyOnTime(Schedule s, long time) {
0609: Collection col = s.getScheduleElementsWithTime(time);
0610: if (col.size() == 1) {
0611: return ((QuantityScheduleElement) (col.toArray())[0])
0612: .getQuantity();
0613: } else {
0614: throw new RuntimeException(
0615: "Should be one Schedule element in schedule for "
0616: + new Date(time) + " but there are "
0617: + col.size());
0618: }
0619: }
0620:
0621: protected static double getQtySumOnSchedOverTime(Schedule s,
0622: long startTime, long endTime) {
0623: Collection col = s.getEncapsulatedScheduleElements(startTime,
0624: endTime);
0625: return ScheduleUtilities.sumElements(col);
0626: }
0627:
0628: /***
0629: *
0630: Iterator it = col.iterator();
0631: while(it.hasNext()) {
0632: QuantityScheduleElement el = (QuantityScheduleElement) it.next();
0633: sum+=el.getQuantity();
0634: }
0635: return sum;
0636: }
0637:
0638: **/
0639:
0640: protected void initializeMockSchedules() {
0641: onHandMockSchedule = getCSchedule(onHandDailySchedule);
0642: projectedMockDueInSchedule = getProjectedDueInSchedule();
0643: projectedRequestedMockDueInSchedule = getProjectedRequestedDueInSchedule();
0644: projectedMockDueOutSchedule = getProjectedDueOutSchedule();
0645: projectedRequestedMockDueOutSchedule = getProjectedRequestedDueOutSchedule();
0646: }
0647:
0648: protected boolean validateDataForSimulatedProjections() {
0649:
0650: boolean theReturn = true;
0651:
0652: if ((onHandDailySchedule == null)
0653: || (reorderLevelSchedule == null || goalLevelSchedule == null)
0654: || (projectedDueInSchedule == null)
0655: || (projectedRequestedDueInSchedule == null)
0656: || (projectedDueOutSchedule == null)
0657: || (projectedRequestedDueOutSchedule == null)) {
0658: System.out
0659: .println("WARNING: Not all the info is there to computeSimulatedProjectionSchedules");
0660:
0661: if (reorderLevelSchedule == null) {
0662: System.out.println("WARNING:reorderLevelSchedule");
0663: reorderLevelSchedule = new ScheduleImpl();
0664: theReturn = false;
0665: }
0666: if (goalLevelSchedule == null) {
0667: System.out.println("WARNING:goalLevelSchedule");
0668: goalLevelSchedule = new ScheduleImpl();
0669: theReturn = false;
0670: }
0671: if (projectedDueInSchedule == null) {
0672: System.out.println("WARNING:projectedDueInSchedule");
0673: }
0674: if (projectedRequestedDueInSchedule == null) {
0675: System.out
0676: .println("WARNING:projectedRequestedDueInSchedule");
0677: }
0678: if (projectedDueOutSchedule == null) {
0679: System.out.println("WARNING:projectedDueOutSchedule");
0680: }
0681: if (projectedRequestedDueOutSchedule == null) {
0682: System.out
0683: .println("WARNING:projectedRequestedDueOutSchedule");
0684: }
0685: if (onHandDailySchedule == null) {
0686: System.out.println("WARNING:onHandDailySchedule");
0687: theReturn = false;
0688: }
0689: }
0690: return theReturn;
0691: }
0692:
0693: public void computeSimulatedProjectionSchedules() {
0694:
0695: if (!validateDataForSimulatedProjections()) {
0696: initializeMockSchedules();
0697: return;
0698: }
0699:
0700: Schedule onHandAlpSched = getCSchedule(onHandDailySchedule);
0701: Schedule projReqDueOutAlpSched = getCSchedule(projectedRequestedDueOutSchedule);
0702: Schedule projReqDueInAlpSched = getCSchedule(projectedRequestedDueInSchedule);
0703: Schedule projDueInAlpSched = getCSchedule(projectedDueInSchedule);
0704: Schedule projDueOutAlpSched = getCSchedule(projectedDueOutSchedule);
0705:
0706: long switchOverDay = Schedule.MAX_VALUE;
0707: if (projReqDueInAlpSched.getAllScheduleElements()
0708: .hasMoreElements()) {
0709: switchOverDay = projReqDueInAlpSched.getStartTime();
0710: }
0711: long endDayTime = Schedule.MAX_VALUE;
0712: if (onHandAlpSched.getAllScheduleElements().hasMoreElements()) {
0713: endDayTime = onHandAlpSched.getEndTime();
0714: }
0715: long startTime = switchOverDay;
0716: double invQty = 0.0;
0717:
0718: projectedRequestedMockDueInSchedule = new Vector();
0719: projectedMockDueInSchedule = new Vector();
0720:
0721: projectedRequestedMockDueOutSchedule = scheduleToNonOverlapVector(new ScheduleImpl(
0722: projReqDueOutAlpSched.getOverlappingScheduleElements(
0723: projReqDueOutAlpSched.MIN_VALUE, switchOverDay)));
0724:
0725: projectedMockDueOutSchedule = scheduleToNonOverlapVector(new ScheduleImpl(
0726: projDueOutAlpSched.getOverlappingScheduleElements(
0727: projDueOutAlpSched.MIN_VALUE, switchOverDay)));
0728:
0729: onHandMockSchedule = new ScheduleImpl(onHandAlpSched
0730: .getOverlappingScheduleElements(
0731: onHandAlpSched.MIN_VALUE, switchOverDay));
0732:
0733: if (startTime != Schedule.MAX_VALUE)
0734: invQty = extractFirstQtyInDay(onHandAlpSched, startTime);
0735:
0736: // System.out.println("UIInventoryImpl:computeSimulatedProj: startTime/switchOverDay is: " + new Date(startTime) + " and end day time is : " + new Date(endDayTime));
0737:
0738: while (startTime < endDayTime) {
0739: long endTime = startTime + getProjectedDueOutPeriodMSecs()
0740: - 1;
0741: if (endTime > endDayTime)
0742: endTime = endDayTime;
0743:
0744: double reqDueOutQty = getQtySumOnSchedOverTime(
0745: projReqDueOutAlpSched, startTime, endTime);
0746:
0747: double dueOutQty = getQtySumOnSchedOverTime(
0748: projDueOutAlpSched, startTime, endTime);
0749:
0750: //take out due outs
0751: invQty = invQty - dueOutQty;
0752:
0753: double reorderLevel = extractFirstQtyInDay(
0754: reorderLevelSchedule, endTime);
0755: double goalLevel = extractFirstQtyInDay(goalLevelSchedule,
0756: endTime);
0757:
0758: double reqDueInQty = deriveMockDueInQty(
0759: projReqDueInAlpSched, startTime, endTime, invQty,
0760: reorderLevel, goalLevel);
0761:
0762: double dueInQty = deriveMockDueInQty(projDueInAlpSched,
0763: startTime, endTime, invQty, reorderLevel, goalLevel);
0764:
0765: //put in due ins
0766: invQty += dueInQty;
0767:
0768: // System.out.println("UIInventoryImpl:computeSimulatedProj: within: " + new Date(startTime) + " and : " + new Date(endTime) + " Due outs are: " + dueOutQty + " due ins are " + dueInQty + " and inventory is: " + invQty + ". reorderLevel shows: " + reorderLevel + " and goalLevel is: " + goalLevel + ".");
0769:
0770: onHandMockSchedule.add(ScheduleUtils
0771: .buildQuantityScheduleElement(invQty, startTime,
0772: endTime));
0773:
0774: projectedRequestedMockDueOutSchedule
0775: .add(new UIQuantityScheduleElement(endTime - 1,
0776: endTime, reqDueOutQty));
0777:
0778: projectedMockDueOutSchedule
0779: .add(new UIQuantityScheduleElement(endTime - 1,
0780: endTime, dueOutQty));
0781:
0782: projectedRequestedMockDueInSchedule
0783: .add(new UIQuantityScheduleElement(endTime - 1,
0784: endTime, reqDueInQty));
0785:
0786: projectedMockDueInSchedule
0787: .add(new UIQuantityScheduleElement(endTime - 1,
0788: endTime, dueInQty));
0789:
0790: startTime = (endTime + 1);
0791: }
0792:
0793: }
0794:
0795: /**
0796: Add schedule elements from an allocation to the due-ins. Get the
0797: end time and quantity from the allocation reported results. Adds
0798: the elements to the inactive or active schedules depending on the
0799: time of the elements. IGNORE ALLOCATION RESULTS IF isSuccess IS
0800: FALSE. */
0801:
0802: public void addDueInSchedule(Allocation allocation) {
0803: Task task = allocation.getTask();
0804: AllocationResult ar = allocation.getReportedResult();
0805: if (TaskUtils.isProjection(task)) {
0806: if (ar == null)
0807: allocation = null; // Ignore allocation if no reported result
0808: for (int i = 0; i < 2; i++) {
0809: boolean isInactive = (i == 0);
0810: Vector schedule = getScheduleFromProjectionTask(task,
0811: isInactive, allocation);
0812: if (schedule != null) {
0813: // if (debug) {
0814: // System.out.println("Adding projected due in schedule from allocation: " +
0815: // allocation.getUID());
0816: // for (int j = 0; j < schedule.size(); j++)
0817: // printQuantityScheduleElement((UIQuantityScheduleElement) schedule.elementAt(j));
0818: // }
0819: if (isInactive) {
0820: inactiveProjectedDueInSchedule.addAll(schedule);
0821: } else {
0822: projectedDueInSchedule.addAll(schedule);
0823: }
0824: }
0825: }
0826: } else if (ar == null) {
0827: // Use request if no allocation result
0828: UIQuantityScheduleElement se = getScheduleElementFromTask(task); // Use end time for due-ins
0829: if (se != null) {
0830: // if (debug) {
0831: // System.out.println("Adding unconfirmed due in schedule from allocation: " +
0832: // allocation.getUID());
0833: // printQuantityScheduleElement(se);
0834: // }
0835: if (isInactive(task, se)) {
0836: inactiveUnconfirmedDueInSchedule.add(se);
0837: } else {
0838: unconfirmedDueInSchedule.add(se);
0839: }
0840: }
0841: } else if (ar.isSuccess()) {
0842: UIQuantityScheduleElement se = getScheduleFromAllocation(allocation
0843: .getReportedResult());
0844: if (se != null) {
0845: // if (debug) {
0846: // System.out.println("Adding due in schedule from allocation: " +
0847: // allocation.getUID());
0848: // printQuantityScheduleElement(se);
0849: // }
0850: if (isInactive(allocation, se)) {
0851: inactiveDueInSchedule.add(se);
0852: } else {
0853: dueInSchedule.add(se);
0854: }
0855: }
0856: } else {
0857: // Ignore if not successful
0858: }
0859: }
0860:
0861: /** Add schedule elements from the preferences in the task in the due-in schedule.
0862: */
0863:
0864: public void addRequestedDueInSchedule(Allocation allocation) {
0865: Task task = allocation.getTask();
0866: if (task == null) {
0867: System.out
0868: .println("UIInventoryImpl WARNING: no task in due-in allocation");
0869: return;
0870: }
0871:
0872: if (TaskUtils.isProjection(task)) {
0873: for (int i = 0; i < 2; i++) {
0874: boolean isInactive = (i == 0);
0875: Vector projectSchedule = getScheduleFromProjectionTask(
0876: task, isInactive, null);
0877: if (projectSchedule != null) {
0878: if (isInactive) {
0879: inactiveProjectedRequestedDueInSchedule
0880: .addAll(projectSchedule);
0881: TimeSpan ts = (TimeSpan) inactiveProjectedRequestedDueInSchedule
0882: .last();
0883: if (debug)
0884: System.out
0885: .println("End of inactive requested duein schedule"
0886: + (ts == null ? "none"
0887: : TimeUtils
0888: .dateString(ts
0889: .getEndTime())));
0890: } else {
0891: projectedRequestedDueInSchedule
0892: .addAll(projectSchedule);
0893: TimeSpan ts = (TimeSpan) projectedRequestedDueInSchedule
0894: .last();
0895: if (debug)
0896: System.out
0897: .println("End of active requested duein schedule"
0898: + (ts == null ? "none"
0899: : TimeUtils
0900: .dateString(ts
0901: .getEndTime())));
0902: }
0903: }
0904: }
0905: } else {
0906: long endTime = getPreferredTime(task, AspectType.END_TIME);
0907: double quantity = getPreferenceValue(task,
0908: AspectType.QUANTITY);
0909:
0910: // must have end time and quantity
0911: if ((quantity != -1) && (endTime != -1)) {
0912: UIQuantityScheduleElement se = new UIQuantityScheduleElement(
0913: endTime - 1, endTime, quantity);
0914: if (isInactive(task, se))
0915: inactiveRequestedDueInSchedule.add(se);
0916: else
0917: requestedDueInSchedule.add(se);
0918: }
0919: }
0920: }
0921:
0922: private Vector convertTimeSpanSet(TimeSpanSet schedule,
0923: String debugLabel) {
0924: if (checkTimeSpanSet(schedule) == null)
0925: return null;
0926:
0927: if (debug) {
0928: // // print original schedule for debugging
0929: System.out.println("ORIGINAL " + debugLabel + " SCHEDULE");
0930: Vector s = new Vector(schedule);
0931: printSchedule(s);
0932: }
0933:
0934: // make an alp schedule so we can use the alp utilities
0935: // to make it non-overlapping
0936: Schedule tmpSchedule = makeNonOverlapping(schedule);
0937: Vector results = scheduleToVector(tmpSchedule);
0938:
0939: if (debug) {
0940: System.out.println("FINAL " + debugLabel + " SCHEDULE");
0941: printSchedule(results);
0942: }
0943: return results;
0944: }
0945:
0946: public Vector getReorderLevelSchedule() {
0947: return getSchedule(scheduleToNonOverlapVector(reorderLevelSchedule));
0948: }
0949:
0950: public Vector getAverageDemandSchedule() {
0951: return getSchedule(scheduleToNonOverlapVector(averageDemandSchedule));
0952: }
0953:
0954: public Vector getGoalLevelSchedule() {
0955: return getSchedule(scheduleToNonOverlapVector(goalLevelSchedule));
0956: }
0957:
0958: /**
0959: Get the schedule that indicates the due-in inventory for this asset.
0960: @return Vector - the schedule for this asset in this cluster
0961: */
0962: public Vector getDueInSchedule() {
0963: return convertTimeSpanSet(dueInSchedule, "DUE IN");
0964: }
0965:
0966: /**
0967: Get the schedule that indicates the due-in inventory for this asset.
0968: @return Vector - the schedule for this asset in this cluster
0969: */
0970: public Vector getUnconfirmedDueInSchedule() {
0971: return convertTimeSpanSet(unconfirmedDueInSchedule,
0972: "UNCONFIRMED DUE IN");
0973: }
0974:
0975: /**
0976: Get the schedule that indicates the projected due-in inventory for this asset.
0977: @return Vector - the schedule for this asset in this cluster
0978: */
0979: public Vector getProjectedDueInSchedule() {
0980: return convertTimeSpanSet(projectedDueInSchedule,
0981: "PROJECTED DUE IN");
0982: }
0983:
0984: /** Get the projected due in schedule for simulated OnHandMockSchedule
0985: */
0986: public Vector getProjectedMockDueInSchedule() {
0987: return getSchedule(projectedMockDueInSchedule);
0988: }
0989:
0990: /**
0991: Get the schedule that indicates the inactive due-in inventory for this asset.
0992: @return Vector - the schedule for this asset in this cluster
0993: */
0994: public Vector getInactiveDueInSchedule() {
0995: return convertTimeSpanSet(inactiveDueInSchedule,
0996: "INACTIVE DUE IN");
0997: }
0998:
0999: /**
1000: Get the schedule that indicates the due-in inventory for this asset.
1001: @return Vector - the schedule for this asset in this cluster
1002: */
1003: public Vector getInactiveUnconfirmedDueInSchedule() {
1004: return convertTimeSpanSet(inactiveUnconfirmedDueInSchedule,
1005: "INACTIVE UNCONFIRMED DUE IN");
1006: }
1007:
1008: /**
1009: Get the schedule that indicates the projected due-in inventory for this asset.
1010: @return Vector - the schedule for this asset in this cluster
1011: */
1012: public Vector getInactiveProjectedDueInSchedule() {
1013: return convertTimeSpanSet(inactiveProjectedDueInSchedule,
1014: "INACTIVE PROJECTED DUE IN");
1015: }
1016:
1017: public static Schedule makeNonOverlapping(TimeSpanSet inSchedule) {
1018: // make an alp schedule so we can use the alp utilities
1019: // to make it non-overlapping
1020: Schedule tmpCSchedule = getCSchedule(inSchedule);
1021: if (isOverlappingSchedule(tmpCSchedule)) {
1022: if (debug)
1023: System.out
1024: .println("UIInventoryImpl::makeNonOverlapping:IS OVERLAPPING");
1025: tmpCSchedule = ScheduleUtilities
1026: .computeNonOverlappingSchedule(tmpCSchedule);
1027: } else if (debug) {
1028: System.out
1029: .println("UIInventoryImpl::makeNonOverlapping:is NOT Overlapping");
1030: }
1031: return tmpCSchedule;
1032: }
1033:
1034: /** Get the requested due in schedule.
1035: */
1036: public Vector getRequestedDueInSchedule() {
1037: if (checkTimeSpanSet(requestedDueInSchedule) == null)
1038: return null;
1039: return new Vector(requestedDueInSchedule);
1040: }
1041:
1042: /** Get the projected requested due in schedule for simulated OnHandMockSchedule
1043: */
1044: public Vector getProjectedRequestedMockDueInSchedule() {
1045: return getSchedule(projectedRequestedMockDueInSchedule);
1046: }
1047:
1048: /** Get the projected requested due in schedule.
1049: */
1050: public Vector getProjectedRequestedDueInSchedule() {
1051: if (checkTimeSpanSet(projectedRequestedDueInSchedule) == null)
1052: return null;
1053: return new Vector(projectedRequestedDueInSchedule);
1054: }
1055:
1056: /** Get the requested due in schedule.
1057: */
1058: public Vector getInactiveRequestedDueInSchedule() {
1059: if (checkTimeSpanSet(inactiveRequestedDueInSchedule) == null)
1060: return null;
1061: return new Vector(inactiveRequestedDueInSchedule);
1062: }
1063:
1064: /** Get the projected requested due in schedule.
1065: */
1066: public Vector getInactiveProjectedRequestedDueInSchedule() {
1067: if (checkTimeSpanSet(inactiveProjectedRequestedDueInSchedule) == null)
1068: return null;
1069: return new Vector(inactiveProjectedRequestedDueInSchedule);
1070: }
1071:
1072: /** Get the schedule that indicates the due-out (allocated)
1073: schedule for a labor asset. This is similar to the due-out
1074: inventory schedule, but uses both the start and end times.
1075: */
1076:
1077: public Vector getDueOutLaborSchedule() {
1078: return getSchedule(dueOutLaborSchedule);
1079: }
1080:
1081: /**
1082: Get the schedule that indicates the due-out inventory for this asset.
1083: The schedule is from the allocations reported results from
1084: the allocations in the role schedules attached to the assets.
1085: @return Vector - the schedule for this asset in this cluster
1086: */
1087:
1088: public Vector getDueOutSchedule() {
1089: return getSchedule(dueOutSchedule);
1090: }
1091:
1092: public Vector getInactiveDueOutSchedule() {
1093: return getSchedule(inactiveDueOutSchedule);
1094: }
1095:
1096: public Vector getProjectedDueOutSchedule() {
1097: return getSchedule(projectedDueOutSchedule);
1098: }
1099:
1100: public Vector getProjectedMockDueOutSchedule() {
1101: return getSchedule(projectedMockDueOutSchedule);
1102: }
1103:
1104: public Vector getInactiveProjectedDueOutSchedule() {
1105: return getSchedule(inactiveProjectedDueOutSchedule);
1106: }
1107:
1108: /* Get allocations to this.asset from the RoleSchedule.
1109: * Create schedule where each element is based on an allocation result. */
1110: private Vector computeDueOutVector(boolean inactive) {
1111: return computeDueOutVectorWVerb(Constants.Verb.Withdraw,
1112: inactive);
1113: }
1114:
1115: /* Get allocations to this.asset from the RoleSchedule.
1116: * Create schedule where each element is based on an allocation result. */
1117: private Vector computeProjectedDueOutVector(boolean inactive) {
1118: return computeDueOutVectorWVerb(Constants.Verb.ProjectWithdraw,
1119: inactive);
1120: }
1121:
1122: /* Get allocations to this.asset from the RoleSchedule.
1123: * Create schedule where each element is based on an allocation result. */
1124: private Vector computeDueOutVectorWVerb(Verb compareVerb,
1125: boolean inactive) {
1126: RoleSchedule roleSchedule = asset.getRoleSchedule();
1127: if (debug) {
1128: System.out.println("UIInventoryImpl-Projected Due Outs:");
1129: }
1130: if (roleSchedule == null) {
1131: System.out
1132: .println("UIInventoryImpl WARNING: no role schedule in asset");
1133: return null;
1134: }
1135: Enumeration e = roleSchedule.getRoleScheduleElements();
1136: if (e == null) {
1137: System.out
1138: .println("UIInventoryImpl WARNING: no role schedule in role schedule");
1139: return null;
1140: }
1141:
1142: Vector due_outs = new Vector();
1143: while (e.hasMoreElements()) {
1144: Allocation allocation = (Allocation) e.nextElement();
1145: Task task = allocation.getTask();
1146: Verb dueOutTaskVerb = task.getVerb();
1147:
1148: if ((dueOutTaskVerb.equals(compareVerb))) {
1149: if (TaskUtils.isProjection(task)) {
1150: Vector projectionScheduleExpansion = getScheduleFromProjectionTask(
1151: task, inactive, allocation);
1152: due_outs.addAll(projectionScheduleExpansion);
1153: } else {
1154: AllocationResult er = allocation
1155: .getEstimatedResult();
1156: UIQuantityScheduleElement el = getScheduleFromAllocation(er);
1157: if ((el != null)
1158: && (isInactive(allocation, el) == inactive)) {
1159: due_outs.addElement(el);
1160: }
1161: }
1162: }
1163: }
1164: return scheduleToNonOverlapVector(due_outs);
1165: }
1166:
1167: private boolean isInactive(Task task, UIQuantityScheduleElement el) {
1168: return isInactive(task, el.getStartTime());
1169: }
1170:
1171: private boolean isInactive(Allocation alloc,
1172: UIQuantityScheduleElement el) {
1173: return isInactive(alloc.getTask(), el.getStartTime());
1174: }
1175:
1176: private boolean isInactive(Allocation alloc, long time) {
1177: return isInactive(alloc.getTask(), time);
1178: }
1179:
1180: private boolean isInactive(Task task, long time) {
1181: if (asset instanceof Inventory) {
1182: Inventory inv = (Inventory) asset;
1183: InventoryPG invpg = inv.getInventoryPG();
1184: /* Keeping the units straight is tricky. There are two time
1185: origins: time zero is the origin of the Java time standard
1186: (January 1970). Inventory start is an arbitrary day boundary
1187: time before interesting things happen to the inventory.
1188: day0 is the day (since time 0) of the start time of the inventory.
1189: today is measured since the start time of the inventory.
1190: (day0 + today) is today since time 0
1191: day is the day (since time 0) of the task.
1192: imputedDay should be the days between today and the day of the task.
1193: imputedDay = day - (day0 + today)
1194: */
1195: int today = invpg.getToday(); // Days since starttime
1196: int day = invpg.convertTimeToDay(time);
1197: int imputedDay = day - today;
1198: double weight = invpg.getProjectionWeight()
1199: .getProjectionWeight(task, imputedDay);
1200:
1201: if (debug) {
1202: Date startDate = new Date(invpg.convertDayToTime(0));
1203: System.out
1204: .println("UIInventoryImpl::isInactive: Weight is "
1205: + weight);
1206: System.out.println("Start time is " + startDate
1207: + " today is (days from them) " + today
1208: + " and time of element is " + day
1209: + " hence imputed is: " + imputedDay);
1210:
1211: }
1212:
1213: return weight < 0.5;
1214: }
1215: return false;
1216: }
1217:
1218: static private Vector scheduleToNonOverlapVector(Vector schedule) {
1219: Vector nonOverlapVector;
1220: // make an alp schedule so we can use the alp utilities
1221: // to make it non-overlapping
1222: if (schedule == null || schedule.size() == 0)
1223: return null;
1224: Schedule tmpCSchedule = getCSchedule(schedule);
1225: return scheduleToNonOverlapVector(tmpCSchedule);
1226: }
1227:
1228: static private Vector scheduleToNonOverlapVector(Schedule schedule) {
1229: Vector nonOverlapVector;
1230: if (debug) {
1231: System.out.println("Original schedule");
1232: printSchedule(schedule);
1233: }
1234: if (isOverlappingSchedule(schedule)) {
1235: Schedule nonoverlapping = ScheduleUtilities
1236: .computeNonOverlappingSchedule(schedule);
1237: nonOverlapVector = scheduleToVector(nonoverlapping);
1238: if (debug) {
1239: System.out
1240: .println("Is Overlapping::Computing non-overlapping schedule");
1241: printSchedule(nonOverlapVector);
1242: }
1243: } else
1244: nonOverlapVector = scheduleToVector(schedule);
1245:
1246: return nonOverlapVector;
1247: }
1248:
1249: private long getPreferredTime(Task task, int aspectType) {
1250: Preference preference = task.getPreference(aspectType);
1251: ScoringFunction scoringFunction = preference
1252: .getScoringFunction();
1253: AspectScorePoint pt = scoringFunction.getBest();
1254: AspectValue aspectValue = pt.getAspectValue();
1255: if (aspectValue instanceof TimeAspectValue)
1256: return ((TimeAspectValue) aspectValue).longValue();
1257: else
1258: return aspectValue.longValue();
1259: }
1260:
1261: private Vector computeRequestedDueOutVector(boolean isInactive) {
1262: return computeRequestedDueOutVectorWVerb(
1263: Constants.Verb.WITHDRAW, isInactive);
1264: }
1265:
1266: private Vector computeProjectedRequestedDueOutVector(
1267: boolean isInactive) {
1268: return computeRequestedDueOutVectorWVerb(
1269: Constants.Verb.PROJECTWITHDRAW, isInactive);
1270: }
1271:
1272: private Vector computeRequestedDueOutVectorWVerb(
1273: String compareVerb, boolean isInactive) {
1274: RoleSchedule roleSchedule = asset.getRoleSchedule();
1275: Vector scheduleElements = new Vector();
1276: if (roleSchedule == null) {
1277: System.out
1278: .println("UIInventoryImpl WARNING: no role schedule in asset");
1279: return null;
1280: }
1281: Enumeration e = roleSchedule.getRoleScheduleElements();
1282: if (e == null) {
1283: System.out
1284: .println("UIInventoryImpl WARNING: no role schedule in role schedule");
1285: return null;
1286: }
1287: while (e.hasMoreElements()) {
1288: Allocation allocation = (Allocation) e.nextElement();
1289: Task task = allocation.getTask();
1290: if (task == null) {
1291: System.out
1292: .println("UIInventoryImpl WARNING: no allocation task in allocation");
1293: continue;
1294: }
1295:
1296: //// If not the right kind of task, then don't compute and add to schedule
1297: if (!(task.getVerb().equals(compareVerb))) {
1298: //System.out.println("UIInventoryImpl::computeRequestedDueOutScheduleWVerb Unexpected verb: " + task.getVerb());
1299: continue;
1300: }
1301: if (TaskUtils.isProjection(task)) {
1302: Vector projectionScheduleExpansion = getScheduleFromProjectionTask(
1303: task, isInactive, null);
1304: scheduleElements.addAll(projectionScheduleExpansion);
1305: } else {
1306: long endTime = getPreferredTime(task,
1307: AspectType.END_TIME);
1308: double quantity = task
1309: .getPreferredValue(AspectType.QUANTITY);
1310: if (debug)
1311: System.out.println("Adding " + compareVerb
1312: + " requested due out task: "
1313: + task.getUID() + " " + quantity + " at "
1314: + new Date(endTime));
1315: // must have end time and quantity
1316: if ((quantity != -1) && (endTime != -1)) {
1317: if (isInactive(task, endTime) == isInactive) {
1318: UIQuantityScheduleElement element;
1319: element = new UIQuantityScheduleElement(
1320: endTime - 1, endTime, quantity);
1321: scheduleElements.addElement(element);
1322: }
1323: }
1324: }
1325: }
1326: return scheduleToNonOverlapVector(scheduleElements);
1327: }
1328:
1329: static private boolean isOverlappingSchedule(Schedule aSchedule) {
1330: if (aSchedule != null) {
1331: Enumeration en = aSchedule.getAllScheduleElements();
1332: if (!en.hasMoreElements())
1333: return false;
1334: long last_time = aSchedule.getStartTime() - 1;
1335: while (en.hasMoreElements()) {
1336: ScheduleElement element = (ScheduleElement) en
1337: .nextElement();
1338: if (element.getStartTime() <= last_time)
1339: return true;
1340: last_time = element.getEndTime();
1341: }
1342: }
1343: return false;
1344: }
1345:
1346: // private boolean isOverlappingSchedule(Schedule aSchedule) {
1347: // long earliestTime = aSchedule.getStartTime();
1348: // long latestTime = aSchedule.getEndTime();
1349: // Calendar calendar = new GregorianCalendar();
1350: // calendar.setTime(new Date(earliestTime));
1351: // Vector scheduleElements = new Vector();
1352: // long time = earliestTime;
1353: // while (time <= latestTime) {
1354: // CountElementsAtTime counter = new CountElementsAtTime(time);
1355: // aSchedule.applyThunkToScheduleElements(counter);
1356: // if (counter.count > 1)
1357: // return true;
1358: // calendar.add(calendar.DAY_OF_YEAR, 1);
1359: // time = calendar.getTime().getTime();
1360: // }
1361: // return false;
1362: // }
1363:
1364: public Vector getRequestedDueOutSchedule() {
1365: return getSchedule(requestedDueOutSchedule);
1366: }
1367:
1368: public Vector getInactiveRequestedDueOutSchedule() {
1369: return getSchedule(inactiveRequestedDueOutSchedule);
1370: }
1371:
1372: public Vector getProjectedRequestedDueOutSchedule() {
1373: return getSchedule(projectedRequestedDueOutSchedule);
1374: }
1375:
1376: public Vector getProjectedRequestedMockDueOutSchedule() {
1377: return getSchedule(projectedRequestedMockDueOutSchedule);
1378: }
1379:
1380: public Vector getInactiveProjectedRequestedDueOutSchedule() {
1381: return getSchedule(inactiveProjectedRequestedDueOutSchedule);
1382: }
1383:
1384: /** Take a schedule of UIQuantityScheduleElements and
1385: make it into an COUGAAR schedule
1386: */
1387:
1388: private static Schedule getCSchedule(Collection mySchedule) {
1389: if (mySchedule == null)
1390: return new ScheduleImpl();
1391: Vector scheduleElements = new Vector();
1392: for (Iterator it = mySchedule.iterator(); it.hasNext();) {
1393: UIQuantityScheduleElement s = (UIQuantityScheduleElement) it
1394: .next();
1395: NewQuantityScheduleElement qse = GLMFactory
1396: .newQuantityScheduleElement();
1397: qse.setStartTime(s.getStartTime());
1398: qse.setEndTime(s.getEndTime());
1399: qse.setQuantity(s.getQuantity());
1400: scheduleElements.addElement(qse);
1401: }
1402: return GLMFactory.newQuantitySchedule(scheduleElements
1403: .elements(), PlanScheduleType.TOTAL_INVENTORY);
1404: }
1405:
1406: // /** Shortfall = requestedDueOut - dueOut (shows as a positive shortage)
1407: // */
1408:
1409: // private void setDueOutShortfallSchedule() {
1410: // if (RequestedDueOutSchedule == null || dueOutSchedule == null)
1411: // return;
1412: // if (dueOutSchedule.size() == 0) {
1413: // if (debug)
1414: // System.out.println("Due out schedule is empty; using requested due out as due out shortfall");
1415: // dueOutShortfallSchedule = dueOutSchedule;
1416: // return;
1417: // }
1418:
1419: // Schedule dueOut = getCSchedule(dueOutSchedule);
1420: // Enumeration scheduleElements =
1421: // RequestedDueOutSchedule.getAllScheduleElements();
1422: // if (!scheduleElements.hasMoreElements()) {
1423: // if (debug) System.out.println("Requested due out schedule is empty; ignoring due out shortfall");
1424: // return;
1425: // }
1426: // Schedule results = ScheduleUtilities.subtractSchedules(dueOut,RequestedDueOutSchedule);
1427: // dueOutShortfallSchedule = scheduleToVector(results);
1428: // }
1429:
1430: // public Vector getDueOutShortfallSchedule() {
1431: // return getSchedule(dueOutShortfallSchedule);
1432: // }
1433:
1434: public Vector getLaborSchedule() {
1435: return getSchedule(laborSchedule);
1436: }
1437:
1438: // for debugging
1439: static private void printSchedule(Schedule s) {
1440: if (s == null)
1441: return;
1442: Enumeration e = s.getAllScheduleElements();
1443: while (e.hasMoreElements()) {
1444: QuantityScheduleElement se = (QuantityScheduleElement) e
1445: .nextElement();
1446: System.out.println("Start date: "
1447: + shortDate(se.getStartTime()) + " end date: "
1448: + shortDate(se.getEndTime()) + " quantity: "
1449: + se.getQuantity());
1450: }
1451: }
1452:
1453: static private void printSchedule(Vector s) {
1454: if (s == null || s.isEmpty()) {
1455: System.out.println("printSchedule() Empty Schedule");
1456: return;
1457: }
1458: Enumeration e = s.elements();
1459: while (e.hasMoreElements()) {
1460: printQuantityScheduleElement((UIQuantityScheduleElement) e
1461: .nextElement());
1462: }
1463: }
1464:
1465: static private void printQuantityScheduleElement(
1466: UIQuantityScheduleElement qse) {
1467: System.out.println("Start date: "
1468: + shortDate(qse.getStartTime()) + " end date: "
1469: + shortDate(qse.getEndTime()) + " quantity: "
1470: + qse.getQuantity());
1471: }
1472:
1473: static private String shortDate(long time) {
1474: String sdate = DateFormat.getDateTimeInstance(DateFormat.SHORT,
1475: DateFormat.SHORT).format(new Date(time));
1476: // map '9/8/00 12:00 AM' to ' 9/8/00 12:00 AM'
1477: while (sdate.length() < 17) {
1478: sdate = " " + sdate;
1479: }
1480: return sdate;
1481: }
1482: }
1483:
1484: class CountElementsAtTime implements org.cougaar.util.Thunk {
1485: private long time;
1486: public int count = 0;
1487:
1488: public CountElementsAtTime(long t) {
1489: time = t;
1490: }
1491:
1492: public void apply(Object o) {
1493: ScheduleElement se = (ScheduleElement) o;
1494: if (time >= se.getStartTime() && time < se.getEndTime()) {
1495: count++;
1496: }
1497: }
1498: }
|