Source Code Cross Referenced for VishnuAggregatorPlugin.java in  » Science » Cougaar12_4 » org » cougaar » lib » vishnu » client » 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.lib.vishnu.client 
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.lib.vishnu.client;
0027:
0028:        import org.cougaar.core.util.UID;
0029:        import org.cougaar.lib.callback.UTILAggregationCallback;
0030:        import org.cougaar.lib.callback.UTILExpansionCallback;
0031:        import org.cougaar.lib.callback.UTILExpansionListener;
0032:        import org.cougaar.lib.callback.UTILFilterCallback;
0033:        import org.cougaar.lib.callback.UTILFilterCallbackAdapter;
0034:        import org.cougaar.lib.callback.UTILGenericListener;
0035:        import org.cougaar.lib.callback.UTILWorkflowCallback;
0036:        import org.cougaar.lib.filter.UTILAggregatorPlugin;
0037:        import org.cougaar.lib.util.UTILPluginException;
0038:        import org.cougaar.lib.util.UTILRuntimeException;
0039:        import org.cougaar.planning.Constants;
0040:        import org.cougaar.planning.ldm.asset.Asset;
0041:        import org.cougaar.planning.ldm.asset.AssetGroup;
0042:        import org.cougaar.planning.ldm.asset.NewItemIdentificationPG;
0043:        import org.cougaar.planning.ldm.plan.Aggregation;
0044:        import org.cougaar.planning.ldm.plan.AllocationResult;
0045:        import org.cougaar.planning.ldm.plan.AspectScorePoint;
0046:        import org.cougaar.planning.ldm.plan.AspectType;
0047:        import org.cougaar.planning.ldm.plan.AspectValue;
0048:        import org.cougaar.planning.ldm.plan.Composition;
0049:        import org.cougaar.planning.ldm.plan.Expansion;
0050:        import org.cougaar.planning.ldm.plan.MPTask;
0051:        import org.cougaar.planning.ldm.plan.NewComposition;
0052:        import org.cougaar.planning.ldm.plan.NewMPTask;
0053:        import org.cougaar.planning.ldm.plan.NewTask;
0054:        import org.cougaar.planning.ldm.plan.PlanElement;
0055:        import org.cougaar.planning.ldm.plan.Preference;
0056:        import org.cougaar.planning.ldm.plan.ScoringFunction;
0057:        import org.cougaar.planning.ldm.plan.Task;
0058:        import org.cougaar.planning.ldm.plan.Verb;
0059:        import org.cougaar.planning.ldm.plan.Workflow;
0060:        import org.cougaar.util.UnaryPredicate;
0061:
0062:        import java.util.Collection;
0063:        import java.util.Collections;
0064:        import java.util.Date;
0065:        import java.util.Enumeration;
0066:        import java.util.HashMap;
0067:        import java.util.HashSet;
0068:        import java.util.Iterator;
0069:        import java.util.List;
0070:        import java.util.Map;
0071:        import java.util.Set;
0072:        import java.util.Vector;
0073:
0074:        /**
0075:         * Aggregator version of ALP-Vishnu Bridge.
0076:         *                                                                          <p>
0077:         * The key thing to note is that the asset in the task->asset               <br> 
0078:         * association is on the WITH preposition of the generated MPTask.
0079:         *                                                                          <p>
0080:         * This is critical, because the allocator downstream will look for this    <br>
0081:         * prep and pluck the asset off to make the allocation.                      
0082:         *                                                                          <p>
0083:         * Uses the assigned start and end times to set the preferences and         <br>
0084:         * allocation results.
0085:         *                                                                          <p>
0086:         * Adjust preferences so that the start time preference is the assigned     <br>
0087:         * start time, and the end time preference has a best date that is the      <br>
0088:         * assigned end time.  The early and late dates of the end time preference  <br>
0089:         * are the same as the first parent task. (This isn't very important, as the<br>
0090:         * downstream allocator should just allocate to the start and best times.)
0091:         *                                                                          <p>
0092:         * Many times subclasses will want to redefine                              <br>
0093:         * <code>interestingTask</code> and <code>interestingAsset</code> to filter <br>
0094:         * what goes to the Vishnu scheduler.  If you do, it's good form to call    <br>
0095:         * super.interestingTask().
0096:         *                                                                          <p>
0097:         * @see org.cougaar.lib.vishnu.client.VishnuPlugin#interestingAsset
0098:         * <!--
0099:         * (When printed, any longer line will wrap...)
0100:         *345678901234567890123456789012345678901234567890123456789012345678901234567890
0101:         *       1         2         3         4         5         6         7         8
0102:         * -->
0103:         */
0104:        public class VishnuAggregatorPlugin extends VishnuPlugin implements 
0105:                UTILAggregatorPlugin, UTILExpansionListener {
0106:            // see explanation below for bug #11866
0107:            protected Map tripletToTask = new HashMap();
0108:            protected Map taskToTriplet = new HashMap();
0109:            // avoids blackboard query
0110:            protected Map uidToMPTask = new HashMap();
0111:            protected UTILFilterCallback mpTaskCallback;
0112:
0113:            boolean propagateRescindPastAggregation;
0114:
0115:            /** creates an XMLResultHandler specially for this plugin */
0116:            protected XMLResultHandler createXMLResultHandler() {
0117:                return new AggregateXMLResultHandler(this , comm, xmlProcessor,
0118:                        domUtil, config, getMyParams(), logger);
0119:            }
0120:
0121:            public void localSetup() {
0122:                super .localSetup();
0123:
0124:                try {
0125:                    if (getMyParams().hasParam(
0126:                            "propagateRescindPastAggregation"))
0127:                        propagateRescindPastAggregation = getMyParams()
0128:                                .getBooleanParam(
0129:                                        "propagateRescindPastAggregation");
0130:                    else
0131:                        propagateRescindPastAggregation = true;
0132:                } catch (Exception e) {
0133:                }
0134:            }
0135:
0136:            /**
0137:             * adds the aggregation filter and two map filters 
0138:             *
0139:             * - one filter looks for MPTasks and keeps track of a map of uid->MPTask,
0140:             * which is used when we need to add new parent tasks to an existing MPTask.
0141:             *
0142:             * - one filter looks for subtasks of the MPTask and updates the triplet->task
0143:             * and task->triplet maps when tasks are removed.  These are also used
0144:             * when we need to add new parent tasks to an existing MPTask and its subtasks.
0145:             *
0146:             * @see #forgetTripletToTask
0147:             */
0148:            public void setupFilters() {
0149:                super .setupFilters();
0150:
0151:                if (isInfoEnabled()) {
0152:                    info(getName() + " : Filtering for Aggregations...");
0153:                }
0154:
0155:                addFilter(myAggCallback = createAggCallback());
0156:
0157:                if (isInfoEnabled()) {
0158:                    info(getName() + " : Filtering for Expansions...");
0159:                }
0160:
0161:                addFilter(new UTILExpansionCallback(this , logger));
0162:
0163:                addFilter(mpTaskCallback = new UTILFilterCallbackAdapter(this ,
0164:                        logger) {
0165:                    protected UnaryPredicate getPredicate() {
0166:                        return new UnaryPredicate() {
0167:                            public boolean execute(Object o) {
0168:                                return (o instanceof  MPTask);
0169:                            }
0170:                        };
0171:                    }
0172:
0173:                    public void reactToChangedFilter() {
0174:                        Enumeration addedtasks = getSubscription()
0175:                                .getAddedList();
0176:                        while (addedtasks.hasMoreElements()) {
0177:                            Task t = (Task) addedtasks.nextElement();
0178:
0179:                            if (!(t instanceof  MPTask))
0180:                                error("huh? " + t + " is not an MPTask??");
0181:
0182:                            if (isInfoEnabled()) {
0183:                                info("uidToMPTask - mapping mptask "
0184:                                        + t.getUID());
0185:                            }
0186:
0187:                            uidToMPTask.put(t.getUID(), t);
0188:                        }
0189:
0190:                        if (getSubscription().getRemovedList()
0191:                                .hasMoreElements()) {
0192:                            Enumeration removedtasks = getSubscription()
0193:                                    .getRemovedList();
0194:                            while (removedtasks.hasMoreElements()) {
0195:                                MPTask mpt = (MPTask) removedtasks
0196:                                        .nextElement();
0197:
0198:                                if (uidToMPTask.remove(mpt.getUID()) == null) {
0199:                                    if (isDebugEnabled()) {
0200:                                        debug("no mp task in map with uid "
0201:                                                + mpt.getUID());
0202:                                    }
0203:                                } else {
0204:                                    if (isInfoEnabled()) {
0205:                                        info("uidToMPTask - removing mp task uid "
0206:                                                + mpt.getUID() + " from map");
0207:                                    }
0208:                                    // OK somehow there's a race where we can add a parent to an MPTask
0209:                                    // and then immediately after the MPTask is removed, WITHOUT the Aggregation being
0210:                                    // removed.  How this is possible, I don't completely understand...
0211:                                    Collection parentsToReplan = new HashSet();
0212:
0213:                                    for (Enumeration en = ((MPTask) mpt)
0214:                                            .getParentTasks(); en
0215:                                            .hasMoreElements();) {
0216:                                        Task parent = (Task) en.nextElement();
0217:                                        if (parent.getPlanElement() != null) {
0218:                                            if (isInfoEnabled()) {
0219:                                                info("uidToMPTask - from MPTask parent enumeration - removing plan element from parent "
0220:                                                        + parent.getUID());
0221:                                            }
0222:                                            parentsToReplan.add(parent);
0223:                                        }
0224:                                    }
0225:
0226:                                    for (Iterator iter = mpt.getComposition()
0227:                                            .getParentTasks().iterator(); iter
0228:                                            .hasNext();) {
0229:                                        Task parent = (Task) iter.next();
0230:                                        if (parent.getPlanElement() != null) {
0231:                                            if (isInfoEnabled()) {
0232:                                                info("uidToMPTask - from composition parent tasks - removing plan element from parent "
0233:                                                        + parent.getUID());
0234:                                            }
0235:                                            parentsToReplan.add(parent);
0236:                                        }
0237:                                    }
0238:
0239:                                    for (Iterator iter = parentsToReplan
0240:                                            .iterator(); iter.hasNext();) {
0241:                                        Task parent = (Task) iter.next();
0242:                                        publishRemove(parent.getPlanElement());
0243:                                        publishChange(parent);
0244:                                    }
0245:
0246:                                    if (!parentsToReplan.isEmpty()) {
0247:                                        // remember to tell scheduler to forget about them too!
0248:                                        handleRemovedTasks(Collections
0249:                                                .enumeration(parentsToReplan));
0250:                                    }
0251:                                }
0252:                            }
0253:                        }
0254:                    }
0255:                });
0256:
0257:                addFilter(new UTILFilterCallbackAdapter(this , logger) {
0258:                    protected UnaryPredicate getPredicate() {
0259:                        return new UnaryPredicate() {
0260:                            public boolean execute(Object o) {
0261:                                if (!(o instanceof  Task))
0262:                                    return false;
0263:                                Task task = (Task) o;
0264:                                PlanElement pe = task.getPlanElement();
0265:                                boolean hasPE = (pe != null);
0266:                                if (hasPE && pe instanceof  Aggregation)
0267:                                    return false;
0268:                                if (o instanceof  MPTask)
0269:                                    return false;
0270:                                else
0271:                                    // non-MPTasks that don't have aggregations
0272:                                    return true;
0273:                            }
0274:                        };
0275:                    }
0276:
0277:                    public void reactToChangedFilter() {
0278:                        if (getSubscription().getRemovedList()
0279:                                .hasMoreElements()) {
0280:                            Enumeration removedtasks = getSubscription()
0281:                                    .getRemovedList();
0282:                            while (removedtasks.hasMoreElements()) {
0283:                                Task removed = (Task) removedtasks
0284:                                        .nextElement();
0285:
0286:                                if (!forgetTripletToTask(removed)) {
0287:                                    if (isInfoEnabled()) {
0288:                                        info("no task in map with uid "
0289:                                                + removed.getUID());
0290:                                    }
0291:                                } else if (isInfoEnabled()) {
0292:                                    info("removing task uid "
0293:                                            + removed.getUID() + " from maps");
0294:                                }
0295:                            }
0296:                        }
0297:                    }
0298:                });
0299:            }
0300:
0301:            /*** Callback for input tasks ***/
0302:            protected UTILWorkflowCallback myWorkflowCallback;
0303:
0304:            /**
0305:             * Callback for input tasks 
0306:             *
0307:             * Creates an instance of the WorkflowCallback, which means the plugin
0308:             * is looking for tasks that are part of workflows.
0309:             *
0310:             * @param bufferingThread -- the thread the callback informs when there are new input tasks
0311:             * @return UTILFilterCallback -- an instance of UTILWorkflowCallback
0312:             **/
0313:            protected UTILFilterCallback createThreadCallback(
0314:                    UTILGenericListener bufferingThread) {
0315:                if (isInfoEnabled()) {
0316:                    info(getName() + " Filtering for tasks with Workflows...");
0317:                }
0318:
0319:                myWorkflowCallback = new UTILWorkflowCallback(bufferingThread,
0320:                        logger);
0321:
0322:                return myWorkflowCallback;
0323:            }
0324:
0325:            /** Callback for input tasks ***/
0326:            protected UTILFilterCallback getWorkflowCallback() {
0327:                return myWorkflowCallback;
0328:            }
0329:
0330:            /*** Callback for Aggregations ***/
0331:            /** Callback for Aggregations **/
0332:            protected UTILAggregationCallback myAggCallback;
0333:
0334:            /** Callback for Aggregations **/
0335:            protected UTILAggregationCallback getAggCallback() {
0336:                return myAggCallback;
0337:            }
0338:
0339:            /** Callback for Aggregations **/
0340:            protected UTILAggregationCallback createAggCallback() {
0341:                return new UTILAggregationCallback(this , logger);
0342:            }
0343:
0344:            /*** Stuff for AggregationListener ***/
0345:
0346:            /**
0347:             * Should almost always call interestingTask. 
0348:             **/
0349:            public boolean interestingParentTask(Task t) {
0350:                boolean isInteresting = interestingTask(t);
0351:
0352:                if (!isInteresting
0353:                        && ((t.getPlanElement().getReportedResult() != null) && !t
0354:                                .getPlanElement().getReportedResult()
0355:                                .isSuccess())) {
0356:                    debug(getName()
0357:                            + ".interestingParentTask - ignoring failed task : "
0358:                            + t.getUID());
0359:                }
0360:
0361:                return isInteresting;
0362:            }
0363:
0364:            /** implemented for AggregationListener */
0365:            public boolean needToRescind(Aggregation agg) {
0366:                return false;
0367:            }
0368:
0369:            /** implemented for AggregationListener */
0370:            public void reportChangedAggregation(Aggregation agg) {
0371:                updateAllocationResult(agg);
0372:            }
0373:
0374:            /** implemented for AggregationListener */
0375:            public void handleSuccessfulAggregation(Aggregation agg) {
0376:                if (agg.getEstimatedResult().getConfidenceRating() > allocHelper.MEDIUM_CONFIDENCE) {
0377:                    // don't do anything
0378:                } else if (isDebugEnabled()) {
0379:                    debug(getName()
0380:                            + ".handleSuccessfulAggregation : got changed agg ("
0381:                            + agg.getUID() + ") with intermediate confidence.");
0382:                }
0383:            }
0384:
0385:            /**
0386:             * implemented for AggregationListener 
0387:             *
0388:             * Cleans up maps of triplets to tasks, task to mptasks
0389:             */
0390:            public void handleRemovedAggregation(Aggregation agg) {
0391:                Vector removedTasks = new Vector();
0392:                removedTasks.add(agg.getTask());
0393:
0394:                handleRemovedTasks(removedTasks.elements());
0395:
0396:                MPTask mpTask = agg.getComposition().getCombinedTask();
0397:                if (mpTask == null)
0398:                    error("no mp task on aggregation of "
0399:                            + agg.getTask().getUID());
0400:                else {
0401:                    AssetGroup newGroup = removeFromDirectObject(agg.getTask(),
0402:                            mpTask);
0403:                    Expansion exp = (Expansion) mpTask.getPlanElement();
0404:                    if (exp == null) {
0405:                        warn("no expansion of mp task " + mpTask.getUID()
0406:                                + " must be in the middle of rescinds...");
0407:                    } else {
0408:                        Enumeration en = exp.getWorkflow().getTasks();
0409:                        while (en.hasMoreElements()) {
0410:                            Task subtask = (Task) en.nextElement();
0411:
0412:                            Vector newSet = new Vector();
0413:                            newSet.addAll(newGroup.getAssets());
0414:                            AssetGroup newAssetGroup = assetHelper
0415:                                    .makeAssetGroup(getLDMService().getLDM()
0416:                                            .getFactory(), newSet);
0417:                            ((NewItemIdentificationPG) newAssetGroup
0418:                                    .getItemIdentificationPG())
0419:                                    .setItemIdentification("group_for_subtask_of_"
0420:                                            + mpTask.getUID()
0421:                                            + "_with_"
0422:                                            + newSet.size() + "_members");
0423:                            ((NewTask) subtask).setDirectObject(newAssetGroup);
0424:
0425:                            publishChange(subtask); // tell persistence these have changed too!
0426:                        }
0427:
0428:                        // post condition check
0429:                        if (isInfoEnabled()) {
0430:                            checkMPTaskDO(mpTask);
0431:                        }
0432:                    }
0433:                }
0434:            }
0435:
0436:            /** implemented for AggregationListener */
0437:            public boolean handleRescindedAggregation(Aggregation agg) {
0438:                return false;
0439:            }
0440:
0441:            /** implemented for AggregationListener */
0442:            public void publishRemovalOfAggregation(Aggregation aggToRemove) {
0443:                Task changedTask = aggToRemove.getTask();
0444:                publishRemove(aggToRemove);
0445:                publishChange(changedTask);
0446:            }
0447:
0448:            /**
0449:             * Implemented for ExpansionListener 
0450:             *
0451:             * Interested in expansions created by this plugin, labeled with a VISHNU prep.
0452:             * (That's how it knows which to be interested in.)
0453:             */
0454:            public boolean interestingExpandedTask(Task t) {
0455:                Expansion exp = (Expansion) t.getPlanElement();
0456:                if (exp == null)
0457:                    return false;
0458:
0459:                Workflow wf = exp.getWorkflow();
0460:
0461:                Enumeration en = wf.getTasks();
0462:
0463:                Object firstTask = null;
0464:
0465:                if (en.hasMoreElements())
0466:                    firstTask = en.nextElement();
0467:                if (firstTask != null)
0468:                    return prepHelper.hasPrepNamed((Task) firstTask, "VISHNU");
0469:                else
0470:                    return false;
0471:            }
0472:
0473:            public boolean wantToChangeExpansion(Expansion exp) {
0474:                return false;
0475:            }
0476:
0477:            public void changeExpansion(Expansion exp) {
0478:            }
0479:
0480:            public void publishChangedExpansion(Expansion exp) {
0481:                publishChange(exp);
0482:            }
0483:
0484:            public void handleConstraintViolation(Expansion exp,
0485:                    List violatedConstraints) {
0486:            }
0487:
0488:            public void handleFailedExpansion(Expansion exp, List failedSubTasks) {
0489:                reportChangedExpansion(exp);
0490:            }
0491:
0492:            public void handleSuccessfulExpansion(Expansion exp,
0493:                    List successfulSubtasks) {
0494:            }
0495:
0496:            /**
0497:             * Implemented for ExpansionListener
0498:             * Report to superior that the expansion has changed. Usually just a pass
0499:             * through to the UTILPluginAdapter's updateAllocationResult.
0500:             *
0501:             * @param exp Expansion that has changed.
0502:             * @see org.cougaar.lib.callback.UTILExpansionListener
0503:             */
0504:            public void reportChangedExpansion(Expansion exp) {
0505:                if (logger.isDebugEnabled()
0506:                        || (exp.getReportedResult() != null && !exp
0507:                                .getReportedResult().isSuccess()))
0508:                    debug(getName()
0509:                            + ".reportChangedExpansion : reporting "
0510:                            + (exp.getReportedResult().isSuccess() ? ""
0511:                                    : " - FAILED - ") + " changed expansion "
0512:                            + exp.getUID() + " of " + exp.getTask().getUID()
0513:                            + " to superior.");
0514:
0515:                updateAllocationResult(exp);
0516:            }
0517:
0518:            public void handleIllFormedTask(Task t) {
0519:                reportIllFormedTask(t);
0520:            }
0521:
0522:            /**
0523:             * define in subclass -- create an aggregation
0524:             *
0525:             * The parameters are what got returned from the vishnu scheduler.
0526:             *
0527:             * @param tasks  tasks to be aggregated together and assigned to asset
0528:             * @param asset asset handling task
0529:             * @param start of main task
0530:             * @param end   of main task
0531:             * @param setupStart start of setup task
0532:             * @param wrapupEnd end of wrapup task
0533:             */
0534:            public void handleMultiAssignment(Vector tasks, Asset asset,
0535:                    Date start, Date end, Date setupStart, Date wrapupEnd,
0536:                    boolean assetWasUsedBefore) {
0537:                if (isDebugEnabled()) {
0538:                    debug(getName() + ".handleMultiAssignment : ");
0539:                    debug("\nAssigned tasks : ");
0540:                    for (int i = 0; i < tasks.size(); i++) {
0541:                        Task task = (Task) tasks.get(i);
0542:
0543:                        Date ready = prefHelper.getReadyAt(task);
0544:                        Date early = prefHelper.getEarlyDate(task);
0545:                        Date late = prefHelper.getLateDate(task);
0546:
0547:                        if (start.before(ready) || end.before(early)
0548:                                || end.after(late))
0549:                            warn(""
0550:                                    + task.getUID()
0551:                                    + " - ready "
0552:                                    + ready
0553:                                    + (start.before(ready) ? (" AFTER start " + start)
0554:                                            : "")
0555:                                    + " early "
0556:                                    + early
0557:                                    + (end.before(early) ? (" AFTER end " + end)
0558:                                            : "")
0559:                                    + " best "
0560:                                    + prefHelper.getBestDate(task)
0561:                                    + " late "
0562:                                    + late
0563:                                    + (end.after(late) ? (" BEFORE end " + end)
0564:                                            : ""));
0565:                        else
0566:                            debug(""
0567:                                    + task.getUID()
0568:                                    + " - ready "
0569:                                    + ready
0570:                                    + (start.before(ready) ? (" AFTER start " + start)
0571:                                            : "")
0572:                                    + " early "
0573:                                    + early
0574:                                    + (end.before(early) ? (" AFTER end " + end)
0575:                                            : "")
0576:                                    + " best "
0577:                                    + prefHelper.getBestDate(task)
0578:                                    + " late "
0579:                                    + late
0580:                                    + (end.after(late) ? (" BEFORE end " + end)
0581:                                            : ""));
0582:                    }
0583:                    debug("\nresource = " + asset + "\nsetup    = "
0584:                            + setupStart + "\nstart    = " + start
0585:                            + "\nend      = " + end + "\nwrapup   = "
0586:                            + wrapupEnd);
0587:                }
0588:
0589:                makePlanElement(tasks, asset, start, end, setupStart,
0590:                        wrapupEnd, assetWasUsedBefore);
0591:            }
0592:
0593:            /**
0594:             * <pre>
0595:             * Background : the missions for a conveyance (ship, plane, truck)
0596:             * are represented by MPTasks which assign an asset group of items
0597:             * to a conveyance for a certain period of time.  We want to prevent
0598:             * the case where multiple MPTasks together represent one actual
0599:             * mission, i.e. they are for the same conveyance and the same period 
0600:             * of time.  It's better for memory footprint, simplicity, and the
0601:             * asset usage display in the TPFDD Viewer.
0602:             * See bug #11866 : https://bugs.ultralog.net/show_bug.cgi?id=11866
0603:             *
0604:             * Makes an aggregation given a list of assignments.
0605:             *
0606:             * Makes an aggregation with a medium confidence and publishes it.  
0607:             * Also makes an expansion of the MPTask.  This may be a 1-to-1,
0608:             * 1-to-2, or 1-to-3 expansion depending on the dates.  If the
0609:             * setup start is before the task start, then a separate setup task
0610:             * is created and added to the expansion.  Similarly for wrapup.
0611:             * These dates are different if the vishnu scheduling specs define
0612:             * setup (e.g. fueling an airplane) or wrapup (e.g. servicing an airplane)
0613:             * durations.  See referenced Vishnu documentation for details on specs.
0614:             *
0615:             * Calls the base class function makeSetupWrapupExpansion.
0616:             *
0617:             * Adds to a previously created MPTask when new tasks are assigned to an
0618:             * asset.
0619:             *
0620:             * </pre>
0621:             * @param tasklist - tasks for this asset
0622:             * @param anAsset that these tasks are grouped for
0623:             * @param start time start
0624:             * @param end time end
0625:             * @param setupStart setup start
0626:             * @param wrapupEnd wrapup end
0627:             * @see org.cougaar.planning.ldm.plan.Aggregation
0628:             * @see org.cougaar.planning.ldm.plan.MPTask
0629:             * @see org.cougaar.lib.vishnu.client.VishnuPlugin#makeSetupWrapupExpansion
0630:             * @see <a href="http://www.cougaar.org/projects/vishnu/fulldoc.html#specs">
0631:             * Click here for more on setup and wrapup specifications.</a>
0632:             * @see #addToPrevious
0633:             */
0634:            public void makePlanElement(Vector tasklist, Asset anAsset,
0635:                    Date start, Date end, Date setupStart, Date wrapupEnd,
0636:                    boolean assetWasUsedBefore) {
0637:                if (assetWasUsedBefore) {
0638:                    if (addToPrevious(tasklist, anAsset, start, end,
0639:                            setupStart, wrapupEnd))
0640:                        return;
0641:                    else {
0642:                        if (isInfoEnabled()) {
0643:                            info("Though we believe "
0644:                                    + anAsset
0645:                                    + " was used before at "
0646:                                    + start
0647:                                    + " we could not find the previous task, so making a new one.");
0648:                        }
0649:                    }
0650:                }
0651:
0652:                List aggResults = aggregateHelper.makeAggregation(this , ldmf,
0653:                        realityPlan, tasklist, getVerbForAgg(tasklist),
0654:                        getPrepPhrasesForAgg(anAsset, tasklist),
0655:                        getDirectObjectsForAgg(tasklist), getPreferencesForAgg(
0656:                                anAsset, tasklist, start, end),
0657:                        getAgentIdentifier(), getAspectValuesMap(tasklist,
0658:                                start, end), allocHelper.MEDIUM_CONFIDENCE);
0659:                publishList(aggResults);
0660:
0661:                cleanupAggregation(anAsset, tasklist, aggResults);
0662:
0663:                Task mpTask = findMPTask(aggResults);
0664:
0665:                if (uidToMPTask.get(mpTask.getUID()) == null) {
0666:                    if (isInfoEnabled()) {
0667:                        info("uidToMPTask - mapping mptask " + mpTask.getUID());
0668:                    }
0669:                    uidToMPTask.put(mpTask.getUID(), mpTask);
0670:
0671:                    if (isInfoEnabled()) {
0672:                        int numParents = 0;
0673:                        for (Enumeration en = ((MPTask) mpTask)
0674:                                .getParentTasks(); en.hasMoreElements();) {
0675:                            Task parent = (Task) en.nextElement();
0676:                            numParents++;
0677:                        }
0678:                        info(getName() + ".addToPrevious - MPTask "
0679:                                + mpTask.getUID() + " has " + numParents
0680:                                + " parents.");
0681:                    }
0682:                }
0683:
0684:                // store each distinct assignment so we can get it later in addToPrevious
0685:                //
0686:                // Bug #11866:
0687:                //
0688:                // The problem (https://bugs.ultralog.net/show_bug.cgi?id=11866) is that
0689:                // addToPrevious initially looks on the role schedule for mptasks assigned to an asset.  
0690:                // BUT the allocator plugin has to get a chance to run to update the role schedule.  So
0691:                // it may seem like no previous task has been assigned, if you just look at the role schedule,
0692:                // even though the assignment has been made (an MPTask created) but not yet reflected in
0693:                // the role schedule via an allocation.  This results in multiple MPTasks being made for the same
0694:                // mission - the same conveyance and for the same period of time.  
0695:                //
0696:                // We need to remember the assignment locally through a map to avoid this problem.
0697:
0698:                if (assetWasUsedBefore) {
0699:                    if (isInfoEnabled()) {
0700:                        info("asset was used before, but made a new mptask : "
0701:                                + mpTask.getUID());
0702:                    }
0703:                }
0704:
0705:                Collection subtasks = makeSetupWrapupExpansion(mpTask, anAsset,
0706:                        start, end, setupStart, wrapupEnd);
0707:
0708:                for (Iterator iter = subtasks.iterator(); iter.hasNext();) {
0709:                    Task subtask = (Task) iter.next();
0710:                    String taskKey = anAsset.getUID().toString() + "-"
0711:                            + prefHelper.getReadyAt(subtask).getTime() + "-"
0712:                            + prefHelper.getBestDate(subtask).getTime();
0713:
0714:                    Task alreadyTask;
0715:                    if ((alreadyTask = (Task) tripletToTask.get(taskKey)) == null) {
0716:                        if (isInfoEnabled()) {
0717:                            info(getName() + " mapping " + taskKey + " to "
0718:                                    + subtask.getUID() + " mptask "
0719:                                    + mpTask.getUID());
0720:                        }
0721:                    } else {
0722:                        if (isWarnEnabled()) {
0723:                            warn(getName()
0724:                                    + " - unexpected : there already is a task "
0725:                                    + subtask.getUID() + " in table with key "
0726:                                    + taskKey + " it was "
0727:                                    + alreadyTask.getUID());
0728:                        }
0729:                    }
0730:
0731:                    rememberTripletToTask(taskKey, subtask);
0732:                }
0733:            }
0734:
0735:            /**
0736:             * Fixes up the following when additional tasks are added to a previous
0737:             * assignment:
0738:             *  1) Adds to the d.o. of the transport task allocated to the asset
0739:             *  2) (Optional) If setup task,  adds to the d.o. of the task
0740:             *  3) (Optional) If wrapup task, adds to the d.o. of the task
0741:             *  4) Adds to the d.o. of the mp task
0742:             *  5) Makes Mp task parent task list reflect new parent tasks
0743:             *  6) Makes aggregations connecting parent tasks to mp task
0744:             *
0745:             * @param tasklist - tasks for this asset
0746:             * @param anAsset that these tasks are grouped for/assigned to
0747:             * @param start time start
0748:             * @param end time end
0749:             * @param setupStart setup start
0750:             * @param wrapupEnd wrapup end
0751:             */
0752:            public boolean addToPrevious(Vector tasklist, Asset anAsset,
0753:                    Date start, Date end, Date setupStart, Date wrapupEnd) {
0754:                // see explanation for bug #11866 above
0755:                Task previousTask;
0756:                String taskKey = anAsset.getUID().toString() + "-"
0757:                        + start.getTime() + "-" + end.getTime();
0758:                previousTask = (Task) tripletToTask.get(taskKey);
0759:
0760:                if (previousTask == null) {
0761:                    if (isInfoEnabled()) {
0762:                        info(getName() + " - couldn't find task with key "
0763:                                + taskKey + " so looking in role schedule of "
0764:                                + anAsset.getUID());
0765:                    }
0766:                    previousTask = getEncapsulatedTask(anAsset, start, end); // look on asset's role schedule
0767:                    if (previousTask != null) {
0768:                        rememberTripletToTask(taskKey, previousTask);
0769:                    }
0770:                }
0771:
0772:                if (previousTask != null) { // found transport task
0773:                    if (isDebugEnabled())
0774:                        debug(getName()
0775:                                + ".addToPrevious - found previous task for asset "
0776:                                + anAsset.getUID());
0777:
0778:                    Vector directObjects = getDirectObjectsForAgg(tasklist);
0779:                    // step 1 - add to d.o. of transport task
0780:                    AssetGroup directObject = addToDirectObject(previousTask,
0781:                            directObjects);
0782:                    if (makeSetupAndWrapupTasks) {
0783:                        if (setupStart.getTime() < start.getTime()) {
0784:                            // step 2 - add to d.o. of setup
0785:                            Vector newSet = new Vector();
0786:                            Vector assetsInGroup = directObject.getAssets();
0787:                            newSet.addAll(assetsInGroup);
0788:                            AssetGroup newAssetGroup = assetHelper
0789:                                    .makeAssetGroup(getLDMService().getLDM()
0790:                                            .getFactory(), newSet);
0791:                            ((NewItemIdentificationPG) newAssetGroup
0792:                                    .getItemIdentificationPG())
0793:                                    .setItemIdentification("setup_group_with_"
0794:                                            + newSet.size() + "_members");
0795:
0796:                            addToPreviousSetupWrapup(anAsset, newAssetGroup,
0797:                                    setupStart, start, "setup");
0798:                        }
0799:                        if (wrapupEnd.getTime() > end.getTime()) {
0800:                            // step 3 - add to d.o. of wrapup
0801:                            Vector newSet = new Vector();
0802:                            Vector assetsInGroup = directObject.getAssets();
0803:                            newSet.addAll(assetsInGroup);
0804:                            AssetGroup newAssetGroup = assetHelper
0805:                                    .makeAssetGroup(getLDMService().getLDM()
0806:                                            .getFactory(), newSet);
0807:                            ((NewItemIdentificationPG) newAssetGroup
0808:                                    .getItemIdentificationPG())
0809:                                    .setItemIdentification("wrapup_group_with_"
0810:                                            + newSet.size() + "_members");
0811:
0812:                            addToPreviousSetupWrapup(anAsset, newAssetGroup,
0813:                                    end, wrapupEnd, "wrapup");
0814:                        }
0815:                    }
0816:
0817:                    if (isInfoEnabled()) {
0818:                        info(getName() + " - looking task "
0819:                                + previousTask.getUID()
0820:                                + "'s mptask parent uid "
0821:                                + previousTask.getParentTaskUID());
0822:                    }
0823:
0824:                    MPTask mpTask = (MPTask) uidToMPTask.get(previousTask
0825:                            .getParentTaskUID());
0826:                    if (mpTask == null) { // should only happen after rehydration
0827:                        if (isInfoEnabled()) {
0828:                            info(getName()
0829:                                    + " - looking for mptask parent of "
0830:                                    + previousTask.getUID()
0831:                                    + " on blackboard via expensive query, since parent uid "
0832:                                    + previousTask.getParentTaskUID()
0833:                                    + " is not in " + uidToMPTask.keySet());
0834:                        }
0835:                        // do expensive blackboard query
0836:                        mpTask = getMPTask(previousTask.getParentTaskUID());
0837:                    }
0838:
0839:                    if (mpTask == null) {
0840:                        if (isInfoEnabled()) {
0841:                            info("Can't find mptask "
0842:                                    + previousTask.getParentTaskUID()
0843:                                    + " parent of " + previousTask.getUID()
0844:                                    + " on blackboard. Must have been removed.");
0845:                        }
0846:
0847:                        return false; // the MP task was removed from the blackboard while scheduler was running
0848:                    }
0849:
0850:                    // step 4 - add to d.o. of MPTask parent
0851:                    Vector newSet = new Vector();
0852:                    Vector assetsInGroup = directObject.getAssets();
0853:                    newSet.addAll(assetsInGroup);
0854:                    AssetGroup newAssetGroup = assetHelper.makeAssetGroup(
0855:                            getLDMService().getLDM().getFactory(), newSet);
0856:                    ((NewItemIdentificationPG) newAssetGroup
0857:                            .getItemIdentificationPG())
0858:                            .setItemIdentification("mpt_transport_group_with_"
0859:                                    + newSet.size() + "_members");
0860:
0861:                    ((NewMPTask) mpTask).setDirectObject(newAssetGroup);
0862:
0863:                    // step 5 - Make MP Task know of new parents
0864:                    Enumeration parents = mpTask.getParentTasks();
0865:                    Vector parentsVector = enumToVector(parents);
0866:                    ((NewMPTask) mpTask).setParentTasks(getEnumWithNewParents(
0867:                            parentsVector, tasklist));
0868:                    if (isInfoEnabled()) {
0869:                        info(getName() + " - publish changing "
0870:                                + mpTask.getUID());
0871:                    }
0872:                    publishChange(mpTask);
0873:
0874:                    // step 6 - make aggregations for connecting parent tasks to MPTask
0875:                    NewComposition comp = (NewComposition) mpTask
0876:                            .getComposition();
0877:                    addAggregations(comp, tasklist, start, end);
0878:                    publishChange(comp);
0879:
0880:                    if (isInfoEnabled()) {
0881:                        int numParents = 0;
0882:                        for (Enumeration en = mpTask.getParentTasks(); en
0883:                                .hasMoreElements();) {
0884:                            Task parent = (Task) en.nextElement();
0885:                            numParents++;
0886:                        }
0887:
0888:                        info(getName() + ".addToPrevious - MPTask "
0889:                                + mpTask.getUID() + " has " + numParents
0890:                                + " parents.");
0891:                    }
0892:
0893:                    return true;
0894:                }
0895:                return false;
0896:            }
0897:
0898:            /**
0899:             * Update the directObject of the setup and wrapup tasks when we get new assignments
0900:             * to an existing mission.  publishChanges the task.
0901:             *
0902:             * We need a triplet - the assigned asset and the start and end dates to unique identify
0903:             * a setup or wrapup task.  These come from the anAsset, start, and end parameters.
0904:             *
0905:             * First looks in the tripletToTask map, and if can't find the task there, looks at the 
0906:             * asset's role schedule, which is problematic (the allocator must have run), see above
0907:             * discussion.  The only time the tripletToTask map will be empty will be after rehydration.
0908:             *
0909:             * @param anAsset - first part of the triplet key
0910:             * @param start   - second part of the triplet key
0911:             * @param end     - third part of the triplet key
0912:             * @param directObject contains the additional assets to add to the direct object of the updated 
0913:             * task
0914:             */
0915:            protected void addToPreviousSetupWrapup(Asset anAsset,
0916:                    Asset directObject, Date start, Date end, String info) {
0917:                Task setupTask;
0918:                String taskKey = anAsset.getUID().toString() + "-"
0919:                        + start.getTime() + "-" + end.getTime();
0920:                if (isInfoEnabled()) {
0921:                    info(getName() + " - " + info
0922:                            + " - checking tripletToTask map for " + taskKey);
0923:                }
0924:                setupTask = (Task) tripletToTask.get(taskKey);
0925:
0926:                if (setupTask == null) {
0927:                    if (isInfoEnabled()) {
0928:                        info(getName()
0929:                                + " - setup - nothing in tripletToTask map for "
0930:                                + taskKey + " so checking role schedule.");
0931:                    }
0932:                    setupTask = getEncapsulatedTask(anAsset, start, end);
0933:                    if (setupTask != null)
0934:                        rememberTripletToTask(taskKey, setupTask);
0935:                }
0936:
0937:                if (setupTask == null) { // shouldn't happen
0938:                    if (isWarnEnabled()) {
0939:                        warn(getAgentIdentifier() + " - " + " on " + anAsset
0940:                                + " missing a " + info + " task from " + start
0941:                                + " to " + end + "?");
0942:                    }
0943:                } else {
0944:                    ((NewTask) setupTask).setDirectObject(directObject);
0945:                    if (isInfoEnabled()) {
0946:                        info(getName() + " - publish changing "
0947:                                + setupTask.getUID());
0948:                    }
0949:                    publishChange(setupTask);
0950:                }
0951:            }
0952:
0953:            /**
0954:             * Update both tripletToTask and taskToTriplet maps - add the subtask to them
0955:             * with the asset-start-end triplet key.
0956:             */
0957:            protected void rememberTripletToTask(String taskKey, Task subtask) {
0958:                if (isInfoEnabled())
0959:                    info("remembering " + subtask.getUID() + " key " + taskKey);
0960:
0961:                tripletToTask.put(taskKey, subtask);
0962:                taskToTriplet.put(subtask, taskKey);
0963:            }
0964:
0965:            /**
0966:             * Update both tripletToTask and taskToTriplet maps - remove the subtask from them
0967:             */
0968:            protected boolean forgetTripletToTask(Object subtask) {
0969:                if (isInfoEnabled()) {
0970:                    info("forgetting " + ((Task) subtask).getUID());
0971:                }
0972:
0973:                boolean retval = true;
0974:
0975:                Object triplet = taskToTriplet.remove(subtask);
0976:                if (triplet != null) {
0977:                    if (isInfoEnabled()) {
0978:                        info("forgetting key " + triplet);
0979:                    }
0980:
0981:                    if (tripletToTask.remove(triplet) == null) {
0982:                        retval = false;
0983:                        if (isInfoEnabled()) {
0984:                            info("no task for " + triplet);
0985:                        }
0986:                    }
0987:
0988:                } else {
0989:                    retval = false;
0990:                    if (isInfoEnabled()) {
0991:                        info("no triplet for " + subtask);
0992:                    }
0993:                }
0994:
0995:                return retval;
0996:            }
0997:
0998:            /**
0999:             * Look for a plan element on the role schedule of the asset 
1000:             * that covers exactly the same span of time 
1001:             *
1002:             * @param asset to look at role schedule
1003:             * @param start time of pe on role schedule
1004:             * @param end time of pe on role schedule
1005:             * @return task that is on role schedule of asset from exactly start to end
1006:             */
1007:            protected Task getEncapsulatedTask(Asset asset, Date start, Date end) {
1008:                Collection tasks = asset.getRoleSchedule()
1009:                        .getEncapsulatedRoleSchedule(start.getTime(),
1010:                                end.getTime());
1011:                if (tasks.isEmpty()) {
1012:                    if (isInfoEnabled()) {
1013:                        info("no task on role schedule of " + asset.getUID()
1014:                                + " - " + asset + " between " + start + " and "
1015:                                + end + "\nschedule was "
1016:                                + asset.getRoleSchedule());
1017:                    }
1018:                    return null;
1019:                }
1020:                for (Iterator iter = tasks.iterator(); iter.hasNext();) {
1021:                    PlanElement pe = (PlanElement) iter.next();
1022:                    long startTime = (long) pe.getEstimatedResult().getValue(
1023:                            AspectType.START_TIME);
1024:                    long endTime = (long) pe.getEstimatedResult().getValue(
1025:                            AspectType.END_TIME);
1026:                    if (startTime == start.getTime()
1027:                            && endTime == end.getTime()) {
1028:                        return pe.getTask();
1029:                    } else {
1030:                        if (isInfoEnabled()) {
1031:                            if (startTime == start.getTime()) {
1032:                                info(asset.getUID()
1033:                                        + " - end times are different, pe end "
1034:                                        + new Date(endTime) + " vs assigned "
1035:                                        + new Date(end.getTime()) + " for "
1036:                                        + asset);
1037:                            } else if (endTime == end.getTime()) {
1038:                                info(asset.getUID()
1039:                                        + " - start times are different, pe start "
1040:                                        + new Date(startTime) + " vs assigned "
1041:                                        + new Date(start.getTime()) + " for "
1042:                                        + asset);
1043:                            } else {
1044:                                info(asset.getUID()
1045:                                        + " - both start and end times are different for "
1046:                                        + asset);
1047:                            }
1048:                        }
1049:                    }
1050:                }
1051:                return null;
1052:            }
1053:
1054:            /**
1055:             * Add objects to task's direct object
1056:             *
1057:             * @param task to add the objects to
1058:             * @param objects to add to the task's d.o.
1059:             * @return AssetGroup with objects added to it
1060:             */
1061:            protected AssetGroup addToDirectObject(Task task, Vector objects) {
1062:                AssetGroup group = (AssetGroup) task.getDirectObject();
1063:                Vector assetsInGroup = group.getAssets();
1064:
1065:                Vector newSet = new Vector();
1066:                newSet.addAll(assetsInGroup);
1067:                newSet.addAll(objects);
1068:                AssetGroup newAssetGroup = assetHelper.makeAssetGroup(
1069:                        getLDMService().getLDM().getFactory(), newSet);
1070:
1071:                ((NewTask) task).setDirectObject(newAssetGroup);
1072:                ((NewItemIdentificationPG) newAssetGroup
1073:                        .getItemIdentificationPG())
1074:                        .setItemIdentification("transport_group_with_"
1075:                                + newSet.size() + "_members");
1076:
1077:                if (isInfoEnabled()) {
1078:                    info(getName() + " - publish changing " + task.getUID()
1079:                            + " now has " + newSet.size() + " items in d.o.");
1080:                }
1081:
1082:                publishChange(task);
1083:
1084:                return newAssetGroup;
1085:            }
1086:
1087:            /**
1088:             * Remove the parent task's direct object from the child mpTask's group
1089:             * of direct objects.
1090:             *
1091:             * @param removedTask to task with the direct object to remove
1092:             * @param mpTask to remove the direct object from
1093:             * @return AssetGroup with objects removed from it
1094:             */
1095:            protected AssetGroup removeFromDirectObject(Task removedTask,
1096:                    MPTask mpTask) {
1097:                AssetGroup group = (AssetGroup) mpTask.getDirectObject();
1098:                Vector assetsInGroup = group.getAssets();
1099:                //    assetsInGroup.remove (removedTask.getDirectObject());
1100:                if (isInfoEnabled()) {
1101:                    info(getName() + " - removing " + removedTask.getUID()
1102:                            + "'s direct object "
1103:                            + removedTask.getDirectObject() + " from mptask "
1104:                            + mpTask.getUID() + "'s direct object");
1105:                }
1106:
1107:                Vector newSet = new Vector();
1108:                newSet.addAll(assetsInGroup);
1109:                if (!newSet.remove(removedTask.getDirectObject())) {
1110:                    error(getName() + " removed task " + removedTask.getUID()
1111:                            + "'s d.o. " + removedTask.getDirectObject()
1112:                            + " is not part of mp task d.o. for mp task "
1113:                            + mpTask.getUID());
1114:                }
1115:
1116:                AssetGroup newAssetGroup = assetHelper.makeAssetGroup(
1117:                        getLDMService().getLDM().getFactory(), newSet);
1118:
1119:                ((NewMPTask) mpTask).setDirectObject(newAssetGroup);
1120:
1121:                publishChange(mpTask);
1122:
1123:                return newAssetGroup;
1124:            }
1125:
1126:            /**
1127:             * post-condition check : MPTask d.o. should be the sum of all parents' d.o.s
1128:             * no more, no less
1129:             */
1130:            protected void checkMPTaskDO(MPTask mpTask) {
1131:                Vector mpTaskDOVector = ((AssetGroup) mpTask.getDirectObject())
1132:                        .getAssets();
1133:
1134:                Set parentDirectObjects = new HashSet();
1135:
1136:                int numParents = 0;
1137:                for (Enumeration en = mpTask.getParentTasks(); en
1138:                        .hasMoreElements();) {
1139:                    Task parent = (Task) en.nextElement();
1140:                    parentDirectObjects.add(parent.getDirectObject());
1141:                    numParents++;
1142:                }
1143:
1144:                info(getName() + " - MPTask " + mpTask.getUID() + " has "
1145:                        + numParents + " parents.");
1146:
1147:                Set parentsNotRepresentedInMPTask = new HashSet(
1148:                        parentDirectObjects);
1149:                parentsNotRepresentedInMPTask.removeAll(mpTaskDOVector);
1150:                if (!parentsNotRepresentedInMPTask.isEmpty()) {
1151:                    for (Iterator iter = parentsNotRepresentedInMPTask
1152:                            .iterator(); iter.hasNext();) {
1153:                        info(getName() + " - MPTask " + mpTask.getUID()
1154:                                + " d.o. is missing parent's d.o. "
1155:                                + iter.next());
1156:                    }
1157:                }
1158:
1159:                if (false) { // this has excessive false positives
1160:                    Set excessAssetsInMPTaskDO = new HashSet(mpTaskDOVector);
1161:                    excessAssetsInMPTaskDO.removeAll(parentDirectObjects);
1162:                    if (!excessAssetsInMPTaskDO.isEmpty()) {
1163:                        for (Iterator iter = excessAssetsInMPTaskDO.iterator(); iter
1164:                                .hasNext();) {
1165:                            info(getName()
1166:                                    + " - MPTask "
1167:                                    + mpTask.getUID()
1168:                                    + " d.o. has extra asset that is not in any parent "
1169:                                    + iter.next());
1170:                        }
1171:                    }
1172:                }
1173:            }
1174:
1175:            /**
1176:             * very expensive - must examine every object on the blackboard - avoid if possible 
1177:             *
1178:             * @param parentUID - uid of MPTask we want from the blackboard
1179:             * @return MPTask with UID equal to the param parentUID
1180:             */
1181:            protected MPTask getMPTask(final UID parentUID) {
1182:                Collection stuff = blackboard.query(new UnaryPredicate() {
1183:                    public boolean execute(Object obj) {
1184:                        boolean isMPTask = (obj instanceof  MPTask);
1185:                        if (!isMPTask)
1186:                            return false;
1187:                        boolean match = ((MPTask) obj).getUID().toString()
1188:                                .equals(parentUID.toString());
1189:                        return match;
1190:                    }
1191:                });
1192:
1193:                if (stuff.iterator().hasNext())
1194:                    return (MPTask) stuff.iterator().next(); // better be only one!
1195:                else
1196:                    return null;
1197:            }
1198:
1199:            protected Vector enumToVector(Enumeration en) {
1200:                Vector vector = new Vector(13);
1201:                for (; en.hasMoreElements();) {
1202:                    vector.add(en.nextElement());
1203:                }
1204:                return vector;
1205:            }
1206:
1207:            protected Enumeration getEnumWithNewParents(Vector oldParents,
1208:                    Vector tasklist) {
1209:                oldParents.addAll(tasklist);
1210:                return oldParents.elements();
1211:            }
1212:
1213:            /**
1214:             * make and publish aggregations for parentTasks
1215:             */
1216:            protected void addAggregations(NewComposition comp,
1217:                    Vector parentTasks, Date start, Date end) {
1218:                Map avMap = getAspectValuesMap(parentTasks, start, end);
1219:                // create aggregations for each parent task
1220:                for (Iterator i = parentTasks.iterator(); i.hasNext();) {
1221:                    Task parentTask = (Task) i.next();
1222:                    AspectValue[] aspectValues = (AspectValue[]) avMap
1223:                            .get(parentTask);
1224:
1225:                    boolean isSuccess = !allocHelper.exceedsPreferences(
1226:                            parentTask, aspectValues);
1227:
1228:                    if (!isSuccess) {
1229:                        if (isWarnEnabled()) {
1230:                            warn("VishnuAggregatorPlugin.addAggregations - making failed aggregation for "
1231:                                    + parentTask);
1232:                        }
1233:                        expandHelper.showPlanElement(parentTask);
1234:                    }
1235:
1236:                    AllocationResult estAR = ldmf.newAllocationResult(
1237:                            allocHelper.HIGHEST_CONFIDENCE, isSuccess,
1238:                            aspectValues);
1239:                    Aggregation agg = ldmf.createAggregation(parentTask
1240:                            .getPlan(), parentTask, comp, estAR);
1241:                    if (isDebugEnabled())
1242:                        debug("VishnuAggregatorPlugin.makeAggregation - Making aggregation for task "
1243:                                + parentTask.getUID() + " agg " + agg.getUID());
1244:                    publishAddWithCheck(agg);
1245:                    comp.addAggregation(agg);
1246:                }
1247:            }
1248:
1249:            /**
1250:             * hook for post-publish processing                           <br>
1251:             * Default does nothing.                                      <br>
1252:             * might want to do :	Task mpTask = findMPTask (aggResults);
1253:             */
1254:            protected void cleanupAggregation(Asset a, List tasklist,
1255:                    List aggResults) {
1256:                //	Task mpTask = findMPTask (aggResults);
1257:            }
1258:
1259:            /**
1260:             * Find MPTask in list returned from UTILAggregate.makeAggregation
1261:             *
1262:             * @see org.cougaar.lib.util.UTILAggregate#makeAggregation
1263:             */
1264:            protected MPTask findMPTask(List results) {
1265:                Iterator i = results.iterator();
1266:                while (i.hasNext()) {
1267:                    Object next = i.next();
1268:                    if (next instanceof  MPTask)
1269:                        return ((MPTask) next);
1270:                }
1271:                throw new UTILPluginException(
1272:                        myClusterName
1273:                                + " couldn't find MPTask in list of Aggregation products");
1274:            }
1275:
1276:            /**
1277:             * Defines the verb of the MPTask
1278:             * Transport by default
1279:             *
1280:             * @return Verb - Transport
1281:             */
1282:            protected Verb getVerbForAgg(List g) {
1283:                return Verb.get("Transport");
1284:            }
1285:
1286:            /**
1287:             * Aggregates direct objects of parent tasks into a vector
1288:             *
1289:             * @return aggregate of parent direct objects
1290:             */
1291:            protected Vector getDirectObjectsForAgg(List parentTasks) {
1292:                Vector assets = new Vector();
1293:
1294:                Iterator pt_i = parentTasks.iterator();
1295:                // prepPhrases and directObjects
1296:                while (pt_i.hasNext()) {
1297:                    Task currentTask = (Task) pt_i.next();
1298:                    assets.addElement(currentTask.getDirectObject());
1299:                }
1300:
1301:                return assets;
1302:            }
1303:
1304:            /**
1305:             * Adjust preferences so that the start time preference is the assigned 
1306:             * start time, and the end time preference has a best date that is the 
1307:             * assigned end time.  The early and late dates of the end time preference
1308:             * are the same as the first parent task. (This isn't very important, as the
1309:             * downstream allocator should just allocate to the start and best times.)  <p>
1310:             *
1311:             * If there is a quantity preference on the first task, will calculate an aggregate <br>
1312:             * quantity preference.  Assumes then that all tasks will have a quantity pref.
1313:             * @param a - the asset associated with the MPTask
1314:             * @param g - parent task list
1315:             * @param start - the date for the START_TIME preference
1316:             * @param end - the best date for the END_TIME preference
1317:             * @return Vector - list of preferences for the MPTask
1318:             */
1319:            protected Vector getPreferencesForAgg(Asset a, List g, Date start,
1320:                    Date end) {
1321:                Task firstParentTask = (Task) g.get(0);
1322:
1323:                Date earlyDate = start.after(prefHelper
1324:                        .getEarlyDate(firstParentTask)) ? start : prefHelper
1325:                        .getEarlyDate(firstParentTask);
1326:
1327:                Vector prefs;
1328:
1329:                synchronized (firstParentTask) { // bug #2124
1330:                    prefs = allocHelper.enumToVector(firstParentTask
1331:                            .getPreferences());
1332:                }
1333:                ;
1334:
1335:                prefs = prefHelper.replacePreference(prefs, prefHelper
1336:                        .makeStartDatePreference(ldmf, start));
1337:                prefs = prefHelper.replacePreference(prefs, prefHelper
1338:                        .makeEndDatePreference(ldmf, earlyDate, end, prefHelper
1339:                                .getLateDate(firstParentTask)));
1340:                long totalQuantity = 0l;
1341:                if (prefHelper.hasPrefWithAspectType(firstParentTask,
1342:                        AspectType.QUANTITY)) {
1343:                    for (Iterator iter = g.iterator(); iter.hasNext();) {
1344:                        try {
1345:                            totalQuantity += prefHelper.getQuantity((Task) iter
1346:                                    .next());
1347:                        } catch (UTILRuntimeException re) {
1348:                            totalQuantity += 1; // the task didn't have a quantity preference
1349:                        }
1350:                    }
1351:
1352:                    prefs = prefHelper.replacePreference(prefs, prefHelper
1353:                            .makeQuantityPreference(ldmf, totalQuantity));
1354:                }
1355:
1356:                return prefs;
1357:            }
1358:
1359:            /**
1360:             * Defines how to get the asset representing the task->asset association.
1361:             *
1362:             * Should be in sync with getPrepPhrasesForAgg, which attaches the prep.
1363:             * @see #getPrepPhrasesForAgg
1364:             * @param combinedTask - the MPTask generated by the plugin
1365:             * @return the asset on the task
1366:             */
1367:            protected Asset getAssetFromMPTask(MPTask combinedTask) {
1368:                return (Asset) prepHelper.getIndirectObject(combinedTask,
1369:                        Constants.Preposition.WITH);
1370:            }
1371:
1372:            /**
1373:             * <pre>
1374:             * Defines how the MPTask holds the asset for the task->asset association.
1375:             *
1376:             * Should be in sync with getAssetFromMPTask, which accesses the prep.
1377:             *
1378:             * Critical, because the allocator downstream will look for this prep and
1379:             * pluck the asset off to make the allocation.
1380:             *
1381:             * </pre>
1382:             * @see #getAssetFromMPTask
1383:             * @param a - asset to attach to task
1384:             * @param g - parent tasks
1385:             * @return the original set of prep phrases from the first parent task PLUS the WITH
1386:             *         prep with the asset
1387:             */
1388:            protected Vector getPrepPhrasesForAgg(Asset a, List g) {
1389:                Vector firstTaskPreps = allocHelper.enumToVector(((Task) g
1390:                        .get(0)).getPrepositionalPhrases());
1391:                Vector preps = new Vector(firstTaskPreps);
1392:
1393:                preps.addElement(prepHelper.makePrepositionalPhrase(ldmf,
1394:                        Constants.Preposition.WITH, a));
1395:                return preps;
1396:            }
1397:
1398:            /**
1399:             * Create aspect values so that the start time aspect is the assigned 
1400:             * start time, and the end time aspect is the 
1401:             * assigned end time.
1402:             * (The downstream allocator should just echo these values.)
1403:             *
1404:             * Gets the preferences and makes aspect values that echo them. At this
1405:             * point the start and end time preferences have been set to the assigned 
1406:             * times.
1407:             *
1408:             * @param a - the asset associated with the MPTask
1409:             * @param g - parent task list
1410:             * @return AspectValue[] - returned aspect values
1411:             */
1412:            protected AspectValue[] getAVsForAgg(Asset a, List g, Date start,
1413:                    Date end) {
1414:                return makeAVsFromPrefs(getPreferencesForAgg(a, g, start, end));
1415:            }
1416:
1417:            /**
1418:             * Create aspect values so that the start time aspect is the assigned 
1419:             * start time, and the end time aspect is the 
1420:             * assigned end time.
1421:             * (The downstream allocator should just echo these values.)
1422:             *
1423:             * Gets the preferences and makes aspect values that echo them. At this
1424:             * point the start and end time preferences have been set to the assigned 
1425:             * times.
1426:             *
1427:             * Does not create excess aspect value arrays.
1428:             *
1429:             * @param g - parent task list
1430:             * @return AspectValue[] - returned aspect values
1431:             */
1432:            protected Map getAspectValuesMap(List g, Date start, Date end) {
1433:                Map taskToAspectValue = new HashMap();
1434:                AspectValue[] timeOnlyAspects = null;
1435:                int i = 0;
1436:                for (Iterator iter = g.iterator(); iter.hasNext();) {
1437:                    Task task = (Task) iter.next();
1438:                    Vector preferences;
1439:                    synchronized (task) { // synchronize on a task's preferences when you get them - bug #2124
1440:                        preferences = allocHelper.enumToVector(task
1441:                                .getPreferences());
1442:                    }
1443:                    // all the time-only preference items will share the same aspects
1444:                    if (preferences.size() == 2) {
1445:                        if (timeOnlyAspects == null)
1446:                            timeOnlyAspects = makeAVsFromPrefs(preferences,
1447:                                    start, end);
1448:                        taskToAspectValue.put(task, timeOnlyAspects);
1449:                        i++;
1450:                    } else {
1451:                        taskToAspectValue.put(task, makeAVsFromPrefs(
1452:                                preferences, start, end));
1453:                    }
1454:                }
1455:
1456:                return taskToAspectValue;
1457:            }
1458:
1459:            /**
1460:             * Create aspect values so that the start time aspect is the assigned 
1461:             * start time, and the end time aspect is the 
1462:             * assigned end time.
1463:             * (The downstream allocator should just echo these values.)
1464:             *
1465:             * Takes the preferences and makes aspect values that echo them. At this
1466:             * point the start and end time preferences have been set to the assigned 
1467:             * times.
1468:             *
1469:             * @param prefs - the preferences associated with the MPTask
1470:             * @return AspectValue[] - returned aspect values
1471:             */
1472:            protected AspectValue[] makeAVsFromPrefs(Vector prefs) {
1473:                Vector tmp_av_vec = new Vector(prefs.size());
1474:                Iterator pref_i = prefs.iterator();
1475:                while (pref_i.hasNext()) {
1476:                    // do something really simple for now.
1477:                    Preference pref = (Preference) pref_i.next();
1478:                    int at = pref.getAspectType();
1479:
1480:                    ScoringFunction sf = pref.getScoringFunction();
1481:                    // allocate as if you can do it at the "Best" point
1482:                    double result = ((AspectScorePoint) sf.getBest())
1483:                            .getValue();
1484:
1485:                    // sometimes would fail task due to rounding error 
1486:                    // (time would appear a few millis before the START_TIME pref)
1487:                    if (at == AspectType.START_TIME)
1488:                        result += 1000.0d; // BOZO : hack -- still needed?
1489:
1490:                    tmp_av_vec.addElement(AspectValue
1491:                            .newAspectValue(at, result));
1492:
1493:                    //debug (getName() + ".makeAVsFromPrefs - adding type " + at + " value " + result);
1494:                }
1495:
1496:                AspectValue[] avs = new AspectValue[tmp_av_vec.size()];
1497:                Iterator av_i = tmp_av_vec.iterator();
1498:                int i = 0;
1499:                while (av_i.hasNext())
1500:                    avs[i++] = (AspectValue) av_i.next();
1501:
1502:                // if there were no preferences...return an empty vector (0 elements)
1503:                return avs;
1504:            }
1505:
1506:            /** replace start and end time aspect values with those from the assignment */
1507:            protected AspectValue[] makeAVsFromPrefs(Vector prefs, Date start,
1508:                    Date end) {
1509:                Vector tmp_av_vec = new Vector(prefs.size());
1510:                Iterator pref_i = prefs.iterator();
1511:                while (pref_i.hasNext()) {
1512:                    // do something really simple for now.
1513:                    Preference pref = (Preference) pref_i.next();
1514:                    int at = pref.getAspectType();
1515:                    double result = 0;
1516:
1517:                    if (at == AspectType.START_TIME) {
1518:                        result = (double) start.getTime();
1519:                    } else if (at == AspectType.END_TIME) {
1520:                        result = (double) end.getTime();
1521:                    } else {
1522:                        ScoringFunction sf = pref.getScoringFunction();
1523:                        // allocate as if you can do it at the "Best" point
1524:                        result = ((AspectScorePoint) sf.getBest()).getValue();
1525:                    }
1526:                    tmp_av_vec.addElement(AspectValue
1527:                            .newAspectValue(at, result));
1528:                }
1529:
1530:                AspectValue[] avs = new AspectValue[tmp_av_vec.size()];
1531:                Iterator av_i = tmp_av_vec.iterator();
1532:                int i = 0;
1533:                while (av_i.hasNext())
1534:                    avs[i++] = (AspectValue) av_i.next();
1535:
1536:                // if there were no preferences...return an empty vector (0 elements)
1537:                return avs;
1538:            }
1539:
1540:            /**
1541:             * publish the generated plan elements, compositions, and tasks
1542:             *
1543:             * Also informs of failed tasks.
1544:             *
1545:             * @param toPublish stuff to publish
1546:             */
1547:            protected void publishList(List toPublish) {
1548:                Iterator i = toPublish.iterator();
1549:                while (i.hasNext()) {
1550:                    Object next_o = i.next();
1551:                    if (next_o instanceof  Task) {
1552:                        Task taskToPublish = (Task) next_o;
1553:                        PlanElement pe = taskToPublish.getPlanElement();
1554:                        if (pe != null && !pe.getEstimatedResult().isSuccess()
1555:                                && isDebugEnabled()) {
1556:                            debug(getName() + ".publishList - Task "
1557:                                    + taskToPublish.getUID() + " failed : ");
1558:                            expandHelper.showPlanElement(taskToPublish);
1559:                        }
1560:                    } else if (next_o instanceof  Composition) {
1561:                        ((NewComposition) next_o)
1562:                                .setIsPropagating(propagateRescindPastAggregation);
1563:                    }
1564:
1565:                    publishAddWithCheck(next_o);
1566:                }
1567:            }
1568:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.