Source Code Cross Referenced for SequentialGlobalAirPlugin.java in  » Science » Cougaar12_4 » org » cougaar » logistics » plugin » trans » 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.trans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * <copyright>
0003:         *  
0004:         *  Copyright 2001-2004 BBNT Solutions, LLC
0005:         *  under sponsorship of the Defense Advanced Research Projects
0006:         *  Agency (DARPA).
0007:         * 
0008:         *  You can redistribute this software and/or modify it under the
0009:         *  terms of the Cougaar Open Source License as published on the
0010:         *  Cougaar Open Source Website (www.cougaar.org).
0011:         * 
0012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023:         *  
0024:         * </copyright>
0025:         */
0026:        package org.cougaar.logistics.plugin.trans;
0027:
0028:        import java.util.ArrayList;
0029:        import java.util.Collection;
0030:        import java.util.Date;
0031:        import java.util.Enumeration;
0032:        import java.util.HashMap;
0033:        import java.util.HashSet;
0034:        import java.util.Map;
0035:        import java.util.Iterator;
0036:        import java.util.List;
0037:        import java.util.Random;
0038:        import java.util.Set;
0039:        import java.util.Vector;
0040:
0041:        import org.cougaar.core.service.BlackboardService;
0042:
0043:        import org.cougaar.glm.callback.GLMOrganizationCallback;
0044:        import org.cougaar.glm.callback.GLMOrganizationListener;
0045:
0046:        import org.cougaar.logistics.ldm.Constants;
0047:
0048:        import org.cougaar.glm.ldm.asset.AirportPG;
0049:        import org.cougaar.glm.ldm.asset.GLMAsset;
0050:        import org.cougaar.glm.ldm.asset.MilitaryOrgPG;
0051:        import org.cougaar.glm.ldm.asset.Organization;
0052:        import org.cougaar.glm.ldm.asset.TransportationNode;
0053:
0054:        import org.cougaar.glm.ldm.plan.GeolocLocation;
0055:
0056:        import org.cougaar.logistics.plugin.trans.GLMTransConst;
0057:        import org.cougaar.logistics.plugin.trans.base.SequentialPlannerPlugin;
0058:        import org.cougaar.logistics.plugin.trans.base.SequentialScheduleElement;
0059:
0060:        import org.cougaar.logistics.plugin.trans.tools.BlackboardPlugin;
0061:        import org.cougaar.logistics.plugin.trans.tools.Locator;
0062:        import org.cougaar.logistics.plugin.trans.tools.LocatorImpl;
0063:
0064:        import org.cougaar.glm.util.AssetUtil;
0065:        import org.cougaar.glm.util.GLMPrepPhrase;
0066:
0067:        import org.cougaar.lib.callback.UTILExpandableTaskCallback;
0068:        import org.cougaar.lib.callback.UTILFilterCallback;
0069:        import org.cougaar.lib.callback.UTILGenericListener;
0070:
0071:        import org.cougaar.lib.util.UTILAllocate;
0072:        import org.cougaar.lib.util.UTILExpand;
0073:        import org.cougaar.lib.util.UTILPreference;
0074:
0075:        import org.cougaar.planning.ldm.asset.Asset;
0076:        import org.cougaar.planning.ldm.asset.LocationSchedulePG;
0077:
0078:        import org.cougaar.planning.ldm.plan.Allocation;
0079:        import org.cougaar.planning.ldm.plan.AspectType;
0080:        import org.cougaar.planning.ldm.plan.AspectValue;
0081:        import org.cougaar.planning.ldm.plan.Expansion;
0082:        import org.cougaar.planning.ldm.plan.Location;
0083:        import org.cougaar.planning.ldm.plan.LocationScheduleElement;
0084:        import org.cougaar.planning.ldm.plan.NewSchedule;
0085:        import org.cougaar.planning.ldm.plan.NewTask;
0086:        import org.cougaar.planning.ldm.plan.PlanElement;
0087:        import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
0088:        import org.cougaar.planning.ldm.plan.Relationship;
0089:        import org.cougaar.planning.ldm.plan.RelationshipSchedule;
0090:        import org.cougaar.planning.ldm.plan.Role;
0091:        import org.cougaar.planning.ldm.plan.Schedule;
0092:        import org.cougaar.planning.ldm.plan.ScheduleImpl;
0093:        import org.cougaar.planning.ldm.plan.Task;
0094:        import org.cougaar.planning.ldm.plan.NewWorkflow;
0095:
0096:        import org.cougaar.util.TimeSpan;
0097:        import org.cougaar.util.log.Logger;
0098:
0099:        /**
0100:         * <pre>
0101:         * This class orchestrates the backwards planning that goes on in GLMTrans.
0102:         *
0103:         * It makes decisions about how to expand incoming tasks into their appropriate
0104:         * forms, e.g CONUSGround-Air-TheaterGround.  It monitors the state of each subtask
0105:         * and then notices when a task that is dependent on another has all its dependencies
0106:         * met and is ready to be planned.  This task is then planned.
0107:         *
0108:         * </pre>
0109:         * <!--
0110:         * (When printed, any longer line will wrap...)
0111:         *2345678901234567890123456789012345678901234567890123456789012345678901234567890
0112:         *        1         2         3         4         5         6         7         8
0113:         * -->
0114:         */
0115:        public class SequentialGlobalAirPlugin extends SequentialPlannerPlugin
0116:                implements  GLMOrganizationListener, BlackboardPlugin {
0117:
0118:            protected TranscomDataXMLize dataXMLizer; // we need it for getOrganizationRole
0119:
0120:            private static final long ONE_HOUR = 1000l * 60l * 60l;
0121:            //private static final double BILLION = 1000000000.0d;
0122:            //private static final String SAND = "SAND";
0123:            public static int CONUS_THEATER_DIVIDING_LONGITUDE = Integer
0124:                    .getInteger(
0125:                            "SequentialGlobalAirPlugin.CONUS_THEATER_DIVIDING_LONGITUDE",
0126:                            25).intValue();
0127:            public int numTheaterGroundAgents = 2;
0128:
0129:            public void localSetup() {
0130:                super .localSetup();
0131:
0132:                try {
0133:                    if (getMyParams().hasParam("bestDateBackoff")) {
0134:                        bestDateBackoff = getMyParams().getLongParam(
0135:                                "bestDateBackoff");
0136:                    } else {
0137:                        bestDateBackoff = ONE_HOUR;
0138:                    }
0139:                    if (getMyParams().hasParam("numTheaterGroundAgents")) {
0140:                        numTheaterGroundAgents = getMyParams().getIntParam(
0141:                                "numTheaterGroundAgents");
0142:                    } else {
0143:                        numTheaterGroundAgents = 2; // by default we run with the TRANSCOM-20 society
0144:                    }
0145:                } catch (Exception e) {
0146:                    warn("got really unexpected exception " + e);
0147:                }
0148:
0149:                if (isDebugEnabled())
0150:                    debug("localSetup - Creating prep helper and asset helper.");
0151:
0152:                if (isDebugEnabled())
0153:                    debug("localSetup - this " + this  + " prep helper "
0154:                            + glmPrepHelper);
0155:
0156:                dataXMLizer = new TranscomDataXMLize(true, logger,
0157:                        new HashSet());
0158:            }
0159:
0160:            protected UTILFilterCallback createThreadCallback(
0161:                    UTILGenericListener bufferingThread) {
0162:                myInputTaskCallback = new UTILExpandableTaskCallback(
0163:                        bufferingThread, logger);
0164:                return myInputTaskCallback;
0165:            }
0166:
0167:            /** 
0168:             * Implemented for UTILGenericListener interface
0169:             *
0170:             * Look for tasks that
0171:             * 1) Have TRANSPORT as their verb
0172:             *
0173:             * @param t Task to check for interest
0174:             * @return boolean true if task is interesting
0175:             * @see org.cougaar.lib.callback.UTILGenericListener
0176:             */
0177:
0178:            public boolean interestingTask(Task t) {
0179:                boolean hasTransportVerb = t.getVerb().equals(
0180:                        Constants.Verb.TRANSPORT);
0181:                if (isDebugEnabled() && hasTransportVerb) {
0182:                    debug(" : interested in expandable task " + t
0183:                            + " with direct obj " + t.getDirectObject());
0184:                }
0185:                if (isDebugEnabled() && !hasTransportVerb)
0186:                    debug(" : Ignoring task with verb " + t.getVerb());
0187:
0188:                return hasTransportVerb;
0189:            }
0190:
0191:            public boolean interestingExpandedTask(Task t) {
0192:                if (!t.getSource().equals(getAgentIdentifier()))
0193:                    return true;
0194:                return glmPrepHelper.hasPrepNamed(t,
0195:                        GLMTransConst.SequentialSchedule);
0196:            }
0197:
0198:            /** 
0199:             * Implemented for AssetListener interface<br>
0200:             * only interested in airports/seaports 
0201:             */
0202:            public boolean interestingAsset(Asset asset) {
0203:                boolean retval = asset instanceof  TransportationNode;
0204:                if (isDebugEnabled())
0205:                    debug(".interestingAsset : "
0206:                            + ((retval) ? "interested in " : "ignoring ")
0207:                            + asset);
0208:
0209:                return retval;
0210:            }
0211:
0212:            /*** Organization Listener ***/
0213:
0214:            public void setupFilters() {
0215:                glmPrepHelper = new GLMPrepPhrase(logger);
0216:                glmAssetHelper = new AssetUtil(logger);
0217:
0218:                super .setupFilters();
0219:
0220:                if (isInfoEnabled())
0221:                    info(" : Filtering for Organizations...");
0222:
0223:                addFilter(myOrgCallback = createOrganizationCallback());
0224:
0225:                makeLocator();
0226:            }
0227:
0228:            /** Instantiate the Locator, which adds a LocationCallback */
0229:            protected void makeLocator() {
0230:                locator = new LocatorImpl(this , logger);
0231:            }
0232:
0233:            /** implemented for BlackboardPlugin interface -- need public access! */
0234:            public BlackboardService getBlackboard() {
0235:                return blackboard;
0236:            }
0237:
0238:            protected GLMOrganizationCallback getOrganizationCallback() {
0239:                return myOrgCallback;
0240:            }
0241:
0242:            protected GLMOrganizationCallback createOrganizationCallback() {
0243:                return new GLMOrganizationCallback(this , logger);
0244:            }
0245:
0246:            public Enumeration getOrganizationAssets() {
0247:                return myOrgCallback.getSubscription().elements();
0248:            }
0249:
0250:            public Organization getSelf() {
0251:                return glmAssetHelper.getSelf(getOrganizationAssets());
0252:            }
0253:
0254:            public void handleNewOrganization(Enumeration org_assets) {
0255:                shouldRefreshOrgList = true;
0256:                for (; org_assets.hasMoreElements();) {
0257:                    info(getName() + " - got new org "
0258:                            + org_assets.nextElement());
0259:                }
0260:            }
0261:
0262:            public void handleChangedOrganization(Enumeration org_assets) {
0263:            }
0264:
0265:            public void handleTask(Task t) {
0266:                NewTask subtask = expandHelper.makeSubTask(ldmf, t, t
0267:                        .getDirectObject(), getAgentIdentifier());
0268:                subtask.setContext(t.getContext());
0269:
0270:                NewWorkflow wf = ldmf.newWorkflow();
0271:                wf.setParentTask(t);
0272:                ((NewTask) subtask).setWorkflow(wf);
0273:                ((NewTask) subtask).setParentTask(t);
0274:                wf.addTask(subtask);
0275:
0276:                Expansion exp = ldmf.createExpansion(t.getPlan(), t, wf, null);
0277:
0278:                publishAdd(subtask);
0279:                publishAdd(exp);
0280:
0281:                super .handleTask(subtask);
0282:            }
0283:
0284:            public Schedule createEmptyPlan(Task parent) {
0285:                TheaterPortion theater = new TheaterPortion(parent);
0286:                // IsbPortion isb = new IsbPortion(parent);
0287:                AirPortion air = new AirPortion(parent);
0288:                ConusPortion conus = new ConusPortion(parent);
0289:
0290:                boolean needsTheater = needsTheater(parent);
0291:                // boolean needsISB     = needsISB (parent);
0292:                boolean needsCONUS = needsCONUS(parent);
0293:                boolean needsAirOrSea = needsAirOrSea(parent);
0294:
0295:                // create the dependencies ------------------
0296:
0297:                if (isDebugEnabled())
0298:                    debug(".createEmptyPlan - "
0299:                            + parent.getDirectObject().getUID().getOwner()
0300:                            + "'s task " + parent.getUID() + " - "
0301:                            + parent.getDirectObject() + " Legs : "
0302:                            + ((needsCONUS) ? "G" : "")
0303:                            + ((needsAirOrSea) ? "A/S" : "")
0304:                            + ((needsTheater) ? "T" : ""));
0305:
0306:                //        Vector isbdep = new Vector();
0307:                //		if (needsTheater)
0308:                //		  isbdep.addElement(theater);
0309:                //        isb.setDependencies(isbdep);
0310:
0311:                //		if (needsISB)
0312:                //		  airdep.addElement(isb);
0313:                if (needsTheater) {
0314:                    Vector airdep = new Vector();
0315:                    airdep.addElement(theater);
0316:                    air.setDependencies(airdep);
0317:                }
0318:
0319:                if (needsAirOrSea) {
0320:                    Vector conusdep = new Vector();
0321:                    conusdep.addElement(air);
0322:                    conus.setDependencies(conusdep);
0323:                }
0324:
0325:                // create the Schedule ------------------
0326:
0327:                NewSchedule retSchedule = new ScheduleImpl();
0328:                if (needsTheater)
0329:                    retSchedule.addScheduleElement(theater);
0330:                //		if (needsISB)
0331:                //		  retSchedule.addScheduleElement(isb);
0332:                if (needsAirOrSea)
0333:                    retSchedule.addScheduleElement(air);
0334:                if (needsAirOrSea && needsCONUS)
0335:                    retSchedule.addScheduleElement(conus);
0336:
0337:                if (isDebugEnabled())
0338:                    debug(".createEmptyPlan - " + retSchedule);
0339:                if (retSchedule.isEmpty()) {
0340:                    Object origin = glmPrepHelper.getFromLocation(parent);
0341:                    Object destination = glmPrepHelper.getToLocation(parent);
0342:                    error(".createEmptyPlan - created an empty portion schedule. "
0343:                            + "For task "
0344:                            + parent.getUID()
0345:                            + " going from "
0346:                            + origin + " to " + destination);
0347:                }
0348:
0349:                return retSchedule;
0350:            }
0351:
0352:            /** 
0353:             * needs a theater leg if TO location is not an airbase OR if FROM loc is in theater (i.e. starts in theater).
0354:             */
0355:            boolean needsTheater(Task task) {
0356:                if (glmAssetHelper.isPassenger(task.getDirectObject()))
0357:                    return false;
0358:                boolean inTheater = startsInTheater(task);
0359:                GeolocLocation destinationGeoloc = (GeolocLocation) glmPrepHelper
0360:                        .getIndirectObject(task, Constants.Preposition.TO);
0361:                Object asset = locator.getAssetAtGeolocCode(destinationGeoloc
0362:                        .getGeolocCode());
0363:
0364:                if (isDebugEnabled()) {
0365:                    if (asset == null) {
0366:                        debug(".needsTheater - Theater move needed, since TO location <"
0367:                                + destinationGeoloc
0368:                                + "> is not a "
0369:                                + type()
0370:                                + " among these "
0371:                                + type()
0372:                                + "s : "
0373:                                + locator.knownGeolocCodes());
0374:                    } else {
0375:                        debug(".needsTheater - no Theater move needed, since TO location <"
0376:                                + destinationGeoloc
0377:                                + "> is a "
0378:                                + type()
0379:                                + " ("
0380:                                + asset + ").");
0381:                    }
0382:                }
0383:
0384:                // if the destination is not an airbase/seaport, add a theater ground move leg
0385:                return (inTheater || (asset == null));
0386:            }
0387:
0388:            protected String type() {
0389:                return "airport";
0390:            }
0391:
0392:            /** 
0393:             * sort of cheesy, but anything starting east of 25 degrees Longitude gets a final theater leg.
0394:             * (The 25 degrees can be set with a system property.)
0395:             */
0396:            boolean startsInTheater(Task task) {
0397:                GeolocLocation sourceGeoloc = (GeolocLocation) glmPrepHelper
0398:                        .getIndirectObject(task, Constants.Preposition.FROM);
0399:                return (sourceGeoloc.getLongitude().getDegrees() > CONUS_THEATER_DIVIDING_LONGITUDE);
0400:            }
0401:
0402:            /** 
0403:             * sort of cheesy, but anything starting west of 25 degrees Longitude gets an initial ground leg.
0404:             * (The 25 degrees can be set with a system property.)
0405:             */
0406:            boolean startsInCONUS(Task task) {
0407:                GeolocLocation sourceGeoloc = (GeolocLocation) glmPrepHelper
0408:                        .getIndirectObject(task, Constants.Preposition.FROM);
0409:                return (sourceGeoloc.getLongitude().getDegrees() < CONUS_THEATER_DIVIDING_LONGITUDE);
0410:            }
0411:
0412:            /** 
0413:             ** if the task is coming from CONUS, needs an air leg to get it to theater 
0414:             ** Also, if the task is coming from an airbase, e.g. Rhein Mein in Germany
0415:             **/
0416:            boolean needsAirOrSea(Task task) {
0417:                String origin = glmPrepHelper.getFromLocation(task)
0418:                        .getGeolocCode();
0419:                boolean startsAtPOE = startsAtPOE(task);
0420:                boolean startsInCONUS = startsInCONUS(task);
0421:
0422:                if (isDebugEnabled() && !startsInCONUS && !startsAtPOE)
0423:                    debug(".needsAirOrSea - could not find FROM " + origin
0424:                            + " on list of possible POEs : "
0425:                            + locator.knownGeolocCodes()
0426:                            + " and doesn't start in CONUS.");
0427:
0428:                return startsInCONUS || startsAtPOE;
0429:            }
0430:
0431:            boolean startsAtPOE(Task task) {
0432:                String origin = glmPrepHelper.getFromLocation(task)
0433:                        .getGeolocCode();
0434:                Object airport = locator.getAssetAtGeolocCode(origin);
0435:                return (airport != null);
0436:            }
0437:
0438:            /*
0439:            boolean needsISB (Task task) {
0440:              GeolocLocation PODGeoloc = 
0441:                (GeolocLocation) glmPrepHelper.getIndirectObject(task, Constants.Preposition.VIA); 
0442:              GLMAsset airport = (GLMAsset) geolocToAirport.get (PODGeoloc.getGeolocCode());
0443:
0444:              try {
0445:                AirportPG airportPG = airport.getAirportPG ();
0446:                if (isDebugEnabled())
0447:            debug(".needsISB - for " + PODGeoloc + 
0448:                  " airport is " + airport + " with runway " + airportPG.getRunwayType());
0449:            	
0450:                return (airportPG.getRunwayType().equals (SAND)); // if the airbase has sand runways, need an isb (= Cairo)
0451:              }
0452:              catch (Exception e) {	  
0453:                error(".needsISB - ERROR - no airport for  " + PODGeoloc);
0454:              }
0455:
0456:              return false;
0457:            }
0458:             */
0459:
0460:            boolean needsCONUS(Task task) {
0461:                if (glmAssetHelper.isPassenger(task.getDirectObject()))
0462:                    return false;
0463:                boolean inCONUS = startsInCONUS(task);
0464:
0465:                if (!inCONUS) {
0466:                    if (isDebugEnabled()) {
0467:                        GeolocLocation sourceGeoloc = (GeolocLocation) glmPrepHelper
0468:                                .getIndirectObject(task,
0469:                                        Constants.Preposition.FROM);
0470:                        debug(".needsCONUS - no CONUS move needed, since from "
0471:                                + sourceGeoloc + " is not in CONUS.");
0472:                    }
0473:                    return false;
0474:                }
0475:
0476:                GeolocLocation sourceGeoloc = (GeolocLocation) glmPrepHelper
0477:                        .getIndirectObject(task, Constants.Preposition.FROM);
0478:                String geoloc = sourceGeoloc.getGeolocCode();
0479:                //    Object airport = geolocToAirport.get (geoloc);
0480:                Object airport = locator.getAssetAtGeolocCode(geoloc);
0481:
0482:                if (isDebugEnabled()) {
0483:                    if (airport == null) {
0484:                        debug(".needsCONUS - CONUS move needed, since from <"
0485:                                + geoloc + "> is not a " + type()
0486:                                + " among these " + type() + "s : "
0487:                                + locator.knownGeolocCodes());
0488:                    } else {
0489:                        debug(".needsCONUS - no CONUS move needed, since from "
0490:                                + sourceGeoloc + " is a " + type() + " ("
0491:                                + airport + ").");
0492:                    }
0493:                }
0494:
0495:                // if the source is not an airbase, add a conus ground move leg to the airbase
0496:                return (airport == null);
0497:            }
0498:
0499:            public Organization findOrgForMiddleStep(Task ignored) {
0500:                Organization organicAir = findOrgWithRole(GLMTransConst.ORGANIC_AIR_ROLE);
0501:                if (organicAir == null) {
0502:                    error(".findOrgForMiddleStep - ERROR - No subordinate with role "
0503:                            + GLMTransConst.ORGANIC_AIR_ROLE);
0504:                    return null;
0505:                }
0506:                return organicAir;
0507:            }
0508:
0509:            boolean warnedBefore = false;
0510:
0511:            protected boolean allNecessaryAssetsReported() {
0512:                Organization conusGround = findOrgWithRole(GLMTransConst.CONUS_GROUND_ROLE);
0513:                if (conusGround == null) {
0514:                    if (isInfoEnabled())
0515:                        info("conus ground subord is missing.");
0516:
0517:                    return false;
0518:                }
0519:
0520:                if (!allNecessaryAssetsReportedMiddleStep()) {
0521:                    if (isInfoEnabled())
0522:                        info("middle (air/sea) subord is missing.");
0523:
0524:                    return false;
0525:                }
0526:
0527:                Organization theater = findOrgWithRole(GLMTransConst.THEATER_MCC_ROLE);
0528:                if (theater == null) {
0529:                    if (isInfoEnabled())
0530:                        info("theater subord is missing.");
0531:
0532:                    return false;
0533:                }
0534:
0535:                List orgs = (List) roleToOrg
0536:                        .get(GLMTransConst.THEATER_MCC_ROLE); // sets roleToOrg
0537:                if (orgs.size() < getNumTheaterGroundAgents()) {
0538:                    if (isWarnEnabled() && !warnedBefore) {
0539:                        warn("only "
0540:                                + orgs.size()
0541:                                + " theater subords have reported, expecting "
0542:                                + numTheaterGroundAgents
0543:                                + ". "
0544:                                + "Set numTheaterGroundAgents to 1 in GLMT.Transcom.env.xml in configs/glmtrans "
0545:                                + "if running in TRANSCOM-7 configuration. "
0546:                                + "2 is correct for the TRANSCOM-20 configuration.");
0547:                        warnedBefore = true;
0548:                    }
0549:
0550:                    shouldRefreshOrgList = true; // let's try again later -- see findOrgWithRole
0551:
0552:                    return false;
0553:                }
0554:
0555:                return true;
0556:            }
0557:
0558:            public int getNumTheaterGroundAgents() {
0559:                Object ammoShipPacker = findOrgWithRole(GLMTransConst.AMMO_SHIP_PACKER_ROLE);
0560:                if (getAgentIdentifier().toString().toLowerCase().startsWith(
0561:                        "ammo")) {
0562:                    return 1; // ammo sea only needs one theater ground agent - ammo theater ground
0563:                } else {
0564:                    return numTheaterGroundAgents;
0565:                }
0566:            }
0567:
0568:            /** overridden in sequentialglobalseaplugin */
0569:            protected boolean allNecessaryAssetsReportedMiddleStep() {
0570:                Organization middleOrg = findOrgWithRole(GLMTransConst.ORGANIC_AIR_ROLE);
0571:                return (middleOrg != null);
0572:            }
0573:
0574:            protected abstract static class ElementBase extends
0575:                    SequentialScheduleElement {
0576:                protected ElementBase(Task parent) {
0577:                    super (parent);
0578:                }
0579:
0580:                /** check to see if was an error */
0581:                protected void reportZeroDuration(Allocation alloc,
0582:                        SequentialPlannerPlugin plugin) {
0583:                    GLMPrepPhrase glmPrepHelper = ((SequentialGlobalAirPlugin) plugin)
0584:                            .getPrepHelper();
0585:                    Logger logger = ((SequentialGlobalAirPlugin) plugin)
0586:                            .getLogger();
0587:
0588:                    Task task = alloc.getTask();
0589:                    Asset directObject = task.getDirectObject();
0590:
0591:                    if (!glmPrepHelper.getFromLocation(task).getGeolocCode()
0592:                            .equals(
0593:                                    glmPrepHelper.getToLocation(task)
0594:                                            .getGeolocCode()))
0595:                        logger
0596:                                .info("SequentialGlobalAirPlugin.finishPlan - WARNING - start = end time for task "
0597:                                        + task.getUID()
0598:                                        + " asset "
0599:                                        + directObject.getUID()
0600:                                        + " from "
0601:                                        + glmPrepHelper.getFromLocation(task)
0602:                                        + " != to "
0603:                                        + glmPrepHelper.getToLocation(task));
0604:                }
0605:            }
0606:
0607:            protected static class TheaterPortion extends ElementBase {
0608:                public TheaterPortion(Task parent) {
0609:                    super (parent);
0610:                }
0611:
0612:                public String toString() {
0613:                    return "TheaterPortion";
0614:                }
0615:
0616:                public Task planMe(SequentialPlannerPlugin myPlugin) {
0617:                    SequentialGlobalAirPlugin plugin = (SequentialGlobalAirPlugin) myPlugin;
0618:                    Logger logger = plugin.getLogger();
0619:                    UTILExpand expandHelper = plugin.getExpandHelper();
0620:                    GLMPrepPhrase glmPrepHelper = plugin.getPrepHelper();
0621:
0622:                    if (logger.isDebugEnabled())
0623:                        logger
0624:                                .debug(".TheaterPortion.planMe - starting planning.");
0625:
0626:                    NewTask new_task = expandHelper.makeSubTask(myPlugin
0627:                            .publicGetFactory(), parentTask, parentTask
0628:                            .getDirectObject(), myPlugin
0629:                            .publicGetMessageAddress());
0630:                    new_task.setContext(parentTask.getContext());
0631:
0632:                    // find the theater org
0633:
0634:                    Organization theater = plugin
0635:                            .findOrgWithRole(GLMTransConst.THEATER_MCC_ROLE);
0636:                    if (theater == null) {
0637:                        logger
0638:                                .error(".TheaterPortion.planMe - ERROR - No subordinate with role "
0639:                                        + GLMTransConst.THEATER_MCC_ROLE);
0640:                        return null;
0641:                    }
0642:
0643:                    // if we've got an air move, find the nearest airbase, otherwise, just do ground move from from loc
0644:                    Location PODLocation = (plugin.startsInTheater(parentTask)) ? glmPrepHelper
0645:                            .getFromLocation(parentTask)
0646:                            : plugin.getPOD(parentTask);
0647:
0648:                    glmPrepHelper.replacePrepOnTask(new_task, glmPrepHelper
0649:                            .makePrepositionalPhrase(plugin.publicGetFactory(),
0650:                                    Constants.Preposition.FROM, PODLocation));
0651:                    if (logger.isDebugEnabled())
0652:                        logger
0653:                                .debug(".TheaterPortion.planMe - created leg FROM "
0654:                                        + PODLocation
0655:                                        + " TO "
0656:                                        + glmPrepHelper.getToLocation(new_task));
0657:
0658:                    glmPrepHelper.removePrepNamed(new_task,
0659:                            GLMTransConst.SEAROUTE);
0660:                    glmPrepHelper.removePrepNamed(new_task,
0661:                            GLMTransConst.SEAROUTE_DISTANCE);
0662:
0663:                    PlanElement pe = plugin.getAllocHelper().makeAllocation(
0664:                            myPlugin, myPlugin.publicGetFactory(),
0665:                            myPlugin.publicGetRealityPlan(), new_task, theater,
0666:                            plugin.getPrefHelper().getReadyAt(new_task),
0667:                            plugin.getPrefHelper().getBestDate(new_task),
0668:                            plugin.getAllocHelper().MEDIUM_CONFIDENCE,
0669:                            Constants.Role.TRANSPORTER);
0670:                    myPlugin.publicPublishAdd(pe);
0671:                    return new_task;
0672:                }
0673:            }
0674:
0675:            /** comment this back in whenever we want to revivify the ISB planning */
0676:            /*
0677:            protected class IsbPortion extends ElementBase {
0678:              protected double myMaxCost = BILLION;
0679:                  
0680:              public IsbPortion(Task parent) {
0681:                super(parent);
0682:              }
0683:
0684:              public String toString () { return "IsbPortion"; }
0685:                  
0686:              public Task planMe(SequentialPlannerPlugin myPlugin) {
0687:                SequentialGlobalAirPlugin plugin = (SequentialGlobalAirPlugin) myPlugin;
0688:                Logger logger = plugin.getLogger();
0689:                UTILExpand expandHelper = plugin.getExpandHelper();
0690:                GLMPrepPhrase glmPrepHelper = plugin.getPrepHelper();
0691:                if (logger.isDebugEnabled())
0692:            logger.debug (".IsbPortion.planMe - starting planning.");
0693:
0694:                NewTask new_task = expandHelper.makeSubTask(myPlugin.publicGetFactory(),
0695:            					  parentTask,
0696:            					  parentTask.getDirectObject(),
0697:            					  myPlugin.publicGetMessageAddress());
0698:                      
0699:                // find the ISB org
0700:                Organization isb = plugin.findOrgWithRole(GLMTransConst.C130_ROLE);
0701:                if (isb == null) {
0702:            logger.error(".IsbPortion.planMe - ERROR - No subordinate with role " + 
0703:            	     GLMTransConst.C130_ROLE);
0704:            return null;
0705:                }
0706:
0707:                Organization theater = plugin.findOrgWithRole(GLMTransConst.THEATER_MCC_ROLE);
0708:                if (theater == null) {
0709:            logger.error(".TheaterPortion.planMe - ERROR - No subordinate with role " + 
0710:            	     GLMTransConst.THEATER_MCC_ROLE);
0711:            return null;
0712:                }
0713:
0714:                Date end = null;
0715:
0716:                if (getDependencies().isEmpty()) { // if there was no theater leg
0717:            end = prefHelper.getLateDate(parentTask);
0718:            if (logger.isDebugEnabled())
0719:              logger.debug (".IsbPortion.planMe - no dependencies, end preference is " +
0720:            		end);
0721:                } else {
0722:            end = ((SequentialScheduleElement)getDependencies().elementAt(0)).getStartDate();
0723:            prefHelper.replacePreference(new_task, 
0724:            			     prefHelper.makeEndDatePreference(myPlugin.publicGetFactory(), end));
0725:            if (logger.isDebugEnabled())
0726:              logger.debug (".IsbPortion.planMe - dependent on theater, end preference is " +
0727:            		end);
0728:                }
0729:
0730:                Location isbLocation = plugin.getISBLocation(end); // doesn't matter when
0731:                Location PODLocation = plugin.getPOD (parentTask);
0732:                      
0733:                glmPrepHelper.replacePrepOnTask(new_task, 
0734:            			      glmPrepHelper.makePrepositionalPhrase(myPlugin.publicGetFactory(),
0735:            								    Constants.Preposition.FROM,
0736:            								    isbLocation));
0737:                glmPrepHelper.replacePrepOnTask(new_task, 
0738:            			      glmPrepHelper.makePrepositionalPhrase(myPlugin.publicGetFactory(),
0739:            								    Constants.Preposition.TO,
0740:            								    PODLocation));
0741:
0742:                glmPrepHelper.removePrepNamed(new_task, GLMTransConst.MODE);
0743:
0744:                new_task.addPreference (prefHelper.makeCostPreference (myPlugin.publicGetFactory(), myMaxCost));
0745:
0746:                List aspects = new ArrayList ();
0747:                aspects.add (AspectValue.newAspectValue (AspectType.START_TIME, 
0748:            			    (double) prefHelper.getReadyAt(new_task).getTime ()));
0749:                aspects.add (AspectValue.newAspectValue (AspectType.END_TIME,   
0750:            			    (double) end.getTime ()));
0751:                aspects.add (AspectValue.newAspectValue (AspectType.COST, 0));
0752:
0753:                PlanElement c130_alloc = plugin.getAllocHelper().makeAllocation (myPlugin,
0754:            							       myPlugin.publicGetFactory(),
0755:            							       myPlugin.publicGetRealityPlan(),
0756:            							       new_task,
0757:            							       isb,
0758:            							       (AspectValue []) aspects.toArray (new AspectValue[0]), 
0759:            							       plugin.getAllocHelper().MEDIUM_CONFIDENCE,
0760:            							       Constants.Role.TRANSPORTER);
0761:                myPlugin.publicPublishAdd(c130_alloc);
0762:                return new_task;
0763:              }
0764:            }
0765:             */
0766:
0767:            protected static class AirPortion extends ElementBase {
0768:                public AirPortion(Task parent) {
0769:                    super (parent);
0770:                }
0771:
0772:                public String toString() {
0773:                    return "AirPortion";
0774:                }
0775:
0776:                public Task planMe(SequentialPlannerPlugin myPlugin) {
0777:                    SequentialGlobalAirPlugin plugin = (SequentialGlobalAirPlugin) myPlugin;
0778:                    Logger logger = plugin.getLogger();
0779:                    UTILExpand expandHelper = plugin.getExpandHelper();
0780:                    GLMPrepPhrase glmPrepHelper = plugin.getPrepHelper();
0781:
0782:                    if (logger.isDebugEnabled())
0783:                        logger.debug(".AirPortion.planMe - starting planning.");
0784:
0785:                    NewTask new_task = expandHelper.makeSubTask(myPlugin
0786:                            .publicGetFactory(), parentTask, parentTask
0787:                            .getDirectObject(), myPlugin
0788:                            .publicGetMessageAddress());
0789:                    new_task.setContext(parentTask.getContext());
0790:
0791:                    Vector getDependencies = getDependencies();
0792:
0793:                    /*
0794:                    boolean dependsOnISB = false;
0795:                    	
0796:                    for (int i = 0; i < getDependencies.size(); i++) {
0797:                    if (getDependencies.get (i) instanceof IsbPortion) {
0798:                    dependsOnISB = true;
0799:                    break;
0800:                    }
0801:                    }
0802:                     */
0803:
0804:                    Location[] locations = plugin.getPOEandPOD(parentTask,
0805:                            new_task);
0806:                    Location fromLocation = locations[0];
0807:                    Location toLocation = locations[1];
0808:
0809:                    Date end = null;
0810:                    Date early, best;
0811:
0812:                    if (getDependencies().isEmpty()) { // if there was neither a theater nor a isb leg
0813:                        end = plugin.getPrefHelper().getLateDate(parentTask);
0814:                        best = end;
0815:                    } else {
0816:                        SequentialScheduleElement sse = (SequentialScheduleElement) getDependencies()
0817:                                .elementAt(0);
0818:                        end = sse.getStartDate();
0819:                        //	early = plugin.getPrefHelper().getReadyAt(new_task);
0820:                        best = new Date(end.getTime() - plugin.bestDateBackoff);
0821:                        early = plugin
0822:                                .getEarlyArrivalMiddleStep(new_task, best);
0823:                        if (best.getTime() < early.getTime())
0824:                            best = early;
0825:
0826:                        plugin.getPrefHelper().replacePreference(
0827:                                new_task,
0828:                                plugin.getPrefHelper().makeEndDatePreference(
0829:                                        myPlugin.publicGetFactory(), early,
0830:                                        best, end));
0831:                        GeolocLocation theaterLegFrom = plugin.getPrepHelper()
0832:                                .getFromLocation(sse.getTask());
0833:
0834:                        if (!theaterLegFrom.getGeolocCode().equals(
0835:                                ((GeolocLocation) toLocation).getGeolocCode()))
0836:                            plugin.getLogger().error(
0837:                                    " - Theater leg task "
0838:                                            + sse.getTask().getUID() + " FROM "
0839:                                            + theaterLegFrom
0840:                                            + " is not equal to air/sea TO "
0841:                                            + toLocation);
0842:
0843:                        // if (dependsOnISB)
0844:                        //	toLocation = plugin.getISBLocation(end); // doesn't matter when
0845:                    }
0846:
0847:                    if (logger.isDebugEnabled())
0848:                        logger.debug(".AirPortion.planMe - created leg FROM "
0849:                                + fromLocation + " TO " + toLocation);
0850:
0851:                    glmPrepHelper.replacePrepOnTask(new_task, glmPrepHelper
0852:                            .makePrepositionalPhrase(myPlugin
0853:                                    .publicGetFactory(),
0854:                                    Constants.Preposition.FROM, fromLocation));
0855:
0856:                    glmPrepHelper.replacePrepOnTask(new_task, glmPrepHelper
0857:                            .makePrepositionalPhrase(myPlugin
0858:                                    .publicGetFactory(),
0859:                                    Constants.Preposition.TO, toLocation));
0860:
0861:                    Organization middleOrg = plugin
0862:                            .findOrgForMiddleStep(new_task);
0863:
0864:                    List aspects = new ArrayList();
0865:                    aspects.add(AspectValue.newAspectValue(
0866:                            AspectType.START_TIME, (double) plugin
0867:                                    .getPrefHelper().getReadyAt(new_task)
0868:                                    .getTime()));
0869:                    aspects.add(AspectValue.newAspectValue(AspectType.END_TIME,
0870:                            (double) best.getTime()));
0871:
0872:                    plugin.removePrepsFromMiddleStep(new_task);
0873:
0874:                    PlanElement pe = plugin.getAllocHelper()
0875:                            .makeAllocation(
0876:                                    myPlugin,
0877:                                    myPlugin.publicGetFactory(),
0878:                                    myPlugin.publicGetRealityPlan(),
0879:                                    new_task,
0880:                                    middleOrg,
0881:                                    (AspectValue[]) aspects
0882:                                            .toArray(new AspectValue[0]),
0883:                                    plugin.getAllocHelper().MEDIUM_CONFIDENCE,
0884:                                    Constants.Role.TRANSPORTER);
0885:
0886:                    myPlugin.publicPublishAdd(pe);
0887:                    return new_task;
0888:                }
0889:
0890:            }
0891:
0892:            protected Date getEarlyArrivalMiddleStep(Task task, Date best) {
0893:                return prefHelper.getReadyAt(task);
0894:            }
0895:
0896:            protected void removePrepsFromMiddleStep(Task new_task) {
0897:                glmPrepHelper.removePrepNamed(new_task, GLMTransConst.SEAROUTE);
0898:                glmPrepHelper.removePrepNamed(new_task,
0899:                        GLMTransConst.SEAROUTE_DISTANCE);
0900:            }
0901:
0902:            protected static class ConusPortion extends ElementBase {
0903:                public ConusPortion(Task parent) {
0904:                    super (parent);
0905:                }
0906:
0907:                public String toString() {
0908:                    return "ConusPortion";
0909:                }
0910:
0911:                public Task planMe(SequentialPlannerPlugin myPlugin) {
0912:                    SequentialGlobalAirPlugin plugin = (SequentialGlobalAirPlugin) myPlugin;
0913:                    Logger logger = plugin.getLogger();
0914:                    UTILExpand expandHelper = plugin.getExpandHelper();
0915:                    GLMPrepPhrase glmPrepHelper = plugin.getPrepHelper();
0916:                    Location toLocation = null;
0917:                    Date end = null;
0918:
0919:                    NewTask new_task = expandHelper.makeSubTask(myPlugin
0920:                            .publicGetFactory(), parentTask, parentTask
0921:                            .getDirectObject(), myPlugin
0922:                            .publicGetMessageAddress());
0923:                    new_task.setContext(parentTask.getContext());
0924:
0925:                    if (!getDependencies().isEmpty()) {
0926:                        SequentialScheduleElement sse = (SequentialScheduleElement) getDependencies()
0927:                                .elementAt(0);
0928:                        Task dependingTask = sse.getTask();
0929:                        if (dependingTask == null) {
0930:                            logger
0931:                                    .error(" - problem with replanning earlier tasks - no task on schedule element "
0932:                                            + sse);
0933:                        } else {
0934:                            end = sse.getStartDate();
0935:                            toLocation = glmPrepHelper
0936:                                    .getFromLocation(dependingTask);
0937:                        }
0938:                    } else {
0939:                        end = plugin.getPrefHelper().getLateDate(new_task);
0940:                        toLocation = plugin.getLocator()
0941:                                .getPOENearestToFromLoc(parentTask);
0942:                    }
0943:
0944:                    Date early = plugin.getPrefHelper().getReadyAt(new_task);
0945:                    Date best = new Date(end.getTime() - 1000);
0946:
0947:                    plugin.getPrefHelper().replacePreference(
0948:                            new_task,
0949:                            plugin.getPrefHelper().makeEndDatePreference(
0950:                                    myPlugin.publicGetFactory(), early, best,
0951:                                    end));
0952:
0953:                    glmPrepHelper.replacePrepOnTask(new_task, glmPrepHelper
0954:                            .makePrepositionalPhrase(myPlugin
0955:                                    .publicGetFactory(),
0956:                                    Constants.Preposition.TO, toLocation));
0957:                    if (logger.isDebugEnabled())
0958:                        logger.debug(".ConusPortion.planMe - created leg FROM "
0959:                                + glmPrepHelper.getFromLocation(new_task)
0960:                                + " TO " + toLocation);
0961:
0962:                    Organization conusGround = plugin
0963:                            .findOrgWithRole(GLMTransConst.CONUS_GROUND_ROLE);
0964:                    if (conusGround == null) {
0965:                        logger
0966:                                .error(".ConusPortion.planMe - ERROR - No subordinate with role "
0967:                                        + GLMTransConst.CONUS_GROUND_ROLE);
0968:                        return null;
0969:                    }
0970:
0971:                    glmPrepHelper.removePrepNamed(new_task,
0972:                            GLMTransConst.SEAROUTE);
0973:                    glmPrepHelper.removePrepNamed(new_task,
0974:                            GLMTransConst.SEAROUTE_DISTANCE);
0975:
0976:                    PlanElement pe = plugin.getAllocHelper().makeAllocation(
0977:                            myPlugin,
0978:                            myPlugin.publicGetFactory(),
0979:                            myPlugin.publicGetRealityPlan(),
0980:                            new_task,
0981:                            conusGround, // allocate to conus ground
0982:                            plugin.getPrefHelper().getReadyAt(new_task), end,
0983:                            plugin.getAllocHelper().MEDIUM_CONFIDENCE,
0984:                            Constants.Role.TRANSPORTER);
0985:                    myPlugin.publicPublishAdd(pe);
0986:                    return new_task;
0987:                }
0988:
0989:                public void finishPlan(Allocation alloc,
0990:                        SequentialPlannerPlugin myPlugin) {
0991:                    SequentialGlobalAirPlugin plugin = (SequentialGlobalAirPlugin) myPlugin;
0992:                    Logger logger = plugin.getLogger();
0993:
0994:                    if (logger.isDebugEnabled())
0995:                        logger
0996:                                .debug(".ConusPortion.finishPlan - Planning complete.");
0997:                    super .finishPlan(alloc, plugin);
0998:                }
0999:            }
1000:
1001:            /** supports finding an ISB at a certain time -- assumes it can move! */
1002:            /*
1003:            Location getISBLocation (Date when) {
1004:              Organization isb = findOrgWithRole (GLMTransConst.C130_ROLE);
1005:              Location loc = (Location) airportToLocation.get (isb);
1006:              if (loc == null) {
1007:                loc = findLocationAtTime (isb, when.getTime());
1008:                airportToLocation.put (isb, loc);
1009:              }
1010:              return loc;
1011:            }
1012:             */
1013:
1014:            /** 
1015:             * <pre>
1016:             * Given a task, find the POE and POD for the task 
1017:             * This will be a search among possible POEs and PODs for those that
1018:             * are closest to the FROM-TO pair on the parent task.
1019:             *
1020:             * The choice will be affected by the how long it takes
1021:             * to get from POE to POD.
1022:             * </pre>
1023:             */
1024:            protected Location[] getPOEandPOD(Task parentTask, Task subtask) {
1025:                Location[] locs = new Location[2];
1026:
1027:                locs[0] = locator.getPOENearestToFromLoc(parentTask);
1028:                locs[1] = getPOD(parentTask);
1029:
1030:                return locs;
1031:            }
1032:
1033:            /** 
1034:             * Uses locator to get POD
1035:             **/
1036:            Location getPOD(Task task) {
1037:                /*
1038:                Location POD =locator.getNearestLocation(glmPrepHelper.getToLocation(task));
1039:                System.out.println ("SeqGlobalAir.getPOD - chose POD " + POD + 
1040:                		" nearest to " + glmPrepHelper.getToLocation(task) + " from among " +
1041:                		((LocatorImpl)locator).myLocations);
1042:                 */
1043:                return (Location) locator.getNearestLocation(glmPrepHelper
1044:                        .getToLocation(task));
1045:            }
1046:
1047:            Location getPOENearestToFromLocMiddleStep(Task parentTask) {
1048:                return locator.getPOENearestToFromLoc(parentTask);
1049:            }
1050:
1051:            /** 
1052:             * cache role to org mapping <p>
1053:             *
1054:             * Supports spawning -- choosing among several possible subordinates with role 
1055:             * <tt>role</tt>. <p>
1056:             *
1057:             * Calls chooseAmongOrgs.
1058:             *
1059:             * @see #chooseAmongOrgs
1060:             */
1061:            public Organization findOrgWithRole(Role role) {
1062:                List orgs = (List) roleToOrg.get(role);
1063:
1064:                if (orgs == null || shouldRefreshOrgList) {
1065:                    orgs = new ArrayList();
1066:                    roleToOrg.put(role, orgs);
1067:                    RelationshipSchedule sched = getSelf()
1068:                            .getRelationshipSchedule();
1069:                    Collection matchingRels = sched.getMatchingRelationships(
1070:                            role, TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE);
1071:                    if (isInfoEnabled()) {
1072:                        info(getName() + " found " + matchingRels.size()
1073:                                + " matches for role " + role);
1074:                    }
1075:                    for (Iterator it = matchingRels.iterator(); it.hasNext();) {
1076:                        Relationship rel = (Relationship) it.next();
1077:                        Object other = sched.getOther(rel);
1078:                        if (isInfoEnabled()) {
1079:                            info(getName() + " adding other " + other
1080:                                    + " to known orgs for " + role);
1081:                        }
1082:                        orgs.add(other);
1083:
1084:                        if (isInfoEnabled()) {
1085:                            info(getName() + " has " + orgs.size()
1086:                                    + " orgs for role " + role);
1087:                        }
1088:                    }
1089:
1090:                    if (matchingRels.size() == 1) {
1091:                        Collection selfProviders = sched
1092:                                .getMatchingRelationships(
1093:                                        Constants.RelationshipType.PROVIDER_SUFFIX,
1094:                                        TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE);
1095:
1096:                        info(getName() + " self providers schedule was "
1097:                                + selfProviders);
1098:                        /*
1099:                        List otherWay = getOrgsWithRole (role);
1100:                        if (otherWay.size () > 1) {
1101:                          info (getName () + " found more orgs by direct interrogation, so using them.");
1102:                          orgs = otherWay;
1103:                        }
1104:                         */
1105:                    }
1106:
1107:                    shouldRefreshOrgList = false;
1108:                }
1109:
1110:                if (orgs.isEmpty()) {
1111:                    if (isInfoEnabled()) {
1112:                        info(getName()
1113:                                + ".findOrgWithRole - could not find any organizations with role "
1114:                                + role
1115:                                + " among subordinates -- relationship schedule is:\n"
1116:                                + getSelf().getRelationshipSchedule());
1117:                    }
1118:
1119:                    return null;
1120:                }
1121:
1122:                return chooseAmongOrgs(orgs);
1123:            }
1124:
1125:            /** 
1126:             * thought this might help, but didn't - self org and individual org role schedules 
1127:             * do in fact agree 
1128:             */
1129:            protected List getOrgsWithRole(Role role) {
1130:                // send subscription contents through again...
1131:                Collection assets = getOrganizationCallback().getSubscription()
1132:                        .getCollection();
1133:                List orgs = new ArrayList();
1134:
1135:                for (Iterator iter = assets.iterator(); iter.hasNext();) {
1136:                    Asset asset = (Asset) iter.next();
1137:                    if (asset instanceof  Organization) {
1138:                        String name = dataXMLizer.getOrganizationRole(asset);
1139:
1140:                        if (isInfoEnabled()) {
1141:                            info(getName() + " examining " + asset
1142:                                    + " for role " + role + " says it's "
1143:                                    + name);
1144:                        }
1145:                        if (role.getName().equals(name)) {
1146:                            if (isInfoEnabled()) {
1147:                                info(getName() + " " + asset
1148:                                        + " indeed has role " + role);
1149:                            }
1150:
1151:                            orgs.add(asset);
1152:                        }
1153:                    }
1154:                }
1155:
1156:                return orgs;
1157:            }
1158:
1159:            /**
1160:             * re-examine the workflow to see if the any tasks overlap the time
1161:             * of the recently changed allocation, if they do, replan tasks
1162:             * that depend on it.
1163:             */
1164:            protected void replanDependingTasks(Task parentTask, long beforeTime) {
1165:                Expansion exp = (Expansion) parentTask.getPlanElement();
1166:                if (exp == null) {
1167:                    if (isInfoEnabled()) {
1168:                        info("no expansion for " + parentTask.getUID()
1169:                                + " must be in middle of rescinds.");
1170:                    }
1171:
1172:                    return;
1173:                }
1174:
1175:                PrepositionalPhrase prep = prepHelper.getPrepNamed(parentTask,
1176:                        GLMTransConst.SequentialSchedule);
1177:                Schedule sched = (Schedule) prep.getIndirectObject();
1178:                Enumeration en = sched.getAllScheduleElements();
1179:                boolean overlap = false;
1180:                Set toReplan = new HashSet();
1181:
1182:                while (en.hasMoreElements()) {
1183:                    SequentialScheduleElement spe = (SequentialScheduleElement) en
1184:                            .nextElement();
1185:                    String uid = "<NO TASK>";
1186:                    if (spe.getTask() != null)
1187:                        uid = spe.getTask().getUID().toString();
1188:
1189:                    if (isInfoEnabled()) {
1190:                        info("for task " + parentTask.getUID() + " spe task "
1191:                                + uid + " spe planned " + spe.isPlanned()
1192:                                + " spe end date " + spe.getEndDate()
1193:                                + " before time " + new Date(beforeTime));
1194:                    }
1195:
1196:                    if (spe.isPlanned()) {
1197:                        for (Iterator iter = spe.getDependencies().iterator(); iter
1198:                                .hasNext();) {
1199:                            SequentialScheduleElement dependency = (SequentialScheduleElement) iter
1200:                                    .next();
1201:
1202:                            // |--- spe ---|               (overlap) 
1203:                            //    |--- dep ---|
1204:                            //   OR 
1205:                            // |--- dep ---| |--- spe ---| (dependency should always be after!)
1206:
1207:                            if (spe.overlapSchedule(dependency)
1208:                                    || dependency.getEndTime() < spe
1209:                                            .getStartTime()) {
1210:                                if (isInfoEnabled()) {
1211:                                    info("for task " + parentTask.getUID()
1212:                                            + " replanning spe at "
1213:                                            + spe.getEndDate());
1214:                                }
1215:                                toReplan.add(spe);
1216:                            }
1217:                        }
1218:                    }
1219:                }
1220:
1221:                for (Iterator iter = toReplan.iterator(); iter.hasNext();) {
1222:                    SequentialScheduleElement replanSSE = (SequentialScheduleElement) iter
1223:                            .next();
1224:                    replanPortion(exp, replanSSE);
1225:                }
1226:
1227:                // let's replan!
1228:                if (!toReplan.isEmpty()) {
1229:                    if (isInfoEnabled()) {
1230:                        info("got overlap of " + parentTask.getUID());
1231:                    }
1232:                    turnCrank(parentTask);
1233:                }
1234:            }
1235:
1236:            protected void replanPortion(Expansion exp,
1237:                    SequentialScheduleElement spe) {
1238:                handleRemovedAlloc((Allocation) spe.getTask().getPlanElement());
1239:                if (exp != null) { // fix for bug #13417
1240:                    try {
1241:                        NewWorkflow nw = (NewWorkflow) exp.getWorkflow();
1242:                        if (nw != null)
1243:                            nw.removeTask(spe.getTask());
1244:                        publishRemove(spe.getTask());
1245:                    } catch (IllegalArgumentException iae) {
1246:                        error(getName()
1247:                                + " - task "
1248:                                + spe.getTask().getUID()
1249:                                + " is not in workflow for task "
1250:                                + exp.getTask().getUID()
1251:                                + " - likely rescinds happening concurrently. Exception was "
1252:                                + iae);
1253:                    }
1254:                    publishChange(exp);
1255:                }
1256:
1257:                spe.unplan();
1258:                spe.setTask(null);
1259:            }
1260:
1261:            /** 
1262:             * this could be more sophisticated in the future 
1263:             * 
1264:             * Right now, just round-robin.
1265:             */
1266:            protected Organization chooseAmongOrgs(List orgs) {
1267:                int i = r.nextInt(orgs.size());
1268:
1269:                if (isDebugEnabled())
1270:                    debug(".chooseAmongOrgs - choosing org #" + i + " ("
1271:                            + orgs.get(i) + ") from " + orgs.size() + " orgs :"
1272:                            + orgs);
1273:
1274:                return (Organization) orgs.get(i);
1275:            }
1276:
1277:            private Location findLocationAtTime(Organization org, long time) {
1278:                LocationSchedulePG locPG = org.getLocationSchedulePG();
1279:                if (locPG == null) {
1280:                    MilitaryOrgPG moPG = org.getMilitaryOrgPG();
1281:                    return moPG.getHomeLocation();
1282:                }
1283:
1284:                Schedule sched = locPG.getSchedule();
1285:                Collection schedElements = sched
1286:                        .getScheduleElementsWithTime(time);
1287:                LocationScheduleElement lse = (LocationScheduleElement) schedElements
1288:                        .iterator().next();
1289:                return lse.getLocation();
1290:            }
1291:
1292:            public GLMPrepPhrase getPrepHelper() {
1293:                return glmPrepHelper;
1294:            }
1295:
1296:            public AssetUtil getAssetHelper() {
1297:                return glmAssetHelper;
1298:            }
1299:
1300:            public UTILExpand getExpandHelper() {
1301:                return expandHelper;
1302:            }
1303:
1304:            public UTILPreference getPrefHelper() {
1305:                return prefHelper;
1306:            }
1307:
1308:            public UTILAllocate getAllocHelper() {
1309:                return allocHelper;
1310:            }
1311:
1312:            public Logger getLogger() {
1313:                return logger;
1314:            }
1315:
1316:            public Locator getLocator() {
1317:                return locator;
1318:            }
1319:
1320:            protected GLMOrganizationCallback myOrgCallback;
1321:
1322:            protected Map roleToOrg = new HashMap();
1323:            protected Locator locator;
1324:
1325:            protected long bestDateBackoff;
1326:            boolean shouldRefreshOrgList = false;
1327:            private Random r = new Random();
1328:
1329:            protected transient GLMPrepPhrase glmPrepHelper;
1330:            protected transient AssetUtil glmAssetHelper;
1331:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.