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

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


0001:        /*
0002:         * <copyright>
0003:         *
0004:         *  Copyright 1997-2004 BBNT Solutions, LLC
0005:         *  under sponsorship of the Defense Advanced Research Projects
0006:         *  Agency (DARPA).
0007:         *
0008:         *  You can redistribute this software and/or modify it under the
0009:         *  terms of the Cougaar Open Source License as published on the
0010:         *  Cougaar Open Source Website (www.cougaar.org).
0011:         *
0012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023:         *
0024:         * </copyright>
0025:         */
0026:
0027:        package org.cougaar.logistics.plugin.inventory;
0028:
0029:        import org.cougaar.core.adaptivity.OMCRange;
0030:        import org.cougaar.core.adaptivity.OMCRangeList;
0031:        import org.cougaar.core.adaptivity.OperatingMode;
0032:        import org.cougaar.core.adaptivity.OperatingModeImpl;
0033:        import org.cougaar.core.agent.service.alarm.Alarm;
0034:        import org.cougaar.core.blackboard.IncrementalSubscription;
0035:        import org.cougaar.core.component.ServiceRevokedEvent;
0036:        import org.cougaar.core.component.ServiceRevokedListener;
0037:        import org.cougaar.core.logging.LoggingServiceWithPrefix;
0038:        import org.cougaar.core.mts.MessageAddress;
0039:        import org.cougaar.core.node.NodeIdentificationService;
0040:        import org.cougaar.core.plugin.ComponentPlugin;
0041:        import org.cougaar.core.service.*;
0042:        import org.cougaar.glm.ldm.asset.*;
0043:        import org.cougaar.glm.ldm.oplan.Oplan;
0044:        import org.cougaar.glm.ldm.oplan.OrgActivity;
0045:        import org.cougaar.logistics.ldm.Constants;
0046:        import org.cougaar.logistics.plugin.utils.QuiescenceAccumulator;
0047:        import org.cougaar.logistics.plugin.utils.ScheduleUtils;
0048:        import org.cougaar.logistics.plugin.utils.TaskScheduler;
0049:        import org.cougaar.logistics.plugin.utils.TaskSchedulingPolicy;
0050:        import org.cougaar.logistics.servlet.CommStatus;
0051:        import org.cougaar.logistics.servlet.LogisticsInventoryServlet;
0052:        import org.cougaar.planning.ldm.PlanningFactory;
0053:        import org.cougaar.planning.ldm.asset.Asset;
0054:        import org.cougaar.planning.ldm.asset.NewItemIdentificationPG;
0055:        import org.cougaar.planning.ldm.asset.NewTypeIdentificationPG;
0056:        import org.cougaar.planning.ldm.plan.*;
0057:        import org.cougaar.planning.plugin.util.AllocationResultHelper;
0058:        import org.cougaar.planning.plugin.util.PluginHelper;
0059:        import org.cougaar.util.*;
0060:
0061:        import java.lang.reflect.Constructor;
0062:        import java.util.*;
0063:
0064:        /** The InventoryPlugin is the Glue of inventory management.
0065:         *  It handles all blackboard services for its modules,
0066:         *  facilitates inter-module communication and manages the
0067:         *  subscriptions.  The InventoryPlugin also creates inventories.
0068:         *  All modules are called from the InventoryPlugin.
0069:         **/
0070:
0071:        public class InventoryPlugin extends ComponentPlugin implements 
0072:                InventoryManager, ClassicRefillGeneratorInventoryManager,
0073:                ReconcileSupplyExpanderInventoryManager,
0074:                LevelOfDetailInventoryManager {
0075:
0076:            protected boolean initialized = false;
0077:            //  protected boolean firstTimeThrough = true;
0078:            protected DomainService domainService;
0079:            protected NodeIdentificationService nodeIdService;
0080:            protected LoggingService logger;
0081:            protected UIDService uidService = null;
0082:            protected TaskUtils taskUtils;
0083:            protected TimeUtils timeUtils;
0084:            protected AssetUtils AssetUtils;
0085:            protected ScheduleUtils scheduleUtils;
0086:            protected HashMap pluginParams;
0087:            protected HashMap inventoryHash;
0088:            //  protected HashMap inventoryInitHash;
0089:            protected HashSet touchedInventories;
0090:            // inventoriesWithDeletions used to refresh snapshots.
0091:            // Ensures correct graphs during deletion periods.
0092:            protected HashSet inventoriesWithDeletions;
0093:            // protected HashSet backwardFlowInventories;  // ### Captures Inventories with unchanged demand
0094:            protected boolean touchedProjections;
0095:            protected boolean touchedChangedProjections = false;
0096:            protected String supplyType;
0097:            //  protected String inventoryFile;
0098:            //   protected boolean fillToCapacity; Will be added bug #1482
0099:            //   protected boolean maintainAtCapacity; Will be added bug #1482
0100:            protected DetReqAggHandler detReqHandler;
0101:            protected Organization myOrganization;
0102:            protected String myOrgName;
0103:            protected ExpanderModule supplyExpander;
0104:            protected AllocatorModule externalAllocator;
0105:            protected RefillGeneratorModule refillGenerator;
0106:            protected RefillProjectionGeneratorModule refillProjGenerator;
0107:            protected ComparatorModule refillComparator;
0108:            protected AllocationAssessor allocationAssessor;
0109:            protected LogisticsPlanModule logisticsPlan;
0110:            protected long startTime;
0111:            protected long cycleStamp;
0112:            protected boolean logToCSV = false;
0113:            protected transient ArrayList newRefills = new ArrayList();
0114:            protected boolean rehydrateInvs = false;
0115:            protected boolean OMChange = false;
0116:            protected long prevLevel6;
0117:            protected boolean turnOnTaskSched = false;
0118:            protected int prepoArrivalOffset = 3;
0119:
0120:            public final String SUPPLY_TYPE = "SUPPLY_TYPE";
0121:            public final String INVENTORY_FILE = "INVENTORY_FILE";
0122:            public final String ENABLE_CSV_LOGGING = "ENABLE_CSV_LOGGING";
0123:            public final String PREPO_ARRIVAL_OFFSET = "PREPO_ARRIVAL_OFFSET";
0124:            public final String TASK_SCHEDULER_ON = "TASK_SCHEDULER_ON";
0125:
0126:            // as a default make the max the end of the oplan (225)
0127:            public final Integer LEVEL_2_MIN = new Integer(40); // later, these should be parameters to plugin...
0128:            public final Integer LEVEL_2_MAX = new Integer(225);
0129:            public final Integer LEVEL_6_MIN = new Integer(20);
0130:            public final Integer LEVEL_6_MAX = new Integer(225);
0131:            // then default to the end of the oplan (max)
0132:            public final String LEVEL_2_TIME_HORIZON = "Level2TimeHorizon";
0133:            public final Integer LEVEL_2_TIME_HORIZON_DEFAULT = LEVEL_2_MAX;
0134:            public final String LEVEL_6_TIME_HORIZON = "Level6TimeHorizon";
0135:            public final Integer LEVEL_6_TIME_HORIZON_DEFAULT = LEVEL_6_MAX;
0136:
0137:            // OPlan variable
0138:            protected LogisticsOPlan logOPlan = null;
0139:
0140:            // Policy variables
0141:            protected InventoryPolicy inventoryPolicy = null;
0142:            protected int criticalLevel = 3;
0143:            protected int reorderPeriod = 3;
0144:            protected long bucketSize = TimeUtils.MSEC_PER_DAY;
0145:            protected boolean fillToCapacity = false;
0146:
0147:            public void load() {
0148:                super .load();
0149:                logger = getLoggingService(this );
0150:                timeUtils = new TimeUtils(this );
0151:                AssetUtils = new AssetUtils(this );
0152:                taskUtils = new TaskUtils(this );
0153:                scheduleUtils = new ScheduleUtils(this );
0154:                detReqHandler = new DetReqAggHandler(this );
0155:                // readParameters() initializes supplyType and inventoryFile
0156:                pluginParams = readParameters();
0157:                supplyExpander = getExpanderModule();
0158:                externalAllocator = getAllocatorModule();
0159:                refillGenerator = getRefillGeneratorModule();
0160:                refillProjGenerator = getRefillProjectionGeneratorModule();
0161:                refillComparator = getComparatorModule();
0162:                allocationAssessor = new AllocationAssessor(this ,
0163:                        getRole(supplyType));
0164:                logisticsPlan = new LogisticsPlan(getAgentIdentifier());
0165:                inventoryHash = new HashMap();
0166:                //    inventoryInitHash = new HashMap();
0167:                touchedInventories = new HashSet();
0168:                inventoriesWithDeletions = new HashSet();
0169:                //backwardFlowInventories = new HashSet();
0170:                touchedProjections = false;
0171:                startTime = currentTimeMillis();
0172:
0173:                domainService = (DomainService) getServiceBroker().getService(
0174:                        this , DomainService.class,
0175:                        new ServiceRevokedListener() {
0176:                            public void serviceRevoked(ServiceRevokedEvent re) {
0177:                                if (DomainService.class.equals(re.getService()))
0178:                                    domainService = null;
0179:                            }
0180:                        });
0181:
0182:                nodeIdService = (NodeIdentificationService) getServiceBroker()
0183:                        .getService(this , NodeIdentificationService.class, null);
0184:                if (nodeIdService == null) {
0185:                    throw new RuntimeException(
0186:                            "Unable to obtain node-id service.");
0187:                }
0188:
0189:                if (uidService == null) {
0190:                    uidService = (UIDService) getServiceBroker().getService(
0191:                            this , UIDService.class,
0192:                            new ServiceRevokedListener() {
0193:                                public void serviceRevoked(
0194:                                        ServiceRevokedEvent re) {
0195:                                    if (UIDService.class
0196:                                            .equals(re.getService()))
0197:                                        uidService = null;
0198:                                }
0199:                            });
0200:                }
0201:
0202:                //   System.out.println("\n LOADING InventoryPlugin of type: " + supplyType +
0203:                //  		       "in org: " + getAgentIdentifier().toString() +
0204:                //    		       " this plugin is: " + this);
0205:            }
0206:
0207:            public void unload() {
0208:                super .unload();
0209:                if (domainService != null) {
0210:                    getServiceBroker().releaseService(this ,
0211:                            DomainService.class, domainService);
0212:                }
0213:                if (nodeIdService != null) {
0214:                    getServiceBroker().releaseService(this ,
0215:                            NodeIdentificationService.class, nodeIdService);
0216:                }
0217:            }
0218:
0219:            public TaskUtils getTaskUtils() {
0220:                return taskUtils;
0221:            }
0222:
0223:            public TimeUtils getTimeUtils() {
0224:                return timeUtils;
0225:            }
0226:
0227:            public AssetUtils getAssetUtils() {
0228:                return AssetUtils;
0229:            }
0230:
0231:            public ScheduleUtils getScheduleUtils() {
0232:                return scheduleUtils;
0233:            }
0234:
0235:            public String getSupplyType() {
0236:                return supplyType;
0237:            }
0238:
0239:            //   protected String getInventoryFileName() {
0240:            //     return inventoryFile;
0241:            //   }
0242:
0243:            public Organization getMyOrganization() {
0244:                return myOrganization;
0245:            }
0246:
0247:            public String getOrgName() {
0248:                return myOrgName;
0249:            }
0250:
0251:            public long getCurrentTimeMillis() {
0252:                return currentTimeMillis();
0253:            }
0254:
0255:            public void publishAdd(Object o) {
0256:                getBlackboardService().publishAdd(o);
0257:            }
0258:
0259:            public BlackboardService getBBService() {
0260:                return getBlackboardService();
0261:            }
0262:
0263:            public NodeIdentificationService getNodeIdService() {
0264:                return nodeIdService;
0265:            }
0266:
0267:            public UIDService getUIDService() {
0268:                return uidService;
0269:            }
0270:
0271:            public void publishAddExpansion(Expansion expansion) {
0272:                PluginHelper.publishAddExpansion(getBlackboardService(),
0273:                        expansion);
0274:            }
0275:
0276:            public void publishChange(Object o) {
0277:                getBlackboardService().publishChange(o);
0278:            }
0279:
0280:            public void publishRemove(Object o) {
0281:                getBlackboardService().publishRemove(o);
0282:            }
0283:
0284:            public void removeSubTask(Task taskToRemove) {
0285:                PluginHelper
0286:                        .removeSubTask(getBlackboardService(), taskToRemove);
0287:                publishRemove(taskToRemove);
0288:            }
0289:
0290:            public PlanningFactory getPlanningFactory() {
0291:                PlanningFactory rootFactory = null;
0292:                if (domainService != null) {
0293:                    rootFactory = (PlanningFactory) domainService
0294:                            .getFactory("planning");
0295:                }
0296:                return rootFactory;
0297:            }
0298:
0299:            public LoggingService getLoggingService(Object requestor) {
0300:                LoggingService ls = (LoggingService) getServiceBroker()
0301:                        .getService(requestor, LoggingService.class, null);
0302:                return LoggingServiceWithPrefix.add(ls, getAgentIdentifier()
0303:                        + ": ");
0304:            }
0305:
0306:            protected void execute() {
0307:                //clear our new refill list
0308:                newRefills.clear();
0309:
0310:                // need to call these at beginning of execute cycle
0311:                supplyTaskScheduler.initForExecuteCycle();
0312:                projectionTaskScheduler.initForExecuteCycle();
0313:
0314:                // if the OM changed and the window is further out then before
0315:                // then mark the flag true so we process previously ignored tasks
0316:                // and allocation results.  If it went down - don't undo work
0317:                if (!Level6OMSubscription.getChangedCollection().isEmpty()) {
0318:                    long currentLevel6 = getEndOfLevelSix();
0319:                    if (logger.isInfoEnabled()) {
0320:                        logger
0321:                                .info("Inv Mgr got changed OM ... new end of level 6 window is: "
0322:                                        + currentLevel6
0323:                                        + " in agent: "
0324:                                        + getAgentIdentifier()
0325:                                        + " supply type: " + getSupplyType());
0326:                    }
0327:                    if (currentLevel6 > prevLevel6) {
0328:                        OMChange = true;
0329:                    }
0330:                    //reset the previous level 6 to the current
0331:                    prevLevel6 = currentLevel6;
0332:                }
0333:
0334:                if (inventoryPolicy == null) {
0335:                    updateInventoryPolicy(inventoryPolicySubscription);
0336:                }
0337:                updateInventoryPolicy(inventoryPolicySubscription
0338:                        .getChangedCollection());
0339:                processDetReq(detReqSubscription.getAddedCollection());
0340:                cycleStamp = (new Date()).getTime();
0341:
0342:                if (inventoryPolicy == null) {
0343:                    if (logger.isInfoEnabled()) {
0344:                        logger.info("\n InventoryPlugin " + supplyType
0345:                                + " not ready to process tasks yet."
0346:                                + " my inv policy is: " + inventoryPolicy
0347:                                + " in " + getMyOrganization());
0348:                    }
0349:                    return;
0350:                }
0351:
0352:                if (myOrganization == null) {
0353:                    myOrganization = getMyOrganization(selfOrganizations
0354:                            .elements());
0355:                }
0356:
0357:                if (myOrganization == null) {
0358:                    if (logger.isInfoEnabled()) {
0359:                        logger.info("\n InventoryPlugin " + supplyType
0360:                                + " not ready to process tasks yet."
0361:                                + " my org is: " + myOrganization);
0362:                    }
0363:                    return;
0364:                }
0365:
0366:                if (!initialized) {
0367:                    myOrgName = myOrganization.getItemIdentificationPG()
0368:                            .getItemIdentification();
0369:                    //       inventoryFile = getInventoryFile(supplyType);
0370:                    //       getInventoryData();
0371:                    initialized = true;
0372:                }
0373:
0374:                logOPlan = logisticsPlan.updateOrgActivities(oplanSubscription,
0375:                        orgActSubscription);
0376:
0377:                if ((logOPlan != null) && orgActSubscription.hasChanged()) {
0378:                    resetLogOPlanForInventories();
0379:                }
0380:
0381:                // if our top level MI task got removed, clean out the references .
0382:                if (!aggMILSubscription.getRemovedCollection().isEmpty()) {
0383:                    detReqHandler.resetAggMITask();
0384:                    if (logger.isDebugEnabled()) {
0385:                        logger.debug("Agent: "
0386:                                + getAgentIdentifier().toString()
0387:                                + " Top Level MI removed[" + supplyType + "]");
0388:                    }
0389:                }
0390:
0391:                //Extra debugging to check for same object on add and remove
0392:                if (logger.isDebugEnabled()) {
0393:                    Collection addedRefills = refillSubscription
0394:                            .getAddedCollection();
0395:                    Collection removedRefills = refillSubscription
0396:                            .getRemovedCollection();
0397:                    Iterator addRefIt = addedRefills.iterator();
0398:                    while (addRefIt.hasNext()) {
0399:                        Task addedRefillTask = (Task) addRefIt.next();
0400:                        if (removedRefills.contains(addedRefillTask)) {
0401:                            logger
0402:                                    .debug("Agent "
0403:                                            + getAgentIdentifier().toString()
0404:                                            + "InvPlugin["
0405:                                            + getSupplyType()
0406:                                            + "] Got a Refill Task added and removed in my subscription "
0407:                                            + addedRefillTask.getVerb() + " "
0408:                                            + addedRefillTask.getUID());
0409:                        }
0410:                    }
0411:
0412:                    Collection addedWithdraws = withdrawTaskSubscription
0413:                            .getAddedCollection();
0414:                    Collection removedWithdraws = withdrawTaskSubscription
0415:                            .getRemovedCollection();
0416:                    Iterator addWD = addedWithdraws.iterator();
0417:                    while (addWD.hasNext()) {
0418:                        Task addedWDTask = (Task) addWD.next();
0419:                        if (removedWithdraws.contains(addedWDTask)) {
0420:                            logger
0421:                                    .debug("Agent "
0422:                                            + getAgentIdentifier().toString()
0423:                                            + "InvPlugin["
0424:                                            + getSupplyType()
0425:                                            + "] Got a Withdraw Task added and removed in my subscription "
0426:                                            + addedWDTask.getVerb() + " "
0427:                                            + addedWDTask.getUID());
0428:                        }
0429:                    }
0430:                }
0431:                if ((detReqHandler
0432:                        .getDetermineRequirementsTask(aggMILSubscription) != null)
0433:                        && (logOPlan != null)) {
0434:                    if (rehydrateInvs) {
0435:                        addRehydratedInventories(blackboard
0436:                                .query(new InventoryPredicate(supplyType)));
0437:                        if (logger.isDebugEnabled()) {
0438:                            logger.debug("Agent: "
0439:                                    + getAgentIdentifier().toString()
0440:                                    + "Rehydrating Inventories for InvPlugin["
0441:                                    + supplyType + "]");
0442:                        }
0443:                        rehydrateInvs = false;
0444:                    }
0445:
0446:                    //Process all the removes at once - note that the supplyExpander.handleRemovedProjections sets the
0447:                    //touchedRemovedProjections boolean for use later.
0448:                    boolean touchedRemovedProjections = processRemoves();
0449:                    Collection addedSupply = supplyTaskScheduler
0450:                            .getAddedCollection();
0451:
0452:                    if (!commStatusSub.isEmpty()) {
0453:                        supplyExpander.determineCommStatus(commStatusSub,
0454:                                addedSupply);
0455:                    }
0456:                    TimeSpan timeSpan = null;
0457:                    if (turnOnTaskSched) {
0458:                        timeSpan = supplyTaskScheduler.getCurrentTimeSpan();
0459:                    } else {
0460:                        timeSpan = new ScheduleElementImpl(
0461:                                getLogOPlanStartTime(), getLogOPlanEndTime());
0462:                    }
0463:                    if (!addedSupply.isEmpty()) {
0464:                        expandIncomingRequisitions(getTasksWithoutPEs(addedSupply)); // fix for bug #1695
0465:                    }
0466:                    Collection changedSupply = supplyTaskScheduler
0467:                            .getChangedCollection();
0468:                    if (!changedSupply.isEmpty()) {
0469:                        supplyExpander.updateChangedRequisitions(changedSupply);
0470:                    }
0471:                    supplyTaskScheduler.finishedExecuteCycle();
0472:
0473:                    Collection addedProjections = projectionTaskScheduler
0474:                            .getAddedCollection();
0475:                    TimeSpan timeSpan2 = null;
0476:                    if (turnOnTaskSched) {
0477:                        timeSpan2 = projectionTaskScheduler
0478:                                .getCurrentTimeSpan();
0479:                    } else {
0480:                        timeSpan2 = new ScheduleElementImpl(
0481:                                getLogOPlanStartTime(), getLogOPlanEndTime());
0482:                    }
0483:                    if (!addedProjections.isEmpty()) {
0484:                        // getTasksWithoutPEs is fix for bug #1695
0485:                        touchedProjections = expandIncomingProjections(getTasksWithoutPEs(addedProjections));
0486:                    }
0487:                    Collection changedProjections = projectionTaskScheduler
0488:                            .getChangedCollection();
0489:                    if (!changedProjections.isEmpty()) {
0490:                        supplyExpander
0491:                                .updateChangedProjections(changedProjections);
0492:                        touchedChangedProjections = true;
0493:                        // System.out.println("Touched changed projections in " + getAgentIdentifier() +
0494:                        //                                " type is" + getSupplyType());
0495:                    }
0496:                    projectionTaskScheduler.finishedExecuteCycle();
0497:
0498:                    // Rescind tasks that no longer have a provider
0499:                    // and
0500:                    // Allocate any refill tasks from previous executions that were not allocated to providers
0501:                    // but only if we are not about to rip out previous work we have done
0502:                    if (didOrgRelationshipsChange()) {
0503:                        if (logger.isDebugEnabled()) {
0504:                            logger
0505:                                    .debug("ORG RELATIONSHIPS CHANGED SDSD myorg: "
0506:                                            + myOrganization
0507:                                            + " supply type:"
0508:                                            + supplyType
0509:                                            + " role: "
0510:                                            + getRole(supplyType) + "\n");
0511:                        }
0512:                        getOverlappingTasks(refillAllocationSubscription,
0513:                                Constants.Verb.Supply);
0514:                        getOverlappingTasks(refillAllocationSubscription,
0515:                                Constants.Verb.ProjectSupply);
0516:
0517:                        // Handle unallocated tasks
0518:                        Collection unalloc = null;
0519:                        if (addedSupply.isEmpty() && changedSupply.isEmpty()) {
0520:                            unalloc = getTaskUtils().getUnallocatedTasks(
0521:                                    refillSubscription, Constants.Verb.Supply);
0522:                            if (!unalloc.isEmpty()) {
0523:                                if (logger.isInfoEnabled())
0524:                                    logger
0525:                                            .info("TRYING TO ALLOCATE SUPPLY REFILL TASKS...");
0526:                                externalAllocator.allocateRefillTasks(unalloc);
0527:                            }
0528:                        }
0529:                        if (addedProjections.isEmpty()
0530:                                && changedProjections.isEmpty()) {
0531:                            unalloc = getTaskUtils().getUnallocatedTasks(
0532:                                    refillSubscription,
0533:                                    Constants.Verb.ProjectSupply);
0534:                            if (!unalloc.isEmpty()) {
0535:                                if (logger.isInfoEnabled())
0536:                                    logger
0537:                                            .info("TRYING TO ALLOCATE PROJECTION REFILL TASKS...");
0538:                                externalAllocator.allocateRefillTasks(unalloc);
0539:                            }
0540:                        }
0541:                    }
0542:
0543:                    // call the Refill Generators if we have new demand
0544:                    if (!getTouchedInventories().isEmpty()) {
0545:                        // update the inventory customer hash tables when we have new demand
0546:                        rebuildPGCustomerHash();
0547:                        //check to see if we have new projections
0548:                        if (touchedProjections || touchedRemovedProjections
0549:                                || touchedChangedProjections) {
0550:                            if (logger.isDebugEnabled()) {
0551:                                logger.debug("Agent: "
0552:                                        + getAgentIdentifier().toString()
0553:                                        + "InvPlugin" + supplyType + "]"
0554:                                        + "something touched: tprojections: "
0555:                                        + touchedProjections + " tRemovedProj"
0556:                                        + touchedRemovedProjections
0557:                                        + " tChangedProj: "
0558:                                        + touchedChangedProjections);
0559:                            }
0560:                            //check to see if the OM changed.  If it did process all inventories
0561:                            //since we probably ignored some demand tasks before the change
0562:                            if (OMChange) {
0563:                                refillProjGenerator.calculateRefillProjections(
0564:                                        getInventories(), criticalLevel,
0565:                                        getEndOfLevelSix(), getEndOfLevelTwo(),
0566:                                        refillComparator);
0567:                            } else {
0568:                                refillProjGenerator.calculateRefillProjections(
0569:                                        getTouchedInventories(), criticalLevel,
0570:                                        getEndOfLevelSix(), getEndOfLevelTwo(),
0571:                                        refillComparator);
0572:                            }
0573:                        }
0574:                        refillGenerator.calculateRefills(
0575:                                getTouchedInventories(), refillComparator);
0576:                        externalAllocator.allocateRefillTasks(newRefills);
0577:
0578:                        //we might get new demand where we don't need to generate any new refills
0579:                        // such as small demand from the stimulator servlet - when this happens we
0580:                        // need to kick the allocation assessor to allocate the withdraws
0581:                        allocationAssessor
0582:                                .reconcileInventoryLevels(getActionableInventories());
0583:
0584:                    }
0585:
0586:                    // if we are in downward flow ONLY check the withdraw expansion results
0587:                    // note we may go through the whole list multiple times - but this seems like the
0588:                    // simplest fix to get rid of places where we miss change reports because the AA
0589:                    // compares previous results to new ones and leaves the old ones if they are equal.
0590:                    // note that the updates only occur if the reported result is not equal to the estimated
0591:                    // so we will not be waking up the whole chain by checking these more than once.
0592:                    HashSet backwardFlowTouched = null;
0593:                    if (getTouchedInventories().isEmpty()) {
0594:                        supplyExpander
0595:                                .updateAllocationResult(expansionSubscription);
0596:                        backwardFlowTouched = externalAllocator
0597:                                .updateAllocationResult(refillAllocationSubscription);
0598:                        // if the OM changed, process ALL inventories for demand projections and
0599:                        // allocation results since some results were likely ignored before
0600:                        // the OM level 6 window changed.
0601:                        if (OMChange) {
0602:                            refillProjGenerator.calculateRefillProjections(
0603:                                    getInventories(), criticalLevel,
0604:                                    getEndOfLevelSix(), getEndOfLevelTwo(),
0605:                                    refillComparator);
0606:                            externalAllocator.allocateRefillTasks(newRefills);
0607:                            allocationAssessor
0608:                                    .reconcileInventoryLevels(getInventories());
0609:                        } else {
0610:                            allocationAssessor
0611:                                    .reconcileInventoryLevels(backwardFlowTouched);
0612:                        }
0613:                    } else {
0614:                        // if the we are not in backwards flow but the OM changed
0615:                        // process ARs anyway because we may not get woken up again to
0616:                        // process them if they have all come in already
0617:                        if (OMChange) {
0618:                            allocationAssessor
0619:                                    .reconcileInventoryLevels(getInventories());
0620:                        }
0621:                    }
0622:
0623:                    // update the Maintain Inventory Expansion results
0624:                    PluginHelper
0625:                            .updateAllocationResult(MIExpansionSubscription);
0626:                    PluginHelper
0627:                            .updateAllocationResult(MITopExpansionSubscription);
0628:                    PluginHelper
0629:                            .updateAllocationResult(DetReqInvExpansionSubscription);
0630:
0631:                    if (backwardFlowTouched != null) {
0632:                        takeInventorySnapshot(backwardFlowTouched);
0633:                    }
0634:                    takeInventorySnapshot(getTouchedInventories());
0635:                    takeInventorySnapshot(getInventoriesWithDeletions());
0636:
0637:                    // touchedInventories and inventoriesWithDeletions should not be cleared until
0638:                    // the end of transaction
0639:                    touchedInventories.clear();
0640:                    inventoriesWithDeletions.clear();
0641:                    //backwardFlowInventories.clear(); //###
0642:                    touchedProjections = false;
0643:                    touchedChangedProjections = false;
0644:                    OMChange = false;
0645:                    //testBG();
0646:                } else {
0647:                    //process any removes if the DetReq task returns null - this should catch the case where it gets rescinded.
0648:                    // to reduce the amount of times this gets run at start up - only do it if we don't have
0649:                    // a log oplan also.  Note that if the oplan gets rescinded this might need to change.
0650:                    if (logOPlan != null) {
0651:                        processRemoves();
0652:                        takeInventorySnapshot(getTouchedInventories());
0653:                        touchedInventories.clear();
0654:                    }
0655:                }
0656:                supplyExpander.checkCommStatusAlarms();
0657:            }
0658:
0659:            protected boolean processRemoves() {
0660:                if (logger.isDebugEnabled()) {
0661:                    logger.debug("Agent: " + getAgentIdentifier().toString()
0662:                            + " Processing Subscription Removes[" + supplyType
0663:                            + "]");
0664:                }
0665:                detReqHandler.handleMILTasks(milSubscription);
0666:                boolean touchedRemovedProjections = supplyExpander
0667:                        .handleRemovedProjections(projectWithdrawTaskSubscription
0668:                                .getRemovedCollection());
0669:                supplyExpander
0670:                        .handleRemovedRequisitions(withdrawTaskSubscription
0671:                                .getRemovedCollection());
0672:                handleRemovedRefills(refillSubscription.getRemovedCollection());
0673:                Collection removedDispositions = dispositions
0674:                        .getRemovedCollection();
0675:                if (!removedDispositions.isEmpty()) {
0676:                    supplyExpander
0677:                            .handleRemovedDispositions(removedDispositions);
0678:                }
0679:                return touchedRemovedProjections;
0680:            }
0681:
0682:            protected void getProviderDates(HashMap providerStartDates,
0683:                    HashMap providerEndDates) {
0684:                RelationshipSchedule relSched = myOrganization
0685:                        .getRelationshipSchedule();
0686:                Collection relationships = relSched.getMatchingRelationships(
0687:                        TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE);
0688:                Iterator rit = relationships.iterator();
0689:                Role myRole = getRole(supplyType);
0690:                // 	  System.out.println("SDSD myorg: " + myOrganization + " supply type:" +
0691:                // 			       supplyType + " role: " + getRole(supplyType) + "\n");
0692:                Date date;
0693:                while (rit.hasNext()) {
0694:                    Relationship r = (Relationship) rit.next();
0695:                    HasRelationships hr = relSched.getOther(r);
0696:                    if (hr instanceof  Organization) {
0697:                        Role role = relSched.getOtherRole(r);
0698:                        if (role == myRole) {
0699:                            date = r.getEndDate();
0700:                            providerEndDates.put(hr, date);
0701:                            date = r.getStartDate();
0702:                            providerStartDates.put(hr, date);
0703:                            //	  System.out.println("SDSD   org: " + hr + " end:" + date + "\n");
0704:                        }
0705:                    }
0706:                }
0707:            }
0708:
0709:            protected HashMap relationshipScheduleMap() {
0710:                HashMap providerAvailSched = new HashMap();
0711:                RelationshipSchedule relSched = myOrganization
0712:                        .getRelationshipSchedule();
0713:                Role myRole = getRole(supplyType);
0714:                Collection relationships = relSched.getMatchingRelationships(
0715:                        myRole, new TimeSpan.Span(TimeSpan.MIN_VALUE,
0716:                                TimeSpan.MAX_VALUE));
0717:                Iterator rit = relationships.iterator();
0718:                Schedule sched = null;
0719:
0720:                while (rit.hasNext()) {
0721:                    Relationship r = (Relationship) rit.next();
0722:                    HasRelationships hr = relSched.getOther(r);
0723:                    //String provider;
0724:                    if (hr instanceof  Organization) {
0725:                        if (!providerAvailSched.containsKey(hr)) {
0726:                            sched = new ScheduleImpl();
0727:                            sched.add(r);
0728:                            providerAvailSched.put(hr, sched);
0729:                            if (myOrgName.indexOf("1-35-ARBN") >= 0
0730:                                    && supplyType.equals("BulkPOL")
0731:                                    && logger.isDebugEnabled()) {
0732:                                logger.debug(" adding a provider to the map "
0733:                                        + hr);
0734:                            }
0735:                        } else {
0736:                            sched = (Schedule) providerAvailSched.get(hr);
0737:                            if (myOrgName.indexOf("1-35-ARBN") >= 0
0738:                                    && supplyType.equals("BulkPOL")
0739:                                    && logger.isDebugEnabled()) {
0740:                                logger
0741:                                        .debug(" adding a relationship to the provider map "
0742:                                                + hr);
0743:                            }
0744:                            sched.add(r);
0745:                        }
0746:                        if (myOrgName.indexOf("1-35-ARBN") >= 0
0747:                                && supplyType.equals("BulkPOL")
0748:                                && logger.isDebugEnabled()) {
0749:                            logger.debug("Time spans are " + r.getStartDate()
0750:                                    + " - " + r.getEndDate() + hr);
0751:                        }
0752:                    }
0753:                }
0754:                return providerAvailSched;
0755:            }
0756:
0757:            // TODO:  may not need this
0758:            protected Set uniqueProviders() {
0759:                RelationshipSchedule myOrgRelSched = myOrganization
0760:                        .getRelationshipSchedule();
0761:                Role myRole = getRole(supplyType);
0762:                Collection relationships = myOrgRelSched
0763:                        .getMatchingRelationships(myRole, new TimeSpan.Span(
0764:                                TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE));
0765:                Iterator rit = relationships.iterator();
0766:                Set uniqueProviders = new HashSet();
0767:                while (rit.hasNext()) {
0768:                    Relationship r = (Relationship) rit.next();
0769:                    HasRelationships hr = myOrgRelSched.getOther(r);
0770:                    if (hr instanceof  Organization) {
0771:                        uniqueProviders.add(hr);
0772:                    }
0773:                }
0774:                return uniqueProviders;
0775:            }
0776:
0777:            protected class EnclosedPredicate implements  UnaryPredicate {
0778:                protected RelationshipSchedule schedule;
0779:                protected Role role;
0780:                HasRelationships other;
0781:                long start, end;
0782:
0783:                public EnclosedPredicate(RelationshipSchedule schedule,
0784:                        Role role, HasRelationships other, long start, long end) {
0785:                    this .schedule = schedule;
0786:                    this .role = role;
0787:                    this .other = other;
0788:                    this .start = start;
0789:                    this .end = end;
0790:                }
0791:
0792:                public boolean execute(Object obj) {
0793:                    Relationship relationship = (Relationship) obj;
0794:                    return ((schedule.getOtherRole(relationship).equals(role))
0795:                            && (schedule.getOther(relationship).equals(other)) && ((relationship
0796:                            .getStartTime() <= start) && (relationship
0797:                            .getEndTime() >= end)));
0798:                }
0799:            }
0800:
0801:            protected class EnclosedSchedPredicate implements  UnaryPredicate {
0802:                long start;
0803:                long end;
0804:
0805:                public EnclosedSchedPredicate(long start, long end) {
0806:                    this .start = start;
0807:                    this .end = end;
0808:                }
0809:
0810:                public boolean execute(Object obj) {
0811:                    if (!(obj instanceof  ScheduleElement)) {
0812:                        throw new IllegalArgumentException(
0813:                                new StringBuffer()
0814:                                        .append(
0815:                                                " EnclosedSchedPredicate was expecting a ScheduleElement ")
0816:                                        .append(obj).toString());
0817:                    }
0818:                    ScheduleElement se = (ScheduleElement) obj;
0819:                    return se.getStartTime() <= start && se.getEndTime() >= end;
0820:                }
0821:            }
0822:
0823:            protected Collection getUncoveredTasks(Collection tasks) {
0824:                ArrayList uncoveredTasks = new ArrayList();
0825:                HashMap providersSched = relationshipScheduleMap();
0826:                boolean overlap;
0827:
0828:                for (Iterator iterator = tasks.iterator(); iterator.hasNext();) {
0829:                    Task task = (Task) iterator.next();
0830:                    overlap = false;
0831:                    Iterator it = providersSched.values().iterator();
0832:                    while (it.hasNext()) {
0833:                        Schedule sched = (Schedule) it.next();
0834:                        if (task.getVerb().equals(Constants.Verb.ProjectSupply)) {
0835:                            long start = TaskUtils.getStartTime(task);
0836:                            long end = TaskUtils.getEndTime(task);
0837:                            if (sched.getEncapsulatedScheduleElements(start,
0838:                                    end).size() > 0
0839:                                    || sched.getOverlappingScheduleElements(
0840:                                            start, end).size() > 0) {
0841:                                overlap = true;
0842:                            }
0843:                        } else { // It is a Supply Task
0844:                            if (sched.getScheduleElementsWithTime(
0845:                                    TaskUtils.getEndTime(task)).size() > 0) {
0846:                                overlap = true;
0847:                            }
0848:                        }
0849:                        if (!overlap) {
0850:                            uncoveredTasks.add(task);
0851:                        }
0852:                    }
0853:                }
0854:                return uncoveredTasks;
0855:            }
0856:
0857:            protected void getOverlappingTasks(Collection refill_allocations,
0858:                    Verb verb) {
0859:                //RelationshipSchedule myOrgRelSched = myOrganization.getRelationshipSchedule();
0860:                HashMap providersSched = relationshipScheduleMap();
0861:                Iterator raIt = refill_allocations.iterator();
0862:                ArrayList unprovidedTasks = new ArrayList();
0863:                ArrayList partial = new ArrayList();
0864:                Role myRole = getRole(supplyType);
0865:                while (raIt.hasNext()) {
0866:                    Allocation alloc = (Allocation) raIt.next();
0867:                    Task task = alloc.getTask();
0868:                    if ((alloc != null) && (task.getVerb().equals(verb))) {
0869:                        long taskEnd = TaskUtils.getEndTime(task);
0870:                        //if the task is totally in the past, don't touch it!
0871:                        if (currentTimeMillis() > taskEnd) {
0872:                            continue;
0873:                        }
0874:                        Organization provider = (Organization) alloc.getAsset();
0875:                        if (alloc.getRole() != getRole(supplyType)) {
0876:                            if (logger.isWarnEnabled())
0877:                                logger.warn("SDSD MISMATCH: " + alloc.getRole()
0878:                                        + " " + task + "\n");
0879:                        }
0880:                        Schedule availSched = (Schedule) providersSched
0881:                                .get(provider);
0882:
0883:                        Date start = null; // just a place holder
0884:                        Collection enclosed;
0885:                        if (availSched != null) {
0886:                            if (verb.equals(Constants.Verb.ProjectSupply)) {
0887:                                // only need provider from start to end - bucketSize
0888:                                long taskStart = TaskUtils.getStartTime(task);
0889:                                start = new Date(taskStart);
0890:
0891:                                //EnclosedPredicate enclosedPred = new EnclosedPredicate(myOrgRelSched, myRole, provider, taskStart, taskEnd);
0892:                                EnclosedSchedPredicate enclosedPred = new EnclosedSchedPredicate(
0893:                                        taskStart, taskEnd);
0894:
0895:                                int size = availSched.filter(enclosedPred)
0896:                                        .size();
0897:                                //System.out.println("Task times " + new Date(taskStart) + " " + start + " size of enclosed" + size);
0898:                                if (size == 0) {
0899:                                    //if (availSched.getEncapsulatedScheduleElements(taskStart, taskEnd - bucketSize).size() == 0) {
0900:                                    if (availSched
0901:                                            .getOverlappingScheduleElements(
0902:                                                    taskStart,
0903:                                                    taskEnd - bucketSize)
0904:                                            .size() > 0) {
0905:                                        partial.add(task);
0906:                                    } else {
0907:                                        unprovidedTasks.add(task);
0908:                                    }
0909:                                }
0910:                            } else { // it is Supply Task
0911:                                enclosed = availSched
0912:                                        .getScheduleElementsWithTime(taskEnd);
0913:                                if (enclosed.size() == 0) {
0914:                                    if (myOrgName.indexOf("1-35-ARBN") >= 0
0915:                                            && supplyType.equals("BulkPOL")
0916:                                            && logger.isDebugEnabled()) {
0917:                                        logger.debug("Adding task to list  "
0918:                                                + start + "  "
0919:                                                + new Date(taskEnd)
0920:                                                + unprovidedTasks.size());
0921:                                    }
0922:                                    unprovidedTasks.add(task);
0923:                                }
0924:                            }
0925:                        }
0926:                    }
0927:                }
0928:                if (myOrgName.indexOf("1-35-ARBN") >= 0
0929:                        && supplyType.equals("BulkPOL")
0930:                        && logger.isDebugEnabled()) {
0931:                    logger.debug("number of unprovided tasks is "
0932:                            + unprovidedTasks.size());
0933:                }
0934:                if (!unprovidedTasks.isEmpty()) {
0935:                    if (logger.isInfoEnabled()) {
0936:                        logger
0937:                                .info("Trying to rescind and reallocate unprovided supply refill tasks...");
0938:                    }
0939:                    externalAllocator.rescindTaskAllocations(unprovidedTasks);
0940:                    externalAllocator.allocateRefillTasks(unprovidedTasks);
0941:                }
0942:                if (!partial.isEmpty()) {
0943:                    ArrayList originalTasks = new ArrayList();
0944:                    ArrayList partialsToAlloc = new ArrayList();
0945:                    Iterator partIt = partial.iterator();
0946:                    ArrayList failedSplits = new ArrayList();
0947:                    while (partIt.hasNext()) {
0948:                        Task taskToSplit = (Task) partIt.next();
0949:                        List splitTimes = getSplitTimes(taskToSplit,
0950:                                providersSched);
0951:                        if (splitTimes.isEmpty()) {
0952:                            failedSplits.add(taskToSplit);
0953:                            continue;
0954:                        }
0955:                        Collection newPartialTasks = getTaskUtils()
0956:                                .splitProjection(taskToSplit, splitTimes, this );
0957:                        originalTasks.add(taskToSplit);
0958:                        partialsToAlloc.addAll(newPartialTasks);
0959:                    }
0960:
0961:                    if (!failedSplits.isEmpty()) {
0962:                        externalAllocator.rescindTaskAllocations(failedSplits);
0963:                        externalAllocator.allocateRefillTasks(failedSplits);
0964:                    }
0965:                    if (!partialsToAlloc.isEmpty()) {
0966:                        externalAllocator.rescindTaskAllocations(originalTasks);
0967:                        externalAllocator.allocateRefillTasks(partialsToAlloc);
0968:                    }
0969:                }
0970:                //return unprovidedTasks;
0971:            }
0972:
0973:            protected List getSplitTimes(Task task, HashMap providerSched) {
0974:                ArrayList splits = new ArrayList();
0975:                long start = TaskUtils.getStartTime(task);
0976:                long end = TaskUtils.getEndTime(task);
0977:                PlanElement pe = task.getPlanElement();
0978:                Organization provider = null;
0979:                if (pe != null && pe instanceof  Allocation) {
0980:                    provider = (Organization) ((Allocation) pe).getAsset();
0981:                }
0982:                Schedule sched = (Schedule) providerSched.get(provider);
0983:                Collection overlaps = sched.getOverlappingScheduleElements(
0984:                        start, end);
0985:                if (overlaps.isEmpty()) {
0986:                    logger
0987:                            .error("InvPlugin got no overlapping elements for task start "
0988:                                    + new Date(start)
0989:                                    + " end "
0990:                                    + new Date(end)
0991:                                    + " provider is: " + provider);
0992:                    return Collections.EMPTY_LIST;
0993:                }
0994:                ScheduleElement firstlap = (ScheduleElement) overlaps
0995:                        .iterator().next();
0996:                TimeSpan first = new MutableTimeSpan();
0997:                TimeSpan second = new MutableTimeSpan();
0998:                if (start >= firstlap.getStartTime()) {
0999:                    if (logger.isInfoEnabled()) {
1000:                        logger.info("GetSplitTimes... task is: "
1001:                                + new Date(start) + " ... " + new Date(end)
1002:                                + "  overlapping relationship is: "
1003:                                + new Date(firstlap.getStartTime()) + " ... "
1004:                                + new Date(firstlap.getEndTime()));
1005:                    }
1006:                    if (!(isValidSpan(start, firstlap.getEndTime()) && isValidSpan(
1007:                            firstlap.getEndTime(), end))) {
1008:                        return Collections.EMPTY_LIST;
1009:                    }
1010:                    ((NewTimeSpan) first).setTimeSpan(start, firstlap
1011:                            .getEndTime());
1012:                    ((NewTimeSpan) second).setTimeSpan(firstlap.getEndTime(),
1013:                            end);
1014:                } else {
1015:                    if (logger.isInfoEnabled()) {
1016:                        logger.info("GetSplitTimes... task is: "
1017:                                + new Date(start) + " ... " + new Date(end)
1018:                                + "  overlapping relationship is: "
1019:                                + new Date(firstlap.getStartTime()) + " ... "
1020:                                + new Date(firstlap.getEndTime()));
1021:                    }
1022:                    if (!(isValidSpan(firstlap.getStartTime(), end) && isValidSpan(
1023:                            start, firstlap.getStartTime()))) {
1024:                        return Collections.EMPTY_LIST;
1025:                    }
1026:                    ((NewTimeSpan) first).setTimeSpan(firstlap.getStartTime(),
1027:                            end);
1028:                    ((NewTimeSpan) second).setTimeSpan(start, firstlap
1029:                            .getStartTime());
1030:                }
1031:                splits.add(first);
1032:                splits.add(second);
1033:                return splits;
1034:            }
1035:
1036:            protected boolean isValidSpan(long start, long end) {
1037:                if (start < end) {
1038:                    return true;
1039:                } else {
1040:                    if (logger.isErrorEnabled()) {
1041:                        logger
1042:                                .error(" Invalid time span in Inventory plugin, start  "
1043:                                        + new Date(start)
1044:                                        + " end "
1045:                                        + new Date(end));
1046:                    }
1047:                    return false;
1048:                }
1049:            }
1050:
1051:            /**
1052:             * @param task
1053:             * @return split times
1054:             */
1055:            public List getNewTaskSplitTimes(Task task) {
1056:                HashMap provHashMap = relationshipScheduleMap();
1057:                ArrayList splits = new ArrayList();
1058:                long start = TaskUtils.getStartTime(task);
1059:                long end = TaskUtils.getEndTime(task);
1060:                Collection values = provHashMap.values();
1061:                Schedule tmp = new ScheduleImpl();
1062:                Iterator valIt = values.iterator();
1063:                while (valIt.hasNext()) {
1064:                    Schedule sched = (Schedule) valIt.next();
1065:                    tmp.addAll(sched);
1066:                }
1067:                // Filter out the elements that enclose the span; if they exist, the relationship
1068:                // schedule was updated and we are covered. Return an empty list and let the plugin run
1069:                // again with the updated info.
1070:                Collection enclosed = tmp.filter(new EnclosedSchedPredicate(
1071:                        start, end));
1072:                if (!enclosed.isEmpty()) {
1073:                    return splits;
1074:                }
1075:                // if we make it here, then there can only be partial overlaps or none
1076:                Collection overlaps = tmp.getOverlappingScheduleElements(start,
1077:                        end);
1078:                if (overlaps.isEmpty()) {
1079:                    return Collections.EMPTY_LIST;
1080:                }
1081:                ScheduleElement firstlap = (ScheduleElement) overlaps
1082:                        .iterator().next();
1083:                TimeSpan first = new MutableTimeSpan();
1084:                TimeSpan second = new MutableTimeSpan();
1085:                if (start >= firstlap.getStartTime()) {
1086:                    if (!(isValidSpan(firstlap.getEndTime(), end) && isValidSpan(
1087:                            start, firstlap.getEndTime()))) {
1088:                        return Collections.EMPTY_LIST;
1089:                    }
1090:                    ((NewTimeSpan) first).setTimeSpan(start, firstlap
1091:                            .getEndTime());
1092:                    ((NewTimeSpan) second).setTimeSpan(firstlap.getEndTime(),
1093:                            end);
1094:                } else {
1095:                    if (!(isValidSpan(firstlap.getStartTime(), end) && isValidSpan(
1096:                            start, firstlap.getStartTime()))) {
1097:                        return Collections.EMPTY_LIST;
1098:                    }
1099:                    ((NewTimeSpan) first).setTimeSpan(firstlap.getStartTime(),
1100:                            end);
1101:                    ((NewTimeSpan) second).setTimeSpan(start, firstlap
1102:                            .getStartTime());
1103:                }
1104:                splits.add(first);
1105:                splits.add(second);
1106:                return splits;
1107:            }
1108:
1109:            protected Collection getUnprovidedTasks(
1110:                    Collection refill_allocations, Verb verb,
1111:                    HashMap providerStartDates, HashMap providerEndDates) {
1112:                Iterator raIt = refill_allocations.iterator();
1113:                ArrayList unprovidedTasks = new ArrayList();
1114:                Task task;
1115:                Organization provider;
1116:                Allocation alloc;
1117:                long taskEnd, taskStart;
1118:                Date providerEndDate, providerStartDate;
1119:                while (raIt.hasNext()) {
1120:                    alloc = (Allocation) raIt.next();
1121:                    task = alloc.getTask();
1122:                    if (task.getVerb().equals(verb)) {
1123:                        taskEnd = TaskUtils.getEndTime(task);
1124:                        provider = (Organization) alloc.getAsset();
1125:                        if (alloc.getRole() != getRole(supplyType)) {
1126:                            if (logger.isWarnEnabled()) {
1127:                                logger.warn("SDSD MISMATCH: " + alloc.getRole()
1128:                                        + " " + task + "\n");
1129:                            }
1130:                        }
1131:                        providerEndDate = (Date) providerEndDates.get(provider);
1132:                        if (verb.equals(Constants.Verb.ProjectSupply)) {
1133:                            taskStart = TaskUtils.getStartTime(task);
1134:                            providerStartDate = (Date) providerStartDates
1135:                                    .get(provider);
1136:
1137:                            // only need provider from start to end - bucketSize
1138:                            if ((providerEndDate != null && providerEndDate
1139:                                    .getTime() < taskEnd - bucketSize)
1140:                                    || (providerStartDate != null && providerStartDate
1141:                                            .getTime() > taskStart)) {
1142:
1143:                                unprovidedTasks.add(task);
1144:                            }
1145:                        } else {
1146:                            if (providerEndDate != null
1147:                                    && providerEndDate.getTime() < taskEnd) {
1148:                                unprovidedTasks.add(task);
1149:                            }
1150:                        }
1151:                    }
1152:                }
1153:                //       if (! unprovidedTasks.isEmpty()) {
1154:                // 	  System.out.println("SDSD unprovided: " + unprovidedTasks + "\n");
1155:                //       }
1156:                return unprovidedTasks;
1157:            }
1158:
1159:            /** Subscription for aggregatable support requests. **/
1160:            protected IncrementalSubscription detReqSubscription;
1161:
1162:            /** Subscription for the aggregated support request **/
1163:            protected IncrementalSubscription aggMILSubscription;
1164:
1165:            /** Subscription for the MIL tasks **/
1166:            protected IncrementalSubscription milSubscription;
1167:
1168:            /** Subscription for the Organization(s) in which this plugin resides **/
1169:            protected IncrementalSubscription selfOrganizations;
1170:
1171:            /** Subscription for incoming Supply tasks **/
1172:            protected TaskScheduler supplyTaskScheduler;
1173:            //  protected IncrementalSubscription supplyTaskSubscription;
1174:
1175:            /** Subscription for incoming Projection tasks **/
1176:            protected TaskScheduler projectionTaskScheduler;
1177:            //  protected IncrementalSubscription projectionTaskSubscription;
1178:
1179:            /** Subscription for Allocations on outgoing Refill (Supply & ProjectSupply) tasks **/
1180:            protected IncrementalSubscription refillAllocationSubscription;
1181:
1182:            /** Subscription for my Refill (Supply & ProjectSupply) tasks **/
1183:            protected IncrementalSubscription refillSubscription;
1184:
1185:            /** Subscription for my Non-Refill (Supply & ProjectSupply) tasks **/
1186:            protected IncrementalSubscription nonrefillSubscription;
1187:
1188:            /** Subscription for Supply/ProjectSupply Expansions **/
1189:            protected IncrementalSubscription expansionSubscription;
1190:
1191:            /** Subscription for InventoryPolicy **/
1192:            protected IncrementalSubscription inventoryPolicySubscription;
1193:
1194:            /** Subscription for OPlan object **/
1195:            protected IncrementalSubscription oplanSubscription;
1196:
1197:            /** Subscription for Withdraw tasks created by this plugin **/
1198:            protected IncrementalSubscription withdrawTaskSubscription;
1199:
1200:            /** Subscription for ProjectWithdraw tasks created by this plugin **/
1201:            protected IncrementalSubscription projectWithdrawTaskSubscription;
1202:
1203:            /** Subscription for MaintainInventory Expansion PlanElements created by this plugin**/
1204:            protected IncrementalSubscription MIExpansionSubscription;
1205:
1206:            /** Subscription for MaintainInventory Expansion for Top level MI task (Aggregate task) **/
1207:            protected IncrementalSubscription MITopExpansionSubscription;
1208:
1209:            /** Subscription for DetermineRequirements of type MaintainInventory Expansion **/
1210:            protected IncrementalSubscription DetReqInvExpansionSubscription;
1211:
1212:            /** special subscription to oms only used in subsistence to deal with the level2 -> level6
1213:             *  issue that occurs because subsistence does not generate level 2 tasks
1214:             **/
1215:            protected IncrementalSubscription Level6OMSubscription;
1216:
1217:            //Org Activity subscription
1218:            protected IncrementalSubscription orgActSubscription;
1219:
1220:            /** Subscription for CommStatus object **/
1221:            protected IncrementalSubscription commStatusSub;
1222:
1223:            /** Subscription for removed dispositions, need to reconcile with prediction tasks **/
1224:            protected IncrementalSubscription dispositions;
1225:
1226:            protected IncrementalSubscription shortfallSummary;
1227:
1228:            protected void setupSubscriptions() {
1229:                if (!getBlackboardService().didRehydrate()) {
1230:                    setupOperatingModes();
1231:                    prevLevel6 = getEndOfLevelSix();
1232:                } else {
1233:                    // if we did rehydrate set a flag to rehydrate the inventories
1234:                    //when we are ready in the execute block
1235:                    rehydrateInvs = true;
1236:                    Collection level2OMs = getBlackboardService().query(
1237:                            new OperatingModePredicate(supplyType,
1238:                                    LEVEL_2_TIME_HORIZON));
1239:                    //there should only be one.
1240:                    Iterator level2it = level2OMs.iterator();
1241:                    if (level2it.hasNext()) {
1242:                        level2Horizon = (OperatingMode) level2it.next();
1243:                    }
1244:                    Collection level6OMs = getBlackboardService().query(
1245:                            new OperatingModePredicate(supplyType,
1246:                                    LEVEL_6_TIME_HORIZON));
1247:                    //there should only be one.
1248:                    Iterator level6it = level6OMs.iterator();
1249:                    if (level6it.hasNext()) {
1250:                        level6Horizon = (OperatingMode) level6it.next();
1251:                    }
1252:                    prevLevel6 = getEndOfLevelSix();
1253:                    if (level2Horizon == null || level6Horizon == null) {
1254:                        if (logger.isErrorEnabled()) {
1255:                            logger
1256:                                    .error("InventoryPlugin in agent: "
1257:                                            + getAgentIdentifier()
1258:                                            + " of supply type: "
1259:                                            + supplyType
1260:                                            + " is missing operating modes upon rehydration... level2 OM is: "
1261:                                            + level2Horizon
1262:                                            + " level 6 OM is: "
1263:                                            + level6Horizon);
1264:                        }
1265:                    }
1266:                }
1267:
1268:                //    Level6OMSubscription = (IncrementalSubscription) blackboard.subscribe(new InventoryPredicateHelper.OperatingModePredicate(supplyType, LEVEL_6_TIME_HORIZON));
1269:                Level6OMSubscription = (IncrementalSubscription) blackboard
1270:                        .subscribe(new OperatingModePredicate(supplyType,
1271:                                LEVEL_6_TIME_HORIZON));
1272:                detReqSubscription = (IncrementalSubscription) blackboard
1273:                        .subscribe(new DetInvReqPredicate(taskUtils));
1274:                aggMILSubscription = (IncrementalSubscription) blackboard
1275:                        .subscribe(new AggMILPredicate());
1276:                milSubscription = (IncrementalSubscription) blackboard
1277:                        .subscribe(new MILPredicate());
1278:                detReqHandler.addMILTasks(milSubscription.elements());
1279:                selfOrganizations = (IncrementalSubscription) blackboard
1280:                        .subscribe(orgsPredicate);
1281:                inventoryPolicySubscription = (IncrementalSubscription) blackboard
1282:                        .subscribe(new InventoryPolicyPredicate(supplyType));
1283:                oplanSubscription = (IncrementalSubscription) blackboard
1284:                        .subscribe(new OplanPredicate());
1285:                //logisticsOPlanSubscription = (IncrementalSubscription) blackboard.subscribe(new LogisticsOPlanPredicate());
1286:                withdrawTaskSubscription = (IncrementalSubscription) blackboard
1287:                        .subscribe(new WithdrawPredicate(supplyType));
1288:                projectWithdrawTaskSubscription = (IncrementalSubscription) blackboard
1289:                        .subscribe(new ProjectWithdrawPredicate(supplyType));
1290:                MIExpansionSubscription = (IncrementalSubscription) blackboard
1291:                        .subscribe(new MIExpansionPredicate(supplyType,
1292:                                taskUtils));
1293:                MITopExpansionSubscription = (IncrementalSubscription) blackboard
1294:                        .subscribe(new MITopExpansionPredicate());
1295:                DetReqInvExpansionSubscription = (IncrementalSubscription) blackboard
1296:                        .subscribe(new DetReqInvExpansionPredicate(taskUtils));
1297:                commStatusSub = (IncrementalSubscription) blackboard
1298:                        .subscribe(new CommStatusPredicate());
1299:                dispositions = (IncrementalSubscription) blackboard
1300:                        .subscribe(new DispositionsPredicate(supplyType,
1301:                                taskUtils));
1302:
1303:                if (getAgentIdentifier() == null && logger.isErrorEnabled()) {
1304:                    logger
1305:                            .error("No agentIdentifier ... subscriptions need this info!!  In plugin: "
1306:                                    + this );
1307:                }
1308:                refillAllocationSubscription = (IncrementalSubscription) blackboard
1309:                        .subscribe(new RefillAllocPredicate(supplyType,
1310:                                getAgentIdentifier().toString(), taskUtils));
1311:                expansionSubscription = (IncrementalSubscription) blackboard
1312:                        .subscribe(new ExpansionPredicate(supplyType,
1313:                                getAgentIdentifier().toString(), taskUtils));
1314:                refillSubscription = (IncrementalSubscription) blackboard
1315:                        .subscribe(new RefillPredicate(supplyType,
1316:                                getAgentIdentifier().toString(), taskUtils));
1317:                nonrefillSubscription = (IncrementalSubscription) blackboard
1318:                        .subscribe(new NonRefillPredicate(supplyType,
1319:                                getAgentIdentifier().toString(), taskUtils));
1320:
1321:                shortfallSummary = (IncrementalSubscription) blackboard
1322:                        .subscribe(new ShortfallSumPredicate(getSupplyType()));
1323:
1324:                //LogOPlan replacment
1325:                orgActSubscription = (IncrementalSubscription) blackboard
1326:                        .subscribe(new OrgActivitiesPredicate());
1327:
1328:                // Setup TaskSchedulers
1329:                setupTaskSchedulers();
1330:            }
1331:
1332:            protected void setupTaskSchedulers() {
1333:                String taskScheduler = (String) pluginParams
1334:                        .get(TASK_SCHEDULER_ON);
1335:                turnOnTaskSched = new Boolean(taskScheduler).booleanValue();
1336:                QuiescenceReportService qrs = (QuiescenceReportService) getServiceBroker()
1337:                        .getService(this , QuiescenceReportService.class, null);
1338:                AgentIdentificationService ais = (AgentIdentificationService) getServiceBroker()
1339:                        .getService(this , AgentIdentificationService.class,
1340:                                null);
1341:                qrs.setAgentIdentificationService(ais);
1342:                QuiescenceAccumulator q = new QuiescenceAccumulator(qrs);
1343:                String id = getAgentIdentifier().toString();
1344:                if (turnOnTaskSched) {
1345:                    if (logger.isInfoEnabled())
1346:                        logger.info("Inv Plugin TASK SCHEDULER ON for " + id
1347:                                + getSupplyType());
1348:                    java.io.InputStream is = null;
1349:                    try {
1350:                        is = getConfigFinder().open("supplyTaskPolicy.xml");
1351:                    } catch (Exception e) {
1352:                        logger
1353:                                .error("Could not find file supplyTaskPolicy.xml");
1354:                    }
1355:                    supplyTaskScheduler = new TaskScheduler(
1356:                            new SupplyTaskPredicate(supplyType, id, taskUtils),
1357:                            TaskSchedulingPolicy.fromXML(is, this ,
1358:                                    getAlarmService()), blackboard, q, logger,
1359:                            "supplyTasks for " + getBlackboardClientName());
1360:                    try {
1361:                        is = getConfigFinder().open("projectionTaskPolicy.xml");
1362:                    } catch (Exception e) {
1363:                        logger
1364:                                .error("Could not find file projectionTaskPolicy.xml");
1365:                    }
1366:                    projectionTaskScheduler = new TaskScheduler(
1367:                            new ProjectionTaskPredicate(supplyType, id,
1368:                                    taskUtils), TaskSchedulingPolicy.fromXML(
1369:                                    is, this , getAlarmService()), blackboard,
1370:                            q, logger, "projTasks for "
1371:                                    + getBlackboardClientName());
1372:                } else { // TaskScheduler OFF
1373:                    if (logger.isInfoEnabled())
1374:                        logger.info("Inv Plugin TASK SCHEDULER OFF for " + id
1375:                                + getSupplyType());
1376:                    supplyTaskScheduler = new TaskScheduler(
1377:                            new SupplyTaskPredicate(supplyType, id, taskUtils),
1378:                            new TaskSchedulingPolicy(
1379:                                    new TaskSchedulingPolicy.Predicate[] { TaskSchedulingPolicy.PASSALL }),
1380:                            blackboard, q, logger, "supplyTasks for "
1381:                                    + getBlackboardClientName());
1382:
1383:                    projectionTaskScheduler = new TaskScheduler(
1384:                            new ProjectionTaskPredicate(supplyType, id,
1385:                                    taskUtils),
1386:                            new TaskSchedulingPolicy(
1387:                                    new TaskSchedulingPolicy.Predicate[] { TaskSchedulingPolicy.PASSALL }),
1388:                            blackboard, q, logger, "projTasks for "
1389:                                    + getBlackboardClientName());
1390:                }
1391:                //    supplyTaskSubscription = (IncrementalSubscription) blackboard.
1392:                //        subscribe(new SupplyTaskPredicate(supplyType, id, taskUtils));
1393:                //    projectionTaskSubscription = (IncrementalSubscription) blackboard.
1394:                //        subscribe(new ProjectionTaskPredicate(supplyType, id, taskUtils));
1395:            }
1396:
1397:            protected static class OrgActivitiesPredicate implements 
1398:                    UnaryPredicate {
1399:                public OrgActivitiesPredicate() {
1400:                }
1401:
1402:                public boolean execute(Object o) {
1403:                    if (o instanceof  OrgActivity) {
1404:                        return true;
1405:                    }
1406:                    return false;
1407:                }
1408:            }
1409:
1410:            protected static UnaryPredicate orgsPredicate = new UnaryPredicate() {
1411:                public boolean execute(Object o) {
1412:                    if (o instanceof  Organization) {
1413:                        return ((Organization) o).isSelf();
1414:                    }
1415:                    return false;
1416:                }
1417:            };
1418:
1419:            protected static class ShortfallSumPredicate implements 
1420:                    UnaryPredicate {
1421:
1422:                String supplyType;
1423:
1424:                public ShortfallSumPredicate(String aSupplyType) {
1425:                    supplyType = aSupplyType;
1426:                }
1427:
1428:                public boolean execute(Object o) {
1429:                    if (o instanceof  ShortfallSummary) {
1430:                        return (((ShortfallSummary) o).getSupplyType()
1431:                                .equals(supplyType));
1432:                    }
1433:                    return false;
1434:                }
1435:            };
1436:
1437:            protected static class SupplyTaskPredicate implements 
1438:                    TaskSchedulingPolicy.Predicate {
1439:                String supplyType;
1440:                String orgName;
1441:                TaskUtils taskUtils;
1442:
1443:                public SupplyTaskPredicate(String type, String myOrg,
1444:                        TaskUtils aTaskUtils) {
1445:                    supplyType = type;
1446:                    orgName = myOrg;
1447:                    taskUtils = aTaskUtils;
1448:                }
1449:
1450:                public boolean execute(Task task) {
1451:                    return task.getVerb().equals(Constants.Verb.SUPPLY)
1452:                            && taskUtils.isDirectObjectOfType(task, supplyType)
1453:                            && (!taskUtils.isMyRefillTask(task, orgName))
1454:                            && (taskUtils.getQuantity(task) > 0);
1455:                }
1456:            }
1457:
1458:            protected static class ProjectionTaskPredicate implements 
1459:                    TaskSchedulingPolicy.Predicate {
1460:                String supplyType;
1461:                String orgName;
1462:                TaskUtils taskUtils;
1463:
1464:                public ProjectionTaskPredicate(String type, String orgname,
1465:                        TaskUtils aTaskUtils) {
1466:                    supplyType = type;
1467:                    orgName = orgname;
1468:                    taskUtils = aTaskUtils;
1469:                }
1470:
1471:                public boolean execute(Task task) {
1472:                    return task.getVerb().equals(Constants.Verb.PROJECTSUPPLY)
1473:                            && taskUtils.isDirectObjectOfType(task, supplyType)
1474:                            && (!taskUtils.isMyInventoryProjection(task,
1475:                                    orgName));
1476:                }
1477:            }
1478:
1479:            /**
1480:             Passes DetermineRequirements tasks of type MaintainInventory.
1481:             **/
1482:            protected static class DetInvReqPredicate implements  UnaryPredicate {
1483:
1484:                protected TaskUtils taskUtils;
1485:
1486:                public DetInvReqPredicate(TaskUtils aTaskUtils) {
1487:                    taskUtils = aTaskUtils;
1488:                }
1489:
1490:                public boolean execute(Object o) {
1491:                    if (o instanceof  Task) {
1492:                        Task t = (Task) o;
1493:                        if (t.getVerb().equals(
1494:                                Constants.Verb.DETERMINEREQUIREMENTS)) {
1495:                            return taskUtils.isTaskOfType(t,
1496:                                    "MaintainInventory");
1497:                        }
1498:                    }
1499:                    return false;
1500:                }
1501:            }
1502:
1503:            /** Grab the Expansion of DetReq MaintainInventory and update ARs **/
1504:            protected static class DetReqInvExpansionPredicate implements 
1505:                    UnaryPredicate {
1506:                private TaskUtils taskUtils;
1507:
1508:                public DetReqInvExpansionPredicate(TaskUtils aTaskUtils) {
1509:                    taskUtils = aTaskUtils;
1510:                }
1511:
1512:                public boolean execute(Object o) {
1513:                    if (o instanceof  Expansion) {
1514:                        Task parent = ((Expansion) o).getTask();
1515:                        if (parent.getVerb().equals(
1516:                                Constants.Verb.DETERMINEREQUIREMENTS)) {
1517:                            return taskUtils.isTaskOfType(parent,
1518:                                    "MaintainInventory");
1519:                        }
1520:                    }
1521:                    return false;
1522:                }
1523:            }
1524:
1525:            /**
1526:             Selects the per-inventory MaintainInventory tasks.
1527:             **/
1528:            protected static class MILPredicate implements  UnaryPredicate {
1529:                public boolean execute(Object o) {
1530:                    if (o instanceof  Task) {
1531:                        Task t = (Task) o;
1532:                        if (t.getVerb()
1533:                                .equals(Constants.Verb.MAINTAININVENTORY)) {
1534:                            return t.getDirectObject() != null; // true if this is the agg task
1535:                        }
1536:                    }
1537:                    return false;
1538:                }
1539:            }
1540:
1541:            /** get the Expansion for the TOP MI task
1542:             * note that this means each instance for each class of supply will
1543:             * be looking for the same task - but since the results are checked and only
1544:             * changed if there's a difference it shouldn't be too bad.
1545:             **/
1546:            protected static class MITopExpansionPredicate implements 
1547:                    UnaryPredicate {
1548:                public boolean execute(Object o) {
1549:                    if (o instanceof  Expansion) {
1550:                        Task parent = ((Expansion) o).getTask();
1551:                        if (parent.getVerb().equals(
1552:                                Constants.Verb.MAINTAININVENTORY)) {
1553:                            if (parent.getDirectObject() == null) {
1554:                                return true;
1555:                            }
1556:                        }
1557:                    }
1558:                    return false;
1559:                }
1560:            }
1561:
1562:            /**
1563:             Selects the aggregate MaintainInventory task
1564:             **/
1565:            protected static class AggMILPredicate implements  UnaryPredicate {
1566:                public boolean execute(Object o) {
1567:                    if (o instanceof  Task) {
1568:                        Task t = (Task) o;
1569:                        if (t.getVerb()
1570:                                .equals(Constants.Verb.MAINTAININVENTORY)) {
1571:                            return t.getDirectObject() == null; // true if this is not the agg task
1572:                        }
1573:                    }
1574:                    return false;
1575:                }
1576:            }
1577:
1578:            /** Selects the MaintainInventory Expansions we create **/
1579:            protected static class MIExpansionPredicate implements 
1580:                    UnaryPredicate {
1581:                String supplyType;
1582:                TaskUtils taskUtils;
1583:
1584:                public MIExpansionPredicate(String type, TaskUtils utils) {
1585:                    supplyType = type;
1586:                    taskUtils = utils;
1587:                }
1588:
1589:                public boolean execute(Object o) {
1590:                    if (o instanceof  Expansion) {
1591:                        Task parent = ((Expansion) o).getTask();
1592:                        if (parent.getVerb().equals(
1593:                                Constants.Verb.MAINTAININVENTORY)) {
1594:                            Asset directObject = parent.getDirectObject();
1595:                            if (directObject != null
1596:                                    && directObject instanceof  Inventory) {
1597:                                LogisticsInventoryPG thePG = (LogisticsInventoryPG) ((Inventory) directObject)
1598:                                        .searchForPropertyGroup(LogisticsInventoryPG.class);
1599:                                Asset resource = thePG.getResource();
1600:                                SupplyClassPG pg = (SupplyClassPG) resource
1601:                                        .searchForPropertyGroup(SupplyClassPG.class);
1602:                                if (pg != null) {
1603:                                    if (supplyType.equals(pg.getSupplyType())) {
1604:                                        //            if (taskUtils.isDirectObjectOfType(parent, supplyType)) {
1605:                                        return true;
1606:                                    }
1607:                                }
1608:                            }
1609:                        }
1610:                    }
1611:                    return false;
1612:                }
1613:            }
1614:
1615:            /**
1616:             Selects the Oplan objects
1617:             **/
1618:            protected static class OplanPredicate implements  UnaryPredicate {
1619:                public boolean execute(Object o) {
1620:                    return o instanceof  Oplan;
1621:                }
1622:            }
1623:
1624:            /**
1625:             Passes Inventory assets that have a valid LogisticsInventoryPG
1626:             **/
1627:
1628:            protected static class InventoryPredicate implements  UnaryPredicate {
1629:                String supplyType;
1630:
1631:                public InventoryPredicate(String type) {
1632:                    supplyType = type;
1633:                }
1634:
1635:                public boolean execute(Object o) {
1636:                    if (o instanceof  Inventory) {
1637:                        Inventory inv = (Inventory) o;
1638:                        LogisticsInventoryPG logInvpg = (LogisticsInventoryPG) inv
1639:                                .searchForPropertyGroup(LogisticsInventoryPG.class);
1640:                        if (logInvpg != null) {
1641:                            String type = getAssetType(logInvpg);
1642:                            if (supplyType.equals(type)) {
1643:                                return true;
1644:                            }
1645:                        }
1646:                    }
1647:                    return false;
1648:                }
1649:
1650:                protected String getAssetType(LogisticsInventoryPG invpg) {
1651:                    Asset a = invpg.getResource();
1652:                    if (a == null)
1653:                        return null;
1654:                    SupplyClassPG pg = (SupplyClassPG) a
1655:                            .searchForPropertyGroup(SupplyClassPG.class);
1656:                    return pg.getSupplyType();
1657:                }
1658:            }
1659:
1660:            //Allocation of refill tasks
1661:            protected static class RefillAllocPredicate implements 
1662:                    UnaryPredicate {
1663:                String type_;
1664:                String orgName_;
1665:                TaskUtils taskUtils;
1666:
1667:                public RefillAllocPredicate(String type, String orgName,
1668:                        TaskUtils aTaskUtils) {
1669:                    type_ = type;
1670:                    orgName_ = orgName;
1671:                    taskUtils = aTaskUtils;
1672:                }
1673:
1674:                public boolean execute(Object o) {
1675:                    if (o instanceof  Allocation) {
1676:                        Task task = ((Allocation) o).getTask();
1677:                        if (task.getVerb().equals(Constants.Verb.SUPPLY)
1678:                                || task.getVerb().equals(
1679:                                        Constants.Verb.PROJECTSUPPLY)) {
1680:                            if (taskUtils.isDirectObjectOfType(task, type_)) {
1681:                                // need to check if externally allocated
1682:                                if (((Allocation) o).getAsset() instanceof  Organization) {
1683:                                    //if (taskUtils.isMyRefillTask(task, orgName_)){
1684:                                    return true;
1685:                                    //}
1686:                                }
1687:                            }
1688:                        }
1689:                    }
1690:                    return false;
1691:                }
1692:            }
1693:
1694:            static class CommStatusPredicate implements  UnaryPredicate {
1695:                public boolean execute(Object o) {
1696:                    return o instanceof  CommStatus;
1697:                }
1698:            }
1699:
1700:            static class DispositionsPredicate implements  UnaryPredicate {
1701:                String type_;
1702:                TaskUtils taskUtils;
1703:
1704:                public DispositionsPredicate(String type, TaskUtils aTaskUtils) {
1705:                    type_ = type;
1706:                    taskUtils = aTaskUtils;
1707:                }
1708:
1709:                public boolean execute(Object o) {
1710:                    if (o instanceof  Disposition) {
1711:                        Task task = ((Disposition) o).getTask();
1712:                        if (task.getVerb().equals(Constants.Verb.SUPPLY)
1713:                                && taskUtils.isDirectObjectOfType(task, type_)) {
1714:                            return true;
1715:                        }
1716:                    }
1717:                    return false;
1718:                }
1719:            }
1720:
1721:            //Refill tasks
1722:            protected static class RefillPredicate implements  UnaryPredicate {
1723:                String type_;
1724:                String orgName_;
1725:                TaskUtils taskUtils;
1726:
1727:                public RefillPredicate(String type, String orgName,
1728:                        TaskUtils aTaskUtils) {
1729:                    type_ = type;
1730:                    orgName_ = orgName;
1731:                    taskUtils = aTaskUtils;
1732:                }
1733:
1734:                public boolean execute(Object o) {
1735:                    if (o instanceof  Task) {
1736:                        Task task = (Task) o;
1737:                        if (task.getVerb().equals(Constants.Verb.SUPPLY)
1738:                                || task.getVerb().equals(
1739:                                        Constants.Verb.PROJECTSUPPLY)) {
1740:                            if (taskUtils.isDirectObjectOfType(task, type_)) {
1741:                                if (taskUtils.isMyRefillTask(task, orgName_)) {
1742:                                    return true;
1743:                                }
1744:                            }
1745:                        }
1746:                    }
1747:                    return false;
1748:                }
1749:            }
1750:
1751:            //Non-Refill tasks
1752:            static class NonRefillPredicate implements  UnaryPredicate {
1753:                String type_;
1754:                String orgName_;
1755:                TaskUtils taskUtils;
1756:
1757:                public NonRefillPredicate(String type, String orgName,
1758:                        TaskUtils aTaskUtils) {
1759:                    type_ = type;
1760:                    orgName_ = orgName;
1761:                    taskUtils = aTaskUtils;
1762:                }
1763:
1764:                public boolean execute(Object o) {
1765:                    if (o instanceof  Task) {
1766:                        Task task = (Task) o;
1767:                        if (task.getVerb().equals(Constants.Verb.SUPPLY)
1768:                                || task.getVerb().equals(
1769:                                        Constants.Verb.PROJECTSUPPLY)) {
1770:                            if (taskUtils.isDirectObjectOfType(task, type_)) {
1771:                                if (taskUtils.isMyNonRefillTask(task, orgName_)) {
1772:                                    return true;
1773:                                }
1774:                            }
1775:                        }
1776:                    }
1777:                    return false;
1778:                }
1779:            }
1780:
1781:            protected class ExpansionPredicate implements  UnaryPredicate {
1782:                String supplyType;
1783:                String orgName;
1784:                TaskUtils taskUtils;
1785:
1786:                public ExpansionPredicate(String type, String orgname,
1787:                        TaskUtils taskUtils) {
1788:                    supplyType = type;
1789:                    orgName = orgname;
1790:                    this .taskUtils = taskUtils;
1791:                }
1792:
1793:                public boolean execute(Object o) {
1794:                    if (o instanceof  Expansion) {
1795:                        Task task = ((Expansion) o).getTask();
1796:                        if (task.getVerb().equals(Constants.Verb.SUPPLY)
1797:                                || task.getVerb().equals(
1798:                                        Constants.Verb.PROJECTSUPPLY)) {
1799:                            if (taskUtils
1800:                                    .isDirectObjectOfType(task, supplyType)) {
1801:                                if (!taskUtils.isMyRefillTask(task, orgName)) {
1802:                                    return true;
1803:                                }
1804:                            }
1805:                        }
1806:                    }
1807:                    return false;
1808:                }
1809:            }
1810:
1811:            protected class InventoryPolicyPredicate implements  UnaryPredicate {
1812:                String type;
1813:
1814:                public InventoryPolicyPredicate(String type) {
1815:                    this .type = type;
1816:                }
1817:
1818:                public boolean execute(Object o) {
1819:                    if (o instanceof  org.cougaar.logistics.plugin.inventory.InventoryPolicy) {
1820:                        String type = ((InventoryPolicy) o).getResourceType();
1821:                        if (type.equals(this .type)) {
1822:                            if (logger.isInfoEnabled()) {
1823:                                logger.info("Found an inventory policy for "
1824:                                        + this .type + "agent is: "
1825:                                        + getMyOrganization());
1826:                            }
1827:                            return true;
1828:                        } else {
1829:                            if (logger.isDebugEnabled()) {
1830:                                logger.debug("Ignoring type of: " + type
1831:                                        + " in " + getMyOrganization()
1832:                                        + " this type is: " + this .type);
1833:                            }
1834:                        }
1835:                    }
1836:                    return false;
1837:                }
1838:            }
1839:
1840:            /**
1841:             * Filters out tasks that already have PEs -- fix for bug #1695
1842:             * @param tasks - possibly from added list
1843:             * @return Collection - tasks that have no PEs
1844:             */
1845:            protected Collection getTasksWithoutPEs(Collection tasks) {
1846:                Set tasksWithoutPEs = new HashSet();
1847:                for (Iterator iter = tasks.iterator(); iter.hasNext();) {
1848:                    Task task = (Task) iter.next();
1849:
1850:                    if (task.getPlanElement() != null) {
1851:                        if (logger.isDebugEnabled()) {
1852:                            logger
1853:                                    .debug(getMyOrganization()
1854:                                            + " - found task that already had a p.e. attached? : "
1855:                                            + task.getUID()
1856:                                            + " - so skipping it.");
1857:                        }
1858:                    } else {
1859:                        tasksWithoutPEs.add(task);
1860:                    }
1861:                }
1862:
1863:                return tasksWithoutPEs;
1864:            }
1865:
1866:            protected class WithdrawPredicate implements  UnaryPredicate {
1867:                String supplyType;
1868:
1869:                public WithdrawPredicate(String type) {
1870:                    supplyType = type;
1871:                }
1872:
1873:                public boolean execute(Object o) {
1874:                    if (o instanceof  Task) {
1875:                        Task task = (Task) o;
1876:                        if (task.getVerb().equals(Constants.Verb.WITHDRAW)) {
1877:                            if (taskUtils
1878:                                    .isDirectObjectOfType(task, supplyType)) {
1879:                                return true;
1880:                            }
1881:                        }
1882:                    }
1883:                    return false;
1884:                }
1885:            }
1886:
1887:            protected class ProjectWithdrawPredicate implements  UnaryPredicate {
1888:                String supplyType;
1889:
1890:                public ProjectWithdrawPredicate(String type) {
1891:                    supplyType = type;
1892:                }
1893:
1894:                public boolean execute(Object o) {
1895:                    if (o instanceof  Task) {
1896:                        Task task = (Task) o;
1897:                        if (task.getVerb().equals(
1898:                                Constants.Verb.PROJECTWITHDRAW)) {
1899:                            if (taskUtils
1900:                                    .isDirectObjectOfType(task, supplyType)) {
1901:                                return true;
1902:                            }
1903:                        }
1904:                    }
1905:                    return false;
1906:                }
1907:            }
1908:
1909:            protected class OperatingModePredicate implements  UnaryPredicate {
1910:                String supplyType;
1911:                String level;
1912:
1913:                public OperatingModePredicate(String type, String level) {
1914:                    supplyType = type;
1915:                    this .level = level;
1916:                }
1917:
1918:                public boolean execute(Object o) {
1919:                    if (o instanceof  OperatingMode) {
1920:                        OperatingMode om = (OperatingMode) o;
1921:                        if (om.getName().equals(level + "_" + supplyType)) {
1922:                            return true;
1923:                        }
1924:                    }
1925:                    return false;
1926:                }
1927:            }
1928:
1929:            protected void expandIncomingRequisitions(Collection tasks) {
1930:                supplyExpander.expandAndDistributeRequisitions(tasks);
1931:            }
1932:
1933:            protected boolean expandIncomingProjections(Collection tasks) {
1934:                return supplyExpander.expandAndDistributeProjections(tasks);
1935:            }
1936:
1937:            /**
1938:             Add some inventories to the inventoryHash.
1939:             Method called during rehydration to populate inventory hash
1940:             **/
1941:            protected void addRehydratedInventories(Collection inventories) {
1942:                for (Iterator i = inventories.iterator(); i.hasNext();) {
1943:                    Inventory inv = (Inventory) i.next();
1944:                    LogisticsInventoryPG logInvPG = (LogisticsInventoryPG) inv
1945:                            .searchForPropertyGroup(LogisticsInventoryPG.class);
1946:                    logInvPG.setStartCDay(logOPlan.getOplanCday());
1947:                    logInvPG.reinitialize(logToCSV, this );
1948:                    addInventory(inv);
1949:                }
1950:            }
1951:
1952:            //AHF
1953:            protected void resetLogOPlanForInventories() {
1954:                Iterator inventories = getInventories().iterator();
1955:                while (inventories.hasNext()) {
1956:                    Inventory inv = (Inventory) inventories.next();
1957:                    LogisticsInventoryPG logInvPG = (LogisticsInventoryPG) inv
1958:                            .searchForPropertyGroup(LogisticsInventoryPG.class);
1959:                    if (logInvPG.getArrivalTime() != getOPlanArrivalInTheaterTime()) {
1960:                        if (logInvPG.getSupplierArrivalTime() != -1) {
1961:                            long newSupplierArrivalTime = logInvPG
1962:                                    .getSupplierArrivalTime()
1963:                                    + (getOPlanArrivalInTheaterTime() - logInvPG
1964:                                            .getArrivalTime());
1965:                            ((NewLogisticsInventoryPG) logInvPG)
1966:                                    .setSupplierArrivalTime(newSupplierArrivalTime);
1967:                        }
1968:                        logInvPG.setArrivalTime(getOPlanArrivalInTheaterTime());
1969:                        logInvPG.setStartCDay(logOPlan.getOplanCday());
1970:                        publishChange(inv);
1971:                        touchInventory(inv);
1972:                        touchedChangedProjections = true;
1973:                    }
1974:                }
1975:            }
1976:
1977:            protected void addInventory(Inventory inventory) {
1978:                String item = getInventoryType(inventory);
1979:                inventoryHash.put(item, inventory);
1980:            }
1981:
1982:            protected void removeInventories(Enumeration inventories) {
1983:                while (inventories.hasMoreElements()) {
1984:                    removeInventory((Inventory) inventories.nextElement());
1985:                }
1986:            }
1987:
1988:            protected void removeInventory(Inventory inventory) {
1989:                String item = getInventoryType(inventory);
1990:                inventoryHash.remove(item);
1991:            }
1992:
1993:            public String getInventoryType(Inventory inventory) {
1994:                ScheduledContentPG scp = inventory.getScheduledContentPG();
1995:                Asset proto = scp.getAsset();
1996:                if (proto == null) {
1997:                    if (logger.isErrorEnabled()) {
1998:                        logger
1999:                                .error("getInventoryType failed to get asset for "
2000:                                        + inventory.getScheduledContentPG()
2001:                                                .getAsset()
2002:                                                .getTypeIdentificationPG());
2003:                    }
2004:                    return "";
2005:                }
2006:                return proto.getTypeIdentificationPG().getTypeIdentification();
2007:            }
2008:
2009:            public void touchInventoryForTask(Task taskWithInventory,
2010:                    Inventory inventory) {
2011:                touchInventory(inventory);
2012:            }
2013:
2014:            public Inventory findOrMakeInventory(Task task) {
2015:                throw new IllegalArgumentException(
2016:                        "this method should not be called in AL.");
2017:                //return null;
2018:            }
2019:
2020:            public Inventory findOrMakeInventory(Asset resource) {
2021:                Inventory inventory = null;
2022:                String item = resource.getTypeIdentificationPG()
2023:                        .getTypeIdentification();
2024:                inventory = (Inventory) inventoryHash.get(item);
2025:                if (inventory != null) {
2026:                    if (logger.isDebugEnabled()) {
2027:                        logger
2028:                                .debug("findOrMakeInventory(), FOUND inventory bing for: "
2029:                                        + AssetUtils.assetDesc(inventory
2030:                                                .getScheduledContentPG()
2031:                                                .getAsset()));
2032:                    }
2033:                    return inventory;
2034:                } else {
2035:                    inventory = createInventory(resource, item);
2036:                    addInventory(inventory);
2037:                    publishAdd(inventory);
2038:                    detReqHandler.findOrMakeMILTask(inventory,
2039:                            aggMILSubscription);
2040:                }
2041:                if (logger.isDebugEnabled()) {
2042:                    logger
2043:                            .debug("findOrMakeInventory(), CREATED inventory bin for: "
2044:                                    + AssetUtils
2045:                                            .assetDesc(inventory
2046:                                                    .getScheduledContentPG()
2047:                                                    .getAsset()));
2048:                }
2049:                return inventory;
2050:            }
2051:
2052:            protected Inventory createInventory(Asset resource, String item) {
2053:                //    double levels[] = null;
2054:                Inventory inventory = null;
2055:                //     levels = (double[]) inventoryInitHash.get(item);
2056:                //     if (levels == null) {
2057:                //	levels = new double[2];
2058:                double capacity = getFuelCapacity(item);
2059:                double initialLevel = getInitialLevel(item);
2060:                //     }
2061:                inventory = (Inventory) getPlanningFactory().createAsset(
2062:                        "Inventory");
2063:                NewLogisticsInventoryPG logInvPG = (NewLogisticsInventoryPG) PropertyGroupFactory
2064:                        .newLogisticsInventoryPG();
2065:                inventory.addOtherPropertyGroup(logInvPG);
2066:                if (getAssetUtils().isLevel2Asset(resource)) {
2067:                    logInvPG.setIsLevel2(true); // will need to key off asset to identify level2 item
2068:                    // Need to distinguish Level2Package aggregates of different supply types otherwise
2069:                    // they are determined to be the same asset and are removed from the blackboard
2070:                    ((NewItemIdentificationPG) inventory
2071:                            .getItemIdentificationPG())
2072:                            .setItemIdentification("Inventory:" + item + ":"
2073:                                    + supplyType);
2074:                } else {
2075:                    logInvPG.setIsLevel2(false);
2076:                    ((NewItemIdentificationPG) inventory
2077:                            .getItemIdentificationPG())
2078:                            .setItemIdentification("Inventory:" + item);
2079:                }
2080:                logInvPG.setCapacity(capacity);
2081:                logInvPG.setFillToCapacity(fillToCapacity);
2082:                logInvPG.setInitialLevel(initialLevel);
2083:                logInvPG.setResource(resource);
2084:                logInvPG.setOrg(getMyOrganization());
2085:                logInvPG.setSupplierArrivalTime(getSupplierArrivalTime());
2086:                logInvPG.setLogInvBG(new LogisticsInventoryBG(logInvPG));
2087:                logInvPG.initialize(startTime, this .getOPlanEndTime(),
2088:                        criticalLevel, reorderPeriod, getOrderShipTime(),
2089:                        bucketSize, getCurrentTimeMillis(), logToCSV, this );
2090:                logInvPG.setArrivalTime(getOPlanArrivalInTheaterTime());
2091:                logInvPG.setStartCDay(logOPlan.getOplanCday());
2092:
2093:                NewTypeIdentificationPG ti = (NewTypeIdentificationPG) inventory
2094:                        .getTypeIdentificationPG();
2095:                ti.setTypeIdentification("InventoryAsset");
2096:                ti.setNomenclature("Inventory Asset");
2097:
2098:                NewScheduledContentPG scp;
2099:                scp = (NewScheduledContentPG) inventory.getScheduledContentPG();
2100:                scp.setAsset(resource);
2101:                scp.setSchedule(scheduleUtils.buildSimpleQuantitySchedule(
2102:                        initialLevel, startTime, startTime
2103:                                + (TimeUtils.MSEC_PER_DAY * 10)));
2104:
2105:                return inventory;
2106:            }
2107:
2108:            // Override these in a subclass if necessary
2109:            protected double getFuelCapacity(String item) {
2110:                return 0.0;
2111:            }
2112:
2113:            protected double getInitialLevel(String item) {
2114:                return 0.0;
2115:            }
2116:
2117:            public void touchInventory(Inventory inventory) {
2118:                if (!touchedInventories.contains(inventory)) {
2119:                    touchedInventories.add(inventory);
2120:                }
2121:            }
2122:
2123:            public Collection getTouchedInventories() {
2124:                return touchedInventories;
2125:            }
2126:
2127:            public Collection getInventories() {
2128:                return inventoryHash.values();
2129:            }
2130:
2131:            public void touchInventoryWithDeletions(Inventory inventory) {
2132:                if (!inventoriesWithDeletions.contains(inventory)) {
2133:                    inventoriesWithDeletions.add(inventory);
2134:                }
2135:            }
2136:
2137:            public Collection getInventoriesWithDeletions() {
2138:                return inventoriesWithDeletions;
2139:            }
2140:
2141:            public void takeInventorySnapshot(Collection inventories) {
2142:                Inventory inv;
2143:                Iterator inv_it = inventories.iterator();
2144:                LogisticsInventoryPG logInvPG = null;
2145:                while (inv_it.hasNext()) {
2146:                    inv = (Inventory) inv_it.next();
2147:                    logInvPG = (LogisticsInventoryPG) inv
2148:                            .searchForPropertyGroup(LogisticsInventoryPG.class);
2149:                    logInvPG.takeSnapshot(inv);
2150:                    if (logToCSV) {
2151:                        logInvPG.logAllToCSVFile(cycleStamp);
2152:                    }
2153:
2154:                    // Force incremental persistence snapshots to include changes to these
2155:                    publishChange(inv);
2156:                }
2157:                checkShortfallStatus(inventories);
2158:            }
2159:
2160:            public void checkShortfallStatus(Collection inventories) {
2161:                Inventory inv;
2162:                Iterator inv_it = inventories.iterator();
2163:                LogisticsInventoryPG logInvPG = null;
2164:                ArrayList shortfallInvs = new ArrayList();
2165:                ArrayList nonShortfallInvs = new ArrayList();
2166:                while (inv_it.hasNext()) {
2167:                    inv = (Inventory) inv_it.next();
2168:                    String invID = LogisticsInventoryServlet
2169:                            .getNomenclature(inv);
2170:
2171:                    ShortfallInventory shortfallInv = checkForShortfall(inv);
2172:                    if (shortfallInv != null) {
2173:                        shortfallInvs.add(shortfallInv);
2174:                    } else {
2175:                        nonShortfallInvs.add(invID);
2176:                    }
2177:                }
2178:                ShortfallSummary shortSum = null;
2179:                if (!shortfallSummary.isEmpty()) {
2180:                    shortSum = (ShortfallSummary) shortfallSummary.iterator()
2181:                            .next();
2182:                }
2183:                //If the shortfall summary doesn't exist yet and there are shortfall inventories
2184:                //Create and publish add the shortfall summary.
2185:                if (shortSum == null) {
2186:                    if (!shortfallInvs.isEmpty()) {
2187:                        shortSum = new ShortfallSummary(getSupplyType(),
2188:                                uidService.nextUID(), bucketSize);
2189:                        Iterator it = shortfallInvs.iterator();
2190:                        shortSum.setShortfallInventories(shortfallInvs);
2191:                        publishAdd(shortSum);
2192:                    }
2193:                    return;
2194:                }
2195:                boolean addedShort = shortSum
2196:                        .addShortfallInventories(shortfallInvs);
2197:                boolean removedShort = shortSum
2198:                        .removeShortfallInventories(nonShortfallInvs);
2199:
2200:                if (addedShort || removedShort) {
2201:                    if (!shortSum.getShortfallInventories().isEmpty()) {
2202:                        /***
2203:                        if(getOrgName().startsWith("47-FSB")) {
2204:                        logger.warn("47-FSB - num short:" + shortSum);
2205:                        }
2206:                         **/
2207:                        publishChange(shortSum);
2208:                    } else {
2209:                        publishRemove(shortSum);
2210:                        /***
2211:                        if(getOrgName().startsWith("47-FSB")) {
2212:                        logger.warn("47-FSB - Removing ShortfallSummary");
2213:                        }
2214:                         **/
2215:
2216:                    }
2217:                }
2218:
2219:            }
2220:
2221:            public ShortfallInventory checkForShortfall(Inventory inv) {
2222:                String invID = LogisticsInventoryServlet.getNomenclature(inv);
2223:                LogisticsInventoryPG logInvPG = (LogisticsInventoryPG) inv
2224:                        .searchForPropertyGroup(LogisticsInventoryPG.class);
2225:                String unitOfIssue = LogisticsInventoryFormatter
2226:                        .getUnitForAsset(inv);
2227:                return logInvPG.checkForShortfall(invID, unitOfIssue);
2228:            }
2229:
2230:            /**
2231:             Read the Plugin parameters(Accepts key/value pairs)
2232:             Initializes supplyType and inventoryFile
2233:             **/
2234:            protected HashMap readParameters() {
2235:                Collection p = getParameters();
2236:
2237:                if (p.isEmpty()) {
2238:                    if (logger.isErrorEnabled()) {
2239:                        logger
2240:                                .error("No parameters: InventoryPlugin requires 1 parameter, Supply Type.  Additional parameter for csv logging, default is disabled.   e.g. org.cougaar.logistics.plugin.inventory.InventoryPlugin("
2241:                                        + SUPPLY_TYPE
2242:                                        + "=BulkPOL, ENABLE_CSV_LOGGING=true)");
2243:                    }
2244:                    return null;
2245:                }
2246:                HashMap map = new HashMap();
2247:                int idx;
2248:
2249:                for (Iterator i = p.iterator(); i.hasNext();) {
2250:                    String s = (String) i.next();
2251:                    if ((idx = s.indexOf('=')) != -1) {
2252:                        String key = new String(s.substring(0, idx));
2253:                        String value = new String(s.substring(idx + 1, s
2254:                                .length()));
2255:                        map.put(key.trim(), value.trim());
2256:                    }
2257:                }
2258:                supplyType = (String) map.get(SUPPLY_TYPE);
2259:                //      inventoryFile = (String)map.get(INVENTORY_FILE);
2260:                if (supplyType == null && logger.isErrorEnabled()) {
2261:                    logger
2262:                            .error("No SUPPLY_TYPE parameter: InventoryPlugin requires 1 parameter, Supply Type.  Additional parameter for csv logging, default is disabled.   e.g. org.cougaar.logistics.plugin.inventory.InventoryPlugin("
2263:                                    + SUPPLY_TYPE
2264:                                    + "=BulkPOL, ENABLE_CSV_LOGGING=true)");
2265:                }
2266:                String loggingEnabled = (String) map.get(ENABLE_CSV_LOGGING);
2267:                if ((loggingEnabled != null)
2268:                        && (loggingEnabled.trim().equals("true"))) {
2269:                    logToCSV = true;
2270:                }
2271:
2272:                String prepoOffsetStr = (String) map.get(PREPO_ARRIVAL_OFFSET);
2273:                if ((prepoOffsetStr != null)
2274:                        && !(prepoOffsetStr.trim().equals(""))) {
2275:                    try {
2276:                        int prepoOffset = Integer.parseInt(prepoOffsetStr);
2277:                        prepoArrivalOffset = prepoOffset;
2278:                    } catch (NumberFormatException ex) {
2279:                        logger
2280:                                .error("InventoryPlugin("
2281:                                        + PREPO_ARRIVAL_OFFSET
2282:                                        + "="
2283:                                        + prepoOffsetStr
2284:                                        + ") value is not a parseable integer.  Defaulting to "
2285:                                        + prepoArrivalOffset);
2286:                    }
2287:
2288:                }
2289:                return map;
2290:            }
2291:
2292:            //   protected String getInventoryFile(String type) {
2293:            //     String result = null;
2294:            //     // if defined in plugin argument list
2295:            //     String inv_file = null;
2296:            //     if ((inv_file = (String) pluginParams.get(INVENTORY_FILE)) != null) {
2297:            //       result = inv_file;
2298:            //       //   }
2299:            //       //    else {
2300:            // //       result = getClusterSuffix(myOrganization.getClusterPG().getMessageAddress().toString()) +
2301:            // // 	"_"+type.toLowerCase()+".inv";
2302:            //     } else if (type.equals("Ammunition")) {
2303:            //       result = getAgentPrefix(getAgentIdentifier().toString()) +
2304:            //           "_" + type.toLowerCase() + ".inv";
2305:            //     } else {
2306:            //       result = getClusterSuffix(getAgentPrefix(getAgentIdentifier().toString())) +
2307:            //           "_" + type.toLowerCase() + ".inv";
2308:            //     }
2309:            //     return result;
2310:            //   }
2311:
2312:            protected String getAgentPrefix(String agentId) {
2313:                int i = agentId.indexOf(".");
2314:                if (i <= 0) {
2315:                    return agentId;
2316:                } else {
2317:                    return agentId.substring(0, i);
2318:                }
2319:            }
2320:
2321:            protected String getClusterSuffix(String clusterId) {
2322:                String result = null;
2323:                int i = clusterId.lastIndexOf("-");
2324:                if (i == -1) {
2325:                    result = clusterId;
2326:                } else {
2327:                    result = clusterId.substring(i + 1);
2328:                }
2329:                return result;
2330:            }
2331:
2332:            public void publishAddToExpansion(Task parent, Task subtask) {
2333:                //attach the subtask to its parent and the parent's workflow
2334:                PlanElement pe = parent.getPlanElement();
2335:                Expansion expansion;
2336:                NewWorkflow wf;
2337:                ((NewTask) subtask).setParentTask(parent);
2338:                ((NewTask) subtask).setContext(parent.getContext());
2339:                ((NewTask) subtask).setPlan(parent.getPlan());
2340:                // Task has not been expanded, create an expansion
2341:                if (pe instanceof  Disposition) {
2342:                    publishRemove(pe);
2343:                    pe = null;
2344:                }
2345:                if (pe == null) {
2346:                    PlanningFactory factory = getPlanningFactory();
2347:                    // Create workflow
2348:                    wf = (NewWorkflow) factory.newWorkflow();
2349:                    wf.setParentTask(parent);
2350:                    wf.setIsPropagatingToSubtasks(true);
2351:                    wf.addTask(subtask);
2352:                    ((NewTask) subtask).setWorkflow(wf);
2353:                    // Build Expansion
2354:                    expansion = factory.createExpansion(parent.getPlan(),
2355:                            parent, wf, null);
2356:                    // Publish Expansion
2357:                    publishAdd(expansion);
2358:                    if (logger.isDebugEnabled()) {
2359:                        logger.debug("Agent: "
2360:                                + getAgentIdentifier().toString()
2361:                                + "Inv Plugin[" + supplyType + "]"
2362:                                + "publish adding expansion: "
2363:                                + expansion.getUID() + " parent "
2364:                                + parent.getVerb() + " task is: "
2365:                                + parent.getUID());
2366:                    }
2367:                }
2368:                // Task already has expansion, add task to the workflow and publish the change
2369:                else if (pe instanceof  Expansion) {
2370:                    expansion = (Expansion) pe;
2371:                    wf = (NewWorkflow) expansion.getWorkflow();
2372:                    wf.addTask(subtask);
2373:                    ((NewTask) subtask).setWorkflow(wf);
2374:                    publishChange(expansion);
2375:                    if (logger.isDebugEnabled()) {
2376:                        logger.debug("Agent: "
2377:                                + getAgentIdentifier().toString()
2378:                                + "Inv Plugin[" + supplyType + "]"
2379:                                + "publish changing expansion: "
2380:                                + expansion.getUID() + " parent "
2381:                                + parent.getVerb() + " task is: "
2382:                                + parent.getUID());
2383:                    }
2384:                } else {
2385:                    if (logger.isErrorEnabled()) {
2386:                        logger
2387:                                .error("publishAddToExpansion: problem pe not Expansion? "
2388:                                        + pe);
2389:                    }
2390:                }
2391:
2392:                // Publish new task
2393:                publishAdd(subtask);
2394:                if (logger.isDebugEnabled()) {
2395:                    logger.debug("Agent: " + getAgentIdentifier().toString()
2396:                            + "Inv Plugin[" + supplyType + "]"
2397:                            + "publish adding a " + subtask.getVerb()
2398:                            + " subtask: " + subtask.getUID());
2399:                }
2400:
2401:                if (((subtask.getVerb().equals(Constants.Verb.SUPPLY)) || (subtask
2402:                        .getVerb().equals(Constants.Verb.PROJECTSUPPLY)))
2403:                        && (subtask.getPrepositionalPhrase("SplitTask") == null)) {
2404:                    newRefills.add(subtask);
2405:                }
2406:            }
2407:
2408:            // called by the RefillGenerator to hook up the refill task to the maintain
2409:            // inventory parent task and workflow.
2410:            public boolean publishRefillTask(Task task, Inventory inventory) {
2411:                Task milTask = detReqHandler.findOrMakeMILTask(inventory,
2412:                        aggMILSubscription);
2413:                if (milTask != null) {
2414:                    publishAddToExpansion(milTask, task);
2415:                    return true;
2416:                }
2417:                return false;
2418:            }
2419:
2420:            public void disposeOfUnusedMILTask(Inventory inventory,
2421:                    boolean noRefills) {
2422:                if (noRefills) {
2423:                    Task milTask = detReqHandler.findOrMakeMILTask(inventory,
2424:                            aggMILSubscription);
2425:                    // If the milTask couldn't be made - just return
2426:                    if (milTask == null) {
2427:                        return;
2428:                    }
2429:                    PlanElement pe = milTask.getPlanElement();
2430:                    // If the PlanElement is already a Disposition then do nothing
2431:                    if (!(pe instanceof  Disposition)) {
2432:                        // If the PlanElement is not null then it is an expansion.
2433:                        // Only Remove expansion if there is nothing in the workflow.
2434:                        if (pe instanceof  Expansion) {
2435:                            Enumeration tasks = ((Expansion) pe).getWorkflow()
2436:                                    .getTasks();
2437:                            if (!tasks.hasMoreElements()) {
2438:                                publishRemove(pe);
2439:                                pe = null;
2440:                            }
2441:                        }
2442:                        if (pe == null) {
2443:                            // Create Disposition
2444:                            AllocationResultHelper helper = new AllocationResultHelper(
2445:                                    milTask, null);
2446:                            AllocationResult dispAR = helper
2447:                                    .getAllocationResult(
2448:                                            Constants.Confidence.OBSERVED, true);
2449:                            Disposition disposition = getPlanningFactory()
2450:                                    .createDisposition(milTask.getPlan(),
2451:                                            milTask, dispAR);
2452:                            publishAdd(disposition);
2453:                        }
2454:                    }
2455:                }
2456:            }
2457:
2458:            protected Organization getMyOrganization(Enumeration orgs) {
2459:                Organization myOrg = null;
2460:                // look for this organization
2461:                if (orgs.hasMoreElements()) {
2462:                    myOrg = (Organization) orgs.nextElement();
2463:                }
2464:                return myOrg;
2465:            }
2466:
2467:            public long getOPlanStartTime() {
2468:                return logOPlan.getStartTime();
2469:            }
2470:
2471:            public long getOPlanEndTime() {
2472:                return logOPlan.getEndTime();
2473:            }
2474:
2475:            public long getOPlanArrivalInTheaterTime() {
2476:                //Before the arrivalt time is updated in the log oplan
2477:                //the default value is just the start time.
2478:                if (logOPlan.getArrivalTime() == Long.MIN_VALUE) {
2479:                    if (logger.isErrorEnabled()) {
2480:                        logger
2481:                                .error("Asking for arrival time in theater, before it is known");
2482:                    }
2483:                    return startTime;
2484:                } else {
2485:                    return logOPlan.getArrivalTime();
2486:                }
2487:            }
2488:
2489:            public long getPrepoArrivalTime() {
2490:                return getOPlanArrivalInTheaterTime()
2491:                        - (bucketSize * prepoArrivalOffset);
2492:            }
2493:
2494:            //   public void getInventoryData() {
2495:            //     String invFile = getInventoryFileName();
2496:            //     if (invFile != null) {
2497:            //       Enumeration initialInv = FileUtils.readConfigFile(invFile, getConfigFinder());
2498:            //       if (initialInv != null) {
2499:            //         stashInventoryInformation(initialInv);
2500:            //       }
2501:            //     }
2502:            //   }
2503:
2504:            //   private void stashInventoryInformation(Enumeration initInv) {
2505:            //     String line;
2506:            //     String item = null;
2507:            //     double capacity, level;
2508:
2509:            //     while (initInv.hasMoreElements()) {
2510:            //       line = (String) initInv.nextElement();
2511:            //       // Find the fields in the line, values seperated by ','
2512:            //       Vector fields = FileUtils.findFields(line, ',');
2513:            //       if (fields.size() < 3)
2514:            //         continue;
2515:            //       item = (String) fields.elementAt(0);
2516:            //       capacity = Double.valueOf((String) fields.elementAt(1)).doubleValue();
2517:            //       level = Double.valueOf((String) fields.elementAt(2)).doubleValue();
2518:            //       double[] levels = {capacity, level};
2519:            //       inventoryInitHash.put(item, levels);
2520:            //     }
2521:            //   }
2522:
2523:            protected Role getRole(String supply_type) {
2524:                if (supply_type.equals("Ammunition"))
2525:                    return Constants.Role.AMMUNITIONPROVIDER;
2526:                if (supply_type.equals("BulkPOL"))
2527:                    return Constants.Role.FUELSUPPLYPROVIDER;
2528:                if (supply_type.equals("Consumable"))
2529:                    return Constants.Role.SPAREPARTSPROVIDER;
2530:                if (supply_type.equals("PackagedPOL"))
2531:                    return Constants.Role.PACKAGEDPOLSUPPLYPROVIDER;
2532:                if (supply_type.equals("Subsistence"))
2533:                    return Constants.Role.SUBSISTENCESUPPLYPROVIDER;
2534:                if (logger.isErrorEnabled()) {
2535:                    logger.error("Unsupported Supply Type");
2536:                }
2537:                return null;
2538:            }
2539:
2540:            protected boolean updateInventoryPolicy(Collection policies) {
2541:                InventoryPolicy pol;
2542:                boolean changed = false;
2543:                Iterator policy_iterator = policies.iterator();
2544:                while (policy_iterator.hasNext()) {
2545:                    pol = (InventoryPolicy) policy_iterator.next();
2546:                    inventoryPolicy = pol;
2547:                    int cl = pol.getCriticalLevel();
2548:                    if ((cl >= 0) && (cl != criticalLevel)) {
2549:                        criticalLevel = cl;
2550:                        changed = true;
2551:                    }
2552:                    int rp = pol.getReorderPeriod();
2553:                    if ((rp >= 0) && (rp != reorderPeriod)) {
2554:                        reorderPeriod = rp;
2555:                        changed = true;
2556:                    }
2557:                    long bucket = pol.getBucketSize();
2558:                    if (bucket >= TimeUtils.MSEC_PER_HOUR) {
2559:                        bucketSize = bucket;
2560:                        changed = true;
2561:                    }
2562:                    boolean ftc = pol.getFillToCapacity();
2563:                    if (ftc != fillToCapacity) {
2564:                        fillToCapacity = ftc;
2565:                        changed = true;
2566:                    }
2567:                }
2568:                return changed;
2569:            }
2570:
2571:            public int getOrderShipTime() {
2572:                return inventoryPolicy.getOrderShipTime();
2573:            }
2574:
2575:            public long getSupplierArrivalTime() {
2576:                return inventoryPolicy.getSupplierArrivalTime();
2577:            }
2578:
2579:            public long getRefillStartTime() {
2580:                return Math.max(getOPlanArrivalInTheaterTime(),
2581:                        getSupplierArrivalTime());
2582:            }
2583:
2584:            public int getMaxLeadTime() {
2585:                return inventoryPolicy.getSupplierAdvanceNoticeTime()
2586:                        + getOrderShipTime();
2587:            }
2588:
2589:            public boolean getFillToCapacity() {
2590:                return inventoryPolicy.getFillToCapacity();
2591:            }
2592:
2593:            public int getCriticalLevel() {
2594:                return inventoryPolicy.getCriticalLevel();
2595:            }
2596:
2597:            /** VTH operating modes */
2598:            protected OperatingMode level2Horizon, level6Horizon;
2599:
2600:            /** create and publish VTH Operating Modes */
2601:            protected void setupOperatingModes() {
2602:                try {
2603:                    //getBlackboardService().openTransaction();
2604:                    OMCRange level2Range = new IntRange(LEVEL_2_MIN.intValue(),
2605:                            LEVEL_2_MAX.intValue());
2606:                    OMCRangeList rangeList = new OMCRangeList(level2Range);
2607:                    publishAdd(level2Horizon = new OperatingModeImpl(
2608:                            LEVEL_2_TIME_HORIZON + "_" + supplyType, rangeList,
2609:                            LEVEL_2_TIME_HORIZON_DEFAULT));
2610:
2611:                    OMCRange level6Range = new IntRange(LEVEL_6_MIN.intValue(),
2612:                            LEVEL_6_MAX.intValue());
2613:                    rangeList = new OMCRangeList(level6Range);
2614:                    publishAdd(level6Horizon = new OperatingModeImpl(
2615:                            LEVEL_6_TIME_HORIZON + "_" + supplyType, rangeList,
2616:                            LEVEL_6_TIME_HORIZON_DEFAULT));
2617:                } catch (Exception e) {
2618:                    if (logger.isErrorEnabled()) {
2619:                        logger
2620:                                .error(
2621:                                        ""
2622:                                                + getMyOrganization()
2623:                                                + " got exception creating operating modes.",
2624:                                        e);
2625:                    }
2626:                    //} finally {
2627:                    //getBlackboardService().closeTransaction();
2628:                }
2629:
2630:                if (logger.isInfoEnabled()) {
2631:                    logger.info("" + getMyOrganization()
2632:                            + " created operating modes - "
2633:                            + "level 2 time horizon is " + level2Horizon
2634:                            + " and level 6 is " + level6Horizon);
2635:                }
2636:            }
2637:
2638:            /** tiny helper class for VTH Operating Modes */
2639:            protected static class IntRange extends OMCRange {
2640:                public IntRange(int a, int b) {
2641:                    super (a, b);
2642:                }
2643:            }
2644:
2645:            /** relative to now -- this is correct, isn't it? */
2646:            protected long getEndOfLevelSix() {
2647:                long now = currentTimeMillis();
2648:                int days = ((Integer) level6Horizon.getValue()).intValue();
2649:
2650:                return timeUtils.addNDays(now, days);
2651:            }
2652:
2653:            /** relative to now -- this is correct, isn't it? */
2654:            public long getEndOfLevelTwo() {
2655:                long now = currentTimeMillis();
2656:                int days = ((Integer) level2Horizon.getValue()).intValue();
2657:
2658:                return timeUtils.addNDays(now, days);
2659:            }
2660:
2661:            /** When one of our Refill tasks gets removed (Supply or ProjectSupply),
2662:             *  remove it from the BG list.
2663:             *  @param removedTasks The collection of removed refill tasks.
2664:             **/
2665:            public void handleRemovedRefills(Collection removedTasks) {
2666:                Iterator removedIter = removedTasks.iterator();
2667:                while (removedIter.hasNext()) {
2668:                    Task removed = (Task) removedIter.next();
2669:                    if (logger.isDebugEnabled()) {
2670:                        logger.debug("Agent: "
2671:                                + getAgentIdentifier().toString()
2672:                                + "Inv Plugin[" + supplyType + "]"
2673:                                + "processing removal of refill: "
2674:                                + removed.getUID());
2675:                    }
2676:                    String item = removed.getDirectObject()
2677:                            .getTypeIdentificationPG().getTypeIdentification();
2678:                    Inventory inventory = (Inventory) inventoryHash.get(item);
2679:                    LogisticsInventoryPG invPG = (LogisticsInventoryPG) inventory
2680:                            .searchForPropertyGroup(LogisticsInventoryPG.class);
2681:                    if (removed.getVerb().equals(Constants.Verb.SUPPLY)) {
2682:                        invPG.removeRefillRequisition(removed);
2683:                    } else {
2684:                        invPG.removeRefillProjection(removed);
2685:                    }
2686:                    if (removed.isDeleted()) {
2687:                        touchInventoryWithDeletions(inventory);
2688:                    } else {
2689:                        touchInventory(inventory);
2690:                    }
2691:                }
2692:            }
2693:
2694:            public MessageAddress getClusterId() {
2695:                return getAgentIdentifier();
2696:            }
2697:
2698:            public TaskScheduler getSupplyTaskScheduler() {
2699:                return supplyTaskScheduler;
2700:            }
2701:
2702:            public Collection getCommStatusSubscription() {
2703:                return commStatusSub;
2704:            }
2705:
2706:            public Collection getSupplyTasks() {
2707:                return supplyTaskScheduler.getAllTasksCollection();
2708:            }
2709:
2710:            public Alarm addAlarm(long timeOut) {
2711:                Alarm alarm = new CougTimeAlarm(timeOut);
2712:                alarmService.addAlarm(alarm);
2713:                return alarm;
2714:            }
2715:
2716:            public Alarm addRealTimeAlarm(long timeOut) {
2717:                Alarm alarm = new CougTimeAlarm(timeOut);
2718:                alarmService.addRealTimeAlarm(alarm);
2719:                return alarm;
2720:            }
2721:
2722:            //
2723:            protected void processDetReq(Collection addedDRs) {
2724:                // with one oplan we should only have one DR for MI.
2725:                Iterator drIt = addedDRs.iterator();
2726:                if (drIt.hasNext()) {
2727:                    Task detReq = (Task) drIt.next();
2728:                    //synch on the detReq task so only one instance of this plugin
2729:                    // checks and creates a single agg task and then creates an
2730:                    // empty expansion (wf) for the maintain inventory for each item tasks
2731:                    synchronized (detReq) {
2732:                        if (detReq.getPlanElement() == null) {
2733:                            detReqHandler.createAggTask(addedDRs);
2734:                        }
2735:                    }
2736:                }
2737:            }
2738:
2739:            // We only want to process inventories that we have no new refills for.
2740:            protected Collection getActionableInventories() {
2741:                ArrayList actionableInvs = new ArrayList(touchedInventories);
2742:                Task refill;
2743:                Asset asset;
2744:                Inventory inventory;
2745:                Iterator refillIt = newRefills.iterator();
2746:                while (refillIt.hasNext()) {
2747:                    refill = (Task) refillIt.next();
2748:                    asset = (Asset) refill.getDirectObject();
2749:                    inventory = findOrMakeInventory(asset);
2750:                    actionableInvs.remove(inventory);
2751:                }
2752:                return actionableInvs;
2753:            }
2754:
2755:            protected void rebuildPGCustomerHash() {
2756:                Collection changedInventories = getTouchedInventories();
2757:                Iterator invIter = changedInventories.iterator();
2758:                Inventory inventory;
2759:                LogisticsInventoryPG thePG;
2760:                while (invIter.hasNext()) {
2761:                    inventory = (Inventory) invIter.next();
2762:                    thePG = (LogisticsInventoryPG) inventory
2763:                            .searchForPropertyGroup(LogisticsInventoryPG.class);
2764:                    thePG.rebuildCustomerHash();
2765:                }
2766:            }
2767:
2768:            protected boolean didOrgRelationshipsChange() {
2769:                boolean relSchedChange = false;
2770:                if (selfOrganizations.hasChanged()) {
2771:                    Set changeReports = selfOrganizations
2772:                            .getChangeReports(getMyOrganization());
2773:
2774:                    Iterator crits = changeReports.iterator();
2775:                    while (crits.hasNext()) {
2776:                        if (crits.next() instanceof  RelationshipSchedule.RelationshipScheduleChangeReport) {
2777:                            relSchedChange = true;
2778:                            break;
2779:                        }
2780:                    }
2781:                }
2782:                return relSchedChange;
2783:            }
2784:
2785:            // get the first day in theater
2786:            public long getLogOPlanStartTime() {
2787:                return logOPlan.getStartTime();
2788:            }
2789:
2790:            // get the last day in theater
2791:            public long getLogOPlanEndTime() {
2792:                return logOPlan.getEndTime();
2793:            }
2794:
2795:            protected AllocatorModule getAllocatorModule() {
2796:                return new ExternalAllocator(this , getRole(supplyType));
2797:            }
2798:
2799:            protected RefillGeneratorModule getRefillGeneratorModule() {
2800:                return new RefillGenerator(this );
2801:            }
2802:
2803:            protected RefillProjectionGeneratorModule getRefillProjectionGeneratorModule() {
2804:                return new RefillProjectionGenerator(this , this );
2805:            }
2806:
2807:            protected ComparatorModule getComparatorModule() {
2808:                String comparatorClass = (String) pluginParams
2809:                        .get("COMPARATOR");
2810:                if (comparatorClass == null) {
2811:                    return new DiffBasedComparator(this );
2812:                } else {
2813:                    if (comparatorClass.indexOf('.') == -1) {
2814:                        comparatorClass = "org.cougaar.logistics.plugin.inventory."
2815:                                + comparatorClass;
2816:                    }
2817:                    try {
2818:                        Class[] paramTypes = { this .getClass() };
2819:                        Object[] initArgs = { this  };
2820:                        Class cls = Class.forName(comparatorClass);
2821:                        Constructor constructor = cls
2822:                                .getConstructor(paramTypes);
2823:                        ComparatorModule comparator = (ComparatorModule) constructor
2824:                                .newInstance(initArgs);
2825:                        if (logger.isInfoEnabled())
2826:                            logger.info("Using comparator " + comparatorClass);
2827:                        return comparator;
2828:                    } catch (Exception e) {
2829:                        logger
2830:                                .error(e
2831:                                        + " Unable to create Expander instance of "
2832:                                        + comparatorClass
2833:                                        + ". "
2834:                                        + "Loading default org.cougaar.logistics.plugin.inventory.DiffBasedComparator");
2835:                    }
2836:                }
2837:                return new RefillComparator(this );
2838:            }
2839:
2840:            protected ExpanderModule getExpanderModule() {
2841:                ExpanderModule em;
2842:                String expanderClass = (String) pluginParams.get("EXPANDER");
2843:                if (expanderClass == null) {
2844:                    em = new SupplyExpander(this );
2845:                } else {
2846:                    if (expanderClass.indexOf('.') == -1) {
2847:                        expanderClass = "org.cougaar.logistics.plugin.inventory."
2848:                                + expanderClass;
2849:                    }
2850:                    try {
2851:                        Class[] paramTypes = { this .getClass() };
2852:                        Object[] initArgs = { this  };
2853:                        Class cls = Class.forName(expanderClass);
2854:                        Constructor constructor = cls
2855:                                .getConstructor(paramTypes);
2856:                        em = (ExpanderModule) constructor.newInstance(initArgs);
2857:                    } catch (Exception e) {
2858:                        logger
2859:                                .error(e
2860:                                        + " Unable to create Expander instance of "
2861:                                        + expanderClass
2862:                                        + ". "
2863:                                        + "Loading default org.cougaar.logistics.plugin.inventory.SupplyExpander");
2864:                        em = new SupplyExpander(this );
2865:                    }
2866:                }
2867:                if (logger.isInfoEnabled()) {
2868:                    expanderClass = em.getClass().toString();
2869:                    logger.info("Using expander " + expanderClass);
2870:                }
2871:                return em;
2872:            }
2873:
2874:            public void updateStartAndEndTimes() {
2875:                if (logOPlan != null) {
2876:                    if (!orgActSubscription.isEmpty()) {
2877:                        logOPlan.updateOrgActivities(orgActSubscription);
2878:                    }
2879:                }
2880:            }
2881:
2882:            public long getNextLegalRefillTime(long today) {
2883:                TimeSpanSet orderedOrgActs = new TimeSpanSet(orgActSubscription);
2884:                Iterator orgActIt = orderedOrgActs.iterator();
2885:                boolean findNext = false;
2886:                while (orgActIt.hasNext()) {
2887:                    OrgActivity orgAct = (OrgActivity) orgActIt.next();
2888:                    boolean legalOrg = ((!(orgAct.getActivityType()
2889:                            .equals(orgAct.DEPLOYMENT))) && (!(orgAct
2890:                            .getActivityType().equals("Transit"))));
2891:                    if ((orgAct.getStartTime() <= today)
2892:                            && (orgAct.getEndTime() >= today)) {
2893:                        if (legalOrg) {
2894:                            return today;
2895:                        } else {
2896:                            findNext = true;
2897:                        }
2898:                    }
2899:                    if (findNext && legalOrg) {
2900:                        return orgAct.getStartTime();
2901:                    }
2902:                }
2903:
2904:                if (!findNext) {
2905:                    return today;
2906:                } else {
2907:                    return logOPlan.getEndTime();
2908:                }
2909:            }
2910:
2911:            /**
2912:             Self-Test
2913:             **/
2914:            public void automatedSelfTest() {
2915:                if (logger.isErrorEnabled()) {
2916:                    if (supplyType == null)
2917:                        logger.error("No SupplyType Plugin parameter.");
2918:                    //      if (inventoryFile == null) logger.error("No Inventory File Plugin parameter.");
2919:                    //       if (inventoryInitHash.isEmpty()) {
2920:                    //         logger.error("No initial inventory information.  Inventory File is empty or non-existant.");
2921:                    //         logger.error("Could not find Inventory file : " + inventoryFile);
2922:                    //       }
2923:                    if (detReqHandler
2924:                            .getDetermineRequirementsTask(aggMILSubscription) == null)
2925:                        logger
2926:                                .error("Missing DetermineRequirements for MaintainInventory task.");
2927:                    if (logOPlan == null)
2928:                        logger
2929:                                .error("Missing LogisticsOPlan object. Is the LogisticsOPlanPlugin loaded?");
2930:                    if (myOrganization == null)
2931:                        logger.error("Missing myorganization");
2932:                    logger.error("Critical Level is " + criticalLevel);
2933:                    logger.error("Reorder Period is " + reorderPeriod);
2934:                    logger.error("Days per bucket is " + bucketSize);
2935:                }
2936:            }
2937:
2938:            protected final class CougTimeAlarm implements  Alarm {
2939:                private long expirationTime;
2940:                private boolean expired = false;
2941:
2942:                public CougTimeAlarm(long expiration) {
2943:                    this .expirationTime = expiration;
2944:                }
2945:
2946:                public long getExpirationTime() {
2947:                    return expirationTime;
2948:                }
2949:
2950:                public synchronized void expire() {
2951:                    if (!expired) {
2952:                        expired = true;
2953:                        BlackboardService bb = getBlackboardService();
2954:                        if (bb != null) {
2955:                            bb.signalClientActivity();
2956:                        } else {
2957:                            if (logger != null && logger.isWarnEnabled()) {
2958:                                logger
2959:                                        .warn("Alarm to trigger at "
2960:                                                + (new Date(expirationTime))
2961:                                                + " has expired,"
2962:                                                + " but the blackboard service is null.  Plugin "
2963:                                                + " model state is "
2964:                                                + getModelState());
2965:                            }
2966:                        }
2967:                    }
2968:                }
2969:
2970:                public synchronized boolean hasExpired() {
2971:                    return expired;
2972:                }
2973:
2974:                public synchronized boolean cancel() {
2975:                    boolean was = expired;
2976:                    expired = true;
2977:                    return was;
2978:                }
2979:            }
2980:
2981:            protected void testBG() {
2982:                Iterator inv_it = inventoryHash.values().iterator();
2983:                Inventory inv;
2984:                LogisticsInventoryPG logInvPG = null;
2985:                cycleStamp = (new Date()).getTime();
2986:                while (inv_it.hasNext()) {
2987:                    inv = (Inventory) inv_it.next();
2988:                    if (logger.isErrorEnabled()) {
2989:                        logger.error("***"
2990:                                + inv.getItemIdentificationPG()
2991:                                        .getItemIdentification());
2992:                    }
2993:                    logInvPG = (LogisticsInventoryPG) inv
2994:                            .searchForPropertyGroup(LogisticsInventoryPG.class);
2995:                    logInvPG.takeSnapshot(inv);
2996:                    if (logToCSV) {
2997:                        logInvPG.logAllToCSVFile(cycleStamp);
2998:                    }
2999:                    logInvPG.Test();
3000:                }
3001:            }
3002:
3003:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.