Source Code Cross Referenced for LogisticsInventoryBG.java in  » Science » Cougaar12_4 » org » cougaar » logistics » plugin » inventory » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » Cougaar12_4 » org.cougaar.logistics.plugin.inventory 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.plugin.inventory;
0028:
0029:        import org.cougaar.core.service.LoggingService;
0030:        import org.cougaar.glm.ldm.asset.Inventory;
0031:        import org.cougaar.glm.ldm.asset.NewScheduledContentPG;
0032:        import org.cougaar.glm.ldm.asset.SupplyClassPG;
0033:        import org.cougaar.glm.ldm.GLMFactory;
0034:        import org.cougaar.glm.ldm.plan.AlpineAspectType;
0035:        import org.cougaar.glm.ldm.plan.PlanScheduleType;
0036:        import org.cougaar.glm.ldm.plan.QuantityScheduleElement;
0037:        import org.cougaar.logistics.ldm.Constants;
0038:        import org.cougaar.logistics.plugin.inventory.TimeUtils;
0039:        import org.cougaar.logistics.plugin.utils.ScheduleUtils;
0040:        import org.cougaar.logistics.servlet.LogisticsInventoryServlet;
0041:        import org.cougaar.planning.ldm.asset.PGDelegate;
0042:        import org.cougaar.planning.ldm.asset.PropertyGroup;
0043:        import org.cougaar.planning.ldm.measure.Duration;
0044:        import org.cougaar.planning.ldm.measure.Rate;
0045:        import org.cougaar.planning.ldm.measure.Scalar;
0046:        import org.cougaar.planning.ldm.plan.*;
0047:        import org.cougaar.planning.ldm.plan.AspectType;
0048:        import org.cougaar.planning.plugin.util.PluginHelper;
0049:        import org.cougaar.util.UnaryPredicate;
0050:
0051:        import java.util.*;
0052:
0053:        /** The LogisticsInventoryBG is responsible for maintaining all
0054:         *  information concerning an Inventory Asset.  The Logistics
0055:         *  InventoryBG collects Withdraws, ProjectWithdraws, Supply and
0056:         *  ProjectSupply tasks as well as calculated information such as
0057:         *  inventory levels, refill levels and demand distribution over
0058:         *  time.
0059:         **/
0060:        public class LogisticsInventoryBG implements  PGDelegate {
0061:
0062:            // Bucket will be a knob, this implementation temporary
0063:            private long msec_per_bucket = TimeUtils.MSEC_PER_DAY * 1;
0064:
0065:            protected LogisticsInventoryPG myPG;
0066:            protected transient long startCDay;
0067:            protected long arrivalTime;
0068:            protected long startTime;
0069:            protected long oplanEndTime;
0070:            protected int timeZero;
0071:            private transient LoggingService logger;
0072:            private transient LogisticsInventoryLogger csvLogger = null;
0073:            private transient LogisticsInventoryFormatter csvWriter = null;
0074:            // customerHash holds the time(long) of the last actual is seen
0075:            // for each customer
0076:            private Map customerHash;
0077:            private TaskUtils taskUtils;
0078:
0079:            protected int endOfLevelSixBucket;
0080:            protected List refillProjections;
0081:            protected List overlappingRefillProjections;
0082:            protected List refillRequisitions;
0083:            protected List dueOutList;
0084:            // projectedDemandList mirrors dueOutList, each element
0085:            // contains the sum of all Projected Demand for corresponding
0086:            // bucket in dueOutList
0087:            protected double projectedDemandArray[];
0088:            protected double criticalLevelsArray[];
0089:            protected double inventoryLevelsArray[];
0090:            // Policy inputs
0091:            protected long bucketSize = msec_per_bucket;
0092:            protected int criticalLevel = 3; // num buckets
0093:            protected int reorderPeriod = 3; // num buckets
0094:            protected int ost = 1;
0095:
0096:            // Lists for csv logging & UI support
0097:            protected List projWithdrawList;
0098:            protected List withdrawList;
0099:            protected List projSupplyList;
0100:            protected List supplyList;
0101:            protected List targetLevelsList;
0102:            protected Schedule bufferedTargetLevels;
0103:            protected List actualDemandTasksList;
0104:            protected Schedule bufferedCriticalLevels;
0105:            protected Schedule bufferedInventoryLevels;
0106:            // booleans used for recalculations
0107:            private boolean failures = false;
0108:            private boolean compute_critical_levels = true;
0109:            private boolean regenerate_projected_demand = false;
0110:            private boolean recalculate_initial_level = true;
0111:            protected int deletionBucket = -1;
0112:
0113:            public LogisticsInventoryBG(LogisticsInventoryPG pg) {
0114:                myPG = pg;
0115:                customerHash = new HashMap();
0116:                dueOutList = new ArrayList();
0117:                refillProjections = new ArrayList();
0118:                refillRequisitions = new ArrayList();
0119:                overlappingRefillProjections = new ArrayList();
0120:                projectedDemandArray = new double[180];
0121:                criticalLevelsArray = new double[180];
0122:                inventoryLevelsArray = new double[180];
0123:                Arrays.fill(criticalLevelsArray, Double.NEGATIVE_INFINITY);
0124:                projWithdrawList = new ArrayList();
0125:                withdrawList = new ArrayList();
0126:                projSupplyList = new ArrayList();
0127:                supplyList = new ArrayList();
0128:                targetLevelsList = new ArrayList();
0129:                actualDemandTasksList = new ArrayList();
0130:                endOfLevelSixBucket = 1;
0131:            }
0132:
0133:            public void initialize(long startTime, long oplanEndTime,
0134:                    int criticalLevel, int reorderPeriod, int ost,
0135:                    long bucketSize, long now, boolean logToCSV,
0136:                    InventoryManager parentPlugin) {
0137:                this .startTime = startTime;
0138:                // Set initial level of inventory from time zero to today.  This assumes that the inventory
0139:                // is created because the existence of demand and the RefillGenerator will be run
0140:                // on this inventory before time has advanced, thus the RefillGenerator will set
0141:                // the inventory level for today and in general we always assume that levels prior
0142:                // to today have been set before the RefillGenerator is run
0143:                // Contract: the inventory for yesterday is always valid because initially it is
0144:                // set by the behavior group of the inventory.
0145:                // FSC - HOURLY:
0146:                this .bucketSize = bucketSize;
0147:                msec_per_bucket = this .bucketSize;
0148:                timeZero = (int) ((startTime / msec_per_bucket) - 1);
0149:
0150:                //Initialize with initial level since the refill generator won't start setting inv levels
0151:                //until the first day it processes which is today + OST - so depending on OST it could be a while.
0152:                inventoryLevelsArray[0] = myPG.getInitialLevel();
0153:
0154:                logger = parentPlugin.getLoggingService(this );
0155:                if (logToCSV) {
0156:                    csvLogger = LogisticsInventoryLogger.createInventoryLogger(
0157:                            myPG.getResource(), myPG.getOrg(), false,
0158:                            parentPlugin);
0159:                    csvWriter = new LogisticsInventoryFormatter(csvLogger,
0160:                            new Date(startCDay), parentPlugin);
0161:                }
0162:                taskUtils = parentPlugin.getTaskUtils();
0163:                if (logger.isDebugEnabled()) {
0164:                    logger.debug("Start day: "
0165:                            + TimeUtils.dateString(startTime) + ", time zero "
0166:                            + TimeUtils.dateString(timeZero));
0167:                }
0168:                this .oplanEndTime = oplanEndTime;
0169:                this .criticalLevel = criticalLevel;
0170:                this .reorderPeriod = reorderPeriod;
0171:                this .ost = ost;
0172:                bufferedCriticalLevels = ScheduleUtils
0173:                        .buildSimpleQuantitySchedule(0, startTime, startTime
0174:                                + (TimeUtils.MSEC_PER_DAY * 10));
0175:                bufferedTargetLevels = ScheduleUtils
0176:                        .buildSimpleQuantitySchedule(0, startTime, startTime
0177:                                + (TimeUtils.MSEC_PER_DAY * 10));
0178:                bufferedInventoryLevels = ScheduleUtils
0179:                        .buildSimpleQuantitySchedule(myPG.getInitialLevel(),
0180:                                startTime, startTime
0181:                                        + (TimeUtils.MSEC_PER_DAY * 10));
0182:            }
0183:
0184:            //Call reinitialize which does the default that has to be done
0185:            //on set up after rehydration.   It does the minimum initialization
0186:            //that has to be done, even upon rehydration.
0187:            //which does the initial set up when the inventory is created.
0188:            public void reinitialize(boolean logToCSV,
0189:                    UtilsProvider parentPlugin) {
0190:                logger = parentPlugin.getLoggingService(this );
0191:                if (logToCSV) {
0192:                    csvLogger = LogisticsInventoryLogger.createInventoryLogger(
0193:                            myPG.getResource(), myPG.getOrg(), true,
0194:                            parentPlugin);
0195:                    csvWriter = new LogisticsInventoryFormatter(csvLogger,
0196:                            new Date(startCDay), parentPlugin);
0197:                }
0198:                taskUtils = parentPlugin.getTaskUtils();
0199:            }
0200:
0201:            public void addWithdrawProjection(Task task) {
0202:                if (!task.getVerb().equals(Constants.Verb.PROJECTWITHDRAW)) { // assertion/pre-condition
0203:                    Exception exception = new Exception(
0204:                            "Adding non-PROJECTWITHDRAW task to inventory BG");
0205:                    if (logger.isErrorEnabled()) {
0206:                        logger
0207:                                .error(
0208:                                        ".addWithdrawProjection - adding non-PROJECTWITHDRAW task "
0209:                                                + task + " to inventory BG.",
0210:                                        exception);
0211:                    }
0212:                }
0213:
0214:                long start = taskUtils.getStartTime(task);
0215:                long end = taskUtils.getEndTime(task);
0216:                // THIS ONE
0217:                int bucket_start = convertTimeToBucket(start, false);
0218:                int bucket_end = convertTimeToBucket(end, true);
0219:                // Adding projections mean changed critical levels and
0220:                // target levels.  Set boolean to recompute critical
0221:                // levels and clear targetLevelsList for CSV logging
0222:                compute_critical_levels = true;
0223:
0224:                // StartBucket for the inventory is the first bucket which has not seen any deletions
0225:                // It is possible to have a case where a projection is added to buckets in the past
0226:                // because the allocation results on a projection can change until the end of the
0227:                // task which may still be in the future.  Allow projections to be added to buckets
0228:                // in the past but not to buckets before the start bucket of the inventory.
0229:                if (bucket_start < getStartBucket()) {
0230:                    if (bucket_end < getStartBucket()) {
0231:                        if (logger.isErrorEnabled()) {
0232:                            logger
0233:                                    .error("addWithdrawProjection not adding old projection. startBucket is "
0234:                                            + TimeUtils
0235:                                                    .dateString(convertBucketToTime(getStartBucket()))
0236:                                            + ", task "
0237:                                            + taskUtils.taskDesc(task));
0238:
0239:                        }
0240:                        return;
0241:                    } else {
0242:                        if (logger.isInfoEnabled()) {
0243:                            logger
0244:                                    .info("addWithdrawProjection not adding projection to deleted buckets. "
0245:                                            + "startBucket is "
0246:                                            + TimeUtils
0247:                                                    .dateString(convertBucketToTime(getStartBucket()))
0248:                                            + ", task "
0249:                                            + taskUtils.taskDesc(task));
0250:                        }
0251:                        bucket_start = getStartBucket();
0252:                    }
0253:                }
0254:
0255:                //If this new projection effects the initial level demand then recalc.
0256:                if ((bucket_start <= getInitialLevelDemandEndBucket())
0257:                        && (bucket_end >= convertTimeToBucket(arrivalTime,
0258:                                false))) {
0259:                    recalculate_initial_level = true;
0260:                }
0261:
0262:                if (bucket_end >= projectedDemandArray.length) {
0263:                    projectedDemandArray = expandArray(projectedDemandArray,
0264:                            bucket_end);
0265:                }
0266:                while (bucket_end >= dueOutList.size()) {
0267:                    dueOutList.add(new ArrayList());
0268:                }
0269:                for (int i = bucket_start; i < bucket_end; i++) {
0270:                    List list = (List) dueOutList.get(i);
0271:                    list.add(task);
0272:                    updateProjectedDemandList(task, i, start, end, true);
0273:                }
0274:            }
0275:
0276:            public void addWithdrawRequisition(Task task) {
0277:                if (!task.getVerb().equals(Constants.Verb.WITHDRAW)) { // assertion/pre-condition
0278:                    Exception exception = new Exception(
0279:                            "Adding non-WITHDRAW task to inventory BG");
0280:                    logger.error(
0281:                            ".addWithdrawRequisition - adding non-WITHDRAW task "
0282:                                    + task + " to inventory BG.", exception);
0283:                }
0284:
0285:                long endTime = taskUtils.getEndTime(task);
0286:                int bucket = convertTimeToBucket(endTime, false);
0287:                if (bucket < getStartBucket()) {
0288:                    if (logger.isErrorEnabled()) {
0289:                        logger
0290:                                .error("addWithdrawRequisition not adding old requisition. startBucket is "
0291:                                        + TimeUtils
0292:                                                .dateString(convertBucketToTime(getStartBucket()))
0293:                                        + ", task " + taskUtils.taskDesc(task));
0294:                    }
0295:                    return;
0296:                }
0297:                Object org = TaskUtils.getCustomer(task);
0298:                if (org != null) {
0299:                    Long lastActualSeen = (Long) customerHash.get(org);
0300:                    if ((lastActualSeen == null)
0301:                            || (endTime > lastActualSeen.longValue())) {
0302:                        customerHash.put(org, new Long(endTime));
0303:                    }
0304:                }
0305:                while (bucket >= dueOutList.size()) {
0306:                    dueOutList.add(new ArrayList());
0307:                }
0308:                List list = (List) dueOutList.get(bucket);
0309:                list.add(task);
0310:            }
0311:
0312:            private void regenerateProjectedDemandList() {
0313:                // clear out old demand
0314:                //         Arrays.fill(projectedDemandArray, 0.0);
0315:                Arrays.fill(projectedDemandArray, getStartBucket(),
0316:                        projectedDemandArray.length - 1, 0.0);
0317:                int size = dueOutList.size();
0318:                for (int i = 0; i < size; i++) {
0319:                    Collection list = getProjectedDemandTasks(i);
0320:                    Iterator list_itr = list.iterator();
0321:                    while (list_itr.hasNext()) {
0322:                        Task task = (Task) list_itr.next();
0323:                        long start = taskUtils.getStartTime(task);
0324:                        long end = taskUtils.getEndTime(task);
0325:                        updateProjectedDemandList(task, i, start, end, true);
0326:                    }
0327:                }
0328:            }
0329:
0330:            // ******* HERE LIES A BUG
0331:            // Boundary condition bug - daily projected demands do not
0332:            // jive when comparing daily buckets to 3-day buckets
0333:            // Updates the running demand sum per bucket
0334:            // AHF 7/31/02 - The bug actually is in the adding of the projection for multiple day buckets
0335:            //  see bug #1823
0336:            private void updateProjectedDemandList(Task task, int bucket,
0337:                    long start, long end, boolean add) {
0338:                if (bucket < 0) {
0339:                    logger.error("updateProjectedDemandList got bucket "
0340:                            + bucket + " for task " + task, new Throwable());
0341:                    bucket = 0;
0342:                }
0343:                if (bucket < getStartBucket()) {
0344:                    if (logger.isInfoEnabled()) {
0345:                        logger
0346:                                .info("updateProjectedDemandList not adding demand for old projection. startBucket is "
0347:                                        + TimeUtils
0348:                                                .dateString(convertBucketToTime(getStartBucket()))
0349:                                        + ", task " + taskUtils.taskDesc(task));
0350:                    }
0351:                    return;
0352:                }
0353:                double demand = getProjectionTaskDemand(task, bucket, start,
0354:                        end);
0355:                if (add) {
0356:                    if (bucket >= projectedDemandArray.length) {
0357:                        projectedDemandArray = expandArray(
0358:                                projectedDemandArray, bucket);
0359:                    }
0360:                    projectedDemandArray[bucket] += demand;
0361:                } else {
0362:                    projectedDemandArray[bucket] -= demand;
0363:                }
0364:                //      logger.error("Bucket "+bucket+": new demand "+demand+", total is "+
0365:                //               projectedDemandArray[bucket]);
0366:            }
0367:
0368:            public double getProjectionTaskDemand(Task task, int bucket,
0369:                    long start, long end) {
0370:                // get the time spanned (if any) for this task within the specified bucket
0371:                long bucket_start = convertBucketToTime(bucket);
0372:                long bucket_end = bucket_start + msec_per_bucket;
0373:                long interval_start = Math.max(start, bucket_start);
0374:                long interval_end = Math.min(end, bucket_end);
0375:                long time_spanned = interval_end - interval_start;
0376:                if (time_spanned <= 0) {
0377:                    // this bucket does not fall into the task's start..end timespan, so
0378:                    // there is no demand for this bucket
0379:                    return 0.0;
0380:                } else if (time_spanned > bucketSize) {
0381:                    logger.error("time_spanned " + time_spanned
0382:                            + " exceeds bucketSize " + bucketSize
0383:                            + " for task " + task.getUID());
0384:                    return 0.0;
0385:                }
0386:                // return the demand within the overlap interval
0387:                Rate rate = taskUtils.getRate(task, interval_start,
0388:                        interval_end);
0389:                Duration d = Duration.newMilliseconds((double) time_spanned);
0390:                Scalar scalar = (Scalar) rate.computeNumerator(d);
0391:                return taskUtils.getDouble(scalar);
0392:            }
0393:
0394:            public void removeWithdrawRequisition(Task task) {
0395:                if (task.isDeleted()) {
0396:                    int end_bucket = convertTimeToBucket(taskUtils
0397:                            .getReportedEndTime(task), false);
0398:                    if (logger.isDebugEnabled()) {
0399:                        logger.debug("Removing task "
0400:                                + taskUtils.taskDesc(task));
0401:                    }
0402:                    setDeletionBucket(end_bucket);
0403:                }
0404:                for (int i = 0; i < dueOutList.size(); i++) {
0405:                    List list = (List) dueOutList.get(i);
0406:                    if (list != null) {
0407:                        list.remove(task);
0408:                    }
0409:                }
0410:            }
0411:
0412:            /** Called by SupplyExpander to remove a Withdraw task that has either
0413:             *  been rescinded or changed.
0414:             *  @param task  The ProjectWithdraw task being removed
0415:             **/
0416:            // TODO possible gotcha - only removing the deleted task from reported end time back.
0417:            //      could it be hiding somewhere else in the list - TEST
0418:            public void removeWithdrawProjection(Task task) {
0419:                if (task.isDeleted()) {
0420:                    int end_bucket = convertTimeToBucket(taskUtils
0421:                            .getReportedEndTime(task), true);
0422:                    if (logger.isDebugEnabled()) {
0423:                        logger.debug("Removing task "
0424:                                + taskUtils.taskDesc(task));
0425:                    }
0426:                    setDeletionBucket(end_bucket - 1);
0427:                } else {
0428:                    compute_critical_levels = true;
0429:                    recalculate_initial_level = true;
0430:                    regenerate_projected_demand = true;
0431:                }
0432:                List list;
0433:                for (int i = 0; i < dueOutList.size(); i++) {
0434:                    list = (List) dueOutList.get(i);
0435:                    if (list != null) {
0436:                        list.remove(task);
0437:                    }
0438:                }
0439:            }
0440:
0441:            /** Called by all methods which remove tasks from lists.
0442:             *  When a task is deleted, the last affected bucket back to the beginning of
0443:             *  list are emptied IFF the buckets have not already been emptied.
0444:             *  @param bucket Last effected bucket by task deletion
0445:             **/
0446:            protected void setDeletionBucket(int bucket) {
0447:                if (bucket > deletionBucket) {
0448:                    deletionBucket = bucket;
0449:                }
0450:            }
0451:
0452:            public void addRefillRequisition(Task task) {
0453:                boolean taskAdded = false;
0454:
0455:                PlanElement pe = task.getPlanElement();
0456:                if (pe != null) {
0457:                    AllocationResult ar = pe.getReportedResult();
0458:                    if (ar == null) {
0459:                        ar = pe.getEstimatedResult();
0460:                    }
0461:                    if (ar != null) {
0462:                        if (!ar.isPhased()) {
0463:                            long endTime = taskUtils.getReportedEndTime(task);
0464:                            addTaskToBucket(endTime, task);
0465:                            taskAdded = true;
0466:                        } else {
0467:                            int[] ats = ar.getAspectTypes();
0468:                            int endInd = csvWriter.getIndexForType(ats,
0469:                                    AspectType.END_TIME);
0470:                            Enumeration phasedResults = ar.getPhasedResults();
0471:                            while (phasedResults.hasMoreElements()) {
0472:                                double[] results = (double[]) phasedResults
0473:                                        .nextElement();
0474:                                long phasedEndTime;
0475:                                phasedEndTime = (long) results[endInd];
0476:                                addTaskToBucket(phasedEndTime, task);
0477:                                taskAdded = true;
0478:                            }
0479:                        }
0480:                    }
0481:                }
0482:                if (!taskAdded) {
0483:                    long endTime = taskUtils.getReportedEndTime(task);
0484:                    addTaskToBucket(endTime, task);
0485:                }
0486:            }
0487:
0488:            private void addTaskToBucket(long endTime, Task task) {
0489:                // probably can factor this out into a separate method.
0490:                int bucket = convertTimeToBucket(endTime, false);
0491:                if (bucket < getStartBucket()) {
0492:                    if (logger.isErrorEnabled()) {
0493:                        logger
0494:                                .error("addRefillRequisition not adding old requisition. startBucket is "
0495:                                        + TimeUtils
0496:                                                .dateString(convertBucketToTime(getStartBucket()))
0497:                                        + ", task " + taskUtils.taskDesc(task));
0498:                    }
0499:                    return;
0500:                }
0501:                while (bucket >= refillRequisitions.size()) {
0502:                    refillRequisitions.add(null);
0503:                }
0504:
0505:                //MWD Debugging
0506:                List refills = (List) refillRequisitions.get(bucket);
0507:                if (refills == null) {
0508:                    refills = new ArrayList();
0509:                    refillRequisitions.set(bucket, refills);
0510:                }
0511:                refills.add(task);
0512:            }
0513:
0514:            public int getLastWithdrawBucket() {
0515:                Iterator list = customerHash.values().iterator();
0516:                long lastSeen = convertBucketToTime(1);
0517:                while (list.hasNext()) {
0518:                    long time = ((Long) list.next()).longValue();
0519:                    if (lastSeen < time) {
0520:                        lastSeen = time;
0521:                    }
0522:                }
0523:                return convertTimeToBucket(lastSeen, false);
0524:            }
0525:
0526:            private int getInitialLevelDemandEndBucket() {
0527:                if (myPG.getSupplierArrivalTime() == -1) {
0528:                    return -1;
0529:                }
0530:                int supplierAvailableBucket = convertTimeToBucket(myPG
0531:                        .getSupplierArrivalTime(), false);
0532:
0533:                //At the top of the supply chain 191-ORDBN has a
0534:                //supplier available bucket that is 8/15 which is before its
0535:                //arrival time.  The supplier is only truly available to you
0536:                //once you arrive.
0537:                int arrivalBucket = convertTimeToBucket(arrivalTime, false);
0538:                if (supplierAvailableBucket < arrivalBucket) {
0539:                    supplierAvailableBucket = arrivalBucket;
0540:                }
0541:
0542:                //Test case where first bucket of demand is beyone the supplierAvailableBucket
0543:                //then we should make sure we cover the 1st days of demand with the ost amount of demand.
0544:                int firstDemandBucket = getFirstProjectWithdrawBucket();
0545:                if (firstDemandBucket > supplierAvailableBucket) {
0546:                    supplierAvailableBucket = firstDemandBucket;
0547:                }
0548:
0549:                //The end of the horizon lookahead to compute the initial level
0550:                int initialLevelDemandEndBucket = supplierAvailableBucket + ost
0551:                        + criticalLevel;
0552:
0553:                return initialLevelDemandEndBucket;
0554:            }
0555:
0556:            private double getDemandDerivedInitialLevel() {
0557:                //Not sure if this should be false or true.
0558:                int startBucket = convertTimeToBucket(arrivalTime, false);
0559:                //This includes the critical level and order ship time.
0560:                int endBucket = getInitialLevelDemandEndBucket();
0561:                if (endBucket == -1) {
0562:                    return -1.0;
0563:                }
0564:                double totalDemand = 0.0;
0565:                for (int i = startBucket; i <= endBucket; i++) {
0566:                    totalDemand += getProjectedDemand(i);
0567:                }
0568:                //Round up, no matter, to the next larger whole integer
0569:                //This is done mainly for class IX components, whose demand
0570:                //is fractional - but we reorder actuals in whole numbers.
0571:                totalDemand = Math.ceil(totalDemand);
0572:                return totalDemand;
0573:            }
0574:
0575:            public int getFirstProjectWithdrawBucket() {
0576:                Iterator list = customerHash.values().iterator();
0577:                // if we don't have any actual demand signal with -1
0578:                if (!list.hasNext()) {
0579:                    return -1;
0580:                }
0581:                long firstSeen = convertBucketToTime(dueOutList.size() - 1);
0582:                while (list.hasNext()) {
0583:                    long time = ((Long) list.next()).longValue();
0584:                    if (firstSeen > time) {
0585:                        firstSeen = time;
0586:                    }
0587:                }
0588:                // return the bucket after the first seen actual's end time bucket
0589:                return (convertTimeToBucket(firstSeen, false) + 1);
0590:            }
0591:
0592:            public int getLastRefillRequisition() {
0593:                int lastRefill = -1;
0594:                for (int i = 0; i < refillRequisitions.size(); i++) {
0595:                    List refills = (List) refillRequisitions.get(i);
0596:                    if ((refills != null) && (refills.size() > 0)) {
0597:                        //The last refill is actually the target date for it's arrival,
0598:                        //because thats what the refill generator is planning on.
0599:                        for (int j = 0; j < refills.size(); j++) {
0600:                            Task task = (Task) refills.get(j);
0601:                            //taskUtils.getEndTime() returns the preference (the best time)
0602:                            int endBucket = convertTimeToBucket(taskUtils
0603:                                    .getEndTime(task), false);
0604:                            lastRefill = Math.max(endBucket, lastRefill);
0605:                        }
0606:                        //Put above for loop and code in to replace line below this
0607:                        //because we were counting all the projections from an early arrival
0608:                        //to the request date of a last refill.
0609:                        //lastRefill = i;
0610:                    }
0611:                }
0612:                return lastRefill;
0613:            }
0614:
0615:            public int getLastDemandBucket() {
0616:                return dueOutList.size() - 1;
0617:            }
0618:
0619:            public void setEndOfLevelSixBucket(int bucket) {
0620:                endOfLevelSixBucket = bucket;
0621:            }
0622:
0623:            public void setArrivalTime(long anArrivalTime) {
0624:                this .arrivalTime = anArrivalTime;
0625:            }
0626:
0627:            public long getArrivalTime() {
0628:                return arrivalTime;
0629:            }
0630:
0631:            public void setStartCDay(long startCTime) {
0632:                this .startCDay = startCTime;
0633:            }
0634:
0635:            public int getEndOfLevelSixBucket() {
0636:                return endOfLevelSixBucket;
0637:            }
0638:
0639:            public void addRefillProjection(Task task) {
0640:                long start = taskUtils.getReportedStartTime(task);
0641:                long end = taskUtils.getReportedEndTime(task);
0642:                // Test for Failed Dispositions Bug #2033
0643:                if (start == 0L) {
0644:                    return;
0645:                }
0646:                int bucket_start = convertTimeToBucket(start, false);
0647:                int bucket_end = convertTimeToBucket(end, true);
0648:                // StartBucket for the inventory is the first bucket which has not seen any deletions
0649:                // It is possible to have a case where a projection is added to buckets in the past
0650:                // because the allocation results on a projection can change until the end of the
0651:                // task which may still be in the future.  Allow projections to be added to buckets
0652:                // in the past but not to buckets before the start bucket of the inventory.
0653:                if (bucket_start < getStartBucket()) {
0654:                    if (bucket_end < getStartBucket()) {
0655:                        if (logger.isErrorEnabled()) {
0656:                            logger
0657:                                    .error("addRefillProjection not adding old projection. startBucket is "
0658:                                            + TimeUtils
0659:                                                    .dateString(convertBucketToTime(getStartBucket()))
0660:                                            + ", task "
0661:                                            + taskUtils.taskDesc(task));
0662:
0663:                        }
0664:                        return;
0665:                    } else {
0666:                        if (logger.isInfoEnabled()) {
0667:                            logger
0668:                                    .info("addRefillProjection not adding projection to deleted buckets. "
0669:                                            + "startBucket is "
0670:                                            + TimeUtils
0671:                                                    .dateString(convertBucketToTime(getStartBucket()))
0672:                                            + ", task "
0673:                                            + taskUtils.taskDesc(task));
0674:                        }
0675:                        bucket_start = getStartBucket();
0676:                    }
0677:                }
0678:
0679:                while (bucket_end >= refillProjections.size()) {
0680:                    refillProjections.add(null);
0681:                }
0682:                for (int i = bucket_start; i < bucket_end; i++) {
0683:                    List refills = (List) refillProjections.get(i);
0684:                    if (refills == null) {
0685:                        refills = new ArrayList();
0686:                        refillProjections.set(i, refills);
0687:                    }
0688:                    if (!refills.contains(task)) {
0689:                        refills.add(task);
0690:                    }
0691:                }
0692:            }
0693:
0694:            public void removeRefillProjection(Task task) {
0695:                if (task.isDeleted()) {
0696:                    int end_bucket = convertTimeToBucket(taskUtils
0697:                            .getReportedEndTime(task), true);
0698:                    if (logger.isDebugEnabled()) {
0699:                        logger.debug("Removing task "
0700:                                + taskUtils.taskDesc(task));
0701:                    }
0702:                    setDeletionBucket(end_bucket - 1);
0703:                }
0704:                removeTask(refillProjections, task);
0705:            }
0706:
0707:            public void removeRefillRequisition(Task task) {
0708:                if (task.isDeleted()) {
0709:                    int end_bucket = convertTimeToBucket(taskUtils
0710:                            .getReportedEndTime(task), false);
0711:                    if (logger.isDebugEnabled()) {
0712:                        logger.debug("Removing task "
0713:                                + taskUtils.taskDesc(task));
0714:                    }
0715:                    setDeletionBucket(end_bucket);
0716:                }
0717:                removeTask(refillRequisitions, task);
0718:            }
0719:
0720:            public List clearRefillTasks(final Date now) {
0721:                // remove uncommitted refill tasks. Add all removed
0722:                // tasks to a second list that will be returned
0723:                // for comparison
0724:                UnaryPredicate p = new UnaryPredicate() {
0725:                    public boolean execute(Object o) {
0726:                        return shouldClearRefill((Task) o, now);
0727:                    }
0728:                };
0729:                return removeTasks(refillRequisitions, p);
0730:            }
0731:
0732:            private boolean shouldClearRefill(Task t, Date now) {
0733:                return (t != null && t.beforeCommitment(now));
0734:            }
0735:
0736:            // clear the projections
0737:            // and return the removed tasks for comparison
0738:            // also keep a list of overlapping refill projection tasks
0739:            public List clearRefillProjectionTasks(final long now) {
0740:                overlappingRefillProjections.clear();
0741:
0742:                UnaryPredicate p = new UnaryPredicate() {
0743:                    public boolean execute(Object o) {
0744:                        return shouldClearProjection((Task) o, now);
0745:                    }
0746:                };
0747:                return removeTasks(refillProjections, p);
0748:            }
0749:
0750:            private boolean shouldClearProjection(Task t, long now) {
0751:                if (t == null) {
0752:                    return false;
0753:                }
0754:                long start = taskUtils.getStartTime(t);
0755:                if (start >= now) {
0756:                    return true;
0757:                }
0758:                if ((start < now) && (taskUtils.getEndTime(t) > now)) {
0759:                    //this task spans now - shorten it
0760:                    if (!overlappingRefillProjections.contains(t)) {
0761:                        overlappingRefillProjections.add(t);
0762:                    }
0763:                }
0764:                return false;
0765:            }
0766:
0767:            private void removeTask(List allTasks, Task task) {
0768:                for (int i = 0; i < allTasks.size(); i++) {
0769:                    List tasks = (List) allTasks.get(i);
0770:                    if (tasks != null && tasks.remove(task) && tasks.size() < 1) {
0771:                        allTasks.set(i, null);
0772:                    }
0773:                }
0774:            }
0775:
0776:            // a generic task removal function:
0777:            private List removeTasks(List allTasks, UnaryPredicate pred) {
0778:                List removed = new ArrayList();
0779:                for (int i = 0; i < allTasks.size(); i++) {
0780:                    List tasks = (List) allTasks.get(i);
0781:                    if (tasks == null) {
0782:                        continue;
0783:                    }
0784:                    List pending = null;
0785:                    for (int j = 0; j < tasks.size(); j++) {
0786:                        Task t = (Task) tasks.get(j);
0787:                        if (!pred.execute(t)) {
0788:                            continue;
0789:                        }
0790:                        if (pending == null) {
0791:                            pending = new ArrayList(tasks.size() - j);
0792:                        }
0793:                        if (!pending.contains(t)) {
0794:                            pending.add(t);
0795:                        }
0796:                        if (!removed.contains(t)) {
0797:                            removed.add(t);
0798:                        }
0799:                    }
0800:                    if (pending != null) {
0801:                        tasks.removeAll(pending);
0802:                    }
0803:                    if (tasks.isEmpty()) {
0804:                        allTasks.set(i, null);
0805:                    }
0806:                }
0807:                return removed;
0808:            }
0809:
0810:            public List getOverlappingRefillProjections() {
0811:                return (List) ((ArrayList) overlappingRefillProjections)
0812:                        .clone();
0813:            }
0814:
0815:            private List getFlattenedList(List listOLists) {
0816:                List uniqueTasks = new ArrayList();
0817:                for (int i = 0; i < listOLists.size(); i++) {
0818:                    List list = (List) listOLists.get(i);
0819:                    if (list != null) {
0820:                        for (int j = 0; j < list.size(); j++) {
0821:                            Task task = (Task) list.get(j);
0822:                            if (!uniqueTasks.contains(task)) {
0823:                                uniqueTasks.add(task);
0824:                            }
0825:                        }
0826:                    }
0827:                }
0828:                return uniqueTasks;
0829:            }
0830:
0831:            private List deepClone(List listOLists) {
0832:                List clone = new ArrayList(listOLists.size());
0833:                for (int i = 0; i < listOLists.size(); i++) {
0834:                    List list = (List) listOLists.get(i);
0835:                    if (list != null) {
0836:                        list = (List) ((ArrayList) list).clone();
0837:                    }
0838:                    clone.add(i, list);
0839:                }
0840:                return clone;
0841:            }
0842:
0843:            public ArrayList getRefillRequisitions() {
0844:                return (ArrayList) ((ArrayList) refillRequisitions).clone();
0845:            }
0846:
0847:            public ArrayList getRefillProjection(int bucket) {
0848:                // make sure the bucket doesn't cause an array out of bounds
0849:                if (bucket < refillProjections.size()) {
0850:                    return (ArrayList) refillProjections.get(bucket);
0851:                } else {
0852:                    return null;
0853:                }
0854:            }
0855:
0856:            public double getCriticalLevel(int bucket) {
0857:                if (compute_critical_levels) {
0858:                    computeCriticalLevels();
0859:                    compute_critical_levels = false;
0860:                }
0861:                if ((bucket >= 0) && (bucket < criticalLevelsArray.length)) {
0862:                    return criticalLevelsArray[bucket];
0863:                }
0864:                return 0.0;
0865:            }
0866:
0867:            public void recalculateInitialLevel() {
0868:                double newInitialLevel = getDemandDerivedInitialLevel();
0869:                if ((recalculate_initial_level) && (getStartBucket() == 0)) {
0870:                    if (newInitialLevel != -1.0) {
0871:                        inventoryLevelsArray[0] = newInitialLevel;
0872:                    }
0873:                }
0874:                recalculate_initial_level = false;
0875:            }
0876:
0877:            private double[] computeCriticalLevels() {
0878:                if (regenerate_projected_demand) {
0879:                    regenerateProjectedDemandList();
0880:                    regenerate_projected_demand = false;
0881:                }
0882:                double Ci;
0883:                criticalLevelsArray = new double[projectedDemandArray.length];
0884:                // criticalLevel falls within a single bucket
0885:                if (criticalLevel == 1) {
0886:                    for (int i = 0; // i = getStartBucket();
0887:                    i < projectedDemandArray.length; i++) {
0888:                        Ci = getProjectedDemand(i);
0889:                        criticalLevelsArray[i] = Ci;
0890:                    }
0891:                } else { // criticalLevel spans multiple buckets
0892:                    //           int start = (getStartBucket() > 1) ? getStartBucket() : 1;
0893:                    int start = 1;
0894:                    int buckets = criticalLevel;
0895:                    Ci = 0.0;
0896:                    for (int i = start; i <= buckets; i++) {
0897:                        Ci += getProjectedDemand(i);
0898:                    }
0899:                    criticalLevelsArray[0] = Ci;
0900:                    for (int i = start; i < projectedDemandArray.length
0901:                            - buckets - 1; i++) {
0902:                        Ci = Ci - getProjectedDemand(i)
0903:                                + getProjectedDemand(i + buckets);
0904:                        if (Ci < 0.0) {
0905:                            Ci = 0.0;
0906:                        }
0907:                        criticalLevelsArray[i] = Ci;
0908:                    }
0909:                    // TODO may want to test start bucket here too but I'm on the fence
0910:                    for (int i = projectedDemandArray.length - buckets - 1; i < projectedDemandArray.length; i++) {
0911:                        Ci = Ci - getProjectedDemand(i);
0912:                        if (Ci < 0.0) {
0913:                            Ci = 0.0;
0914:                        }
0915:                        criticalLevelsArray[i] = Ci;
0916:                    }
0917:                }
0918:
0919:                //No critical level before we arrive in theatre.
0920:                //We're not supposed to order refills before we arrive in theatre.
0921:                int arrivalTimeBucket = convertTimeToBucket(arrivalTime, false);
0922:                for (int i = getStartBucket(); i < arrivalTimeBucket; i++) {
0923:                    criticalLevelsArray[i] = 0.0;
0924:                }
0925:
0926:                return criticalLevelsArray;
0927:            }
0928:
0929:            public double getLevel(int bucket) {
0930:                if (bucket < 0) {
0931:                    logger.error("getLevel asked for level at bucket " + bucket
0932:                            + " when inventoryLevelsArray has length "
0933:                            + inventoryLevelsArray.length, new Throwable());
0934:                    return inventoryLevelsArray[0];
0935:                }
0936:                if (bucket >= inventoryLevelsArray.length) {
0937:                    return inventoryLevelsArray[inventoryLevelsArray.length - 1];
0938:                }
0939:                return inventoryLevelsArray[bucket];
0940:            }
0941:
0942:            public void setLevel(int bucket, double value) {
0943:                if (bucket < getStartBucket()) {
0944:                    if (bucket < 0) {
0945:                        if (logger.isErrorEnabled()) {
0946:                            logger.error("setLevel called with bucket "
0947:                                    + bucket + " when startBucket is "
0948:                                    + getStartBucket(), new Throwable());
0949:                        }
0950:                    }
0951:                    if (logger.isDebugEnabled()) {
0952:                        logger.debug("setLevel called with bucket " + bucket
0953:                                + " when startBucket is " + getStartBucket());
0954:                    }
0955:                    return;
0956:                }
0957:                if (bucket >= inventoryLevelsArray.length) {
0958:                    inventoryLevelsArray = expandArray(inventoryLevelsArray,
0959:                            bucket);
0960:                }
0961:                //Potentially if you reset the first inventory level bucket, you
0962:                //will want to reset it on the next refillGenerator call to recalculate
0963:                if (bucket == 0) {
0964:                    recalculate_initial_level = true;
0965:                }
0966:                inventoryLevelsArray[bucket] = value;
0967:            }
0968:
0969:            public void setTarget(int bucket, double value) {
0970:                if (bucket < getStartBucket()) {
0971:                    if (bucket < 0) {
0972:                        if (logger.isErrorEnabled()) {
0973:                            logger.error("setTarget called with bucket "
0974:                                    + bucket + " and value " + value,
0975:                                    new Throwable());
0976:                        }
0977:                    }
0978:                    if (logger.isDebugEnabled()) {
0979:                        logger.debug("setTarget called with bucket " + bucket
0980:                                + " when startBucket is " + getStartBucket());
0981:                    }
0982:                    return;
0983:                }
0984:                // The intention of the List is to hold values for the buckets
0985:                // that have target levels and hold nulls for those buckets that
0986:                // do not have a target level
0987:                int len = targetLevelsList.size();
0988:                if (bucket >= len) {
0989:                    for (int i = len; i < bucket + 20; i++) {
0990:                        targetLevelsList.add(null);
0991:                    }
0992:                }
0993:                targetLevelsList.set(bucket, new Double(value));
0994:            }
0995:
0996:            public void clearTargetLevels(int startBucket) {
0997:                if (startBucket < 0) {
0998:                    if (logger.isErrorEnabled()) {
0999:                        logger.error(
1000:                                "clearTargetLevels called with startBucket "
1001:                                        + startBucket, new Throwable());
1002:                    }
1003:                    startBucket = 0;
1004:                }
1005:                if (logger.isDebugEnabled()) {
1006:                    logger
1007:                            .debug(getOrgName()
1008:                                    + " clearTargetLevels called with bucket "
1009:                                    + TimeUtils
1010:                                            .dateString(convertBucketToTime(startBucket))
1011:                                    + " when start bucket is "
1012:                                    + TimeUtils
1013:                                            .dateString(convertBucketToTime(getStartBucket())));
1014:                }
1015:                // Below will be replaced by the following once debugging is complete
1016:                // startBucket = (startBucket < getStartBucket()) ? getStartBucket() : startBucket;
1017:                if (startBucket < getStartBucket()) {
1018:                    startBucket = getStartBucket();
1019:                }
1020:
1021:                // Clear target levels from the given bucket to end of array
1022:                int len = targetLevelsList.size();
1023:                for (int i = startBucket; i < len; i++) {
1024:                    targetLevelsList.set(i, null);
1025:                }
1026:            }
1027:
1028:            public void updateRefillRequisition(Task task) {
1029:                removeRefillRequisition(task);
1030:                addRefillRequisition(task);
1031:            }
1032:
1033:            public void updateRefillProjection(Task task) {
1034:                removeRefillProjection(task);
1035:                addRefillProjection(task);
1036:            }
1037:
1038:            public void updateWithdrawRequisition(Task task) {
1039:                removeWithdrawRequisition(task);
1040:                addWithdrawRequisition(task);
1041:            }
1042:
1043:            public void updateWithdrawProjection(Task task) {
1044:                removeWithdrawProjection(task);
1045:                addWithdrawProjection(task);
1046:            }
1047:
1048:            public double getProjectedDemand(int bucket) {
1049:                if (regenerate_projected_demand) {
1050:                    regenerateProjectedDemandList();
1051:                    regenerate_projected_demand = false;
1052:                }
1053:                if ((bucket >= projectedDemandArray.length) || (bucket < 0)) {
1054:                    return 0.0;
1055:                }
1056:                return projectedDemandArray[bucket];
1057:            }
1058:
1059:            public Collection getProjectedDemandTasks(int bucket) {
1060:                return getTasks(bucket, Constants.Verb.PROJECTWITHDRAW);
1061:            }
1062:
1063:            public double getActualDemand(int bucket) {
1064:                if (bucket >= dueOutList.size()) {
1065:                    return 0.0;
1066:                }
1067:                long bucket_start = convertBucketToTime(bucket);
1068:                long bucket_end = bucket_start + msec_per_bucket;
1069:
1070:                double actualDemand = 0.0;
1071:                for (Iterator list = ((List) dueOutList.get(bucket)).iterator(); list
1072:                        .hasNext();) {
1073:                    Task task = (Task) list.next();
1074:                    long firstProjectionTime = getFirstProjectionTime(task);
1075:                    actualDemand += taskUtils.getActualDemand(task,
1076:                            bucket_start, bucket_end, firstProjectionTime);
1077:                }
1078:                return actualDemand;
1079:            }
1080:
1081:            public Collection getActualDemandTasks(int bucket) {
1082:                List demand = new ArrayList();
1083:                if (bucket >= dueOutList.size()) {
1084:                    return demand;
1085:                }
1086:                long end_of_bucket = (convertBucketToTime(bucket + 1) - 1);
1087:                Iterator dueOutIter = ((List) dueOutList.get(bucket))
1088:                        .iterator();
1089:                while (dueOutIter.hasNext()) {
1090:                    Task task = (Task) dueOutIter.next();
1091:                    if (task.getVerb().equals(Constants.Verb.PROJECTWITHDRAW)) {
1092:                        long firstProjectionTime = getFirstProjectionTime(task);
1093:                        long start = (long) PluginHelper
1094:                                .getPreferenceBestValue(task,
1095:                                        AspectType.START_TIME);
1096:                        long end = (long) PluginHelper.getPreferenceBestValue(
1097:                                task, AspectType.END_TIME);
1098:                        start = Math.max(start, firstProjectionTime);
1099:                        if ((start >= end) || (start >= end_of_bucket)) {
1100:                            // task is outside bucket
1101:                            continue;
1102:                        }
1103:                    }
1104:                    demand.add(task);
1105:                }
1106:                return demand;
1107:            }
1108:
1109:            public double getReorderPeriod() {
1110:                return reorderPeriod;
1111:            }
1112:
1113:            /**
1114:              Ignore projected demand that occurs before customer switchover day.
1115:             **/
1116:            public synchronized long getEffectiveProjectionStart(Task task,
1117:                    long start) {
1118:                long firstProjectionTime = getFirstProjectionTime(task);
1119:                return Math.max(firstProjectionTime, start);
1120:            }
1121:
1122:            private long getFirstProjectionTime(Task task) {
1123:                Object org = taskUtils.getCustomer(task);
1124:                if (org != null) {
1125:                    Long lastActualSeen = (Long) customerHash.get(org);
1126:                    if (lastActualSeen != null) {
1127:                        long firstProjectionTime = lastActualSeen.longValue()
1128:                                + msec_per_bucket;
1129:                        firstProjectionTime = truncateToBucketStart(firstProjectionTime);
1130:                        return firstProjectionTime;
1131:                    }
1132:                }
1133:                return -1;
1134:            }
1135:
1136:            private Collection getTasks(int bucket, String verb) {
1137:                List task_list = new ArrayList();
1138:                if (bucket < dueOutList.size()) {
1139:                    Iterator list = ((List) dueOutList.get(bucket)).iterator();
1140:                    while (list.hasNext()) {
1141:                        Task task = (Task) list.next();
1142:                        if (task.getVerb().equals(verb)) {
1143:                            task_list.add(task);
1144:                        }
1145:                    }
1146:                }
1147:                return task_list;
1148:            }
1149:
1150:            public Collection getWithdrawTasks(int bucket) {
1151:                return getTasks(bucket, Constants.Verb.WITHDRAW);
1152:            }
1153:
1154:            public Collection getProjectWithdrawTasks(int bucket) {
1155:                return getTasks(bucket, Constants.Verb.PROJECTWITHDRAW);
1156:            }
1157:
1158:            public void rebuildCustomerHash() {
1159:                customerHash.clear();
1160:                // first run through the projectwithdraws and make the lastActualSeen the
1161:                // day before the start of the earliest projectwithdraw.  We won't really have
1162:                // gotten an actual then, but its the only way to make sure that a customer who
1163:                // ONLY sends projectwithdraws (instead of atleast one withdraw) actually
1164:                // gets an entry put in the customer has for itself.
1165:                for (int i = dueOutList.size() - 1; i >= 0; i--) {
1166:                    List list = (ArrayList) dueOutList.get(i);
1167:                    if (list.isEmpty()) {
1168:                        continue;
1169:                    }
1170:                    Iterator listIter = list.iterator();
1171:                    while (listIter.hasNext()) {
1172:                        Task task = (Task) listIter.next();
1173:                        if (!task.getVerb().equals(
1174:                                Constants.Verb.PROJECTWITHDRAW)) {
1175:                            continue;
1176:                        }
1177:                        Object org = TaskUtils.getCustomer(task);
1178:                        long startTime = taskUtils.getStartTime(task);
1179:                        // now make end time the bucket before the start time of the first projectwithdraw
1180:                        long endTime = startTime - (msec_per_bucket * 2);
1181:                        Long lastActualSeen = (Long) customerHash.get(org);
1182:                        if ((lastActualSeen == null)
1183:                                || (endTime < lastActualSeen.longValue())) {
1184:                            customerHash.put(org, new Long(endTime));
1185:                        }
1186:                    }
1187:                }
1188:
1189:                // now reset the customer has values for those customers that really did
1190:                // send atleast one withdraw task
1191:                for (int i = dueOutList.size() - 1; i >= 0; i--) {
1192:                    List list = (List) dueOutList.get(i);
1193:                    if (list.isEmpty()) {
1194:                        continue;
1195:                    }
1196:                    Iterator listIter = list.iterator();
1197:                    while (listIter.hasNext()) {
1198:                        Task task = (Task) listIter.next();
1199:                        if (!task.getVerb().equals(Constants.Verb.WITHDRAW)) {
1200:                            continue;
1201:                        }
1202:                        Object org = TaskUtils.getCustomer(task);
1203:                        long endTime = taskUtils.getEndTime(task);
1204:                        Long lastActualSeen = (Long) customerHash.get(org);
1205:                        if ((lastActualSeen == null)
1206:                                || (endTime > lastActualSeen.longValue())) {
1207:                            customerHash.put(org, new Long(endTime));
1208:                        }
1209:                    }
1210:                }
1211:            }
1212:
1213:            public HashMap getCustomerHash() {
1214:                return (HashMap) customerHash;
1215:            }
1216:
1217:            public void logAllToCSVFile(long aCycleStamp) {
1218:                if (csvLogger != null) {
1219:                    csvWriter.logToExcelOutput(myPG, aCycleStamp);
1220:                }
1221:            }
1222:
1223:            public long getStartTime() {
1224:                return startTime;
1225:            }
1226:
1227:            public int getStartBucket() {
1228:                return deletionBucket + 1;
1229:            }
1230:
1231:            public ArrayList getProjWithdrawList() {
1232:                return (ArrayList) projWithdrawList;
1233:            }
1234:
1235:            public ArrayList getWithdrawList() {
1236:                return (ArrayList) withdrawList;
1237:            }
1238:
1239:            public ArrayList getProjSupplyList() {
1240:                return (ArrayList) getFlattenedList(projSupplyList);
1241:            }
1242:
1243:            public ArrayList getSupplyList() {
1244:                return (ArrayList) getFlattenedList(supplyList);
1245:            }
1246:
1247:            public Schedule getBufferedCritLevels() {
1248:                return bufferedCriticalLevels;
1249:            }
1250:
1251:            public Schedule getBufferedInvLevels() {
1252:                return bufferedInventoryLevels;
1253:            }
1254:
1255:            public Schedule getBufferedTargetLevels() {
1256:                return bufferedTargetLevels;
1257:            }
1258:
1259:            public ArrayList getActualDemandTasksList() {
1260:                return (ArrayList) actualDemandTasksList;
1261:            }
1262:
1263:            public ShortfallInventory checkForShortfall(String invID,
1264:                    String unitOfIssue) {
1265:                ShortfallInventory shortfallInv = newShortfallInventory(invID,
1266:                        unitOfIssue);
1267:
1268:                int numDemandProj = countProjFailures(getProjWithdrawList(),
1269:                        true, true);
1270:                int numPermDemandProj = countProjFailures(
1271:                        getProjWithdrawList(), true, false);
1272:                shortfallInv.setNumDemandProj(numDemandProj);
1273:                shortfallInv.setNumTempDemandProj(numDemandProj
1274:                        - numPermDemandProj);
1275:
1276:                int numResupplyProj = countProjFailures(getProjSupplyList(),
1277:                        false, true);
1278:                int numPermResupplyProj = countProjFailures(
1279:                        getProjSupplyList(), false, false);
1280:                shortfallInv.setNumResupplyProj(numResupplyProj);
1281:                shortfallInv.setNumTempResupplyProj(numResupplyProj
1282:                        - numPermResupplyProj);
1283:
1284:                int numDemandSupply = countActualShortfall(getWithdrawList(),
1285:                        true);
1286:                int numPermDemandSupply = countActualShortfall(
1287:                        getWithdrawList(), false);
1288:                shortfallInv.setNumDemandSupply(numDemandSupply);
1289:                shortfallInv.setNumTempDemandSupply(numDemandSupply
1290:                        - numPermDemandSupply);
1291:                int numResupplySupply = countActualShortfall(getSupplyList(),
1292:                        true);
1293:                int numPermResupplySupply = countActualShortfall(
1294:                        getSupplyList(), false);
1295:                shortfallInv.setNumResupplySupply(numResupplySupply);
1296:                shortfallInv.setNumTempResupplySupply(numResupplySupply
1297:                        - numPermResupplySupply);
1298:
1299:                if (shortfallInv.getNumTotalShortfall() <= 0) {
1300:                    return null;
1301:                }
1302:                addShortfallPeriods(shortfallInv);
1303:                return shortfallInv;
1304:            }
1305:
1306:            protected ShortfallInventory newShortfallInventory(String invId,
1307:                    String unitOfIssue) {
1308:                return new ShortfallInventory(invId, unitOfIssue);
1309:            }
1310:
1311:            protected void addShortfallPeriods(ShortfallInventory shortfallInv) {
1312:                int startBucket = getStartBucket();
1313:                int endBucket = getLastDemandBucket();
1314:
1315:                long startOfPeriod = -1;
1316:                long endOfPeriod = -1;
1317:                boolean inShortfallPeriod = false;
1318:
1319:                for (int i = startBucket; i <= endBucket; i++) {
1320:                    double level = getLevel(i);
1321:                    if (level == 0.0) {
1322:                        if (!inShortfallPeriod) {
1323:                            startOfPeriod = convertBucketToTime(i);
1324:                            inShortfallPeriod = true;
1325:                        }
1326:                    } else {
1327:                        if (inShortfallPeriod) {
1328:                            //The bucket before the current one was the last shortfall period bucket.  Therefore i-1
1329:                            endOfPeriod = convertBucketToTime(i) - 1;
1330:                            ShortfallPeriod newPeriod = newShortfallPeriod(
1331:                                    startOfPeriod, endOfPeriod);
1332:                            calculateShortfallPeriod(newPeriod,
1333:                                    getProjWithdrawList());
1334:                            calculateShortfallPeriod(newPeriod,
1335:                                    getWithdrawList());
1336:                            shortfallInv.addShortfallPeriod(newPeriod);
1337:                            inShortfallPeriod = false;
1338:                        }
1339:                    }
1340:                }
1341:
1342:                if (inShortfallPeriod) {
1343:                    //The bucket before the current one was the last shortfall period bucket.  Therefore i-1
1344:                    endOfPeriod = convertBucketToTime(endBucket) - 1;
1345:                    ShortfallPeriod newPeriod = newShortfallPeriod(
1346:                            startOfPeriod, endOfPeriod);
1347:                    calculateShortfallPeriod(newPeriod, getProjWithdrawList());
1348:                    calculateShortfallPeriod(newPeriod, getWithdrawList());
1349:                    shortfallInv.addShortfallPeriod(newPeriod);
1350:                }
1351:            }
1352:
1353:            protected ShortfallPeriod newShortfallPeriod(long start, long end) {
1354:                return new ShortfallPeriod(start, end);
1355:            }
1356:
1357:            protected void calculateShortfallPeriod(
1358:                    ShortfallPeriod shortPeriod, List tasks) {
1359:                double totalDemand = 0.0d;
1360:                double totalFilled = 0.0d;
1361:                for (Iterator taskIt = tasks.iterator(); taskIt.hasNext();) {
1362:                    Task t = (Task) taskIt.next();
1363:
1364:                    long minStart = shortPeriod.getStartTime();
1365:                    long maxEnd = shortPeriod.getEndTime();
1366:                    if (taskUtils.isProjection(t)) {
1367:                        minStart = Math
1368:                                .max(minStart, getFirstProjectionTime(t));
1369:                    }
1370:
1371:                    totalDemand += taskUtils.calculateDemand(t, minStart,
1372:                            maxEnd);
1373:                    totalFilled += taskUtils.calculateFilled(t, minStart,
1374:                            maxEnd);
1375:                }
1376:
1377:                shortPeriod.setTotalDemand(shortPeriod.getTotalDemand()
1378:                        + totalDemand);
1379:                shortPeriod.setTotalFilled(shortPeriod.getTotalFilled()
1380:                        + totalFilled);
1381:            }
1382:
1383:            protected int countProjFailures(List taskList, boolean isDemand,
1384:                    boolean includeTemps) {
1385:                int ctr = 0;
1386:                for (Iterator it = taskList.iterator(); it.hasNext();) {
1387:                    Task t = (Task) it.next();
1388:                    PlanElement pe = t.getPlanElement();
1389:                    if (pe == null) {
1390:                        continue;
1391:                    }
1392:                    long minStart = (isDemand ? getFirstProjectionTime(t)
1393:                            : convertBucketToTime(getLastRefillRequisition() + 1));
1394:                    if (taskUtils.isProjFailure(t, minStart, includeTemps)) {
1395:                        ctr++;
1396:                    }
1397:                }
1398:                return ctr;
1399:            }
1400:
1401:            protected int countActualShortfall(List taskList,
1402:                    boolean includeTemps) {
1403:                int ctr = 0;
1404:                for (Iterator it = taskList.iterator(); it.hasNext();) {
1405:                    Task t = (Task) it.next();
1406:                    if (taskUtils.isActualShortfall(t, includeTemps)) {
1407:                        ctr++;
1408:                    }
1409:                }
1410:                return ctr;
1411:            }
1412:
1413:            protected double totalShortfall(List taskList) {
1414:                double requested = 0;
1415:                double granted = 0;
1416:                for (Iterator it = taskList.iterator(); it.hasNext();) {
1417:                    Task t = (Task) it.next();
1418:                    requested += taskUtils.getTotalQuantity(t);
1419:                    granted += taskUtils.getGrantedQuantity(t);
1420:                }
1421:                double diff = granted - requested;
1422:                if ((diff <= 0) && (diff > -0.00005)) {
1423:                    diff = 0.0;
1424:                }
1425:                return diff;
1426:            }
1427:
1428:            /**
1429:             *  Take the incomming time and convert it to the beginning of the bucket
1430:             *  in which it falls
1431:             */
1432:            public long truncateToBucketStart(long aTime) {
1433:                int bucket = convertTimeToBucket(aTime, false);
1434:                return convertBucketToTime(bucket);
1435:            }
1436:
1437:            /**
1438:             * Convert a time (long) into a bucket of this inventory that can be
1439:             * used to index duein/out vectors, levels, etc.
1440:             **/
1441:            public int convertTimeToBucket(long time, boolean partialBuckets) {
1442:                if (time < 0) {
1443:                    logger.error("convertTimeToBucket: Got negative time "
1444:                            + TimeUtils.dateString(time), new Throwable());
1445:                    return 0;
1446:                }
1447:                int this Bucket = (int) (time / msec_per_bucket);
1448:                if (partialBuckets) {
1449:                    // FCS - HOURLY : Added this code from Bug #2413
1450:                    if ((time % msec_per_bucket) > 0.0) {
1451:                        this Bucket += 1;
1452:                    }
1453:                    // FCS - HOURLY : End added code
1454:                }
1455:                if (this Bucket < timeZero) {
1456:                    logger
1457:                            .error("convertTimeToBucket: For Org: "
1458:                                    + getOrgName() + "-" + getSupplyType()
1459:                                    + " item: " + getItemName()
1460:                                    + " - thisBucket(" + this Bucket
1461:                                    + ") - timeZero(" + timeZero
1462:                                    + ") is < 0! (" + (this Bucket - timeZero)
1463:                                    + ") when started with time "
1464:                                    + TimeUtils.dateString(time) + "!",
1465:                                    new Throwable());
1466:                    return 0;
1467:                }
1468:                return this Bucket - timeZero;
1469:            }
1470:
1471:            /**
1472:             * Convert a bucket (int) into the start time of the bucket.
1473:             * The end time of the bucket must be inferred from the
1474:             * next sequential bucket's start time (non-inclusive).
1475:             **/
1476:            public long convertBucketToTime(int bucket) {
1477:                if (bucket < 0) {
1478:                    logger.error("convertBucketToTime: Got negative bucket "
1479:                            + bucket, new Throwable());
1480:                    return 0;
1481:                }
1482:                return (bucket + timeZero) * msec_per_bucket;
1483:            }
1484:
1485:            /** @return long The amount of ms the bucket spans **/
1486:            public long getBucketMillis() {
1487:                return msec_per_bucket;
1488:            }
1489:
1490:            // Grow the array by 50% at a time, but at least enough to cover
1491:            // the incoming request
1492:            private double[] expandArray(double[] doubleArray, int newMinLength) {
1493:                if (newMinLength < doubleArray.length)
1494:                    return doubleArray;
1495:
1496:                double biggerArray[] = new double[Math.max(newMinLength,
1497:                        (int) (doubleArray.length * 1.5))];
1498:                for (int i = 0; i < doubleArray.length; i++) {
1499:                    biggerArray[i] = doubleArray[i];
1500:                }
1501:                return biggerArray;
1502:            }
1503:
1504:            public int getCriticalLevel() {
1505:                return criticalLevel;
1506:            }
1507:
1508:            public void takeSnapshot(Inventory inventory) {
1509:                List tmpProjWdraw = new ArrayList();
1510:                List tmpWdraw = new ArrayList();
1511:                List tmpProjResupply = new ArrayList();
1512:
1513:                Iterator due_outs;
1514:                for (int i = 0; i < dueOutList.size(); i++) {
1515:                    due_outs = ((List) dueOutList.get(i)).iterator();
1516:                    while (due_outs.hasNext()) {
1517:                        Task task = (Task) due_outs.next();
1518:                        if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
1519:                            tmpWdraw.add(task);
1520:                        } else { // PROJECTWITHDRAW
1521:                            if (!tmpProjWdraw.contains(task)) {
1522:                                tmpProjWdraw.add(task);
1523:                            }
1524:                        }
1525:                    }
1526:                }
1527:                projWithdrawList = tmpProjWdraw;
1528:                withdrawList = tmpWdraw;
1529:
1530:                projSupplyList = deepClone(refillProjections);
1531:                supplyList = deepClone(refillRequisitions);
1532:
1533:                // MWD took this out when converted list to a schedule.
1534:                //    bufferedTargetLevels = (List) targetLevelsList.clone();
1535:
1536:                List tmpActualDemandTasksList = new ArrayList();
1537:                for (int i = 0; i < dueOutList.size(); i++) {
1538:                    tmpActualDemandTasksList.add(getActualDemandTasks(i));
1539:                }
1540:                actualDemandTasksList = tmpActualDemandTasksList;
1541:
1542:                Vector list = new Vector();
1543:                long start = convertBucketToTime(0);
1544:                //the length of the critical level and inventory level
1545:                //arrays should match up
1546:                int length = Math.max(getMeaningfulLength(criticalLevelsArray),
1547:                        getMeaningfulLength(inventoryLevelsArray));
1548:
1549:                length = Math.max(length, (convertTimeToBucket(oplanEndTime,
1550:                        false) + 1));
1551:
1552:                int maxArrayLength = Math.min(criticalLevelsArray.length,
1553:                        inventoryLevelsArray.length);
1554:
1555:                if ((length > maxArrayLength) && (logger.isWarnEnabled())) {
1556:                    logger
1557:                            .warn(getOrgName()
1558:                                    + "-"
1559:                                    + getItemName()
1560:                                    + " Meaningful length is "
1561:                                    + length
1562:                                    + "but, criticalLevelsArray length is "
1563:                                    + criticalLevelsArray.length
1564:                                    + " and the inventoryLevelsArray length is "
1565:                                    + inventoryLevelsArray.length
1566:                                    + ". Will truncate to eliminate array index out of bounds error.");
1567:                }
1568:
1569:                //We want to make sure the meaningful length doesn't exceed
1570:                //the length of either array.
1571:                length = Math.min(length, maxArrayLength);
1572:
1573:                for (int i = 0; i < length; i++) {
1574:                    if (criticalLevelsArray[i] >= 0.0) {
1575:                        list.add(ScheduleUtils.buildQuantityScheduleElement(
1576:                                criticalLevelsArray[i], start, start
1577:                                        + msec_per_bucket));
1578:                    }
1579:                    start += msec_per_bucket;
1580:                }
1581:                bufferedCriticalLevels = GLMFactory.newQuantitySchedule(list
1582:                        .elements(), PlanScheduleType.OTHER);
1583:                start = convertBucketToTime(0);
1584:                list.clear();
1585:                for (int i = 0; i < targetLevelsList.size(); i++) {
1586:                    Double targetLevel = (Double) targetLevelsList.get(i);
1587:                    if (targetLevel != null) {
1588:                        list.add(ScheduleUtils.buildQuantityScheduleElement(
1589:                                targetLevel.doubleValue(), start, start
1590:                                        + msec_per_bucket));
1591:                    }
1592:                    start += msec_per_bucket;
1593:                }
1594:                bufferedTargetLevels = GLMFactory.newQuantitySchedule(list
1595:                        .elements(), PlanScheduleType.OTHER);
1596:
1597:                start = convertBucketToTime(0);
1598:                list.clear();
1599:                //length =
1600:                for (int i = 0; i < length; i++) {
1601:                    list.add(ScheduleUtils.buildQuantityScheduleElement(
1602:                            inventoryLevelsArray[i], start, start
1603:                                    + msec_per_bucket));
1604:                    start += msec_per_bucket;
1605:                }
1606:                bufferedInventoryLevels = GLMFactory.newQuantitySchedule(list
1607:                        .elements(), PlanScheduleType.OTHER);
1608:                NewScheduledContentPG scp = (NewScheduledContentPG) inventory
1609:                        .getScheduledContentPG();
1610:                scp.setSchedule(bufferedInventoryLevels);
1611:
1612:            }
1613:
1614:            public boolean getFailuresFlag() {
1615:                return failures;
1616:            }
1617:
1618:            // failures boolean used to determine when due outs
1619:            // need to be re-bucketed
1620:            public void setFailuresFlag(boolean value) {
1621:                failures = value;
1622:            }
1623:
1624:            // Ask Beth about persistance.  Would like to make sure structures
1625:            // are persisted when they are added to the code
1626:            public PGDelegate copy(PropertyGroup pg) {
1627:                return new LogisticsInventoryBG((LogisticsInventoryPG) pg);
1628:            }
1629:
1630:            private int printQuantityScheduleTimes(Schedule sched) {
1631:                Enumeration elements = sched.getAllScheduleElements();
1632:                QuantityScheduleElement qse;
1633:                while (elements.hasMoreElements()) {
1634:                    qse = (QuantityScheduleElement) elements.nextElement();
1635:                    if (logger.isInfoEnabled()) {
1636:                        logger.info("qty: " + qse.getQuantity() + " "
1637:                                + qse.getStartDate() + " to "
1638:                                + qse.getEndDate());
1639:                    }
1640:                }
1641:                return 0;
1642:            }
1643:
1644:            public void Test() {
1645:                logger.error("Bucket size is " + msec_per_bucket
1646:                        / TimeUtils.MSEC_PER_HOUR + " hrs.");
1647:                //      logger.error("ReorderPeriod is "+reorderPeriod+", getReorderPeriod() "+getReorderPeriod()+
1648:                //                     ", critical level "+criticalLevel);
1649:                //      computeCriticalLevels();
1650:                //      setLevel(0, myPG.getInitialLevel());
1651:                //      for (int i = 1; i < projectedDemandArray.length; i++) {
1652:                //        double new_level = getLevel(i - 1) - projectedDemandArray[i];
1653:                //        setLevel(i, new_level);
1654:                //      }
1655:                //      logger.error("Date for Bucket Zero is "+TimeUtils.dateString(convertBucketToTime(0)));
1656:                //      for (int i = 0; i < projectedDemandArray.length; i++) {
1657:                //        logger.error("Bucket "+i+", Demand "+getActualDemand(i)+", criticalLevel "+
1658:                //                       criticalLevelsArray[i]+" Level "+inventoryLevelsArray[i]);
1659:                //      }
1660:                if (logger.isErrorEnabled()) {
1661:                    logger.error("********* ProjectWithdrawList ********");
1662:                    for (int i = 0; i < projWithdrawList.size(); i++) {
1663:                        logger.error(taskUtils.taskDesc((Task) projWithdrawList
1664:                                .get(i)));
1665:                    }
1666:                    logger.error("********* WithdrawList ********");
1667:                    for (int i = 0; i < withdrawList.size(); i++) {
1668:                        logger.error(taskUtils.taskDesc((Task) withdrawList
1669:                                .get(i)));
1670:                    }
1671:                    logger.error("********* ProjectSupplyList ********");
1672:                    List flatProjList = getFlattenedList(projSupplyList);
1673:                    for (int i = 0; i < flatProjList.size(); i++) {
1674:                        logger.error(taskUtils.taskDesc((Task) flatProjList
1675:                                .get(i)));
1676:                    }
1677:                    logger.error("********* SupplyList ********");
1678:                    List flatSupplyList = getFlattenedList(supplyList);
1679:                    for (int i = 0; i < flatSupplyList.size(); i++) {
1680:                        logger.error(taskUtils.taskDesc((Task) flatSupplyList
1681:                                .get(i)));
1682:                    }
1683:                    logger.error("********* Buffered Critical Levels ********");
1684:                    printQuantityScheduleTimes(bufferedCriticalLevels);
1685:                    logger
1686:                            .error("********* Buffered Inventory Levels ********");
1687:                    printQuantityScheduleTimes(bufferedInventoryLevels);
1688:                }
1689:            }
1690:
1691:            private int getMeaningfulLength(double[] list) {
1692:                if (list.length < 5) {
1693:                    return list.length;
1694:                }
1695:                int lastMeaningfulPosition = list.length - 1;
1696:                for (int i = list.length - 1; i > 0; i--) {
1697:                    if (list[i] == list[i - 1]) {
1698:                        lastMeaningfulPosition = i;
1699:                    } else {
1700:                        break;
1701:                    }
1702:                }
1703:                return lastMeaningfulPosition + 1;
1704:            }
1705:
1706:            public String getOrgName() {
1707:                return myPG.getOrg().getItemIdentificationPG()
1708:                        .getItemIdentification();
1709:            }
1710:
1711:            public String getItemName() {
1712:                return myPG.getResource().getTypeIdentificationPG()
1713:                        .getTypeIdentification();
1714:            }
1715:
1716:            public String getSupplyType() {
1717:                SupplyClassPG pg = (SupplyClassPG) myPG.getResource()
1718:                        .searchForPropertyGroup(SupplyClassPG.class);
1719:                return pg.getSupplyType();
1720:            }
1721:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.