Source Code Cross Referenced for InventoryManager.java in  » Science » Cougaar12_4 » org » cougaar » glm » plugins » inventory » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » Cougaar12_4 » org.cougaar.glm.plugins.inventory 
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.plugins.inventory;
0027:
0028:        import org.cougaar.core.blackboard.IncrementalSubscription;
0029:        import org.cougaar.glm.ldm.Constants;
0030:        import org.cougaar.glm.ldm.asset.DueOut;
0031:        import org.cougaar.glm.ldm.asset.Inventory;
0032:        import org.cougaar.glm.ldm.asset.InventoryPG;
0033:        import org.cougaar.glm.ldm.asset.Organization;
0034:        import org.cougaar.glm.ldm.asset.ProjectionWeight;
0035:        import org.cougaar.glm.ldm.asset.ProjectionWeightImpl;
0036:        import org.cougaar.glm.ldm.plan.GeolocLocation;
0037:        import org.cougaar.glm.plugins.AssetUtils;
0038:        import org.cougaar.glm.plugins.MaintainedItem;
0039:        import org.cougaar.glm.plugins.TaskUtils;
0040:        import org.cougaar.glm.plugins.TimeUtils;
0041:        import org.cougaar.planning.ldm.asset.Asset;
0042:        import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
0043:        import org.cougaar.planning.ldm.measure.AbstractMeasure;
0044:        import org.cougaar.planning.ldm.measure.Count;
0045:        import org.cougaar.planning.ldm.measure.CountRate;
0046:        import org.cougaar.planning.ldm.measure.FlowRate;
0047:        import org.cougaar.planning.ldm.measure.Mass;
0048:        import org.cougaar.planning.ldm.measure.MassTransferRate;
0049:        import org.cougaar.planning.ldm.measure.Measure;
0050:        import org.cougaar.planning.ldm.measure.Rate;
0051:        import org.cougaar.planning.ldm.measure.Scalar;
0052:        import org.cougaar.planning.ldm.measure.Volume;
0053:        import org.cougaar.planning.ldm.plan.Allocation;
0054:        import org.cougaar.planning.ldm.plan.AllocationResult;
0055:        import org.cougaar.planning.ldm.plan.AspectType;
0056:        import org.cougaar.planning.ldm.plan.AspectValue;
0057:        import org.cougaar.planning.ldm.plan.NewTask;
0058:        import org.cougaar.planning.ldm.plan.PlanElement;
0059:        import org.cougaar.planning.ldm.plan.Preference;
0060:        import org.cougaar.planning.ldm.plan.ScoringFunction;
0061:        import org.cougaar.planning.ldm.plan.Task;
0062:        import org.cougaar.planning.ldm.plan.TimeAspectValue;
0063:        import org.cougaar.planning.plugin.deletion.DeletionPolicyBase;
0064:        import org.cougaar.util.MoreMath;
0065:        import org.cougaar.util.UnaryPredicate;
0066:        import org.cougaar.util.log.Logger;
0067:        import org.cougaar.util.log.Logging;
0068:
0069:        import java.util.Collection;
0070:        import java.util.Date;
0071:        import java.util.Enumeration;
0072:        import java.util.HashSet;
0073:        import java.util.Iterator;
0074:        import java.util.List;
0075:        import java.util.Set;
0076:        import java.util.Vector;
0077:
0078:        public abstract class InventoryManager extends InventoryProcessor {
0079:
0080:            protected IncrementalSubscription inventoryAllocSubscription_ = null;
0081:            protected IncrementalSubscription modifiedInventorySubscription_ = null;
0082:            /**
0083:             * Subscription to policies
0084:             */
0085:            protected IncrementalSubscription inventoryPolicySubscription_;
0086:            private Inventory selectedInventory = null;
0087:            protected boolean forcePrintConcise = false;
0088:            private static final int DONE = -1;
0089:            private static Logger logger = Logging
0090:                    .getLogger(InventoryManager.class);
0091:
0092:            /**
0093:             * daysOnHand_    keep enough inventory on hand to cover N days of demand
0094:             * daysForward_   When calculating average daily demand, look N days forward
0095:             * from this day.
0096:             * daysBackward_  When calculating average daily demand, look N days backward
0097:             * from this day.
0098:             * goalLevelMultiplier_     Multiplier for reorder level which yields goal level
0099:             */
0100:            protected int daysOnHand_ = 3;
0101:            protected int daysForward_ = 15;
0102:            protected int daysBackward_ = 15;
0103:            protected double goalLevelMultiplier_ = 2.0;
0104:            private double shortfall; // For debugging only
0105:            private Set changedSet_;
0106:
0107:            public final int REFILL_ALTER_TASK = 0;
0108:            public final int REFILL_REPLACE_TASK = 1;
0109:            public final int REFILL_ADD_TASK = 2; // This one doesn't work. Don't use it.
0110:            public final int REFILL_CHANGE_METHOD = REFILL_REPLACE_TASK;
0111:            private NewTask defaultSupplyTask = (NewTask) buildNewTask(null,
0112:                    Constants.Verb.SUPPLY, null);
0113:
0114:            static class PolicyPredicate implements  UnaryPredicate {
0115:                String type_;
0116:
0117:                public PolicyPredicate(String type) {
0118:                    type_ = type;
0119:                }
0120:
0121:                public boolean execute(Object o) {
0122:                    if (o instanceof  InventoryPolicy) {
0123:                        String type = ((InventoryPolicy) o).getResourceType();
0124:                        if (type.equals(type_)) {
0125:                            return true;
0126:                        }
0127:                    }
0128:                    return false;
0129:                }
0130:            }
0131:
0132:            // Allocations of tasks with quantity > 0 to Inventory objects
0133:            static class AllocToInventoryPredicate implements  UnaryPredicate {
0134:                String type_;
0135:
0136:                public AllocToInventoryPredicate(String type) {
0137:                    type_ = type;
0138:                }
0139:
0140:                public boolean execute(Object o) {
0141:                    if (o instanceof  Allocation) {
0142:                        Task task = ((Allocation) o).getTask();
0143:                        if (task.getVerb().equals(Constants.Verb.WITHDRAW)
0144:                                || task.getVerb().equals(
0145:                                        Constants.Verb.PROJECTWITHDRAW)) {
0146:                            if (TaskUtils.isDirectObjectOfType(task, type_)) {
0147:                                // need to check if alloced to inventory
0148:                                if (((Allocation) o).getAsset() instanceof  Inventory) {
0149:                                    return true;
0150:                                }
0151:                            }
0152:                        }
0153:                    }
0154:                    return false;
0155:                }
0156:            }
0157:
0158:            static class ModifiedInventoryPredicate implements  UnaryPredicate {
0159:                String type_;
0160:
0161:                public ModifiedInventoryPredicate(String type) {
0162:                    type_ = type;
0163:                }
0164:
0165:                public boolean execute(Object o) {
0166:                    if (o instanceof  Inventory) {
0167:                        InventoryPG invpg = (InventoryPG) ((Inventory) o)
0168:                                .getInventoryPG();
0169:                        return ((invpg != null) && AssetUtils
0170:                                .isSupplyClassOfType(invpg.getResource(), type_));
0171:                    }
0172:                    return false;
0173:                }
0174:            }
0175:
0176:            public InventoryManager(InventoryPlugin plugin, Organization org,
0177:                    String type) {
0178:                super (plugin, org, type);
0179:                inventoryAllocSubscription_ = subscribe(new AllocToInventoryPredicate(
0180:                        supplyType_));
0181:                modifiedInventorySubscription_ = subscribe(new ModifiedInventoryPredicate(
0182:                        supplyType_));
0183:                inventoryPolicySubscription_ = subscribe(new PolicyPredicate(
0184:                        type));
0185:
0186:                checkDeletionPolicy();
0187:            }
0188:
0189:            // ********************************************************
0190:            //                                                        *
0191:            // Point Of Entry to InventoryManager                     *
0192:            //                                                        *
0193:            // ********************************************************
0194:
0195:            /**
0196:             * This method is called everytime a subscription has changed.
0197:             */
0198:
0199:            public void update() {
0200:                // Skeleton algorithm (Template Method pattern)  (learned at JavaOne)
0201:                // Used by all concrete subclasses
0202:                super .update();
0203:                // RJB keep track of inventories that need to be run, until you actually run them
0204:                changedSet_ = needUpdate(changedSet_);
0205:                Iterator changedInventories = changedSet_.iterator();
0206:
0207:                if (!changedSet_.isEmpty()) {
0208:                    if (logger.isDebugEnabled()) {
0209:                        logger
0210:                                .debug("\n\n\nBEGIN CYCLE___________________________________________\n");
0211:                    }
0212:
0213:                    if (inventoryPlugin_.getDetermineRequirementsTask() == null) {
0214:                        Enumeration inventories = inventoryPlugin_
0215:                                .getInventoryBins(supplyType_);
0216:                        changedSet_ = new HashSet();
0217:                        while (inventories.hasMoreElements()) {
0218:                            changedSet_.add(inventories.nextElement());
0219:                        }
0220:                        if (logger.isDebugEnabled()) {
0221:                            logger
0222:                                    .debug("#####"
0223:                                            + clusterId_
0224:                                            + " is running because (inventoryPlugin_.getDetermineRequirementsTask() == null)");
0225:                        }
0226:
0227:                        handleRescinds();
0228:
0229:                        // RJB now we have handled all inventories
0230:                        changedSet_ = null;
0231:
0232:                    } else if (inventoryPlugin_.hasSeenAllConsumers()) {
0233:                        handleChangedInventories();
0234:                        // RJB now we have handled all inventories
0235:                        changedSet_ = null;
0236:                    }
0237:                    if (logger.isDebugEnabled()) {
0238:                        logger
0239:                                .debug("\n\nEND CYCLE___________________________________________\n\n");
0240:                    }
0241:                }
0242:            }
0243:
0244:            private void handleRescinds() {
0245:                //nominal handling of rescinds
0246:                resetInventories();
0247:                accountForWithdraws();
0248:                addPreviousRefills();
0249:                refreshInventorySchedule();
0250:
0251:                // MWD hook for any additional handling of rescinds by subclasses
0252:                handleGLSRescind();
0253:            }
0254:
0255:            private void handleChangedInventories() {
0256:                resetInventories();
0257:                accountForWithdraws();
0258:                generateHandleDueIns();
0259:                adjustForInadequateInventory();
0260:                updateWithdrawAllocations();
0261:                refreshInventorySchedule();
0262:            }
0263:
0264:            public static class IMDeletionPolicy extends DeletionPolicyBase {
0265:                public String supplyType_;
0266:            }
0267:
0268:            private IMDeletionPolicy createDeletionPolicy(long deletionDelay) {
0269:                IMDeletionPolicy policy = (IMDeletionPolicy) ldmFactory_
0270:                        .newPolicy(IMDeletionPolicy.class.getName());
0271:                policy.supplyType_ = supplyType_;
0272:                policy.init(supplyType_ + " Due Out Deletion", inventoryPlugin_
0273:                        .getDueOutPredicate(supplyType_), deletionDelay);
0274:                return policy;
0275:            }
0276:
0277:            /**
0278:             * This predicate finds our deletion policies. They must be
0279:             * instances of IMDeletionPolicy and have a supplyType_ matching
0280:             * our supplyType_;
0281:             */
0282:            private UnaryPredicate deletionPolicyPredicate = new UnaryPredicate() {
0283:                public boolean execute(Object o) {
0284:                    if (o instanceof  IMDeletionPolicy) {
0285:                        IMDeletionPolicy policy = (IMDeletionPolicy) o;
0286:                        return policy.supplyType_.equals(supplyType_);
0287:                    }
0288:                    return false;
0289:                }
0290:            };
0291:
0292:            /**
0293:             * Checks the current deletion policy and insures that it is
0294:             * consistent with the current on hand policy. Generally, due out
0295:             * tasks must not be deleted until the daysBackward_ days have
0296:             * passed. The DeletionPolicy is created or updated to reflect
0297:             * this.
0298:             */
0299:            protected void checkDeletionPolicy() {
0300:                long deletionDelay = daysBackward_ * TimeUtils.MSEC_PER_DAY;
0301:                Collection policies = delegate_.query(deletionPolicyPredicate);
0302:                if (policies.isEmpty()) {
0303:                    IMDeletionPolicy policy = createDeletionPolicy(deletionDelay);
0304:                    delegate_.publishAdd(policy);
0305:                } else {
0306:                    IMDeletionPolicy policy = (IMDeletionPolicy) policies
0307:                            .iterator().next();
0308:                    policy.setDeletionDelay(deletionDelay);
0309:                    delegate_.publishChange(policy);
0310:                }
0311:            }
0312:
0313:            // ********************************************************
0314:            //                                                        *
0315:            // Need Update / Reset Section                            *
0316:            //                                                        *
0317:            // ********************************************************
0318:
0319:            protected abstract Set needUpdate(Set inv);
0320:
0321:            // Reset Inventories
0322:
0323:            private void resetInventories() {
0324:                Inventory inventory;
0325:                Iterator list = changedSet_.iterator();
0326:                if (logger.isDebugEnabled()) {
0327:                    logger.debug("STEP 1: RESETINVENTORIES(), Today: "
0328:                            + TimeUtils.dateString(startTime_));
0329:                }
0330:                while (list.hasNext()) {
0331:                    inventory = (Inventory) list.next();
0332:                    InventoryPG invpg = (InventoryPG) inventory
0333:                            .getInventoryPG();
0334:                    //              if (selectedInventory == null) {
0335:                    //                  if (invpg.getResource().getTypeIdentificationPG().getTypeIdentification().equals("NSN/9150001806383")) {
0336:                    //                      selectedInventory = inventory;
0337:                    //                  }
0338:                    //              }
0339:                    invpg.resetInventory(inventory, startTime_);
0340:                }
0341:            }
0342:
0343:            // ********************************************************
0344:            //                                                        *
0345:            // Account for withdraws                                  *
0346:            //                                                        *
0347:            // ********************************************************
0348:
0349:            private void accountForWithdraws() {
0350:                if (logger.isDebugEnabled()) {
0351:                    logger.debug("STEP 2: ACCOUNTFORWITHDRAWS()");
0352:                }
0353:                Iterator inventories = changedSet_.iterator();
0354:                while (inventories.hasNext()) {
0355:                    Inventory inventory = (Inventory) inventories.next();
0356:                    InventoryPG invpg = (InventoryPG) inventory
0357:                            .getInventoryPG();
0358:                    invpg.withdrawFromInventory(inventory, clusterId_);
0359:                    invpg.determineInventoryLevels();
0360:                    computeThresholdSchedule(inventory);
0361:                    //  	    invpg.printInventoryLevels(inventory, clusterId_);
0362:                }
0363:            }
0364:
0365:            private void computeThresholdSchedule(Inventory inventory) {
0366:                InventoryPG invpg = (InventoryPG) inventory.getInventoryPG();
0367:                invpg.computeThresholdSchedule(daysOnHand_, daysForward_,
0368:                        daysBackward_, getMinReorderLevel(inventory),
0369:                        getMaxReorderLevel(inventory), goalLevelMultiplier_);
0370:            }
0371:
0372:            private Vector generateInactiveProjections(Inventory inventory,
0373:                    int switchoverDay) {
0374:                if (logger.isDebugEnabled()) {
0375:                    logger.debug("STEP 2:  GenerateInactiveProjections() for "
0376:                            + AssetUtils.getAssetIdentifier(inventory));
0377:                }
0378:                Vector projections = new Vector();
0379:                InventoryPG invpg = inventory.getInventoryPG();
0380:                int today = invpg.getFirstPlanningDay();
0381:                int periodBegin = today;
0382:                Scalar previous = invpg.getProjected(periodBegin);
0383:                /* Loop from tomorrow to the switchover day. The extra step at
0384:                 * the end insures that the final segment is processed. */
0385:                for (int day = today + 1; day <= switchoverDay; day++) {
0386:                    Scalar current = (day < switchoverDay) ? invpg
0387:                            .getProjected(day) : null;
0388:
0389:                    if (previous == null) {
0390:                        System.out.println("#####"
0391:                                + clusterId_
0392:                                + " current projection is null on day "
0393:                                + day
0394:                                + " for "
0395:                                + inventory.getItemIdentificationPG()
0396:                                        .getItemIdentification());
0397:                        break;
0398:                    }
0399:
0400:                    if (!previous.equals(current)) {
0401:                        double value = convertScalarToDouble(previous);
0402:                        if (!Double.isNaN(value) && value > 0.0) {
0403:                            long start = invpg.getStartOfDay(periodBegin);
0404:                            int nDays = day - periodBegin;
0405:                            long end = start + nDays * TimeUtils.MSEC_PER_DAY;
0406:                            Rate dailyRate = createDailyRate(previous);
0407:                            Task t = newProjectSupplyTask(inventory, start,
0408:                                    end, dailyRate);
0409:                            projections.add(t);
0410:                        }
0411:
0412:                        previous = current;
0413:                        periodBegin = day;
0414:                    }
0415:                }
0416:                return projections;
0417:            }
0418:
0419:            protected Rate createDailyRate(Measure qty) {
0420:                Rate rate = null;
0421:                if (qty instanceof  Volume) {
0422:                    rate = FlowRate.newGallonsPerDay(((Volume) qty)
0423:                            .getGallons());
0424:                } else if (qty instanceof  Count) {
0425:                    rate = CountRate.newEachesPerDay(((Count) qty).getEaches());
0426:                } else if (qty instanceof  Mass) {
0427:                    rate = MassTransferRate.newShortTonsPerDay(((Mass) qty)
0428:                            .getShortTons());
0429:                }
0430:                return rate;
0431:            }
0432:
0433:            protected double ignoreSmallIncrement(double increment, double x) {
0434:                double t = x + increment;
0435:                double diff = (x - increment) / t;
0436:                if (diff < 0.0001 && diff > -0.0001)
0437:                    return x;
0438:                return x + increment;
0439:            }
0440:
0441:            private Rate createIncrementedDailyRate(Measure qty,
0442:                    double increment) {
0443:                Rate rate = null;
0444:                if (qty instanceof  Volume) {
0445:                    double d = ignoreSmallIncrement(increment, ((Volume) qty)
0446:                            .getGallons());
0447:                    if (d <= 0.0)
0448:                        return null;
0449:                    rate = FlowRate.newGallonsPerDay(d);
0450:                } else if (qty instanceof  Count) {
0451:                    double d = ignoreSmallIncrement(increment, ((Count) qty)
0452:                            .getEaches());
0453:                    if (d <= 0.0)
0454:                        return null;
0455:                    rate = CountRate.newEachesPerDay(d);
0456:                } else if (qty instanceof  Mass) {
0457:                    double d = ignoreSmallIncrement(increment, ((Mass) qty)
0458:                            .getShortTons());
0459:                    if (d <= 0.0)
0460:                        return null;
0461:                    rate = MassTransferRate.newShortTonsPerDay(d);
0462:                }
0463:                return rate;
0464:            }
0465:
0466:            private Task newProjectSupplyTask(Inventory inventory, long start,
0467:                    long end, Rate rate) {
0468:                Task parentTask = inventoryPlugin_.findOrMakeMILTask(inventory);
0469:                // Create start and end time preferences (strictly at)
0470:                ScoringFunction score;
0471:                Vector prefs = new Vector();
0472:                score = ScoringFunction.createStrictlyAtValue(TimeAspectValue
0473:                        .create(AspectType.START_TIME, start));
0474:                prefs.addElement(ldmFactory_.newPreference(
0475:                        AspectType.START_TIME, score));
0476:                score = ScoringFunction.createStrictlyAtValue(TimeAspectValue
0477:                        .create(AspectType.END_TIME, end));
0478:                prefs.addElement(ldmFactory_.newPreference(AspectType.END_TIME,
0479:                        score));
0480:                Vector prep_phrases = new Vector();
0481:                prep_phrases.add(newPrepositionalPhrase(
0482:                        Constants.Preposition.FOR, myOrgName_));
0483:                prep_phrases.add(newPrepositionalPhrase(
0484:                        Constants.Preposition.OFTYPE, supplyType_));
0485:                Asset resource = inventory.getInventoryPG().getResource();
0486:                TypeIdentificationPG tip = ((Asset) resource)
0487:                        .getTypeIdentificationPG();
0488:                MaintainedItem itemID = MaintainedItem
0489:                        .findOrMakeMaintainedItem("Inventory", tip
0490:                                .getTypeIdentification(), null, tip
0491:                                .getNomenclature());
0492:                prep_phrases.add(newPrepositionalPhrase(
0493:                        Constants.Preposition.MAINTAINING, itemID));
0494:                prep_phrases
0495:                        .add(newPrepositionalPhrase(Constants.Preposition.REFILL));
0496:
0497:                InventoryPG invpg = (InventoryPG) inventory.getInventoryPG();
0498:                NewTask t = (NewTask) buildTask(parentTask,
0499:                        Constants.Verb.PROJECTSUPPLY, invpg.getResource(),
0500:                        prep_phrases, prefs.elements());
0501:                t.setPreference(TaskUtils.createDemandRatePreference(
0502:                        ldmFactory_, rate));
0503:                t.setPreference(TaskUtils.createDemandMultiplierPreference(
0504:                        ldmFactory_, 1.0));
0505:                t.setCommitmentDate(new Date(end));
0506:                //  	printDebug("newProjectSupplyTask(), created new ProjectSupply task "+TaskUtils.taskDesc(t));
0507:                return t;
0508:            }
0509:
0510:            private Inventory getInventoryForTask(Task task) {
0511:                return inventoryPlugin_.findOrMakeInventory(supplyType_,
0512:                        (Asset) task.getDirectObject());
0513:            }
0514:
0515:            // ********************************************************
0516:            //                                                        *
0517:            // Generate/Handle Due Ins Section                        *
0518:            //                                                        *
0519:            // ********************************************************
0520:
0521:            private void generateHandleDueIns() {
0522:                if (logger.isDebugEnabled()) {
0523:                    logger.debug("Step 3: generateHandleDueIns()");
0524:                }
0525:                addPreviousRefills();
0526:            }
0527:
0528:            private void addPreviousRefills() {
0529:
0530:                if (logger.isDebugEnabled()) {
0531:                    logger.debug("      : addPreviousRefills()");
0532:                }
0533:                int total = 0;
0534:                Iterator inventories = changedSet_.iterator();
0535:                Inventory inv;
0536:                InventoryPG invpg;
0537:                while (inventories.hasNext()) {
0538:                    inv = (Inventory) inventories.next();
0539:                    invpg = (InventoryPG) inv.getInventoryPG();
0540:                    // maintainInventory Task is the parent of all the refills for this inventory
0541:                    Task maintainInventory = inventoryPlugin_
0542:                            .findOrMakeMILTask(inv);
0543:                    // should never be null but may want to add a check AHF
0544:                    total += invpg
0545:                            .addPreviousRefillsToInventory(maintainInventory);
0546:                    invpg.determineInventoryLevels();
0547:                    //  	    invpg.printInventoryLevels(inv, clusterId_);
0548:                }
0549:                if (logger.isDebugEnabled()) {
0550:                    logger.debug("end addDueIns(), number of refillTasks is "
0551:                            + total);
0552:                }
0553:            }
0554:
0555:            public long defaultRefillEndTime(long time, Inventory inv) {
0556:                if (time == startTime_) {
0557:                    time = TimeUtils.addNDays(startTime_, 1);
0558:                }
0559:                return time;
0560:            }
0561:
0562:            private Task createRefillTask(Inventory inv, double refill_qty,
0563:                    long time) {
0564:                Asset item = getInventoryAsset(inv);
0565:                // create request task
0566:                Vector prefs = new Vector();
0567:                Preference p_start, p_end, p_qty;
0568:
0569:                long end_time = defaultRefillEndTime(time, inv);
0570:                //  	long start_time = defaultRefillStartTime(time,inv);
0571:
0572:                //  	p_start = createDateAfterPreference(AspectType.START_TIME, start_time);
0573:                p_end = createDateBeforePreference(AspectType.END_TIME,
0574:                        end_time);
0575:
0576:                p_qty = createRefillQuantityPreference(refill_qty);
0577:                //  	prefs.addElement(p_start);
0578:                prefs.addElement(p_end);
0579:                prefs.addElement(p_qty);
0580:
0581:                Vector pp_vector = new Vector();
0582:                pp_vector.addElement(newPrepositionalPhrase(
0583:                        Constants.Preposition.FOR, myOrgName_));
0584:                pp_vector.add(newPrepositionalPhrase(
0585:                        Constants.Preposition.OFTYPE, supplyType_));
0586:
0587:                Object io;
0588:                Enumeration geolocs = AssetUtils.getGeolocLocationAtTime(
0589:                        myOrganization_, end_time);
0590:                if (geolocs.hasMoreElements()) {
0591:                    io = (GeolocLocation) geolocs.nextElement();
0592:                } else {
0593:                    io = this Geoloc_;
0594:                }
0595:                pp_vector.addElement(newPrepositionalPhrase(
0596:                        Constants.Preposition.TO, io));
0597:                Asset resource = inv.getInventoryPG().getResource();
0598:                TypeIdentificationPG tip = ((Asset) resource)
0599:                        .getTypeIdentificationPG();
0600:                MaintainedItem itemID = MaintainedItem
0601:                        .findOrMakeMaintainedItem("Inventory", tip
0602:                                .getTypeIdentification(), null, tip
0603:                                .getNomenclature());
0604:                pp_vector.addElement(newPrepositionalPhrase(
0605:                        Constants.Preposition.MAINTAINING, itemID));
0606:                pp_vector
0607:                        .addElement(newPrepositionalPhrase(Constants.Preposition.REFILL));
0608:
0609:                NewTask task = (NewTask) buildTask(null, Constants.Verb.SUPPLY,
0610:                        item, pp_vector, prefs.elements());
0611:                return task;
0612:
0613:            }
0614:
0615:            protected Preference createRefillQuantityPreference(
0616:                    double refill_qty) {
0617:                AspectValue lowAV = AspectValue.newAspectValue(
0618:                        AspectType.QUANTITY, 0.01);
0619:                AspectValue bestAV = AspectValue.newAspectValue(
0620:                        AspectType.QUANTITY, refill_qty);
0621:                AspectValue highAV = AspectValue.newAspectValue(
0622:                        AspectType.QUANTITY, refill_qty + 1.0);
0623:                ScoringFunction qtySF = ScoringFunction.createVScoringFunction(
0624:                        lowAV, bestAV, highAV);
0625:                return ldmFactory_.newPreference(AspectType.QUANTITY, qtySF);
0626:                //  	return createQuantityPreference(AspectType.QUANTITY, refill_qty);
0627:            }
0628:
0629:            // Refill Inventories
0630:
0631:            /**
0632:             * Generate a refill order to replenish the item in storage,
0633:             * assuming we already have determined we have at least an
0634:             * Economic Reorder Quantity. Allocate task to provider Org.
0635:             * @return true if an order was placed or changed
0636:             */
0637:            private boolean orderRefill(Inventory inventory, int day) {
0638:                InventoryPG invpg = (InventoryPG) inventory.getInventoryPG();
0639:                double currentInventory = convertScalarToDouble(invpg
0640:                        .getLevel(day));
0641:                double goal_level = invpg.getGoalLevel(day);
0642:                double refill_qty = goal_level - currentInventory;
0643:                double reorder_level = invpg.getReorderLevel(day);
0644:
0645:                defaultSupplyTask.setDirectObject(invpg.getResource());
0646:                if (invpg.getProjectionWeight().getProjectionWeight(
0647:                        defaultSupplyTask, invpg.getImputedDay(day)) <= 0.0) {
0648:                    // This test is to avoid generating refill SUPPLY tasks for times when the system
0649:                    //  will ignore their effect on inventory
0650:                    return false; // Can't do a refill
0651:                }
0652:
0653:                if (!invpg.getFillToCapacity()) {
0654:                    // ** THIS IS A KLUDGE FOR SUBSISTENCE -- WITHOUT IT WE FAIL THE FIRST ORDER.
0655:                    //    SHOULDN'T HAPPEN LIKE THAT -- FIX ASAP -- RUSTY AND AMY!!
0656:                    //    	    refill_qty = refill_qty*1.3;
0657:                    // *** KLUDGE ********
0658:                }
0659:
0660:                boolean isCount = invpg.getCapacity() instanceof  Count;
0661:                if (refill_qty > 0.0) {
0662:                    if (logger.isDebugEnabled()) {
0663:                        logger.debug("orderRefill goal=" + goal_level
0664:                                + " reorder level=" + reorder_level
0665:                                + " current level=" + currentInventory);
0666:                    }
0667:                    Task task = null;
0668:                    Task prev_refill = invpg.refillAlreadyFailedOnDay(day);
0669:                    if (prev_refill != null) {
0670:                        double min_qty = reorder_level - currentInventory;
0671:                        if (min_qty <= 0.0) { // Refill unneeded
0672:                            min_qty = 1e-10;
0673:                            //                      invpg.removeDueIn(prev_refill);
0674:                            //                      plugin_.publishRemoveFromExpansion(prev_refill);
0675:                            //                      return true;
0676:                        }
0677:                        double prev_qty = TaskUtils.getQuantity(prev_refill);
0678:                        if (isCount)
0679:                            min_qty = Math.ceil(min_qty);
0680:                        if (min_qty < prev_qty) {
0681:                            refill_qty = min_qty; // Retry the refill with the min needed
0682:                        } else {
0683:                            return false; // Can't refill on this day.
0684:                        }
0685:                    } else {
0686:                        prev_refill = invpg.getRefillOnDay(day);
0687:                    }
0688:                    if (isCount) {
0689:                        refill_qty = Math.ceil(refill_qty);
0690:                    }
0691:                    if (prev_refill != null) {
0692:                        return orderRefillWithPrevious(inventory, day, invpg,
0693:                                refill_qty);
0694:                    } else {
0695:                        return orderNewRefill(inventory, day, invpg, refill_qty);
0696:                    }
0697:                } else {
0698:                    if (logger.isDebugEnabled()) {
0699:                        logger
0700:                                .debug("OrderRefill qty < 0: " + refill_qty
0701:                                        + " = " + goal_level + " - "
0702:                                        + currentInventory);
0703:                    }
0704:                }
0705:                return true;
0706:            }
0707:
0708:            private boolean orderNewRefill(Inventory inventory, int day,
0709:                    InventoryPG invpg, double refill_qty) {
0710:                long time = invpg.convertDayToTime(day);
0711:                Task task = createRefillTask(inventory, refill_qty, time);
0712:                // FIX ME - sets to today??? check dates.
0713:                // 	task.setCommitmentDate(date);
0714:                //      		printDebug(1,"orderRefill task:"+TaskUtils.taskDesc(task));
0715:                Task parentTask = inventoryPlugin_.findOrMakeMILTask(inventory);
0716:                plugin_.publishAddToExpansion(parentTask, task);
0717:                if (logger.isDebugEnabled()) {
0718:                    logger
0719:                            .debug("orderNewRefill() "
0720:                                    + task.getUID()
0721:                                    + " "
0722:                                    + refill_qty
0723:                                    + " on "
0724:                                    + TimeUtils.dateString(invpg
0725:                                            .convertDayToTime(day)));
0726:                }
0727:                invpg.addDueIn(task);
0728:                return true;
0729:            }
0730:
0731:            /**
0732:             * Modify an existing refill task if possible to increase the
0733:             * refill as indicated. If the previous refill has failed we don't
0734:             * expect an additional refill to succeed, but if the new amount
0735:             * is smaller than the previous one, then it might succeed so we go
0736:             * ahead with the change. Otherwise, we increase the amount of the
0737:             * existing refill (or replace with a larger refill, or add an
0738:             * additional refill depending on REFILL_CHANGE_METHOD).
0739:             * Note -- This routine is actually never called with a failed
0740:             * refill on day (See refillInventory).
0741:             * @param inventory the Inventory -- not used
0742:             * @param day the day of the refill
0743:             * @param invpg the InventoryPG of the inventory.
0744:             * @param refill_qty the amount needed to be added to the inventory
0745:             */
0746:            private boolean orderRefillWithPrevious(Inventory inventory,
0747:                    int day, InventoryPG invpg, double refill_qty) {
0748:                Task refill_task = invpg.getRefillOnDay(day);
0749:                double prev_qty = TaskUtils.getQuantity(refill_task);
0750:                boolean failed = false;
0751:                Allocation alloc = (Allocation) refill_task.getPlanElement();
0752:                if (alloc != null) {
0753:                    AllocationResult report = alloc.getReportedResult();
0754:                    if (report != null) {
0755:                        failed = !report.isSuccess();
0756:                    }
0757:                }
0758:                if (failed) {
0759:                    if (prev_qty <= refill_qty) {
0760:                        System.out.println("Known failed refill: "
0761:                                + TaskUtils.taskDesc(refill_task));
0762:                        //  		printLog("Known failed refill: "+TaskUtils.taskDesc(refill_task));
0763:                        return false;
0764:                    } // If quantity reduced make the change
0765:                }
0766:                // Send orders for whole items, i.e. do not order 0.5 O-rings
0767:                if (invpg.getCapacity() instanceof  Count) {
0768:                    refill_qty = Math.ceil(refill_qty);
0769:                }
0770:
0771:                if (logger.isDebugEnabled()) {
0772:                    logger
0773:                            .debug("orderRefillWithPrevious() "
0774:                                    + refill_task.getUID()
0775:                                    + " "
0776:                                    + prev_qty
0777:                                    + "-->"
0778:                                    + refill_qty
0779:                                    + " on "
0780:                                    + TimeUtils.dateString(invpg
0781:                                            .convertDayToTime(day)));
0782:                }
0783:                invpg.removeDueIn(refill_task);
0784:                switch (REFILL_CHANGE_METHOD) {
0785:                case REFILL_ALTER_TASK:
0786:                    /* Change the quantity preference on the existing task.
0787:                    refill_qty is the additional amount needed, prev_qty is
0788:                    the effective quantity of the current task. */
0789:                    if (!failed)
0790:                        refill_qty += prev_qty;
0791:                    Preference qpref = createRefillQuantityPreference(refill_qty);
0792:                    ((NewTask) refill_task).setPreference(qpref);
0793:                    PlanElement pe = refill_task.getPlanElement();
0794:                    if (pe != null) {
0795:                        pe
0796:                                .setEstimatedResult(createEstimatedAllocationResult(refill_task));
0797:                    }
0798:                    delegate_.publishChange(refill_task);
0799:                    invpg.addDueIn(refill_task);
0800:                    return true;
0801:                case REFILL_REPLACE_TASK:
0802:                    if (!failed) {
0803:                        refill_qty += prev_qty;
0804:                    }
0805:                    plugin_.publishRemoveFromExpansion(refill_task);
0806:                    return orderNewRefill(inventory, day, invpg, refill_qty);
0807:                case REFILL_ADD_TASK:
0808:                    invpg.addDueIn(refill_task);
0809:                    return orderNewRefill(inventory, day, invpg, refill_qty);
0810:                }
0811:                return false;
0812:            }
0813:
0814:            // ********************************************************
0815:            //                                                        *
0816:            // Adjust Withdraws Section                               *
0817:            //                                                        *
0818:            // ********************************************************
0819:
0820:            private void adjustForInadequateInventory() {
0821:                if (logger.isDebugEnabled()) {
0822:                    logger.debug("adjustForInadequateInventory()");
0823:                }
0824:                // For each inventory
0825:                Iterator inventories = changedSet_.iterator();
0826:                while (inventories.hasNext()) {
0827:                    Inventory inventory = (Inventory) inventories.next();
0828:                    //              forcePrintConcise(inventory == selectedInventory);
0829:                    adjustForInadequateInventory(inventory);
0830:                }
0831:            }
0832:
0833:            private void adjustForInadequateInventory(Inventory inventory) {
0834:                InventoryPG invpg = (InventoryPG) inventory.getInventoryPG();
0835:                int firstDay = invpg.getFirstPlanningDay();
0836:                int days = invpg.getPlanningDays();
0837:                int switchoverDay = days;
0838:                {
0839:                    Task testTask = buildNewTask(null,
0840:                            Constants.Verb.PROJECTSUPPLY, null);
0841:                    int imputedDay0 = invpg.getImputedDay(0);
0842:                    for (switchoverDay = 0; switchoverDay < days; switchoverDay++) {
0843:                        double weight = invpg.getProjectionWeight()
0844:                                .getProjectionWeight(testTask,
0845:                                        imputedDay0 + switchoverDay);
0846:                        if (weight > 0.0)
0847:                            break; // found switchoverDay
0848:                    }
0849:                }
0850:                Vector projections = generateInactiveProjections(inventory,
0851:                        switchoverDay);
0852:                for (int day = firstDay; day < switchoverDay; day++) {
0853:                    if (checkFailedRefill(inventory, invpg, day)) { // Check and update any failed refills
0854:                        invpg.determineInventoryLevels();
0855:                    }
0856:                }
0857:                int refillDay = refillNeeded(inventory, firstDay);
0858:                int periodBegin = switchoverDay;
0859:                Rate currentRate = null;
0860:                double pendingDelta = 0.0;
0861:                for (int day = firstDay; day <= days; day++) {
0862:                    Scalar projected = invpg.getProjected(day);
0863:                    double projectedDemand = convertScalarToDouble(projected);
0864:                    if (day < switchoverDay) {
0865:                        if (day == refillDay) {
0866:                            // Try to do a refill
0867:                            if (orderRefill(inventory, day)) {
0868:                                invpg.determineInventoryLevels();
0869:                                // If the refill succeeded, then we are above
0870:                                // the reorder level so we advance to the next
0871:                                // day and loop.
0872:                                refillDay = refillNeeded(inventory, day + 1);
0873:                            } else {
0874:                                while (day == refillDay) {
0875:                                    if (failDueOut(inventory, invpg, day)) {
0876:                                        invpg.determineInventoryLevels();
0877:                                        refillDay = refillNeeded(inventory, day);
0878:                                    } else {
0879:                                        // Can this happen? If it does, just go to the next day
0880:                                        refillDay = refillNeeded(inventory,
0881:                                                day + 1);
0882:                                    }
0883:                                }
0884:                            }
0885:                        }
0886:                    } else {
0887:                        Scalar nextProjection = invpg.getProjectedRefill(day);
0888:                        Rate newRate = null;
0889:                        double delta = 0.0;
0890:                        if (day < days) {
0891:                            double target = 0.5 * (invpg.getReorderLevel(day) + invpg
0892:                                    .getGoalLevel(day));
0893:                            if (logger.isDebugEnabled()) {
0894:                                logger.debug("target("
0895:                                        + TimeUtils.dateString(invpg
0896:                                                .convertDayToTime(day)) + ")="
0897:                                        + target);
0898:                            }
0899:                            double qty = convertScalarToDouble(invpg
0900:                                    .getLevel(day))
0901:                                    + pendingDelta;
0902:                            double nextRefill = convertScalarToDouble(nextProjection);
0903:                            if (!MoreMath.nearlyEquals(qty, target, 0.0001)) {
0904:                                delta = Math.max(target - qty, -nextRefill); // Can only reduce by projection amount
0905:                            }
0906:                            newRate = createIncrementedDailyRate(
0907:                                    nextProjection, delta);
0908:                            if (newRate == null)
0909:                                delta = 0.0; // Can't do negative, cancel the delta (I think this does nothing)
0910:                        }
0911:                        if (isSameRate(currentRate, newRate)) {
0912:                            /* If we use the currentRate instead of newRate,
0913:                               then the delta we achieve is not the delta we
0914:                               computed above. Compute a new delta that
0915:                               reflects what the currentRate achieves. */
0916:                            //                      delta += (TaskUtils.getDailyQuantity(currentRate)
0917:                            //                                - TaskUtils.getDailyQuantity(newRate));
0918:                            pendingDelta += delta;
0919:                            continue;
0920:                        }
0921:                        for (int i = periodBegin; i < day; i++) {
0922:                            invpg.removeRefillProjection(i);
0923:                        }
0924:                        if (currentRate != null) { // Terminate the current rate
0925:                            long start = invpg.getStartOfDay(periodBegin);
0926:                            long end = invpg.getStartOfDay(day);
0927:                            Task t = newProjectSupplyTask(inventory, start,
0928:                                    end, currentRate);
0929:                            projections.add(t);
0930:                            invpg.addDueIn(t);
0931:                        }
0932:                        currentRate = newRate;
0933:                        periodBegin = day;
0934:                        pendingDelta = delta;
0935:                    }
0936:                }
0937:                publishChangeProjection(inventory, projections.elements());
0938:            }
0939:
0940:            private boolean isSameRate(Rate rate1, Rate rate2) {
0941:                if (rate1 == rate2)
0942:                    return true;
0943:                if (rate1 == null || rate2 == null)
0944:                    return false;
0945:                double val1 = rate1.getValue(rate1.getCommonUnit());
0946:                double val2 = rate2.getValue(rate2.getCommonUnit());
0947:                return MoreMath.nearlyEquals(val1, val2, 0.0001);
0948:            }
0949:
0950:            private boolean checkFailedRefill(Inventory inventory,
0951:                    InventoryPG invpg, int day) {
0952:                Task prev_refill = invpg.refillAlreadyFailedOnDay(day);
0953:                if (prev_refill != null) {
0954:                    return orderRefill(inventory, day);
0955:                }
0956:                return false;
0957:            }
0958:
0959:            //    protected abstract boolean orderRefill(Inventory inventory, int day);
0960:
0961:            private boolean failDueOut(Inventory inventory, InventoryPG invpg,
0962:                    int day) {
0963:                DueOut lowestPriorityDueOut = invpg
0964:                        .getLowestPriorityDueOutBeforeDay(day);
0965:                if (lowestPriorityDueOut == null)
0966:                    return false;
0967:                //      printDebug("Inventory level before failing allocation is "+
0968:                //                 TimeUtils.dateString(invpg.convertDayToTime(day)) + " : "+invpg.getLevel(day)+
0969:                //                 ", Reorder level :"+invpg.getReorderLevel(day));
0970:                invpg.setDueOutFilled(lowestPriorityDueOut, false);
0971:                lowestPriorityDueOut.setFilled(false);
0972:                if (logger.isDebugEnabled()) {
0973:                    if (lowestPriorityDueOut.getPreviouslyFilled() != false) {
0974:                        Task task = lowestPriorityDueOut.getTask();
0975:                        logger
0976:                                .debug("adjustForInadequateInventory() shortfall="
0977:                                        + shortfall
0978:                                        + " on "
0979:                                        + day
0980:                                        + "="
0981:                                        + TimeUtils.dateString(invpg
0982:                                                .getStartOfDay(day))
0983:                                        + " failed "
0984:                                        + task.getUID()
0985:                                        + " having "
0986:                                        + TaskUtils.getDailyQuantity(task)
0987:                                        + " on "
0988:                                        + TimeUtils
0989:                                                .dateString(invpg
0990:                                                        .convertDayToTime(lowestPriorityDueOut
0991:                                                                .getDay())));
0992:                    }
0993:                }
0994:                //      printDebug("Inventory level after failing allocation is "
0995:                //                 + TimeUtils.dateString(invpg.convertDayToTime(day))
0996:                //                 + " : "+invpg.getLevel(day));
0997:                return true;
0998:            }
0999:
1000:            private void updateWithdrawAllocations() {
1001:                if (logger.isDebugEnabled()) {
1002:                    logger.debug("updateWithdrawAllocations()");
1003:                }
1004:                Iterator inventories = changedSet_.iterator();
1005:                while (inventories.hasNext()) {
1006:                    Inventory inventory = (Inventory) inventories.next();
1007:                    InventoryPG invpg = (InventoryPG) inventory
1008:                            .getInventoryPG();
1009:                    List changes = invpg.updateDueOutAllocations();
1010:                    for (int i = 0, n = changes.size(); i < n; i++) {
1011:                        PlanElement pe = (PlanElement) changes.get(i);
1012:                        delegate_.publishChange(pe);
1013:                    }
1014:                }
1015:            }
1016:
1017:            /**
1018:             * Computes the next day on which a refill is needed. This simply
1019:             * looks for the next day that the inventory drops below the
1020:             * reorder level. It is likely that this is overridden in a
1021:             * subclass. Indeed, GeneralInventoryManager _does_ override.
1022:             */
1023:            private int refillNeeded(Inventory inventory, int startDay) {
1024:                InventoryPG invpg = (InventoryPG) inventory.getInventoryPG();
1025:                int days = invpg.getPlanningDays();
1026:                for (int day = startDay; day < days; day++) {
1027:                    if (needRefill(inventory, day))
1028:                        return day;
1029:                }
1030:                return DONE;
1031:            }
1032:
1033:            private boolean needRefill(Inventory inventory, int day) {
1034:                InventoryPG invpg = inventory.getInventoryPG();
1035:                double qty = convertScalarToDouble(invpg.getLevel(day));
1036:                double level = invpg.getReorderLevel(day);
1037:                shortfall = level - qty;
1038:                return (shortfall > 0.0);
1039:            }
1040:
1041:            // ********************************************************
1042:            //                                                        *
1043:            // CheckForOverflow Section - only relevent for limited   *
1044:            //                            capacity inventories        *
1045:            //                                                        *
1046:            // ********************************************************
1047:
1048:            // ********************************************************
1049:            //                                                        *
1050:            // Refresh ScheduledContentPG on Inventory  Section       *
1051:            //                                                        *
1052:            // ********************************************************
1053:
1054:            private void refreshInventorySchedule() {
1055:                Inventory inventory;
1056:                InventoryPG invpg;
1057:                Iterator inventories = changedSet_.iterator();
1058:
1059:                if (logger.isDebugEnabled()) {
1060:                    logger.debug("LAST STEP: REFRESHINVENTORYSCHEDULE()");
1061:                }
1062:                while (inventories.hasNext()) {
1063:                    inventory = (Inventory) inventories.next();
1064:                    invpg = (InventoryPG) inventory.getInventoryPG();
1065:                    // invpg.printInventoryLevels(inventory, clusterId_);
1066:                    invpg.updateContentSchedule(inventory);
1067:
1068:                    // detailed Inventory Schedule for demo purposes only
1069:                    Boolean detailed = (Boolean) inventoryPlugin_
1070:                            .getParam("Detailed");
1071:                    if ((detailed != null) && detailed.booleanValue()) {
1072:                        invpg.updateDetailedContentSchedule(inventory);
1073:                    }
1074:                    invpg.updateInventoryLevelsSchedule(inventory);
1075:                }
1076:            }
1077:
1078:            /**
1079:             * method called from update when a GLS Rescind is detected. This
1080:             * is an entry point for any additional handling by subclasses.
1081:             */
1082:            protected void handleGLSRescind() {
1083:            }
1084:
1085:            // ********************************************************
1086:            //                                                        *
1087:            // Utilities Section                                      *
1088:            //                                                        *
1089:            // ********************************************************
1090:
1091:            /**
1092:             * @return a double indicating the amount requests by the task (in terms of the standard unit of measure for the item)
1093:             */
1094:            protected double getAmountRequested(Task task) {
1095:                return TaskUtils.getPreference(task, AspectType.QUANTITY);
1096:            }
1097:
1098:            /**
1099:             * Given a Scalar, return a double value representing
1100:             * Gallons for Volume,
1101:             * Eaches for Count and
1102:             * Short Tons for Mass.
1103:             */
1104:            static protected double convertScalarToDouble(Scalar measure) {
1105:                double d = Double.NaN;
1106:                if (measure instanceof  Volume) {
1107:                    d = ((Volume) measure).getGallons();
1108:                } else if (measure instanceof  Count) {
1109:                    d = ((Count) measure).getEaches();
1110:                } else if (measure instanceof  Mass) {
1111:                    d = ((Mass) measure).getShortTons();
1112:                }
1113:                return d;
1114:            }
1115:
1116:            static protected Scalar newScalarFromOldToDouble(Scalar old,
1117:                    double newVal) {
1118:                if (old instanceof  Volume) {
1119:                    return Volume.newGallons(newVal);
1120:                } else if (old instanceof  Count) {
1121:                    return Count.newEaches(newVal);
1122:                } else if (old instanceof  Mass) {
1123:                    return Mass.newShortTons(newVal);
1124:                }
1125:
1126:                String oldUnitName = old.getUnitName(old.getCommonUnit());
1127:                return (Scalar) AbstractMeasure.newMeasure(oldUnitName,
1128:                        (int) newVal);
1129:            }
1130:
1131:            //Max at the capacity
1132:            protected double getMaxReorderLevel(Inventory inventory) {
1133:                InventoryPG invpg = (InventoryPG) inventory
1134:                        .searchForPropertyGroup(InventoryPG.class);
1135:                return convertScalarToDouble(invpg.getCapacity());
1136:            }
1137:
1138:            //Min at zero unless maintainAtCapacity inventory, then min is capacity.
1139:            protected double getMinReorderLevel(Inventory inventory) {
1140:                double mrl = 0.0;
1141:                InventoryPG invpg = (InventoryPG) inventory
1142:                        .searchForPropertyGroup(InventoryPG.class);
1143:                if (invpg.getMaintainAtCapacity()) {
1144:                    mrl = convertScalarToDouble(invpg.getCapacity());
1145:                }
1146:                return mrl;
1147:            }
1148:
1149:            /**
1150:             * Update the current InventoryPolicy
1151:             */
1152:            protected boolean updateInventoryPolicy(Enumeration policies) {
1153:                InventoryPolicy pol;
1154:                boolean changed = false;
1155:                //  	printDebug("updateInventoryPolicy(), Days On Hand Policy for "+supplyType_+". DaysOnHand: "+daysOnHand_+
1156:                //  		   ", Days Forward: "+daysForward_+", Days Backward: "+daysBackward_+", Window size: "+
1157:                //  		   (daysForward_+daysBackward_));
1158:                while (policies.hasMoreElements()) {
1159:                    pol = (InventoryPolicy) policies.nextElement();
1160:                    int days = pol.getDaysOnHand();
1161:                    if ((days >= 0) && (days != daysOnHand_)) {
1162:                        daysOnHand_ = days;
1163:                        changed = true;
1164:                    }
1165:                    int forward = pol.getDaysForward();
1166:                    if ((forward >= 0) && (forward != daysForward_)) {
1167:                        daysForward_ = forward;
1168:                        changed = true;
1169:                    }
1170:                    int backward = pol.getDaysBackward();
1171:                    if ((backward >= 0) && (backward != daysBackward_)) {
1172:                        daysBackward_ = backward;
1173:                        checkDeletionPolicy(); // Changed daysBackward, need to change deletion policy
1174:                        changed = true;
1175:                    }
1176:                    double multiplier = pol.getGoalLevelMultiplier();
1177:                    if ((multiplier > 1.0)
1178:                            && (multiplier != goalLevelMultiplier_)) {
1179:                        goalLevelMultiplier_ = multiplier;
1180:                        changed = true;
1181:                    }
1182:                    if (pol.hasFillToCapacityRule()) {
1183:                        inventoryPlugin_.setFillToCapacity(supplyType_, pol
1184:                                .getFillToCapacity());
1185:                        changed = true;
1186:                    }
1187:                    if (pol.hasMaintainAtCapacityRule()) {
1188:                        inventoryPlugin_.setMaintainAtCapacity(supplyType_, pol
1189:                                .getMaintainAtCapacity());
1190:                        changed = true;
1191:                    }
1192:                    if (pol.hasSwitchoverRule()) {
1193:                        ProjectionWeight newWeight = new ProjectionWeightImpl(
1194:                                pol.getWithdrawSwitchoverDay(), pol
1195:                                        .getRefillSwitchoverDay(), pol
1196:                                        .getTurnOffProjections());
1197:                        inventoryPlugin_.setProjectionWeight(supplyType_,
1198:                                newWeight);
1199:                        changed = true;
1200:                    }
1201:                }
1202:                if (changed) {
1203:                    if (logger.isDebugEnabled()) {
1204:                        logger
1205:                                .debug("updateInventoryPolicy(), Days On Hand Policy CHANGED for "
1206:                                        + supplyType_
1207:                                        + ". DaysOnHand: "
1208:                                        + daysOnHand_
1209:                                        + ", Days Forward: "
1210:                                        + daysForward_
1211:                                        + ", Days Backward: "
1212:                                        + daysBackward_
1213:                                        + ", Window size: "
1214:                                        + (daysForward_ + daysBackward_)
1215:                                        + ", goal level multiplier: "
1216:                                        + goalLevelMultiplier_);
1217:                    }
1218:                }
1219:                return changed;
1220:            }
1221:
1222:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.