Source Code Cross Referenced for InventoryBG.java in  » Science » Cougaar12_4 » org » cougaar » glm » ldm » asset » 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.glm.ldm.asset 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*--------------------------------------------------------------------------
0002:         * <copyright>
0003:         *  
0004:         *  Copyright 2000-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:        package org.cougaar.glm.ldm.asset;
0027:
0028:        import org.cougaar.core.mts.MessageAddress;
0029:        import org.cougaar.glm.execution.common.InventoryReport;
0030:        import org.cougaar.glm.ldm.Constants;
0031:        import org.cougaar.glm.ldm.GLMFactory;
0032:        import org.cougaar.glm.ldm.plan.AlpineAspectType;
0033:        import org.cougaar.glm.ldm.plan.NewQuantityScheduleElement;
0034:        import org.cougaar.glm.ldm.plan.PlanScheduleType;
0035:        import org.cougaar.glm.ldm.plan.QuantityScheduleElement;
0036:        import org.cougaar.glm.plugins.AssetUtils;
0037:        import org.cougaar.glm.plugins.ScheduleUtils;
0038:        import org.cougaar.glm.plugins.TaskUtils;
0039:        import org.cougaar.glm.plugins.TimeUtils;
0040:        import org.cougaar.planning.ldm.asset.Asset;
0041:        import org.cougaar.planning.ldm.asset.PGDelegate;
0042:        import org.cougaar.planning.ldm.asset.PropertyGroup;
0043:        import org.cougaar.planning.ldm.measure.Count;
0044:        import org.cougaar.planning.ldm.measure.Mass;
0045:        import org.cougaar.planning.ldm.measure.Scalar;
0046:        import org.cougaar.planning.ldm.measure.Volume;
0047:        import org.cougaar.planning.ldm.plan.AllocationResult;
0048:        import org.cougaar.planning.ldm.plan.AspectType;
0049:        import org.cougaar.planning.ldm.plan.AspectValue;
0050:        import org.cougaar.planning.ldm.plan.Expansion;
0051:        import org.cougaar.planning.ldm.plan.PlanElement;
0052:        import org.cougaar.planning.ldm.plan.Schedule;
0053:        import org.cougaar.planning.ldm.plan.Task;
0054:        import org.cougaar.planning.ldm.plan.Workflow;
0055:        import org.cougaar.planning.plugin.util.AllocationResultHelper;
0056:        import org.cougaar.util.log.Logger;
0057:        import org.cougaar.util.log.Logging;
0058:
0059:        import java.io.IOException;
0060:        import java.io.NotActiveException;
0061:        import java.io.ObjectInputStream;
0062:        import java.util.ArrayList;
0063:        import java.util.Calendar;
0064:        import java.util.Comparator;
0065:        import java.util.Date;
0066:        import java.util.Enumeration;
0067:        import java.util.HashMap;
0068:        import java.util.Hashtable;
0069:        import java.util.Iterator;
0070:        import java.util.List;
0071:        import java.util.Map;
0072:        import java.util.Vector;
0073:
0074:        public class InventoryBG implements  PGDelegate {
0075:
0076:            public static final int PRIORITY_LEVELS = 10;
0077:            public static final long CANONICAL_TIME_OFFSET = TimeUtils.MSEC_PER_DAY - 1;
0078:            public static final double GOAL_LEVEL_BOOST_CAPACITY_FACTOR = 1.1;
0079:
0080:            protected InventoryPG myPG_;
0081:            // Each element in these Vectors represents a day.
0082:            // Element zero of each Vector is today
0083:            // Refill Tasks
0084:            protected transient Vector dueIns_;
0085:            protected transient Vector dueInTasks_;
0086:            // Supply Tasks
0087:            protected transient Vector dueOut_;
0088:            // ProjectSupply Tasks
0089:            protected transient double[] level_;
0090:            protected transient int dirtyDay_;
0091:            protected transient boolean needInitializeInventoryLevels;
0092:            protected transient Vector dueInsByRequestDay_;
0093:            // Was the BG properly initialized, if not, it is unusable
0094:            protected boolean initialized_ = false;
0095:            // today is the alp day right now
0096:            private boolean isStartTimeSet = false;
0097:            private int startDay_;
0098:            protected int today_;
0099:            protected int firstDayOfDemand_;
0100:            private ProjectionWeight weight_;
0101:            // Stuff for execution below
0102:            protected ArrayList report_history;
0103:            protected InventoryReport latest_report;
0104:            protected InventoryReport oldest_report;
0105:            protected Calendar calendar_ = Calendar.getInstance();
0106:
0107:            // target level stuff
0108:            protected double[] demandSchedule_ = null;
0109:            protected double goalLevelMultiplier_;
0110:            protected double minReorderLevel_;
0111:            protected double maxReorderLevel_;
0112:            protected int daysOfDemand_;
0113:            protected int daysForward_;
0114:            protected int daysBackward_;
0115:
0116:            protected int goalExceededCap = 0;
0117:            final static protected int GOAL_EXCEEDED_CAPACITY_DEBUG_THRESHOLD = 2;
0118:            private static Logger logger = Logging.getLogger(InventoryBG.class);
0119:
0120:            public InventoryBG(InventoryPG pg) {
0121:                myPG_ = pg;
0122:                dueIns_ = new Vector();
0123:                dueOut_ = new Vector();
0124:                dueInsByRequestDay_ = new Vector();
0125:                level_ = null;
0126:                report_history = new ArrayList();
0127:                latest_report = null;
0128:                oldest_report = null;
0129:            }
0130:
0131:            public void setProjectionWeight(ProjectionWeight weight) {
0132:                weight_ = weight;
0133:            }
0134:
0135:            // put in so that we can check whether a requisition will be counted
0136:            public ProjectionWeight getProjectionWeight() {
0137:                return weight_;
0138:            }
0139:
0140:            //Reinit transient variables from input serialization
0141:            private void readObject(ObjectInputStream s) throws IOException,
0142:                    ClassNotFoundException, NotActiveException {
0143:                s.defaultReadObject();
0144:
0145:                dueIns_ = new Vector();
0146:                dueOut_ = new Vector();
0147:                dueInsByRequestDay_ = new Vector();
0148:                level_ = null;
0149:            }
0150:
0151:            // GLK temp changed void to int
0152:            public int resetInventory(Inventory inventory, long today) {
0153:                needInitializeInventoryLevels = true;
0154:
0155:                if (!isStartTimeSet) {// Only do this check once
0156:                    Scalar ignore = getScalar(0.0);// Insure we know how to manage this type
0157:                }
0158:                for (int i = 0, n = dueOut_.size(); i < n; i++) {
0159:                    ((DueOutList) dueOut_.elementAt(i)).clear();
0160:                }
0161:                for (int i = 0, n = dueIns_.size(); i < n; i++) {
0162:                    ((DueInList) dueIns_.elementAt(i)).clear();
0163:                }
0164:                dueInsByRequestDay_.clear();
0165:
0166:                initializeTime(inventory, today);
0167:                if (!inventory.hasScheduledContentPG()) {
0168:                    Asset proto = inventory.getPrototype();
0169:                    String id = proto.getTypeIdentificationPG()
0170:                            .getNomenclature();
0171:                    if (logger.isErrorEnabled()) {
0172:                        logger
0173:                                .error(" initInventory - NO ScheduledContentPG on Inventory Object- "
0174:                                        + id + ", EXIT!");
0175:                    }
0176:                    System.exit(1);
0177:                }
0178:
0179:                //     printDebug("Initializing inventory: "+inventoryDesc(inventory));
0180:                //     printInventory(inventory,null);
0181:
0182:                // GLK temp return
0183:                return 0;
0184:            }
0185:
0186:            /**
0187:               Set the startTime to the earliest of today or the oldest
0188:               inventory report. In all cases, the start time is pushed to the
0189:               end of the day in which it falls.
0190:             **/
0191:            private void initializeTime(Inventory inventory, long today) {
0192:                try {
0193:                    if (!isStartTimeSet) { // Need to set start time
0194:                        long start_time = today;
0195:                        InventoryReport oldest = getOldestInventoryReport();
0196:                        if (oldest != null) {
0197:                            start_time = Math.min(start_time,
0198:                                    oldest.theReportDate);
0199:                        }
0200:                        startDay_ = (int) (start_time / TimeUtils.MSEC_PER_DAY);
0201:                        isStartTimeSet = true;
0202:                    }
0203:                    today_ = convertTimeToDay(today);
0204:                } catch (RuntimeException re) {
0205:                    System.err.print(re + ": today=" + today + ", today_ = "
0206:                            + today_);
0207:                    throw re;
0208:                }
0209:            }
0210:
0211:            public long getStartTime() {
0212:                return convertDayToTime(0);
0213:            }
0214:
0215:            private int getStartDay() {
0216:                //          if (!isStartTimeSet) throw new RuntimeException("startDay_ never set");
0217:                return startDay_;
0218:            }
0219:
0220:            public int getImputedDayOfTime(long time) {
0221:                return getImputedDay(convertTimeToDay(time));
0222:            }
0223:
0224:            public int getImputedDay(int day) {
0225:                return day - getToday();
0226:            }
0227:
0228:            public int getFirstPlanningDay() {
0229:                // The first planning day is the first day of demand unless
0230:                // that day falls in the past, in which case the first
0231:                // planning day is today.
0232:                return Math.max(today_ + 1, firstDayOfDemand_);
0233:            }
0234:
0235:            /**
0236:             * @return the day number of the current execution time.
0237:             **/
0238:            public int getToday() {
0239:                return today_;
0240:            }
0241:
0242:            /**
0243:             * Get the inventory level at a particular execution time
0244:             **/
0245:            public Scalar getLevel(long time) {
0246:                return getLevel(convertTimeToDay(time));
0247:            }
0248:
0249:            /**
0250:             * Get inventory level on a particular day relative to the start
0251:             * time of the inventory. If the specified day is before the start
0252:             * time of the inventory, the initial level is returned. If after
0253:             * the maximum day, the level on that maximum day is returned.
0254:             **/
0255:            public Scalar getLevel(int day) {
0256:                if ((day < 0) || (level_ == null)) {
0257:                    return myPG_.getInitialLevel();
0258:                }
0259:                if (day >= level_.length) {
0260:                    day = level_.length - 1;
0261:                }
0262:                if (day >= dirtyDay_)
0263:                    updateLevels(day);
0264:                return getScalar(level_[day]);
0265:            }
0266:
0267:            private void updateDirtyDay(int day) {
0268:                if (day > 0 && day < dirtyDay_) {
0269:                    dirtyDay_ = day;
0270:                }
0271:            }
0272:
0273:            /**
0274:             * Record all demand tasks as dueouts. As a side effect compute the firstDayOfDemand_
0275:             **/
0276:            public int withdrawFromInventory(Inventory inventory,
0277:                    MessageAddress clusterID) {
0278:                Enumeration role_sched = inventory.getRoleSchedule()
0279:                        .getRoleScheduleElements();
0280:                long earliestDemand = Long.MAX_VALUE;
0281:                while (role_sched.hasMoreElements()) {
0282:                    PlanElement pe = (PlanElement) role_sched.nextElement();
0283:                    Task task = pe.getTask();
0284:                    if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
0285:                        addDueOut(task);
0286:                        earliestDemand = Math.min(earliestDemand, TaskUtils
0287:                                .getEndTime(task));
0288:                    } else if (task.getVerb().equals(
0289:                            Constants.Verb.PROJECTWITHDRAW)) {
0290:                        addDueOutProjection(task);
0291:                        earliestDemand = Math.min(earliestDemand, TaskUtils
0292:                                .getStartTime(task));
0293:                    } else {
0294:                        System.err
0295:                                .println("What the .... Task added to role schedule "
0296:                                        + TaskUtils.taskDesc(task));
0297:                    }
0298:                }
0299:                if (earliestDemand != Long.MAX_VALUE)
0300:                    firstDayOfDemand_ = convertTimeToDay(earliestDemand);
0301:                return 0;
0302:            }
0303:
0304:            /**
0305:             * Convert a time (long) into a day of this inventory that can be
0306:             * used to index duein/out vectors, levels, etc.
0307:             **/
0308:            public int convertTimeToDay(long time) {
0309:                int this Day = (int) (time / TimeUtils.MSEC_PER_DAY);
0310:                int startDay = getStartDay();
0311:                return this Day - startDay;
0312:            }
0313:
0314:            public long convertDayToTime(int day) {
0315:                int startDay = getStartDay();
0316:                return TimeUtils.MSEC_PER_DAY * (day + startDay)
0317:                        + CANONICAL_TIME_OFFSET;
0318:            }
0319:
0320:            public long getStartOfDay(int day) {
0321:                int startDay = getStartDay();
0322:                return TimeUtils.MSEC_PER_DAY * (day + startDay);
0323:            }
0324:
0325:            private long canonicalTime(long time) {
0326:                return convertDayToTime(convertTimeToDay(time));
0327:            }
0328:
0329:            private abstract class DueIOList {
0330:                List list = null; // Create on demand
0331:                protected double actualTotal;
0332:                protected double projectedTotal;
0333:                protected int day;
0334:                protected int imputedDay;
0335:
0336:                protected DueIOList(int day) {
0337:                    this .day = day;
0338:                    setImputedDay();
0339:                }
0340:
0341:                private void setImputedDay() {
0342:                    imputedDay = day - today_;
0343:                }
0344:
0345:                public double getTotal() {
0346:                    return actualTotal + projectedTotal;
0347:                }
0348:
0349:                public double getActualTotal() {
0350:                    return actualTotal;
0351:                }
0352:
0353:                public double getProjectedTotal() {
0354:                    return projectedTotal;
0355:                }
0356:
0357:                public int size() {
0358:                    if (list == null)
0359:                        return 0;
0360:                    return list.size();
0361:                }
0362:
0363:                public void clear() {
0364:                    if (list != null)
0365:                        list.clear();
0366:                    if (actualTotal != 0.0 || projectedTotal != 0.0) {
0367:                        actualTotal = 0.0;
0368:                        projectedTotal = 0.0;
0369:                        updateDirtyDay(day);
0370:                    }
0371:                    setImputedDay();
0372:                }
0373:
0374:                public void add(DueIO d) {
0375:                    Task t = d.getTask();
0376:                    if (d.getFilled()) {
0377:                        adjustTotals(t, 1.0);
0378:                        updateDirtyDay(day);
0379:                    }
0380:                    if (list == null)
0381:                        list = new ArrayList(1);
0382:                    list.add(d);
0383:                }
0384:
0385:                public void remove(Task t) {
0386:                    for (int i = 0, n = list.size(); i < n; i++) {
0387:                        DueIO d = (DueIO) list.get(i);
0388:                        if (d.getTask() == t) {
0389:                            if (d.getFilled()) {
0390:                                adjustTotals(t, -1.0);
0391:                                updateDirtyDay(day);
0392:                            }
0393:                            list.remove(d);
0394:                            return;
0395:                        }
0396:                    }
0397:                }
0398:
0399:                protected abstract void adjustTotals(Task t, double w);
0400:            }
0401:
0402:            private class DueOutList extends DueIOList {
0403:                public DueOutList(int day) {
0404:                    super (day);
0405:                }
0406:
0407:                public DueOut get(int ix) {
0408:                    return (DueOut) list.get(ix);
0409:                }
0410:
0411:                public List getWithdrawTasks() {
0412:                    if (list == null)
0413:                        return null;
0414:                    Iterator tasks = list.iterator();
0415:                    ArrayList actualsList = new ArrayList();
0416:                    Task t;
0417:                    while (tasks.hasNext()) {
0418:                        t = ((DueIO) tasks.next()).getTask();
0419:                        if (t.getVerb().equals(Constants.Verb.WITHDRAW)
0420:                                && (getWeightingFactor(t, imputedDay) > 0.0)) {
0421:                            actualsList.add(t);
0422:                        }
0423:                    }
0424:                    return actualsList;
0425:                }
0426:
0427:                protected void adjustTotals(Task t, double w) {
0428:                    double wf = getWeightingFactor(t, imputedDay) * w;
0429:                    if (t.getVerb().equals(Constants.Verb.WITHDRAW)) {
0430:                        actualTotal += TaskUtils.getWithdrawQuantity(t) * wf;
0431:                    } else {
0432:                        projectedTotal += TaskUtils.getDailyQuantity(t) * wf;
0433:                    }
0434:                }
0435:            }
0436:
0437:            private class DueInList extends DueIOList {
0438:                public DueInList(int day) {
0439:                    super (day);
0440:                }
0441:
0442:                public DueIn get(int ix) {
0443:                    return (DueIn) list.get(ix);
0444:                }
0445:
0446:                public List getSupplyTasks() {
0447:                    if (list == null)
0448:                        return null;
0449:                    Iterator tasks = list.iterator();
0450:                    ArrayList actualsList = new ArrayList();
0451:                    Task t;
0452:                    while (tasks.hasNext()) {
0453:                        t = ((DueIO) tasks.next()).getTask();
0454:                        if (t.getVerb().equals(Constants.Verb.SUPPLY)
0455:                                && (getWeightingFactor(t, imputedDay) > 0.0)) {
0456:                            actualsList.add(t);
0457:                        }
0458:                    }
0459:                    return actualsList;
0460:                }
0461:
0462:                protected void adjustTotals(Task t, double w) {
0463:                    double wf = getWeightingFactor(t, imputedDay);
0464:                    if (TaskUtils.isProjection(t)) {
0465:                        double q = TaskUtils.getDailyQuantity(t);
0466:                        if (q == 0.0 && w > 0.0) {
0467:                            if (logger.isErrorEnabled()) {
0468:                                logger
0469:                                        .error("Added refill projection having 0.0 quantity "
0470:                                                + TaskUtils.taskDesc(t));
0471:                            }
0472:                        }
0473:                        projectedTotal += q * w * wf;
0474:                    } else {
0475:                        if (wf < 1.0) {
0476:                            if (logger.isErrorEnabled()) {
0477:                                logger.error("Inv Day: " + day
0478:                                        + " imputedDay: " + imputedDay
0479:                                        + " Zero weighted supply task: "
0480:                                        + TaskUtils.taskDesc(t));
0481:                            }
0482:                        }
0483:                        actualTotal += TaskUtils.getRefillQuantity(t) * w * wf;
0484:                    }
0485:                    //              System.out.println("adjustTotals " + TimeUtils.dateString(convertDayToTime(day)) + ": " + getTotal());
0486:                }
0487:            }
0488:
0489:            private void addDueOut(DueOut dueOut) {
0490:                int day = dueOut.getDay();
0491:                while (day >= dueOut_.size()) {
0492:                    dueOut_.add(new DueOutList(dueOut_.size()));
0493:                }
0494:                DueOutList v = (DueOutList) dueOut_.get(day);
0495:                v.add(dueOut);
0496:            }
0497:
0498:            private void addDueOut(Task request) {
0499:                int day = convertTimeToDay(TaskUtils.getEndTime(request));
0500:                if (day < 0) {
0501:                    day = 0;
0502:                    if (logger.isErrorEnabled()) {
0503:                        logger
0504:                                .error("addDueOut(), Request happens in the past.(Start Time "
0505:                                        + TimeUtils.dateString(getStartTime())
0506:                                        + ")"
0507:                                        + "Task time:"
0508:                                        + TimeUtils.dateString(TaskUtils
0509:                                                .getEndTime(request))
0510:                                        + ", Task: "
0511:                                        + TaskUtils.taskDesc(request));
0512:                    }
0513:                }
0514:                PlanElement pe = request.getPlanElement();
0515:                // If the request has just been rescinded, the plan element will be null.
0516:                // This task should not affect planning
0517:                if (pe == null)
0518:                    return;
0519:                boolean filled = true;
0520:                AllocationResult ar = pe.getEstimatedResult();
0521:                if (ar != null)
0522:                    filled = ar.isSuccess();
0523:                addDueOut(new DueOut(request, filled, day));
0524:            }
0525:
0526:            // DRAT!!! Golden opportunity for refactoring.  Emergency demo solution
0527:            // AHF -- Need to merge common code from addDueOut() and addDueOutProjeciton()
0528:            // 
0529:            private void addDueOutProjection(Task task) {
0530:                PlanElement pe = task.getPlanElement();
0531:                // If the task has just been rescinded, the plan element will be null.
0532:                // This task should not affect planning
0533:                if (pe == null)
0534:                    return;
0535:                //          Rate r = TaskUtils.getRate(task);
0536:                //          double rate = r.getValue(0);
0537:                AllocationResultHelper helper = new AllocationResultHelper(
0538:                        task, task.getPlanElement());
0539:                for (int i = 0, n = helper.getPhaseCount(); i < n; i++) {
0540:                    AllocationResultHelper.Phase phase = (AllocationResultHelper.Phase) helper
0541:                            .getPhase(i);
0542:                    double qty = phase.getAspectValue(
0543:                            AlpineAspectType.DEMANDRATE).getValue();
0544:                    boolean filled = qty > 0.0;
0545:                    int start = convertTimeToDay(phase.getStartTime());
0546:                    int end = convertTimeToDay(phase.getEndTime());
0547:                    if (start < 0)
0548:                        start = 0;
0549:                    for (int day = start; day < end; day++) {
0550:                        addDueOut(new DueOut(task, filled, day));
0551:                    }
0552:                }
0553:            }
0554:
0555:            /**
0556:             * Update the allocations results of all the allocations of
0557:             * DueOuts for this inventory. Cycles through all the dueouts and
0558:             * updates the allocation results to be success or fail on the day
0559:             * of the dueout.
0560:             * @return List of the changed Allocations
0561:             **/
0562:            public List updateDueOutAllocations() {
0563:                List result = new ArrayList();
0564:                int size = dueOut_.size();
0565:                Map helpers = new HashMap();
0566:                for (int day = 0; day < size; day++) {
0567:                    long startTime = getStartOfDay(day);
0568:                    long endTime = startTime + TimeUtils.MSEC_PER_DAY;
0569:                    DueOutList dueOuts = (DueOutList) dueOut_.get(day);
0570:                    for (int i = 0, n = dueOuts.size(); i < n; i++) {
0571:                        DueOut dueout = dueOuts.get(i);
0572:                        Task task = dueout.getTask();
0573:                        PlanElement pe = task.getPlanElement();
0574:                        if (pe == null)
0575:                            continue; // Probably being rescinded
0576:                        AllocationResultHelper helper = (AllocationResultHelper) helpers
0577:                                .get(pe);
0578:                        if (helper == null) {
0579:                            helper = new AllocationResultHelper(task, pe);
0580:                            helpers.put(pe, helper);
0581:                        }
0582:                        if (dueout.getFilled() != dueout.getPreviouslyFilled()) {
0583:                            if (dueout.getFilled()) {
0584:                                if (TaskUtils.isProjection(task)) {
0585:                                    helper.setBest(AlpineAspectType.DEMANDRATE,
0586:                                            startTime, endTime);
0587:                                } else {
0588:                                    helper.setBest(AspectType.QUANTITY,
0589:                                            startTime, endTime);
0590:                                }
0591:                            } else {
0592:                                if (TaskUtils.isProjection(task)) {
0593:                                    helper.setFailed(
0594:                                            AlpineAspectType.DEMANDRATE,
0595:                                            startTime, endTime);
0596:                                } else {
0597:                                    helper.setFailed(AspectType.QUANTITY,
0598:                                            startTime, endTime);
0599:                                }
0600:                            }
0601:                        }
0602:                    }
0603:                }
0604:                for (Iterator i = helpers.keySet().iterator(); i.hasNext();) {
0605:                    PlanElement pe = (PlanElement) i.next();
0606:                    AllocationResultHelper helper = (AllocationResultHelper) helpers
0607:                            .get(pe);
0608:                    if (helper.isChanged()) {
0609:                        AllocationResult ar = helper.getAllocationResult(1.0);
0610:                        pe.setEstimatedResult(ar);
0611:                        result.add(pe);
0612:                    }
0613:                }
0614:                return result;
0615:            }
0616:
0617:            // Looking for the lowest priority dueout from today to the given day.
0618:            public DueOut getLowestPriorityDueOutBeforeDay(int end) {
0619:                DueOut lowest = null;
0620:                // Also includes this day
0621:                int low = Math.max(0, today_);
0622:                int size = dueOut_.size() - 1;
0623:                if (end > size)
0624:                    end = size;
0625:                // Scan all dueouts for the specified days
0626:                for (int i = end; i >= low; i--) {
0627:                    DueOutList demand = (DueOutList) dueOut_.get(i);
0628:                    for (int h = 0, n = demand.size(); h < n; h++) {
0629:                        DueOut d = demand.get(h);
0630:                        if (d.getFilled()) {
0631:                            double weight = getWeightingFactor(d.getTask(), i
0632:                                    - today_);
0633:                            if (weight > 0.0) {
0634:                                if (lowest == null
0635:                                        || comparePriority(d, lowest) < 0) {
0636:                                    lowest = d;
0637:                                }
0638:                            }
0639:                        }
0640:                    }
0641:                }
0642:                return lowest; // Nothing found
0643:            }
0644:
0645:            public void setDueOutFilled(DueOut dueOut, boolean newFilled) {
0646:                dueOut.setFilled(newFilled);
0647:                updateDirtyDay(dueOut.getDay());
0648:            }
0649:
0650:            /**
0651:             * Compare two DueOuts for priority.
0652:             * Returns priority(d1) - priority(d2).
0653:             * Remember: priority 0 is high
0654:             * Remember: previouslyFilled is high
0655:             * Remember: 0.0 quantity is low
0656:             * @return the difference in priority of the DueOuts which will be
0657:             * negative if d1 has the lowest priority.
0658:             **/
0659:            private int comparePriority(DueOut d1, DueOut d2) {
0660:                int diff;
0661:                Task t1 = d1.getTask();
0662:                Task t2 = d2.getTask();
0663:                diff = TaskUtils.getNumericPriority(t1)
0664:                        - TaskUtils.getNumericPriority(t2);
0665:                if (diff != 0)
0666:                    return diff;
0667:                diff = (d1.getPreviouslyFilled() ? 1 : 0)
0668:                        - (d2.getPreviouslyFilled() ? 1 : 0);
0669:                if (diff != 0)
0670:                    return diff;
0671:                diff = d2.getDay() - d1.getDay();
0672:                if (diff != 0)
0673:                    return diff;
0674:                double q1 = getRequestedDailyQuantity(t1);
0675:                double q2 = getRequestedDailyQuantity(t2);
0676:                if (q1 != q2)
0677:                    return (q1 < q2) ? -1 : 1;
0678:                return 0;
0679:            }
0680:
0681:            private double getRequestedDailyQuantity(Task task) {
0682:                if (TaskUtils.isProjection(task)) {
0683:                    return TaskUtils.getDailyQuantity(task);
0684:                } else {
0685:                    return TaskUtils.getQuantity(task);
0686:                }
0687:            }
0688:
0689:            public void computeThresholdSchedule(int daysOfDemand,
0690:                    int daysForward, int daysBackward, double minReorderLevel,
0691:                    double maxReorderLevel, double goalLevelMultiplier) {
0692:
0693:                minReorderLevel_ = minReorderLevel;
0694:                maxReorderLevel_ = maxReorderLevel;
0695:                goalLevelMultiplier_ = goalLevelMultiplier;
0696:
0697:                daysOfDemand_ = daysOfDemand;
0698:                daysForward_ = daysForward;
0699:                daysBackward_ = daysBackward;
0700:
0701:                computeDemandSchedule();
0702:
0703:            }
0704:
0705:            protected double getTotalValidDueOuts(int day) {
0706:                double result = Double.NaN;
0707:                if (isDueOutValid(day))
0708:                    result = getDueOutTotal(day);
0709:
0710:                if (Double.isNaN(result))
0711:                    return 0.0;
0712:                else
0713:                    return result;
0714:            }
0715:
0716:            protected void computeDemandSchedule() {
0717:                computeDemandSchedule(daysOfDemand_, daysForward_,
0718:                        daysBackward_);
0719:            }
0720:
0721:            /**
0722:             *  Compute a schedule of the NDaysOfDemand using and averaging
0723:             *  window put the results in the a schedule.
0724:             */
0725:
0726:            protected void computeDemandSchedule(int daysOfDemand,
0727:                    int daysForward, int daysBackward) {
0728:
0729:                int days = level_.length;
0730:
0731:                double[] newDSched = new double[days];
0732:                int maxDay = dueOut_.size();
0733:                int nDays = 0;
0734:                double demand = 0.0;
0735:                int totalPeriod = days + daysForward - 1;
0736:
0737:                ///GLMDebug.DEBUG("InventoryBG::computeDemandSchedule:MWD", "MWD TESTING Start");
0738:                //if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG::computeDemandSchedule:MWD", "Days Forward:" + daysForward + " Days Backward: " + daysBackward + " Days of Demand:" + daysOfDemand + " Max Day: " + maxDay);
0739:
0740:                for (int i = 0; i < totalPeriod; i++) {
0741:
0742:                    //currDay is the day around which the window is built
0743:                    //i is really the leading edge of the window
0744:                    //start is the trailing end.
0745:                    int currDay = i - daysForward + 1;
0746:                    int start = currDay - daysBackward;
0747:
0748:                    double startDemand = 0.0;
0749:                    double endDemand = getTotalValidDueOuts(i);
0750:
0751:                    if (start >= 0) {
0752:                        startDemand = getTotalValidDueOuts(start - 1);
0753:                    }
0754:
0755:                    //If the start of the window hasn't come onto the scene
0756:                    //just add another day of demand
0757:                    if (currDay <= daysBackward) {
0758:                        demand += endDemand;
0759:                        nDays++;
0760:                    } else {
0761:                        //nominally the new day of demand comes from the right
0762:                        //of the window, and the 1st day of window falls off the 
0763:                        //left
0764:                        demand = demand + (endDemand - startDemand);
0765:                    }
0766:
0767:                    if (currDay >= 0) {
0768:                        if (nDays == 0)
0769:                            nDays = 1;
0770:                        //moved daysOfDemand_ to getNDaysOfDemand
0771:                        newDSched[currDay] = demand / nDays;
0772:                    }
0773:                }
0774:
0775:                int len = days;
0776:                if (demandSchedule_ != null) {
0777:                    int oldlen = demandSchedule_.length;
0778:                    for (int i = 0; i < len; i++) {
0779:                        if (i < oldlen) {
0780:                            double num = newDSched[i] - demandSchedule_[i];
0781:                            double den = newDSched[i] + demandSchedule_[i];
0782:                            if (den > 0.0) {
0783:                                if (num < 0.0 || Math.abs(num) / den < 0.1) {
0784:                                    newDSched[i] = demandSchedule_[i];
0785:                                }
0786:                            }
0787:                        }
0788:                    }
0789:                }
0790:                demandSchedule_ = newDSched;
0791:            }
0792:
0793:            public double getGoalLevel(int day) {
0794:
0795:                if (myPG_.getFillToCapacity()) {
0796:                    return getDouble(myPG_.getCapacity());
0797:                } else {
0798:                    double goal_level = goalLevelMultiplier_
0799:                            * getReorderLevel(day);
0800:                    double capacity = getDouble(myPG_.getCapacity());
0801:
0802:                    if (goal_level > capacity) {
0803:
0804:                        if (goalExceededCap == GOAL_EXCEEDED_CAPACITY_DEBUG_THRESHOLD) {
0805:                            if (logger.isErrorEnabled()) {
0806:                                logger
0807:                                        .error("getGoalLevel()::WARNING the goal level is exceeding the capacity.   It is probable that you should up the capacity in the inv config file.");
0808:                            }
0809:                        }
0810:
0811:                        if (goalExceededCap <= GOAL_EXCEEDED_CAPACITY_DEBUG_THRESHOLD) {
0812:                            goalExceededCap++;
0813:                        }
0814:                    }
0815:
0816:                    return goal_level;
0817:                }
0818:            }
0819:
0820:            public double getNDaysDemand(int day) {
0821:                if (day >= demandSchedule_.length) {
0822:                    //	    if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG","ARRGH Inventory array level is : " + level_.length);
0823:                    throw new IllegalArgumentException(
0824:                            "Demand Schedule Index is wrong! index = " + day
0825:                                    + " array is length "
0826:                                    + demandSchedule_.length);
0827:                }
0828:
0829:                return (daysOfDemand_ * demandSchedule_[day]);
0830:            }
0831:
0832:            public double getReorderLevel(int day) {
0833:
0834:                double rl = getNDaysDemand(day);
0835:
0836:                if (minReorderLevel_ > maxReorderLevel_) {
0837:                    throw new RuntimeException(
0838:                            "Minimum Reorder Level is Greater than Max Reorder Level");
0839:                }
0840:
0841:                rl = Math.min(maxReorderLevel_,
0842:                        (Math.max(minReorderLevel_, rl)));
0843:
0844:                return rl;
0845:            }
0846:
0847:            public int addPreviousRefillsToInventory(Task maintainInv) {
0848:                int totalFilled = 0;
0849:                if (maintainInv == null) {
0850:                    return 0;
0851:                }
0852:                PlanElement pe = maintainInv.getPlanElement();
0853:                if ((pe != null) && (pe instanceof  Expansion)) {
0854:                    Expansion expansion = (Expansion) pe;
0855:                    Workflow wf = expansion.getWorkflow();
0856:                    Enumeration tasks = wf.getTasks();
0857:                    while (tasks.hasMoreElements()) {
0858:                        Task refill = (Task) tasks.nextElement();
0859:                        totalFilled += addDueIn(refill);
0860:                    }
0861:                }
0862:                return totalFilled;
0863:            }
0864:
0865:            private void addDueIn(DueIn dueIn, int day) {
0866:                if (day >= 0) {
0867:                    while (day >= dueIns_.size()) {
0868:                        dueIns_.add(new DueInList(dueIns_.size()));
0869:                    }
0870:                    DueInList v = (DueInList) dueIns_.get(day);
0871:                    v.add(dueIn);
0872:                } else {
0873:                    throw new IllegalArgumentException(
0874:                            "InventoryBG: addDueIn(), Refill Starts in the past (start time "
0875:                                    + TimeUtils.dateString(getStartTime())
0876:                                    + "). Task = "
0877:                                    + TaskUtils.taskDesc(dueIn.getTask()));
0878:                }
0879:            }
0880:
0881:            public int addDueIn(Task refillTask) {
0882:                if (TaskUtils.isProjection(refillTask)) {
0883:                    return addDueInProjection(refillTask);
0884:                } else {
0885:                    return addDueInSupply(refillTask);
0886:                }
0887:            }
0888:
0889:            private void addDueInByRequestDay(DueIn d) {
0890:                int day = convertTimeToDay(TaskUtils.getEndTime(d.getTask()));
0891:                while (day >= dueInsByRequestDay_.size()) {
0892:                    dueInsByRequestDay_.add(new Vector(1));
0893:                }
0894:                Vector v = (Vector) dueInsByRequestDay_.elementAt(day);
0895:                v.addElement(d);
0896:            }
0897:
0898:            private void removeDueInByRequestDay(Task refillTask) {
0899:                int day = convertTimeToDay(TaskUtils.getEndTime(refillTask));
0900:                if (day < dueInsByRequestDay_.size()) {
0901:                    Vector v = (Vector) dueInsByRequestDay_.elementAt(day);
0902:                    for (Iterator i = v.iterator(); i.hasNext();) {
0903:                        DueIn d = (DueIn) i.next();
0904:                        if (d.getTask() == refillTask) {
0905:                            i.remove();
0906:                            return;
0907:                        }
0908:                    }
0909:                }
0910:            }
0911:
0912:            private int addDueInSupply(Task refill) {
0913:                int totalFilled = 0;
0914:                boolean filled = true;
0915:                double qty = TaskUtils.getRefillQuantity(refill);
0916:                if (qty == 0.0) {
0917:                    filled = false;
0918:                } else {
0919:                    filled = true;
0920:                    totalFilled++;
0921:                }
0922:                // Add Refill to daily schedule
0923:                // All times set to Midnight of that day
0924:                long refillTime = TaskUtils.getRefillTime(refill);
0925:                int day = convertTimeToDay(refillTime);
0926:                if (day >= 0) {
0927:                    DueIn d = new DueIn(refill, filled);
0928:                    addDueIn(d, day);
0929:                    addDueInByRequestDay(d);
0930:                } else {
0931:                    if (logger.isErrorEnabled()) {
0932:                        logger.error("addDueIn() on day " + day
0933:                                + ", refillTime="
0934:                                + TimeUtils.dateString(refillTime));
0935:                    }
0936:                }
0937:                return totalFilled;
0938:            }
0939:
0940:            private int addDueInProjection(Task task) {
0941:                int totalFilled = 0;
0942:                PlanElement pe = task.getPlanElement();
0943:                if (pe != null) {
0944:                    AllocationResultHelper helper = new AllocationResultHelper(
0945:                            task, pe);
0946:                    for (int i = 0, n = helper.getPhaseCount(); i < n; i++) {
0947:                        AllocationResultHelper.Phase phase = helper.getPhase(i);
0948:                        AspectValue av = phase
0949:                                .getAspectValue(AlpineAspectType.DEMANDRATE);
0950:                        boolean filled = av.getValue() != 0.0;
0951:                        totalFilled += addDueInRange(task,
0952:                                phase.getStartTime(), phase.getEndTime(),
0953:                                filled);
0954:                    }
0955:                } else {
0956:                    totalFilled += addDueInRange(task, TaskUtils
0957:                            .getStartTime(task), TaskUtils.getEndTime(task),
0958:                            true);
0959:                }
0960:                return totalFilled;
0961:            }
0962:
0963:            private int addDueInRange(Task task, long startTime, long endTime,
0964:                    boolean filled) {
0965:                int totalFilled = 0;
0966:                int start = convertTimeToDay(startTime);
0967:                int end = convertTimeToDay(endTime);
0968:                if (start < 0) {
0969:                    start = 0;
0970:                }
0971:                for (int day = start; day < end; day++) {
0972:                    addDueIn(new DueIn(task, filled), day);
0973:                    if (filled)
0974:                        totalFilled++;
0975:                }
0976:                return totalFilled;
0977:            }
0978:
0979:            public int removeDueIn(Task refillTask) {
0980:                // Remove Task from local structure
0981:                int day = convertTimeToDay(TaskUtils.getEndTime(refillTask));
0982:                try {
0983:                    DueInList v = (DueInList) dueIns_.get(day);
0984:                    v.remove(refillTask);
0985:                } catch (ArrayIndexOutOfBoundsException exception) {
0986:                    if (logger.isErrorEnabled()) {
0987:                        logger.error("removeDueIn, day " + day
0988:                                + ": Refill not found. "
0989:                                + TaskUtils.taskDesc(refillTask));
0990:                    }
0991:                }
0992:                removeDueInByRequestDay(refillTask);
0993:                return 0;
0994:            }
0995:
0996:            public int getPlanningDays() {
0997:                if (level_ == null) {
0998:                    determineInventoryLevels();
0999:                }
1000:                return level_.length;
1001:            }
1002:
1003:            public int determineInventoryLevels() {
1004:                if (needInitializeInventoryLevels) {
1005:                    initializeInventoryLevels();
1006:                    needInitializeInventoryLevels = false;
1007:                }
1008:                return 0;
1009:            }
1010:
1011:            protected void initializeInventoryLevels() {
1012:                int today = getToday();
1013:                int size = today + 1; // Always include tomorrow in the levels.
1014:                double reported_levels[] = getTimeOrderedReportedLevels();
1015:                if (dueIns_.size() > size)
1016:                    size = dueIns_.size();
1017:                if (dueOut_.size() > size)
1018:                    size = dueOut_.size();
1019:                if (reported_levels.length > size)
1020:                    size = reported_levels.length;
1021:
1022:                if (level_ == null || level_.length < size) {
1023:                    double[] replacementLevel = new double[size];
1024:
1025:                    //Don't lose info that's already been computed.
1026:                    if (level_ != null) {
1027:                        System.arraycopy(level_, 0, replacementLevel, 0,
1028:                                level_.length);
1029:                    }
1030:
1031:                    level_ = replacementLevel;
1032:                    computeDemandSchedule();
1033:                }
1034:
1035:                /* Note that there is always at least one item in
1036:                   reported_levels so dirtyDay_ will always end up being
1037:                   greater than zero */
1038:                for (int i = dirtyDay_, n = reported_levels.length; i < n; i++) {
1039:                    double lvl = reported_levels[i];
1040:                    if (!Double.isNaN(lvl)) {
1041:                        level_[i] = reported_levels[i];
1042:                        dirtyDay_ = i + 1;
1043:                    }
1044:                }
1045:            }
1046:
1047:            private void updateLevels(int day) {
1048:                double lvl = level_[dirtyDay_ - 1]; // dirtyDay_ always > 0 (see above)
1049:                for (int i = dirtyDay_; i <= day; i++) {
1050:                    double dueout = getDueOutTotal(i);
1051:                    double duein = getDueInTotal(i);
1052:                    lvl += duein - dueout;
1053:                    level_[i] = lvl;
1054:                }
1055:                dirtyDay_ = day + 1;
1056:            }
1057:
1058:            private boolean isDueOutValid(int day) {
1059:                if (day < 0)
1060:                    return false;
1061:                if (day >= dueOut_.size())
1062:                    return false;
1063:                return true;
1064:            }
1065:
1066:            private double getDueOutTotal(int day) {
1067:                if (!isDueOutValid(day))
1068:                    return 0.0;
1069:                DueOutList dueOuts = (DueOutList) dueOut_.get(day);
1070:                return dueOuts.getTotal();
1071:            }
1072:
1073:            public Scalar getProjected(int day) {
1074:                if (!isDueOutValid(day)) {
1075:                    return null;
1076:                }
1077:                DueOutList dueOuts = (DueOutList) dueOut_.get(day);
1078:                return getScalar(dueOuts.getProjectedTotal());
1079:            }
1080:
1081:            public Scalar getProjectedRefill(int day) {
1082:                if (!isDueInValid(day))
1083:                    return getScalar(0.0);
1084:                DueInList dueIns = (DueInList) dueIns_.get(day);
1085:                return getScalar(dueIns.getProjectedTotal());
1086:            }
1087:
1088:            private double getWeightingFactor(Task task, int imputedDay) {
1089:                if (weight_ != null) {
1090:                    return weight_.getProjectionWeight(task, imputedDay);
1091:                } else {
1092:                    if (logger.isErrorEnabled()) {
1093:                        logger
1094:                                .error("getWeightingFactor(), Weighting Factor NOT set.");
1095:                    }
1096:                    return 0.0;
1097:                }
1098:            }
1099:
1100:            private boolean isDueInValid(int day) {
1101:                if (day < 0)
1102:                    return false;
1103:                if (day >= dueIns_.size())
1104:                    return false;
1105:                return true;
1106:            }
1107:
1108:            private double getDueInTotal(int day) {
1109:                if (!isDueInValid(day))
1110:                    return 0.0;
1111:                DueInList dueIns = (DueInList) dueIns_.get(day);
1112:                return dueIns.getTotal();
1113:            }
1114:
1115:            public Task refillAlreadyFailedOnDay(int day) {
1116:                Enumeration dueins = null;
1117:                if (day < dueInsByRequestDay_.size()) {
1118:                    Vector v = (Vector) dueInsByRequestDay_.get(day);
1119:                    dueins = v.elements();
1120:                }
1121:                if (dueins != null) {
1122:                    while (dueins.hasMoreElements()) {
1123:                        DueIn d = (DueIn) dueins.nextElement();
1124:                        Task task = d.getTask();
1125:                        if (task.getVerb().equals(Constants.Verb.SUPPLY)) {
1126:                            if (!d.getFilled())
1127:                                return task;
1128:                        }
1129:                    }
1130:                }
1131:                return null;
1132:            }
1133:
1134:            /**
1135:               Get _the_ refill for a particular day. This assumes that only
1136:               one refill exists for a particular day. In fact, we return the
1137:               smallest refill for a particular day.
1138:             **/
1139:            public Task getRefillOnDay(int day) {
1140:                Enumeration dueins = null;
1141:                if (day < dueInsByRequestDay_.size()) {
1142:                    Vector v = (Vector) dueInsByRequestDay_.get(day);
1143:                    dueins = v.elements();
1144:                }
1145:                if (dueins != null) {
1146:                    Task smallestRefill = null;
1147:                    double smallestQuantity = Double.POSITIVE_INFINITY;
1148:                    while (dueins.hasMoreElements()) {
1149:                        DueIn d = (DueIn) dueins.nextElement();
1150:                        Task task = d.getTask();
1151:                        if (task.getVerb().equals(Constants.Verb.SUPPLY)) {
1152:                            double q = TaskUtils.getRefillQuantity(task);
1153:                            if (q < smallestQuantity) {
1154:                                smallestQuantity = q;
1155:                                smallestRefill = task;
1156:                            }
1157:                        }
1158:                    }
1159:                    return smallestRefill;
1160:                }
1161:                return null;
1162:            }
1163:
1164:            public void removeRefillProjection(int day) {
1165:                if (!isDueInValid(day))
1166:                    return; // Nothing to remove
1167:                DueInList dueIns = (DueInList) dueIns_.get(day);
1168:                dueIns.clear();
1169:            }
1170:
1171:            public Date lastDemandTaskEnd(Inventory inventory) {
1172:                long latest_time = -1;
1173:                long end_time;
1174:                Task task;
1175:                Enumeration role_sched = inventory.getRoleSchedule()
1176:                        .getRoleScheduleElements();
1177:                while (role_sched.hasMoreElements()) {
1178:                    PlanElement pe = (PlanElement) role_sched.nextElement();
1179:                    task = pe.getTask();
1180:                    latest_time = Math.max(latest_time, TaskUtils
1181:                            .getRefillTime(task));
1182:                }
1183:                if (latest_time < 0)
1184:                    return null;
1185:                latest_time = canonicalTime(latest_time);
1186:                return new Date(latest_time);
1187:            }
1188:
1189:            public Integer getFirstOverflow(int i, MessageAddress cluster) {
1190:                if (level_ == null)
1191:                    determineInventoryLevels();
1192:                int size = level_.length;
1193:                double capacity = getDouble(myPG_.getCapacity());
1194:                Integer day = null;
1195:                if ((i > size) || (i < 0))
1196:                    return null;
1197:                for (; i < size; i++) {
1198:                    //  	    if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG()", cluster, "getFirstOverflow(), checking for overflow on "+
1199:                    //  			   (TimeUtils.dateString(TimeUtils.addNDays(getStartTime(), i)))+" Level: "+level_[i]+" capacity: "+capacity);
1200:                    if (Math.floor(level_[i] - capacity) > 1.0) {
1201:                        //Put in printDebug statement because you put together the
1202:                        // strings whether you print them or not which can get
1203:                        // costly performance wise.
1204:                        if (logger.isDebugEnabled()) {
1205:                            logger.debug("getFirstOverflow(), OVERFLOW on "
1206:                                    + (TimeUtils
1207:                                            .dateString(convertDayToTime(i))));
1208:                        }
1209:                        return new Integer(i);
1210:                    }
1211:                }
1212:                return null;
1213:            }
1214:
1215:            public int updateContentSchedule(Inventory inventory) {
1216:                ScheduledContentPG scp = inventory.getScheduledContentPG();
1217:                QuantityScheduleElement qse;
1218:                Vector new_elements = new Vector();
1219:                if (level_ == null) {
1220:                    determineInventoryLevels();
1221:                }
1222:                if (level_ == null) {
1223:                    if (logger.isDebugEnabled()) {
1224:                        logger
1225:                                .debug("UpdateContentSchedule(), No DueOuts or DueIns, resetting schedule.");
1226:                    }
1227:                    clearContentSchedule(inventory);
1228:                } else {
1229:                    int days = level_.length;
1230:                    updateLevels(days - 1); // Be sure we have all the days computed.
1231:                    //  	    if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG", "UpdateContentSchedule(), Creating new Schedule for "+AssetUtils.assetDesc(inventory));
1232:                    for (int i = 0; i < days; i++) {
1233:                        // start time is eigher today or time 1st request was received + number of planning days
1234:                        long start = TimeUtils.addNDaysTime(getStartTime(), i);
1235:                        // end time is a millisecond before start time of next day
1236:                        long end = TimeUtils.addNDaysTime(getStartTime(),
1237:                                (i + 1));
1238:                        try {
1239:                            qse = ScheduleUtils.buildQuantityScheduleElement(
1240:                                    level_[i], start, end);
1241:                        } catch (IllegalArgumentException iae) {
1242:                            iae.printStackTrace();
1243:                            continue;
1244:                        }
1245:                        //  		if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG", "UpdateContentSchedule(), Start:"+TimeUtils.dateString(start)+
1246:                        //  			       ", End:"+TimeUtils.dateString(end)+", Qty: "+level_[i]);
1247:                        new_elements.add(qse);
1248:                    }
1249:                }
1250:                Schedule new_schedule = GLMFactory.newQuantitySchedule(
1251:                        new_elements.elements(),
1252:                        PlanScheduleType.TOTAL_INVENTORY);
1253:
1254:                if (ScheduleUtils.isOffendingSchedule(new_schedule)) {
1255:                    if (logger.isErrorEnabled()) {
1256:                        logger
1257:                                .error("UpdateContentSchedule(),  CREATED BAD SCHEDULE ");
1258:                    }
1259:                    printQuantityScheduleTimes(new_schedule);
1260:                }
1261:                ((NewScheduledContentPG) scp).setSchedule(new_schedule);
1262:                return 0;
1263:            }
1264:
1265:            public int updateInventoryLevelsSchedule(Inventory inventory) {
1266:                InventoryLevelsPG ilp = inventory.getInventoryLevelsPG();
1267:                QuantityScheduleElement dse, rlse, glse;
1268:                Vector new_av_demand_elements = new Vector();
1269:                Vector new_reorder_elements = new Vector();
1270:                Vector new_goal_elements = new Vector();
1271:                if (demandSchedule_ == null) {
1272:                    if (logger.isDebugEnabled()) {
1273:                        logger
1274:                                .debug("UpdateInventoryLevelsSchedule(), No Demand Schedule Set.");
1275:                    }
1276:                    clearInventoryLevelsSchedule(inventory);
1277:                } else {
1278:                    int days = demandSchedule_.length;
1279:                    //  	    if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG", "UpdateInventoryLevelsSchedule(), Creating new Schedule for "+AssetUtils.assetDesc(inventory));
1280:                    for (int i = 0; i < days; i++) {
1281:                        // start time is eigher today or time 1st request was received + number of planning days
1282:                        long start = TimeUtils.addNDaysTime(getStartTime(), i);
1283:                        // end time is a millisecond before start time of next day
1284:                        long end = TimeUtils.addNDaysTime(getStartTime(),
1285:                                (i + 1));
1286:                        try {
1287:                            dse = ScheduleUtils.buildQuantityScheduleElement(
1288:                                    demandSchedule_[i], start, end);
1289:                            rlse = ScheduleUtils.buildQuantityScheduleElement(
1290:                                    getReorderLevel(i), start, end);
1291:                            glse = ScheduleUtils.buildQuantityScheduleElement(
1292:                                    getGoalLevel(i), start, end);
1293:                        } catch (IllegalArgumentException iae) {
1294:                            iae.printStackTrace();
1295:                            continue;
1296:                        }
1297:                        //  	if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG", "UpdateInventoryLevelschedule(), Start:"+TimeUtils.dateString(start)+
1298:                        //  			       ", End:"+TimeUtils.dateString(end)+", Qty: "+level_[i]);
1299:                        new_av_demand_elements.add(dse);
1300:                        new_reorder_elements.add(rlse);
1301:                        new_goal_elements.add(glse);
1302:                    }
1303:                }
1304:                Schedule new_av_demand_schedule = GLMFactory
1305:                        .newQuantitySchedule(new_av_demand_elements.elements(),
1306:                                PlanScheduleType.TOTAL_INVENTORY);
1307:                Schedule new_reorder_schedule = GLMFactory.newQuantitySchedule(
1308:                        new_reorder_elements.elements(),
1309:                        PlanScheduleType.TOTAL_INVENTORY);
1310:                Schedule new_goal_schedule = GLMFactory.newQuantitySchedule(
1311:                        new_goal_elements.elements(),
1312:                        PlanScheduleType.TOTAL_INVENTORY);
1313:
1314:                if (ScheduleUtils.isOffendingSchedule(new_av_demand_schedule)) {
1315:                    if (logger.isErrorEnabled()) {
1316:                        logger
1317:                                .error("UpdateInventoryLevelschedule(),  CREATED BAD nDays SCHEDULE  ");
1318:                    }
1319:                    printQuantityScheduleTimes(new_av_demand_schedule);
1320:                }
1321:                if (ScheduleUtils.isOffendingSchedule(new_reorder_schedule)) {
1322:                    if (logger.isErrorEnabled()) {
1323:                        logger
1324:                                .error("UpdateInventoryLevelschedule(),  CREATED BAD reorder SCHEDULE  ");
1325:                    }
1326:                    printQuantityScheduleTimes(new_reorder_schedule);
1327:                }
1328:                if (ScheduleUtils.isOffendingSchedule(new_goal_schedule)) {
1329:                    if (logger.isErrorEnabled()) {
1330:                        logger
1331:                                .error("UpdateInventoryLevelschedule(),  CREATED BAD goal SCHEDULE  ");
1332:                    }
1333:                    printQuantityScheduleTimes(new_goal_schedule);
1334:                }
1335:                ((NewInventoryLevelsPG) ilp)
1336:                        .setAverageDemandSchedule(new_av_demand_schedule);
1337:                ((NewInventoryLevelsPG) ilp)
1338:                        .setReorderLevelSchedule(new_reorder_schedule);
1339:                ((NewInventoryLevelsPG) ilp)
1340:                        .setGoalLevelSchedule(new_goal_schedule);
1341:                return 0;
1342:            }
1343:
1344:            public int updateDetailedContentSchedule(Inventory inventory) {
1345:                if (!isStartTimeSet)
1346:                    return -1;
1347:                if (level_ == null) {
1348:                    determineInventoryLevels();
1349:                }
1350:                if (level_ == null)
1351:                    return -1;
1352:                //      System.out.println(">>>UpdateDetailedContentSchedule ");
1353:                int days = level_.length;
1354:                updateLevels(days - 1); // Be sure we have all the days computed.
1355:                Vector quantity_schedule_elements = new Vector();
1356:                for (int i = 0; i < days; i++) {
1357:                    quantity_schedule_elements = createDailyScheduleElements(
1358:                            quantity_schedule_elements, i);
1359:                }
1360:                Schedule sched = GLMFactory.newQuantitySchedule(
1361:                        quantity_schedule_elements.elements(),
1362:                        PlanScheduleType.TOTAL_INVENTORY);
1363:                if (ScheduleUtils.isOffendingSchedule(sched)) {
1364:                    if (logger.isErrorEnabled()) {
1365:                        logger
1366:                                .error("UpdateContentSchedule(),  CREATED BAD SCHEDULE ");
1367:                    }
1368:                }
1369:                NewDetailedScheduledContentPG newDetailedPG = org.cougaar.glm.ldm.asset.PropertyGroupFactory
1370:                        .newDetailedScheduledContentPG();
1371:                newDetailedPG.setSchedule(sched);
1372:                inventory.setPropertyGroup(newDetailedPG);
1373:                printDetailedSchedule(sched);
1374:                return 0;
1375:            }
1376:
1377:            private Vector createDailyScheduleElements(
1378:                    Vector quantity_schedule_elements, int day) {
1379:                long start = TimeUtils.addNDaysTime(getStartTime(), day);
1380:                long end = TimeUtils.addNDaysTime(getStartTime(), day + 1);
1381:                double current_level;
1382:                if (day == 0) {
1383:                    current_level = getDouble(myPG_.getInitialLevel());
1384:                } else {
1385:                    current_level = level_[day - 1];
1386:                }
1387:                ArrayList activityToday = new ArrayList();
1388:                double projectedDueIns = 0;
1389:                DueInList dil = null;
1390:                if (dueIns_.size() > day) {
1391:                    dil = (DueInList) dueIns_.get(day);
1392:                    if ((dil != null) && (dil.size() > 0)) {
1393:                        activityToday.addAll(dil.getSupplyTasks());
1394:                        projectedDueIns = dil.getProjectedTotal();
1395:                    }
1396:                }
1397:                double projectedDueOuts = 0;
1398:                DueOutList dol = null;
1399:                if (dueOut_.size() > day) {
1400:                    dol = (DueOutList) dueOut_.get(day);
1401:                    if ((dol != null) && (dol.size() > 0)) {
1402:                        activityToday.addAll(dol.getWithdrawTasks());
1403:                        projectedDueOuts = dol.getProjectedTotal();
1404:                    }
1405:                }
1406:
1407:                current_level += projectedDueIns;
1408:                current_level -= projectedDueOuts;
1409:                quantity_schedule_elements
1410:                        .add(ScheduleUtils.buildQuantityScheduleElement(
1411:                                current_level, start, end));
1412:
1413:                return accountForDailyTasks(quantity_schedule_elements,
1414:                        activityToday);
1415:
1416:            }
1417:
1418:            private Vector accountForDailyTasks(
1419:                    Vector quantity_schedule_elements, ArrayList activityToday) {
1420:
1421:                if (!activityToday.isEmpty()) {
1422:                    Task[] ordered_tasks = (Task[]) activityToday
1423:                            .toArray(new Task[activityToday.size()]);
1424:                    java.util.Arrays.sort(ordered_tasks, new Comparator() {
1425:                        public int compare(Object o1, Object o2) {
1426:                            long t1_end_time = TaskUtils.getEndTime((Task) o1);
1427:                            long t2_end_time = TaskUtils.getEndTime((Task) o2);
1428:                            long diff = t1_end_time - t2_end_time;
1429:                            if (diff < 0L)
1430:                                return -1;
1431:                            if (diff > 0L)
1432:                                return 1;
1433:                            return 0;
1434:                        }
1435:                    });
1436:                    long time;
1437:                    int size = ordered_tasks.length;
1438:                    for (int k = 0; k < size; k++)
1439:                        System.out.println(">>>        "
1440:                                + TaskUtils.shortTaskDesc(ordered_tasks[k]));
1441:                    for (int i = 0; i < size; i++) {
1442:                        time = TaskUtils.getEndTime(ordered_tasks[i]);
1443:                        QuantityScheduleElement qse = (QuantityScheduleElement) quantity_schedule_elements
1444:                                .get(quantity_schedule_elements.size() - 1);
1445:                        long previous_start = qse.getStartTime();
1446:                        long previous_end = qse.getEndTime();
1447:                        double level = qse.getQuantity();
1448:                        if (time > previous_start) {
1449:                            quantity_schedule_elements.set(
1450:                                    quantity_schedule_elements.size() - 1,
1451:                                    ScheduleUtils.buildQuantityScheduleElement(
1452:                                            level, previous_start, time));
1453:                            if (ordered_tasks[i].getVerb().equals(
1454:                                    Constants.Verb.SUPPLY))
1455:                                level += TaskUtils
1456:                                        .getRefillQuantity(ordered_tasks[i]);
1457:                            else
1458:                                level -= TaskUtils
1459:                                        .getWithdrawQuantity(ordered_tasks[i]);
1460:                            quantity_schedule_elements.add(ScheduleUtils
1461:                                    .buildQuantityScheduleElement(level, time,
1462:                                            previous_end));
1463:                        } else { // time is equal to old start time
1464:                            if (ordered_tasks[i].getVerb().equals(
1465:                                    Constants.Verb.SUPPLY))
1466:                                level += TaskUtils
1467:                                        .getRefillQuantity(ordered_tasks[i]);
1468:                            else
1469:                                level -= TaskUtils
1470:                                        .getWithdrawQuantity(ordered_tasks[i]);
1471:                            ((NewQuantityScheduleElement) qse)
1472:                                    .setQuantity(level);
1473:                        }
1474:                    }
1475:                }
1476:                return quantity_schedule_elements;
1477:            }
1478:
1479:            private void printDetailedSchedule(Schedule sched) {
1480:                Enumeration e = sched.getAllScheduleElements();
1481:                QuantityScheduleElement qse;
1482:                while (e.hasMoreElements()) {
1483:                    qse = (QuantityScheduleElement) e.nextElement();
1484:                    double qty = qse.getQuantity();
1485:                    long start = qse.getStartTime();
1486:                    long end = qse.getEndTime();
1487:                    System.out.println("           Start: "
1488:                            + TimeUtils.dateString(start) + " End: "
1489:                            + TimeUtils.dateString(end) + " Quantity: " + qty);
1490:                }
1491:            }
1492:
1493:            public int clearContentSchedule(Inventory inventory) {
1494:                if (!isStartTimeSet)
1495:                    return -1;
1496:                ScheduledContentPG scp = inventory.getScheduledContentPG();
1497:                Schedule sched = scp.getSchedule();
1498:                QuantityScheduleElement qse;
1499:                Vector new_elements = new Vector();
1500:                long start = TimeUtils.addNDaysTime(getStartTime(), 0);
1501:                long end = TimeUtils.addNDaysTime(getStartTime(), 30);
1502:
1503:                qse = ScheduleUtils.buildQuantityScheduleElement(
1504:                        getDouble(myPG_.getInitialLevel()), start, end);
1505:                new_elements.add(qse);
1506:                Schedule new_schedule = GLMFactory.newQuantitySchedule(
1507:                        new_elements.elements(),
1508:                        PlanScheduleType.TOTAL_INVENTORY);
1509:
1510:                if (ScheduleUtils.isOffendingSchedule(new_schedule)) {
1511:                    if (logger.isErrorEnabled()) {
1512:                        logger
1513:                                .error("UpdateContentSchedule(),  CREATED BAD SCHEDULE ");
1514:                    }
1515:                    printQuantityScheduleTimes(new_schedule);
1516:                }
1517:                ((NewScheduledContentPG) scp).setSchedule(new_schedule);
1518:                return 0;
1519:
1520:            }
1521:
1522:            public int clearInventoryLevelsSchedule(Inventory inventory) {
1523:                if (!isStartTimeSet)
1524:                    return -1;
1525:                InventoryLevelsPG ilp = inventory.getInventoryLevelsPG();
1526:                QuantityScheduleElement dse, rlse, glse;
1527:                Vector new_av_demand_elements = new Vector();
1528:                Vector new_reorder_elements = new Vector();
1529:                Vector new_goal_elements = new Vector();
1530:                long start = TimeUtils.addNDaysTime(getStartTime(), 0);
1531:                long end = TimeUtils.addNDaysTime(getStartTime(), 30);
1532:
1533:                dse = ScheduleUtils.buildQuantityScheduleElement(0, start, end);
1534:                rlse = ScheduleUtils
1535:                        .buildQuantityScheduleElement(0, start, end);
1536:                glse = ScheduleUtils
1537:                        .buildQuantityScheduleElement(0, start, end);
1538:                new_av_demand_elements.add(dse);
1539:                new_reorder_elements.add(rlse);
1540:                new_goal_elements.add(glse);
1541:
1542:                Schedule new_av_demand_schedule = GLMFactory
1543:                        .newQuantitySchedule(new_av_demand_elements.elements(),
1544:                                PlanScheduleType.TOTAL_INVENTORY);
1545:                Schedule new_reorder_schedule = GLMFactory.newQuantitySchedule(
1546:                        new_reorder_elements.elements(),
1547:                        PlanScheduleType.TOTAL_INVENTORY);
1548:                Schedule new_goal_schedule = GLMFactory.newQuantitySchedule(
1549:                        new_goal_elements.elements(),
1550:                        PlanScheduleType.TOTAL_INVENTORY);
1551:
1552:                if (ScheduleUtils.isOffendingSchedule(new_av_demand_schedule)) {
1553:                    if (logger.isErrorEnabled()) {
1554:                        logger
1555:                                .error("clearInventoryLevelSchedule(),  CREATED BAD nDays SCHEDULE  ");
1556:                    }
1557:                    printQuantityScheduleTimes(new_av_demand_schedule);
1558:                }
1559:                if (ScheduleUtils.isOffendingSchedule(new_reorder_schedule)) {
1560:                    if (logger.isErrorEnabled()) {
1561:                        logger
1562:                                .error("clearInventoryLevelSchedule(),  CREATED BAD reorder SCHEDULE  ");
1563:                    }
1564:                    printQuantityScheduleTimes(new_reorder_schedule);
1565:                }
1566:                if (ScheduleUtils.isOffendingSchedule(new_goal_schedule)) {
1567:                    if (logger.isErrorEnabled()) {
1568:                        logger
1569:                                .error("clearInventoryLevelSchedule(),  CREATED BAD goal SCHEDULE  ");
1570:                    }
1571:                    printQuantityScheduleTimes(new_goal_schedule);
1572:                }
1573:                ((NewInventoryLevelsPG) ilp)
1574:                        .setAverageDemandSchedule(new_av_demand_schedule);
1575:                ((NewInventoryLevelsPG) ilp)
1576:                        .setReorderLevelSchedule(new_reorder_schedule);
1577:                ((NewInventoryLevelsPG) ilp)
1578:                        .setGoalLevelSchedule(new_goal_schedule);
1579:
1580:                return 0;
1581:
1582:            }
1583:
1584:            public int printQuantityScheduleTimes(Schedule sched) {
1585:                Enumeration elements = sched.getAllScheduleElements();
1586:                QuantityScheduleElement qse;
1587:
1588:                while (elements.hasMoreElements()) {
1589:                    qse = (QuantityScheduleElement) elements.nextElement();
1590:                    if (logger.isDebugEnabled()) {
1591:                        logger.debug("printQuantityScheduleTimes()    qty: "
1592:                                + qse.getQuantity() + " " + qse.getStartTime()
1593:                                + " to " + qse.getEndTime());
1594:                    }
1595:                }
1596:                return 0;
1597:            }
1598:
1599:            public PGDelegate copy(PropertyGroup pg) {
1600:                return new InventoryBG((InventoryPG) pg);
1601:            }
1602:
1603:            /**
1604:             * Add the newInventoryReport to the report_history ArrayList
1605:             **/
1606:            public void addInventoryReport(InventoryReport newInventoryReport) {
1607:                synchronized (this ) {
1608:                    report_history.add(newInventoryReport);
1609:                    if (latest_report == null
1610:                            || latest_report.theReportDate < newInventoryReport.theReportDate) {
1611:                        latest_report = newInventoryReport;
1612:                    }
1613:                    if (oldest_report == null
1614:                            || oldest_report.theReportDate > newInventoryReport.theReportDate) {
1615:                        oldest_report = newInventoryReport;
1616:                    }
1617:                }
1618:                if (logger.isDebugEnabled()) {
1619:                    logger.debug("addInventoryReport(), Report added!!!!!!! : "
1620:                            + this .hashCode());
1621:                }
1622:            }
1623:
1624:            /**
1625:             * Remove inventory reports older than a specified time. Never removes the latest report.
1626:             **/
1627:            public void pruneOldInventoryReports(long pruneTime) {
1628:                synchronized (this ) {
1629:                    for (Iterator i = report_history.iterator(); i.hasNext();) {
1630:                        InventoryReport report = (InventoryReport) i.next();
1631:                        if (pruneTime > report.theReportDate
1632:                                && report != latest_report) {
1633:                            i.remove();
1634:                        }
1635:                    }
1636:                    oldest_report = null; // We probably removed this, recompute when asked
1637:                }
1638:            }
1639:
1640:            /**
1641:             * Returns the report_history ArrayList
1642:             **/
1643:            private ArrayList getInventoryReportHistory() {
1644:                synchronized (this ) {
1645:                    return report_history;
1646:                }
1647:            }
1648:
1649:            /**
1650:             * Returns the InventoryReport with the latest date
1651:             **/
1652:            public InventoryReport getLatestInventoryReport() {
1653:                synchronized (this ) {
1654:                    if (latest_report == null) { // This is almost always up-to-date, but in case it isn't...
1655:                        for (Iterator i = report_history.iterator(); i
1656:                                .hasNext();) {
1657:                            InventoryReport report = (InventoryReport) i.next();
1658:                            if (latest_report == null
1659:                                    || latest_report.theReportDate < report.theReportDate) {
1660:                                latest_report = report;
1661:                            }
1662:                        }
1663:                    }
1664:                    return latest_report;
1665:                }
1666:            }
1667:
1668:            /**
1669:             * Returns the InventoryReport with the oldest date
1670:             **/
1671:            public InventoryReport getOldestInventoryReport() {
1672:                synchronized (this ) {
1673:                    if (oldest_report == null) { // This is almost always up-to-date, but in case it isn't...
1674:                        for (Iterator i = report_history.iterator(); i
1675:                                .hasNext();) {
1676:                            InventoryReport report = (InventoryReport) i.next();
1677:                            if (oldest_report == null
1678:                                    || oldest_report.theReportDate > report.theReportDate) {
1679:                                oldest_report = report;
1680:                            }
1681:                        }
1682:                    }
1683:                    return oldest_report;
1684:                }
1685:            }
1686:
1687:            /**
1688:             * Returns a time-ordered list of known InventoryReports
1689:             **/
1690:            private double[] getTimeOrderedReportedLevels() {
1691:                double ordered_list[];
1692:                InventoryReport[] reports;
1693:                synchronized (this ) { // Must be synchronized so reports cannot change while we process them
1694:                    List list = getInventoryReportHistory();
1695:                    int size = list.size();
1696:                    reports = (InventoryReport[]) list
1697:                            .toArray(new InventoryReport[size]);
1698:                }
1699:                // No Reports - use PG for initial inventory level
1700:                if (reports.length == 0) {
1701:                    ordered_list = new double[1];
1702:                    ordered_list[0] = getDouble(myPG_.getInitialLevel());
1703:                    //  	    if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG", "getTimeOrderedReportedLevels(), List is empty.");
1704:                } else {
1705:                    //  	    if(GLMDebug.printDebug()) GLMDebug.DEBUG("InventoryBG", "getTimeOrderedReportedLevels(), Sorting Report list.");
1706:                    // Sort the Reports by time in ascending order
1707:                    // Yah, it's inefficient but it's only a few lines of code and there should never
1708:                    // be more than 5 items in this list
1709:                    java.util.Arrays.sort(reports, new Comparator() {
1710:                        public int compare(Object o1, Object o2) {
1711:                            InventoryReport r1 = (InventoryReport) o1;
1712:                            InventoryReport r2 = (InventoryReport) o2;
1713:                            long diff = r1.theReportDate - r2.theReportDate;
1714:                            if (diff < 0L)
1715:                                return -1;
1716:                            if (diff > 0L)
1717:                                return 1;
1718:                            return 0;
1719:                        }
1720:                    });
1721:                    long latest = reports[reports.length - 1].theReportDate;
1722:
1723:                    // create a double[] containing inventory levels indexed by day
1724:                    int reportDay = convertTimeToDay(latest);
1725:                    int len = reportDay + 1;
1726:                    if (len <= 0) {
1727:                        len = 1;
1728:                    }
1729:                    ordered_list = new double[len];
1730:                    java.util.Arrays.fill(ordered_list, Double.NaN);
1731:                    ordered_list[0] = getDouble(myPG_.getInitialLevel());
1732:                    for (int i = 0, n = reports.length; i < n; i++) {
1733:                        long report_date = reports[i].theReportDate;
1734:                        int day = convertTimeToDay(report_date);
1735:                        // Last Report that was received before or on day 0 becomes initial value
1736:                        if (day < 0) {
1737:                            day = 0;
1738:                        }
1739:                        ordered_list[day] = reports[i].theQuantity;
1740:                        if (logger.isDebugEnabled()) {
1741:                            logger
1742:                                    .debug("getTimeOrderedReportedLevels(), Report day is "
1743:                                            + day
1744:                                            + "("
1745:                                            + TimeUtils.dateString(report_date)
1746:                                            + "), Value is: "
1747:                                            + ordered_list[day]);
1748:                        }
1749:                    }
1750:                }
1751:                return ordered_list;
1752:            }
1753:
1754:            private static final Volume zeroVolume = new Volume(0,
1755:                    Volume.GALLONS);
1756:            private static final Count zeroCount = new Count(0, Count.EACHES);
1757:            private static final Mass zeroMass = new Mass(0, Mass.SHORT_TONS);
1758:
1759:            /** 
1760:             * Given a double, create scalar apropriate for this type of inventory 
1761:             **/
1762:            private Scalar getScalar(double amt) {
1763:                Scalar measure = myPG_.getInitialLevel();
1764:                if (measure instanceof  Volume) {
1765:                    if (amt == 0.0)
1766:                        return zeroVolume;
1767:                    else
1768:                        return new Volume(amt, Volume.GALLONS);
1769:                }
1770:                if (measure instanceof  Count) {
1771:                    if (amt == 0.0)
1772:                        return zeroCount;
1773:                    else
1774:                        return new Count(amt, Count.EACHES);
1775:                }
1776:                if (measure instanceof  Mass) {
1777:                    if (amt == 0.0)
1778:                        return zeroMass;
1779:                    else
1780:                        return new Mass(amt, Mass.SHORT_TONS);
1781:                }
1782:                throw new RuntimeException(
1783:                        "InventoryBG: Unknown type of initial level");
1784:            }
1785:
1786:            /** 
1787:             * Given a Scalar, return a double value representing
1788:             * Gallons for Volume,
1789:             * Eaches for Count and
1790:             * Short Tons for Mass.
1791:             **/
1792:            private double getDouble(Scalar measure) {
1793:                double result = Double.NaN;
1794:                if (measure instanceof  Volume) {
1795:                    result = ((Volume) measure).getGallons();
1796:                } else if (measure instanceof  Count) {
1797:                    result = ((Count) measure).getEaches();
1798:                } else if (measure instanceof  Mass) {
1799:                    result = ((Mass) measure).getShortTons();
1800:                } else {
1801:                    if (logger.isErrorEnabled()) {
1802:                        logger
1803:                                .error("getDouble(), Inventory cannot determine type of measure");
1804:                    }
1805:                }
1806:                return result;
1807:            }
1808:
1809:            public Enumeration getAllDueIns() {
1810:                Hashtable dueInTaskHT = new Hashtable(500);
1811:                dueInTasks_ = new Vector(500);
1812:                int size = dueIns_.size();
1813:                Vector div;
1814:                for (int i = 0; i < size; i++) {
1815:                    div = (Vector) (dueIns_.get(i));
1816:                    for (int j = 0; j < div.size(); j++) {
1817:                        if (dueInTaskHT.get(((DueIn) div.get(j)).getTask()) == null) {
1818:                            dueInTaskHT.put(((DueIn) div.get(j)).getTask(),
1819:                                    ((DueIn) div.get(j)));
1820:                            dueInTasks_.add(((DueIn) div.get(j)).getTask()
1821:                                    .getPlanElement());
1822:                        }
1823:                    }
1824:                }
1825:                return dueInTasks_.elements();
1826:            }
1827:
1828:            public int printInventoryLevels(Inventory inventory,
1829:                    MessageAddress clusterID) {
1830:                if (logger.isDebugEnabled()) {
1831:                    logger.debug("printInventoryLevels(), Day 0 is "
1832:                            + TimeUtils.dateString(getStartTime()));
1833:                }
1834:                if (level_ != null) {
1835:                    int size = level_.length;
1836:                    ScheduledContentPG scpg = inventory.getScheduledContentPG();
1837:                    if (logger.isDebugEnabled()) {
1838:                        logger.debug("printInventoryLevels(), for "
1839:                                + AssetUtils.assetDesc(scpg.getAsset()));
1840:                    }
1841:
1842:                    for (int i = 0; i < size; i++) {
1843:                        if (logger.isDebugEnabled()) {
1844:                            logger.debug("printInventoryLevels(), day: "
1845:                                    + TimeUtils.dateString(TimeUtils.addNDays(
1846:                                            getStartTime(), i)) + "(" + i
1847:                                    + ") " + ", level: " + level_[i]);
1848:                        }
1849:                    }
1850:                }
1851:                return 0;
1852:            }
1853:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.