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

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


0001:        /*
0002:         * <copyright>
0003:         *
0004:         *  Copyright 1997-2004 BBNT Solutions, LLC
0005:         *  under sponsorship of the Defense Advanced Research Projects
0006:         *  Agency (DARPA).
0007:         *
0008:         *  You can redistribute this software and/or modify it under the
0009:         *  terms of the Cougaar Open Source License as published on the
0010:         *  Cougaar Open Source Website (www.cougaar.org).
0011:         *
0012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023:         *
0024:         * </copyright>
0025:         */
0026:
0027:        package org.cougaar.logistics.plugin.inventory;
0028:
0029:        import org.cougaar.core.mts.MessageAddress;
0030:        import org.cougaar.glm.ldm.asset.Inventory;
0031:        import org.cougaar.glm.ldm.asset.SupplyClassPG;
0032:        import org.cougaar.glm.ldm.plan.AlpineAspectType;
0033:        import org.cougaar.glm.ldm.plan.ObjectScheduleElement;
0034:        import org.cougaar.glm.ldm.plan.PlanScheduleElementType;
0035:        import org.cougaar.glm.ldm.plan.QuantityScheduleElement;
0036:        import org.cougaar.glm.ldm.plan.QuantityScheduleElementImpl;
0037:        import org.cougaar.logistics.ldm.Constants;
0038:        import org.cougaar.logistics.plugin.packer.GenericPlugin;
0039:        import org.cougaar.planning.ldm.PlanningFactory;
0040:        import org.cougaar.planning.ldm.asset.AggregateAsset;
0041:        import org.cougaar.planning.ldm.asset.Asset;
0042:        import org.cougaar.planning.ldm.measure.*;
0043:        import org.cougaar.planning.ldm.plan.*;
0044:        import org.cougaar.planning.plugin.util.PluginHelper;
0045:        import org.cougaar.util.MoreMath;
0046:        import org.cougaar.util.TimeSpan;
0047:        import org.cougaar.util.log.Logger;
0048:
0049:        import java.io.Serializable;
0050:        import java.util.*;
0051:
0052:        /** Provides convenience methods. */
0053:        public class TaskUtils extends PluginHelper implements  Serializable { // revisit making Serializable later...
0054:
0055:            private transient Logger logger;
0056:            private transient UtilsProvider utilProvider;
0057:            private transient AssetUtils assetUtils;
0058:
0059:            public TaskUtils(UtilsProvider provider) {
0060:                super ();
0061:                utilProvider = provider;
0062:                logger = (Logger) utilProvider.getLoggingService(this );
0063:                assetUtils = utilProvider.getAssetUtils();
0064:            }
0065:
0066:            public TaskUtils(Logger aLogger) {
0067:                super ();
0068:                utilProvider = null;
0069:                logger = aLogger;
0070:                assetUtils = new AssetUtils(aLogger);
0071:            }
0072:
0073:            /** @param task the task
0074:             *  @return true if the task has an packer INTERNAL prep phrase */
0075:            public static boolean isInternal(Task task) {
0076:                PrepositionalPhrase pp = task
0077:                        .getPrepositionalPhrase(GenericPlugin.INTERNAL);
0078:                if (pp == null) {
0079:                    return false;
0080:                }
0081:                return true;
0082:            }
0083:
0084:            /** @param t the task
0085:             *  @param type type identification string
0086:             *  @return true if the task's OFTYPE preposition's indirect object is
0087:             *  an asset with nomeclature equal to 'type'.*/
0088:            public static boolean isTaskOfType(Task t, String type) {
0089:                PrepositionalPhrase pp = t
0090:                        .getPrepositionalPhrase(Constants.Preposition.OFTYPE);
0091:                if (pp != null) {
0092:                    Object obj = pp.getIndirectObject();
0093:                    if (obj instanceof  Asset) {
0094:                        Asset a = (Asset) obj;
0095:                        return a.getTypeIdentificationPG()
0096:                                .getTypeIdentification().equals(type);
0097:                    }
0098:                }
0099:                return false;
0100:            }
0101:
0102:            /** @param t the task
0103:             *  @param type type identification string
0104:             *  @return true if the task's OFTYPE preposition's indirect object is
0105:             *  an string with nomeclature equal to 'type'.*/
0106:            public static boolean isTaskOfTypeString(Task t, String type) {
0107:                PrepositionalPhrase pp = t
0108:                        .getPrepositionalPhrase(Constants.Preposition.OFTYPE);
0109:                if (pp != null) {
0110:                    Object obj = pp.getIndirectObject();
0111:                    if (obj instanceof  String) {
0112:                        return ((String) obj).equals(type);
0113:                    }
0114:                }
0115:                return false;
0116:            }
0117:
0118:            public boolean isDirectObjectOfType(Task t, String type) {
0119:                boolean result = false;
0120:                Asset asset = t.getDirectObject();
0121:                // Check for aggregate assets and grab the prototype
0122:                if (asset instanceof  AggregateAsset) {
0123:                    asset = ((AggregateAsset) asset).getAsset();
0124:                }
0125:                try {
0126:                    SupplyClassPG pg = (SupplyClassPG) asset
0127:                            .searchForPropertyGroup(SupplyClassPG.class);
0128:                    if (pg != null) {
0129:                        result = type.equals(pg.getSupplyType());
0130:                        if ((result == true)
0131:                                && (type.equals("PackagedPOL"))
0132:                                && asset.getTypeIdentificationPG()
0133:                                        .getTypeIdentification().endsWith(
0134:                                                "Aggregate")) {
0135:                            logger
0136:                                    .debug("\n direct object type... type for plugin is: "
0137:                                            + type
0138:                                            + "]"
0139:                                            + " type for DO is: ["
0140:                                            + pg.getSupplyType() + "]");
0141:                        }
0142:
0143:                    } else {
0144:                        logger.debug("No SupplyClassPG found on asset "
0145:                                + this .taskDesc(t));
0146:                    }
0147:                } catch (Exception e) {
0148:                    logger.error("Tasks DO is null " + this .taskDesc(t) + "\n"
0149:                            + e);
0150:                }
0151:                return result;
0152:            }
0153:
0154:            // utility functions
0155:            public String taskDesc(Task task) {
0156:                if (isProjection(task)) {
0157:                    return task.getUID()
0158:                            + ": "
0159:                            + task.getVerb()
0160:                            + "("
0161:                            + getDailyQuantity(task, getStartTime(task))
0162:                            + " "
0163:                            + getTaskItemName(task)
0164:                            + ") "
0165:                            + getTimeUtils().dateString(
0166:                                    new Date(getStartTime(task)))
0167:                            + "  -  "
0168:                            + getTimeUtils().dateString(
0169:                                    new Date(getEndTime(task)));
0170:                } else {
0171:                    return task.getUID()
0172:                            + ": "
0173:                            + task.getVerb()
0174:                            + "("
0175:                            + getQuantity(task)
0176:                            + " "
0177:                            + getTaskItemName(task)
0178:                            + ") "
0179:                            + getTimeUtils().dateString(
0180:                                    new Date(getEndTime(task)));
0181:                }
0182:            }
0183:
0184:            public String getTaskItemName(Task task) {
0185:                Asset prototype = (Asset) task.getDirectObject();
0186:                if (prototype == null)
0187:                    return "null";
0188:                return assetUtils.assetDesc(prototype);
0189:            }
0190:
0191:            public static boolean isMyRefillTask(Task task, String myOrgName) {
0192:                PrepositionalPhrase pp = task
0193:                        .getPrepositionalPhrase(Constants.Preposition.REFILL);
0194:                if (pp == null) {
0195:                    return false;
0196:                }
0197:                pp = task.getPrepositionalPhrase(Constants.Preposition.FOR);
0198:                if (pp == null) {
0199:                    return false;
0200:                }
0201:                Object io = pp.getIndirectObject();
0202:                if (io instanceof  String) {
0203:                    String orgName = (String) io;
0204:                    if (orgName.equals(myOrgName)) {
0205:                        return true;
0206:                    }
0207:                }
0208:                return false;
0209:            }
0210:
0211:            public static boolean isMyNonRefillTask(Task task, String myOrgName) {
0212:                PrepositionalPhrase pp = task
0213:                        .getPrepositionalPhrase(Constants.Preposition.REFILL);
0214:                if (pp != null) {
0215:                    return false;
0216:                }
0217:                pp = task.getPrepositionalPhrase(Constants.Preposition.FOR);
0218:                if (pp == null) {
0219:                    return false;
0220:                }
0221:                Object io = pp.getIndirectObject();
0222:                if (io instanceof  String) {
0223:                    String orgName = (String) io;
0224:                    if (orgName.equals(myOrgName)) {
0225:                        return true;
0226:                    }
0227:                }
0228:                return false;
0229:            }
0230:
0231:            public static boolean isMyInventoryProjection(Task task,
0232:                    String myOrgName) {
0233:                PrepositionalPhrase pp = task
0234:                        .getPrepositionalPhrase(Constants.Preposition.FOR);
0235:                if (pp == null) {
0236:                    return false;
0237:                }
0238:                Object io = pp.getIndirectObject();
0239:                if (io instanceof  String) {
0240:                    String orgName = (String) io;
0241:                    if (orgName.equals(myOrgName)) {
0242:                        pp = task
0243:                                .getPrepositionalPhrase(Constants.Preposition.MAINTAINING);
0244:                        if (pp != null) {
0245:                            try {
0246:                                if (((MaintainedItem) pp.getIndirectObject())
0247:                                        .getMaintainedItemType().equals(
0248:                                                "Inventory")) {
0249:                                    return true;
0250:                                }
0251:                            } catch (ClassCastException exc) {
0252:                                return false;
0253:                            }
0254:                        }
0255:                    }
0256:                }
0257:                return false;
0258:            }
0259:
0260:            public boolean isReadyForTransport(Task task) {
0261:                PrepositionalPhrase pp = task
0262:                        .getPrepositionalPhrase(Constants.Preposition.READYFORTRANSPORT);
0263:                return (pp != null);
0264:            }
0265:
0266:            public boolean isMyDemandForecastProjection(Task task,
0267:                    String orgName) {
0268:                PrepositionalPhrase pp = task
0269:                        .getPrepositionalPhrase(Constants.Preposition.FOR);
0270:                if (pp == null) {
0271:                    return false;
0272:                }
0273:                Object io = pp.getIndirectObject();
0274:                if (io instanceof  String) {
0275:                    String taskOrg = (String) io;
0276:                    if (taskOrg.equals(orgName)) {
0277:                        pp = task
0278:                                .getPrepositionalPhrase(Constants.Preposition.REFILL);
0279:                        return (pp == null);
0280:                    }
0281:                }
0282:                return false;
0283:            }
0284:
0285:            /** return the preference of the given aspect type.  Returns null if
0286:             *  the task does not have the given aspect. */
0287:            public static double getPreference(Task t, int aspect_type) {
0288:                Preference p = t.getPreference(aspect_type);
0289:                if (p == null)
0290:                    return Double.NaN;
0291:
0292:                AspectScorePoint asp = p.getScoringFunction().getBest();
0293:                return asp.getValue();
0294:            }
0295:
0296:            public static boolean isProjection(Task t) {
0297:                return (t
0298:                        .getPrepositionalPhrase(Constants.Preposition.DEMANDRATE) != null || t
0299:                        .getPreference(AlpineAspectType.DEMANDRATE) != null);
0300:            }
0301:
0302:            public static boolean isSupply(Task t) {
0303:                return !isProjection(t);
0304:            }
0305:
0306:            public boolean isLevel2(Task t) {
0307:                return assetUtils.isLevel2Asset(t.getDirectObject());
0308:            }
0309:
0310:            // TASK PREFERENCE UTILS
0311:
0312:            public static double getQuantity(Task task) {
0313:                return getPreferenceBestValue(task, AspectType.QUANTITY);
0314:            }
0315:
0316:            public static Preference createDemandRatePreference(
0317:                    PlanningFactory rf, Rate rate) {
0318:                ScoringFunction sf = ScoringFunction
0319:                        .createStrictlyAtValue(AspectValue.newAspectValue(
0320:                                AlpineAspectType.DEMANDRATE, rate));
0321:                return rf.newPreference(AlpineAspectType.DEMANDRATE, sf);
0322:            }
0323:
0324:            /**
0325:             * Compare the preferences of two tasks return true if the tasks
0326:             * have preferences for the same aspect types and if all
0327:             * corresponding AspectValues are nearly equal.
0328:             * This needs to be fixed to be more efficient.
0329:             **/
0330:            private boolean comparePreferences(Task a, Task b) {
0331:                return comparePreferencesInner(a, b)
0332:                        && comparePreferencesInner(b, a);
0333:            }
0334:
0335:            private boolean comparePreferencesInner(Task a, Task b) {
0336:                Enumeration ae = a.getPreferences();
0337:                while (ae.hasMoreElements()) {
0338:                    Preference p = (Preference) ae.nextElement();
0339:                    int at = p.getAspectType();
0340:                    double av = p.getScoringFunction().getBest().getValue();
0341:                    double bv = getPreferenceBestValue(b, at);
0342:                    if (at == AspectType.START_TIME
0343:                            || at == AspectType.END_TIME) {
0344:                        //for times say they are nearly equal if they are within the same hour
0345:                        // it could be longer if we only had daily buckets - but this should
0346:                        // work for both daily and hourly buckets
0347:                        long aHourLong = (long) av / 3600000;
0348:                        long bHourLong = (long) bv / 3600000;
0349:                        if (aHourLong != bHourLong)
0350:                            return false;
0351:                    } else {
0352:                        if (!MoreMath.nearlyEquals(av, bv, 0.0001))
0353:                            return false;
0354:                    }
0355:                }
0356:                return true;
0357:            }
0358:
0359:            /** @param task
0360:             *  @return Value of the FOR Preposition if available, else null
0361:             */
0362:            public static Object getCustomer(Task task) {
0363:                PrepositionalPhrase pp_for = task
0364:                        .getPrepositionalPhrase(Constants.Preposition.FOR);
0365:                Object org;
0366:                if (pp_for != null) {
0367:                    org = pp_for.getIndirectObject();
0368:                    return org;
0369:                }
0370:                return null;
0371:            }
0372:
0373:            public boolean isFlowRate(Task task) {
0374:                // select any rate in the rate_schedule, e.g. the first:
0375:                Rate r = getRate(task);
0376:                return (r instanceof  FlowRate);
0377:            }
0378:
0379:            public Rate getRate(Task task) {
0380:                return getRate(task, getStartTime(task));
0381:            }
0382:
0383:            public Rate getRate(Task task, long time) {
0384:                return getRate(task, time, time);
0385:            }
0386:
0387:            public Rate getRate(Task task, long start, long end) {
0388:                // look for time-phased rate schedule
0389:                PrepositionalPhrase pp_rate = task
0390:                        .getPrepositionalPhrase(Constants.Preposition.DEMANDRATE);
0391:                if (pp_rate != null) {
0392:                    Object indObj = pp_rate.getIndirectObject();
0393:                    if (indObj instanceof  Schedule) {
0394:                        Schedule sched = (Schedule) indObj;
0395:                        Collection rate_elems = (start == end ? sched
0396:                                .getScheduleElementsWithTime(start) : sched
0397:                                .getOverlappingScheduleElements(start, end));
0398:                        int n = (rate_elems == null ? 0 : rate_elems.size());
0399:                        if (n > 0) {
0400:                            if (n == 1 || (start >= end)) {
0401:                                // return the single matching rate
0402:                                ObjectScheduleElement ose = (ObjectScheduleElement) rate_elems
0403:                                        .iterator().next();
0404:                                return (Rate) ose.getObject();
0405:                            }
0406:                            // compute the average rate for this timespan
0407:                            Rate avgRate = null;
0408:                            long prevStart = start;
0409:                            Rate firstRate = null;
0410:                            double totalQty = 0.0;
0411:                            for (Iterator iter = rate_elems.iterator(); iter
0412:                                    .hasNext();) {
0413:                                ObjectScheduleElement ose = (ObjectScheduleElement) iter
0414:                                        .next();
0415:                                long st = Math.max(prevStart, ose
0416:                                        .getStartTime());
0417:                                long et = Math.min(ose.getEndTime(), end);
0418:                                long time_spanned = (et - st);
0419:                                if (time_spanned <= 0) {
0420:                                    continue;
0421:                                }
0422:                                prevStart = et;
0423:                                Rate r = (Rate) ose.getObject();
0424:                                if (firstRate == null) {
0425:                                    firstRate = r;
0426:                                }
0427:                                double dailyRate = getDailyQuantity(r);
0428:                                if (Double.isNaN(dailyRate)) {
0429:                                    continue;
0430:                                }
0431:                                double qty = (dailyRate * ((double) time_spanned / TimeUtils.MSEC_PER_DAY));
0432:                                totalQty += qty;
0433:                            }
0434:                            Duration dur = new Duration((end - start),
0435:                                    Duration.MILLISECONDS);
0436:                            if (firstRate instanceof  FlowRate) {
0437:                                Volume vol = new Volume(totalQty,
0438:                                        Volume.GALLONS);
0439:                                avgRate = new FlowRate(vol, dur);
0440:                            } else if (firstRate instanceof  CountRate) {
0441:                                Count cnt = new Count(totalQty, Count.EACHES);
0442:                                avgRate = new CountRate(cnt, dur);
0443:                            } else if (firstRate instanceof  MassTransferRate) {
0444:                                Mass mass = new Mass(totalQty, Mass.SHORT_TONS);
0445:                                avgRate = new MassTransferRate(mass, dur);
0446:                            } else {
0447:                                avgRate = null;
0448:                            }
0449:                            return avgRate;
0450:                        }
0451:                    }
0452:                }
0453:                // look for preference
0454:                AspectValue best = getPreferenceBest(task,
0455:                        AlpineAspectType.DEMANDRATE);
0456:                if (best != null) {
0457:                    return ((AspectRate) best).getRateValue();
0458:                }
0459:                // not a projection?
0460:                return null;
0461:            }
0462:
0463:            public double getDailyQuantity(Task task) {
0464:                return getDailyQuantity(task, getEndTime(task));
0465:            }
0466:
0467:            public double getDailyQuantity(Task task, long time) {
0468:                return getDailyQuantity(task, time, time);
0469:            }
0470:
0471:            public double getDailyQuantity(Task task, long start, long end) {
0472:                if (isProjection(task)) {
0473:                    return getDailyQuantity(getRate(task, start, end));
0474:                } else {
0475:                    return getQuantity(task);
0476:                }
0477:            }
0478:
0479:            public static double getDailyQuantity(Rate r) {
0480:                if (r instanceof  FlowRate) {
0481:                    return ((FlowRate) r).getGallonsPerDay();
0482:                } else if (r instanceof  CountRate) {
0483:                    return ((CountRate) r).getEachesPerDay();
0484:                } else if (r instanceof  MassTransferRate) {
0485:                    return ((MassTransferRate) r).getShortTonsPerDay();
0486:                } else {
0487:                    return Double.NaN;
0488:                }
0489:            }
0490:
0491:            /**
0492:             * Given a Scalar, return a double value representing
0493:             * Gallons for Volume,
0494:             * Eaches for Count and
0495:             * Short Tons for Mass.
0496:             **/
0497:            public double getDouble(Scalar measure) {
0498:                double result = Double.NaN;
0499:                if (measure instanceof  Volume) {
0500:                    result = ((Volume) measure).getGallons();
0501:                } else if (measure instanceof  Count) {
0502:                    result = ((Count) measure).getEaches();
0503:                } else if (measure instanceof  Mass) {
0504:                    result = ((Mass) measure).getShortTons();
0505:                } else {
0506:                    logger
0507:                            .error("InventoryBG.getDouble(), Inventory cannot determine type of measure");
0508:                }
0509:                return result;
0510:            }
0511:
0512:            public static double getQuantity(AllocationResult ar) {
0513:                return getARAspectValue(ar, AspectType.QUANTITY);
0514:            }
0515:
0516:            // Hand in the demandRate from a phase of particular allocation result
0517:            // and its parent task.  This function basically handles the
0518:            // contained demand rate result and returns the corresponding
0519:            // daily rate.    If its fuel (FlowRate) that's already gallons
0520:            // per day, otherwise its eaches per millisecond and should be
0521:            // multiplied correspondingly.
0522:            public double convertResultsToDailyRate(Task task, double demandRate) {
0523:                if (isProjection(task) && !isFlowRate(task)) {
0524:                    return demandRate * TimeUtils.SEC_PER_DAY;
0525:                }
0526:                return demandRate;
0527:            }
0528:
0529:            public double getQuantity(Task task, AllocationResult ar) {
0530:                if (isProjection(task)) {
0531:                    // 	  logger.warn("TaskUtils::getting qty from projection!");
0532:                    return convertResultsToDailyRate(task, getARAspectValue(ar,
0533:                            AlpineAspectType.DEMANDRATE));
0534:                } else {
0535:                    return getQuantity(ar);
0536:                }
0537:            }
0538:
0539:            public double getQuantity(Task task, AllocationResult ar,
0540:                    long time_spanned) {
0541:                if (isProjection(task)) {
0542:                    Rate rate = getARAspectRate(ar);
0543:                    Duration d = Duration
0544:                            .newMilliseconds((double) time_spanned);
0545:                    Scalar scalar = (Scalar) rate.computeNumerator(d);
0546:                    return getDouble(scalar);
0547:                } else {
0548:                    return getQuantity(ar);
0549:                }
0550:            }
0551:
0552:            public double getTotalQuantity(Task task) {
0553:                return getTotalQuantity(task, getStartTime(task),
0554:                        getEndTime(task));
0555:            }
0556:
0557:            public double getTotalQuantity(Task task, long startTime,
0558:                    long endTime) {
0559:                if (isProjection(task)) {
0560:                    double time_spanned = endTime - startTime;
0561:                    if (time_spanned > 0) {
0562:                        Rate rate = getRate(task, startTime, endTime);
0563:                        Duration d = Duration
0564:                                .newMilliseconds((double) time_spanned);
0565:                        Scalar scalar = (Scalar) rate.computeNumerator(d);
0566:                        return getDouble(scalar);
0567:                    } else {
0568:                        return 0.0d;
0569:                    }
0570:                } else {
0571:                    return getQuantity(task);
0572:                }
0573:            }
0574:
0575:            public double getTotalQuantity(Task task, double demandRate,
0576:                    long startTime, long endTime) {
0577:                if (isProjection(task)) {
0578:                    double time_spanned = endTime - startTime;
0579:                    if (time_spanned > 0) {
0580:                        double dailyRate = convertResultsToDailyRate(task,
0581:                                demandRate);
0582:                        return (dailyRate * (time_spanned / TimeUtils.MSEC_PER_DAY));
0583:                    } else {
0584:                        return 0.0d;
0585:                    }
0586:                } else {
0587:                    return getQuantity(task);
0588:                }
0589:            }
0590:
0591:            public static Rate getARAspectRate(AllocationResult ar) {
0592:                if (ar == null)
0593:                    return null;
0594:                AspectValue[] avs = ar.getAspectValueResults();
0595:                for (int ii = 0; ii < avs.length; ii++) {
0596:                    if (avs[ii].getAspectType() == AlpineAspectType.DEMANDRATE) {
0597:                        return ((AspectRate) avs[ii]).getRateValue();
0598:                    }
0599:                }
0600:                return null;
0601:            }
0602:
0603:            public TimeUtils getTimeUtils() {
0604:                return utilProvider.getTimeUtils();
0605:            }
0606:
0607:            public static Collection getUnallocatedTasks(Collection tasks,
0608:                    Verb verb) {
0609:                Iterator taskIt = tasks.iterator();
0610:                ArrayList list = new ArrayList();
0611:                Task task;
0612:                while (taskIt.hasNext()) {
0613:                    task = (Task) taskIt.next();
0614:                    if ((task.getPlanElement() == null)
0615:                            && (task.getVerb().equals(verb))) {
0616:                        list.add(task);
0617:                    }
0618:                }
0619:                return list;
0620:            }
0621:
0622:            public Schedule newObjectSchedule(Collection tasks) {
0623:                Vector os_elements = new Vector();
0624:                ScheduleImpl s = new ScheduleImpl();
0625:                s.setScheduleElementType(PlanScheduleElementType.OBJECT);
0626:                s.setScheduleType(ScheduleType.OTHER);
0627:
0628:                for (Iterator iterator = tasks.iterator(); iterator.hasNext();) {
0629:                    Task task = (Task) iterator.next();
0630:                    try {
0631:                        os_elements.add(new ObjectScheduleElement(
0632:                                getStartTime(task), getEndTime(task), task));
0633:                    } catch (IllegalArgumentException iae) {
0634:                        if (logger.isErrorEnabled()) {
0635:                            logger
0636:                                    .error("newObjectSchedule failed, start and end time is "
0637:                                            + new Date(getStartTime(task))
0638:                                            + " for task "
0639:                                            + task
0640:                                            + "\n"
0641:                                            + iae.getMessage());
0642:                        }
0643:                    }
0644:                }
0645:                s.setScheduleElements(os_elements.elements());
0646:                return s;
0647:            }
0648:
0649:            /** Change the prev task's preferences to the new tasks preferences if they are different.
0650:             * @param prev_task previously published task.
0651:             * @param new_task already defined to have the same taskKey as task a.
0652:             * @return null if the two tasks are the same,
0653:             *         or returns task a modified for a publishChange.
0654:             */
0655:            public Task changeTask(Task prev_task, Task new_task) {
0656:                // Checks for changed preferences.
0657:                if (prev_task == new_task) {
0658:                    //return new_task;
0659:                    return null;
0660:                }
0661:                if (!comparePreferences(new_task, prev_task)) {
0662:                    synchronized (new_task) {
0663:                        Enumeration ntPrefs = new_task.getPreferences();
0664:                        ((NewTask) prev_task).setPreferences(ntPrefs);
0665:                    } // synch
0666:                    return prev_task;
0667:                }
0668:                return null;
0669:            }
0670:
0671:            // Time Preference Utils
0672:
0673:            /** Create a Time Preference for a Refill Task or a Demand Task
0674:             *  Use a Piecewise Linear Scoring Function.
0675:             *  For details see the IM SDD.
0676:             *  @param bestDay The time you want this preference to represent
0677:             *  @param early The earliest time this preference can have
0678:             *  @param end The last time this preference can have (such as Oplan end time)
0679:             *  @param aspectType The AspectType of the preference- should be start_time or end_time
0680:             *  @param clusterId Agent cluster ID
0681:             *  @param planningFactory Planning factory from plugin
0682:             *  @param thePG InventoryPG for the item maintained by a refill task
0683:             *  @return Preference The new Time Preference
0684:             **/
0685:            public Preference createTimePreference(long bestDay, long early,
0686:                    long end, int aspectType, MessageAddress clusterId,
0687:                    PlanningFactory planningFactory, LogisticsInventoryPG thePG) {
0688:                double daysBetween;
0689:                long late;
0690:                if (thePG != null) {
0691:                    daysBetween = ((end - bestDay) / thePG.getBucketMillis()) - 1;
0692:                    late = bestDay + thePG.getBucketMillis();
0693:                } else {
0694:                    late = getTimeUtils().addNDays(bestDay, 1);
0695:                    daysBetween = ((end - bestDay) / 86400000);
0696:                }
0697:
0698:                // Negative value here is bad. Note that end==bestDay is OK. This case
0699:                // is handled below, where we skip adding the end AspectScorePoint
0700:                if (daysBetween < 0.0) {
0701:                    if (logger.isWarnEnabled())
0702:                        logger
0703:                                .warn(clusterId
0704:                                        + ".createTimePref had OplanEnd < bestDay! OplanEnd: "
0705:                                        + new Date(end) + ". Best: "
0706:                                        + new Date(bestDay));
0707:                }
0708:
0709:                //Use .0033 as a slope for now
0710:                double late_score = .0033 * daysBetween;
0711:                // define alpha .25
0712:                double alpha = .25;
0713:
0714:                Vector points = new Vector();
0715:                AspectScorePoint earliest = new AspectScorePoint(AspectValue
0716:                        .newAspectValue(aspectType, early), alpha);
0717:                AspectScorePoint best = new AspectScorePoint(AspectValue
0718:                        .newAspectValue(aspectType, bestDay), 0.0);
0719:                AspectScorePoint first_late = new AspectScorePoint(AspectValue
0720:                        .newAspectValue(aspectType, late), alpha);
0721:                AspectScorePoint latest = new AspectScorePoint(AspectValue
0722:                        .newAspectValue(aspectType, end), (alpha + late_score));
0723:
0724:                // Don't add the early point if best is same time or earlier
0725:                if (bestDay > early) {
0726:                    points.addElement(earliest);
0727:                } else if (bestDay == early) {
0728:                    if (logger.isInfoEnabled()) {
0729:                        logger
0730:                                .info(clusterId
0731:                                        + ".createTimePref skipping early point: best == early (OplanStart)! bestDay: "
0732:                                        + new Date(bestDay) + ". AspectType: "
0733:                                        + aspectType);
0734:                    }
0735:                } else {
0736:                    if (logger.isWarnEnabled()) {
0737:                        logger
0738:                                .warn(clusterId
0739:                                        + ".createTimePref skipping early point: best < early (OplanStart)! bestDay: "
0740:                                        + new Date(bestDay) + ", early: "
0741:                                        + new Date(early) + ". AspectType: "
0742:                                        + aspectType);
0743:                    }
0744:                }
0745:
0746:                points.addElement(best);
0747:                points.addElement(first_late);
0748:
0749:                // Only add the "late" point if it's value is later than first_late
0750:                if (end > late) {
0751:                    points.addElement(latest);
0752:                } else if (logger.isInfoEnabled()) {
0753:                    // Note that this case is equivalent to any daysBetween value <= 1.0,
0754:                    // including the case above where daysBetween < 0.0
0755:
0756:                    // If bestDay == end, this is almost certainly an end Preference, where the preference
0757:                    // is OplanEnd. So best+1 is necessarily > end
0758:                    // check aspectType == AspectType.END_TIME
0759:                    logger
0760:                            .info(clusterId
0761:                                    + ".createTimePref skipping end point: end <= late! end: "
0762:                                    + new Date(end)
0763:                                    + ", late: "
0764:                                    + new Date(late)
0765:                                    + ((bestDay == end && aspectType == AspectType.END_TIME) ? ". A Task EndPref where best==OplanEnd."
0766:                                            : ". AspectType: " + aspectType));
0767:                }
0768:
0769:                ScoringFunction timeSF = ScoringFunction
0770:                        .createPiecewiseLinearScoringFunction(points.elements());
0771:                return planningFactory.newPreference(aspectType, timeSF);
0772:            }
0773:
0774:            /** copies a Supply task from another to split it**/
0775:            public NewTask copySupplyTask(Task origTask, long start, long end,
0776:                    LogisticsInventoryPG invPG, InventoryManager inventoryPlugin) {
0777:
0778:                NewTask task = inventoryPlugin.getPlanningFactory().newTask();
0779:                task.setVerb(origTask.getVerb());
0780:                task.setDirectObject(origTask.getDirectObject());
0781:                task.setParentTaskUID(origTask.getParentTaskUID());
0782:                task.setContext(origTask.getContext());
0783:                task.setPlan(origTask.getPlan());
0784:                Enumeration pp = origTask.getPrepositionalPhrases();
0785:                Vector ppv = new Vector();
0786:                while (pp.hasMoreElements()) {
0787:                    ppv.addElement(pp.nextElement());
0788:                }
0789:                NewPrepositionalPhrase newPP = inventoryPlugin
0790:                        .getPlanningFactory().newPrepositionalPhrase();
0791:                newPP.setPreposition("SplitTask");
0792:                ppv.add(newPP);
0793:                task.setPrepositionalPhrases(ppv.elements());
0794:                task.setPriority(origTask.getPriority());
0795:                task.setSource(inventoryPlugin.getClusterId());
0796:                changeDatePrefs(task, start, end, inventoryPlugin, invPG);
0797:                // TODO: is this ok to to just add these prefs to the a vector?
0798:                // TODO: the changeDatePrefs clones the scoring function
0799:                Enumeration origPrefs = task.getPreferences();
0800:                Vector newPrefs = new Vector();
0801:                Preference currentPref;
0802:                while (origPrefs.hasMoreElements()) {
0803:                    currentPref = (Preference) origPrefs.nextElement();
0804:                    newPrefs.add(currentPref);
0805:                }
0806:                // old pref-style rate w/o rate_schedule
0807:                AspectValue rate_best = getPreferenceBest(task,
0808:                        AlpineAspectType.DEMANDRATE);
0809:                if (rate_best != null) {
0810:                    Rate rate = ((AspectRate) rate_best).getRateValue();
0811:                    if (rate != null) {
0812:                        newPrefs.addElement(createDemandRatePreference(
0813:                                inventoryPlugin.getPlanningFactory(), rate));
0814:                    }
0815:                }
0816:                // start and end from schedule element
0817:
0818:                task.setPreferences(newPrefs.elements());
0819:                return task;
0820:            }
0821:
0822:            public void changeDatePrefs(NewTask task, long start, long end,
0823:                    InventoryManager inventoryPlugin, LogisticsInventoryPG invPG) {
0824:                Preference startPref = createTimePreference(start,
0825:                        inventoryPlugin.getOPlanArrivalInTheaterTime(),
0826:                        inventoryPlugin.getOPlanEndTime(),
0827:                        AspectType.START_TIME, inventoryPlugin.getClusterId(),
0828:                        inventoryPlugin.getPlanningFactory(), invPG);
0829:                Preference endPref = createTimePreference(end, inventoryPlugin
0830:                        .getOPlanArrivalInTheaterTime(), inventoryPlugin
0831:                        .getOPlanEndTime(), AspectType.END_TIME,
0832:                        inventoryPlugin.getClusterId(), inventoryPlugin
0833:                                .getPlanningFactory(), invPG);
0834:
0835:                Enumeration origPrefs = task.getPreferences();
0836:                Preference currentPref, copiedPref;
0837:                Vector newPrefs = new Vector();
0838:                while (origPrefs.hasMoreElements()) {
0839:                    currentPref = (Preference) origPrefs.nextElement();
0840:                    if (!(currentPref.getAspectType() == AspectType.START_TIME || currentPref
0841:                            .getAspectType() == AspectType.END_TIME)) {
0842:                        copiedPref = inventoryPlugin.getPlanningFactory()
0843:                                .newPreference(
0844:                                        currentPref.getAspectType(),
0845:                                        (ScoringFunction) currentPref
0846:                                                .getScoringFunction().clone());
0847:                        newPrefs.add(copiedPref);
0848:                    }
0849:                }
0850:                newPrefs.add(startPref);
0851:                newPrefs.add(endPref);
0852:                synchronized (task) {
0853:                    task.setPreferences(newPrefs.elements());
0854:                }
0855:            }
0856:
0857:            public Collection splitProjection(Task task, List howToSplit,
0858:                    InventoryManager invPlugin) {
0859:                ArrayList newSplitTasks = new ArrayList();
0860:                Asset asset = task.getDirectObject();
0861:                Inventory inventory = invPlugin.findOrMakeInventory(asset);
0862:                LogisticsInventoryPG invPG = (LogisticsInventoryPG) inventory
0863:                        .searchForPropertyGroup(LogisticsInventoryPG.class);
0864:                //remove the orig task from the BG - we'll re-add after the split
0865:                invPG.removeRefillProjection(task);
0866:                Iterator tsIt = howToSplit.iterator();
0867:                TimeSpan first = (TimeSpan) tsIt.next();
0868:                //first element from howToSplit is the one to reuse the allocation
0869:                long startOfSplit = first.getStartTime();
0870:                long endOfSplit = first.getEndTime();
0871:                TimeSpan second = (TimeSpan) tsIt.next();
0872:                long startOfSecondSplit = second.getStartTime();
0873:                long endOfSecondSplit = second.getEndTime();
0874:                if (task.getPlanElement() != null) {
0875:                    changeDatePrefs((NewTask) task, startOfSplit, endOfSplit,
0876:                            invPlugin, invPG);
0877:                    invPG.addRefillProjection(task);
0878:                    invPlugin.publishChange(task);
0879:                    //add the changed list to newSplitTasks to be sent to the ExtAlloc so it can update its estimated result
0880:                    newSplitTasks.add(task);
0881:                    newSplitTasks.add(makeNewSplit(task, startOfSecondSplit,
0882:                            endOfSecondSplit, invPG, invPlugin, inventory));
0883:                } else {
0884:                    newSplitTasks.add(makeNewSplit(task, startOfSplit,
0885:                            endOfSplit, invPG, invPlugin, inventory));
0886:                    newSplitTasks.add(makeNewSplit(task, startOfSecondSplit,
0887:                            endOfSecondSplit, invPG, invPlugin, inventory));
0888:                }
0889:                return newSplitTasks;
0890:            }
0891:
0892:            private Task makeNewSplit(Task task, long startOfSplit,
0893:                    long endOfSplit, LogisticsInventoryPG invPG,
0894:                    InventoryManager invPlugin, Inventory inventory) {
0895:                Task newSplitTask = copySupplyTask(task, startOfSplit,
0896:                        endOfSplit, invPG, invPlugin);
0897:                if (logger.isDebugEnabled()) {
0898:                    logger.debug("Made a new split task with dates of: "
0899:                            + new Date(startOfSplit) + "..."
0900:                            + new Date(endOfSplit));
0901:                }
0902:                invPG.addRefillProjection(newSplitTask);
0903:                //hookup newSplitTask
0904:                invPlugin.publishRefillTask(newSplitTask, inventory);
0905:                return newSplitTask;
0906:            }
0907:
0908:            public long getReportedStartTime(Task task) {
0909:                PlanElement pe = task.getPlanElement();
0910:                // If the task has no plan element then return the StartTime Pref
0911:                if (pe == null) {
0912:                    return getStartTime(task);
0913:                }
0914:                AllocationResult ar = pe.getReportedResult();
0915:                if (ar == null) {
0916:                    ar = pe.getEstimatedResult();
0917:                } else if (!ar.isSuccess()) {
0918:                    return getStartTime(task);
0919:                }
0920:                return (long) getStartTime(ar);
0921:            }
0922:
0923:            public long getReportedEndTime(Task task) {
0924:                PlanElement pe = task.getPlanElement();
0925:                // If the task has no plan element then return the EndTime Pref
0926:                if (pe == null) {
0927:                    return getEndTime(task);
0928:                }
0929:                AllocationResult ar = pe.getReportedResult();
0930:                if (ar == null) {
0931:                    ar = pe.getEstimatedResult();
0932:                }
0933:                // make sure that we got atleast a valid reported OR estimated allocation result
0934:                if (ar != null) {
0935:                    if (!ar.isSuccess()) {
0936:                        getEndTime(task); // bug?
0937:                    }
0938:                    double resultTime;
0939:                    // make sure END_TIME is specified - otherwise use START_TIME
0940:                    // UniversalAllocator plugin only gives start times
0941:                    if (ar.isDefined(AspectType.END_TIME)) {
0942:                        resultTime = ar.getValue(AspectType.END_TIME);
0943:                    } else {
0944:                        resultTime = ar.getValue(AspectType.START_TIME);
0945:                    }
0946:                    return (long) resultTime;
0947:                } else {
0948:                    // if for some reason we have a pe but no ar return the pref
0949:                    return getEndTime(task);
0950:                }
0951:            }
0952:
0953:            public double calculateDemand(Task t, long minStart, long maxEnd) {
0954:                if (isProjection(t)) {
0955:                    long start = Math.max(getReportedStartTime(t), minStart);
0956:                    long end = Math.min(getReportedEndTime(t), maxEnd);
0957:                    return getTotalQuantity(t, start, end);
0958:                }
0959:                long taskEnd = getEndTime(t);
0960:                if ((taskEnd < minStart) || (taskEnd > maxEnd)) {
0961:                    return 0.0d;
0962:                }
0963:                return getQuantity(t);
0964:            }
0965:
0966:            public double calculateFilled(Task t, long minStart, long maxEnd) {
0967:                PlanElement pe = t.getPlanElement();
0968:                AllocationResult ar = null;
0969:                if (pe != null) {
0970:                    ar = pe.getReportedResult();
0971:                    if (ar == null) {
0972:                        ar = pe.getEstimatedResult();
0973:                    }
0974:                }
0975:                if (isProjection(t)) {
0976:                    long start = Math.max(getReportedStartTime(t), minStart);
0977:                    long end = Math.min(getReportedEndTime(t), maxEnd);
0978:                    if (ar != null && !ar.isSuccess()) {
0979:                        return 0.0d;
0980:                    }
0981:                    double taskQty = getTotalQuantity(t, start, end);
0982:                    if (ar == null || !ar.isPhased()) {
0983:                        return taskQty;
0984:                    }
0985:
0986:                    int[] ats = ar.getAspectTypes();
0987:                    int rateInd = LogisticsInventoryFormatter.getIndexForType(
0988:                            ats, AlpineAspectType.DEMANDRATE);
0989:                    int startInd = LogisticsInventoryFormatter.getIndexForType(
0990:                            ats, AspectType.START_TIME);
0991:                    int endInd = LogisticsInventoryFormatter.getIndexForType(
0992:                            ats, AspectType.END_TIME);
0993:
0994:                    double totalQty = 0;
0995:                    for (Enumeration phasedResults = ar.getPhasedResults(); phasedResults
0996:                            .hasMoreElements();) {
0997:                        double[] results = (double[]) phasedResults
0998:                                .nextElement();
0999:                        double phaseRate = results[rateInd];
1000:                        double phaseStart = results[startInd];
1001:                        double phaseEnd = results[endInd];
1002:                        start = Math.max((long) phaseStart, minStart);
1003:                        end = Math.min((long) phaseEnd, maxEnd);
1004:                        totalQty += getTotalQuantity(t, phaseRate, start, end);
1005:                    }
1006:                    return totalQty;
1007:                }
1008:                long taskEnd = getEndTime(t);
1009:                if ((taskEnd < minStart) || (taskEnd > maxEnd)) {
1010:                    return 0.0d;
1011:                }
1012:
1013:                if (ar == null) {
1014:                    return getQuantity(t);
1015:                }
1016:                if (!ar.isPhased()) {
1017:                    if (ar.isSuccess()) {
1018:                        double arEnd = getEndTime(ar);
1019:                        double taskQty = getQuantity(t, ar);
1020:                        if ((arEnd >= minStart) && (arEnd <= maxEnd)) {
1021:                            return taskQty;
1022:                        }
1023:                    }
1024:                    return 0.0d;
1025:                }
1026:
1027:                int[] ats = ar.getAspectTypes();
1028:                int qtyInd = LogisticsInventoryFormatter.getIndexForType(ats,
1029:                        AspectType.QUANTITY);
1030:                int endInd = LogisticsInventoryFormatter.getIndexForType(ats,
1031:                        AspectType.END_TIME);
1032:
1033:                double totalQty = 0;
1034:                for (Enumeration phasedResults = ar.getPhasedResults(); phasedResults
1035:                        .hasMoreElements();) {
1036:                    double[] results = (double[]) phasedResults.nextElement();
1037:                    double phaseQty = results[qtyInd];
1038:                    double phaseEnd = results[endInd];
1039:                    if (phaseEnd <= maxEnd) {
1040:                        totalQty += phaseQty;
1041:                    }
1042:                }
1043:                return totalQty;
1044:            }
1045:
1046:            public boolean isProjFailure(Task t, long minStart,
1047:                    boolean includeTemps) {
1048:                PlanElement pe = t.getPlanElement();
1049:                if (pe == null) {
1050:                    return false;
1051:                }
1052:                AllocationResult ar = pe.getReportedResult();
1053:                if (ar == null) {
1054:                    ar = pe.getEstimatedResult();
1055:                }
1056:                if (ar == null) {
1057:                    return false;
1058:                }
1059:                if (ar.isSuccess() && (!includeTemps || !ar.isPhased())) {
1060:                    return false;
1061:                }
1062:                int[] ats = ar.getAspectTypes();
1063:                int rateInd = LogisticsInventoryFormatter.getIndexForType(ats,
1064:                        AlpineAspectType.DEMANDRATE);
1065:                if (rateInd < 0) {
1066:                    // no rate response, assume success?
1067:                    return false;
1068:                }
1069:
1070:                long start = Math.max(getReportedStartTime(t), minStart);
1071:                long end = getReportedEndTime(t);
1072:                double taskTotal = getTotalQuantity(t, start, end);
1073:                if ((!ar.isSuccess()) && (taskTotal > 0)) {
1074:                    return true;
1075:                }
1076:                if (!includeTemps || !ar.isPhased()) {
1077:                    return false;
1078:                }
1079:
1080:                int startInd = LogisticsInventoryFormatter.getIndexForType(ats,
1081:                        AspectType.START_TIME);
1082:                int endInd = LogisticsInventoryFormatter.getIndexForType(ats,
1083:                        AspectType.END_TIME);
1084:
1085:                double totalQty = 0;
1086:                long maxPhaseEnd = 0;
1087:
1088:                for (Enumeration phasedResults = ar.getPhasedResults(); phasedResults
1089:                        .hasMoreElements();) {
1090:                    double[] results = (double[]) phasedResults.nextElement();
1091:                    double phaseRate = results[rateInd];
1092:                    double phaseStart = results[startInd];
1093:                    double phaseEnd = results[endInd];
1094:                    long arStart = Math.max((long) phaseStart, start);
1095:                    //long arEnd = (long) Math.min(end, (long) phaseEnd);
1096:                    totalQty += getTotalQuantity(t, phaseRate, arStart,
1097:                            (long) phaseEnd);
1098:                    maxPhaseEnd = Math.max((long) phaseEnd, maxPhaseEnd);
1099:                }
1100:                // When doing all this addition of double rates some precision is lost so we
1101:                // need a small offset to avoid "false shortfalls".
1102:                double offset = 0.001d;
1103:                if (taskTotal > (totalQty + offset)) {
1104:                    return true;
1105:                } else if (maxPhaseEnd > getEndTime(t)) {
1106:                    return true;
1107:                }
1108:                return false;
1109:            }
1110:
1111:            public boolean isActualShortfall(Task t, boolean includeTemps) {
1112:                PlanElement pe = t.getPlanElement();
1113:                if (pe == null) {
1114:                    return false;
1115:                }
1116:                AllocationResult ar = pe.getReportedResult();
1117:                if (ar == null) {
1118:                    ar = pe.getEstimatedResult();
1119:                }
1120:                if ((ar == null) || isProjection(t)) {
1121:                    return false;
1122:                }
1123:                if (!ar.isSuccess()) {
1124:                    return true;
1125:                }
1126:                double unfilled = 0;
1127:                double arEndTime = 0;
1128:                double taskEndTime = getEndTime(t);
1129:
1130:                if (!ar.isPhased()) {
1131:                    unfilled = getQuantity(t) - getQuantity(ar);
1132:                    arEndTime = getEndTime(ar);
1133:                } else {
1134:                    int[] ats = ar.getAspectTypes();
1135:                    int qtyInd = -1;
1136:                    int endInd = -1;
1137:                    double totalQty = 0;
1138:                    qtyInd = LogisticsInventoryFormatter.getIndexForType(ats,
1139:                            AspectType.QUANTITY);
1140:                    endInd = LogisticsInventoryFormatter.getIndexForType(ats,
1141:                            AspectType.END_TIME);
1142:                    Enumeration phasedResults = ar.getPhasedResults();
1143:                    while (phasedResults.hasMoreElements()) {
1144:                        double[] results = (double[]) phasedResults
1145:                                .nextElement();
1146:                        if (qtyInd != -1) {
1147:                            totalQty += results[qtyInd];
1148:                        } else {
1149:                            totalQty = getQuantity(t);
1150:                        }
1151:                        double endTime = (endInd == -1 ? taskEndTime
1152:                                : results[endInd]);
1153:                        arEndTime = Math.max(arEndTime, endTime);
1154:                    }
1155:                    unfilled = getQuantity(t) - totalQty;
1156:                }
1157:                double offset = 0.001d;
1158:                if ((unfilled - offset) > 0) {
1159:                    return true;
1160:                } else if (includeTemps && (arEndTime > taskEndTime)) {
1161:                    return true;
1162:                }
1163:                return false;
1164:            }
1165:
1166:            public double getGrantedQuantity(Task t) {
1167:                PlanElement pe = t.getPlanElement();
1168:                if (pe == null) {
1169:                    return 0;
1170:                }
1171:                AllocationResult ar = pe.getReportedResult();
1172:                if (ar == null) {
1173:                    ar = pe.getEstimatedResult();
1174:                }
1175:                double taskQty;
1176:                if (ar == null) {
1177:                    taskQty = getTotalQuantity(t);
1178:                } else if (isProjection(t)) {
1179:                    if (ar.isSuccess()) {
1180:                        taskQty = 0;
1181:                    } else {
1182:                        taskQty = getTotalQuantity(t);
1183:                    }
1184:                } else {
1185:                    taskQty = getQuantity(ar);
1186:                }
1187:                return taskQty;
1188:            }
1189:
1190:            public double getActualDemand(Task task, long startTime,
1191:                    long endTime, long minStart) {
1192:                if (!isProjection(task)) {
1193:                    return getQuantity(task);
1194:                }
1195:                long start = (long) getPreferenceBestValue(task,
1196:                        AspectType.START_TIME);
1197:                long end = (long) getPreferenceBestValue(task,
1198:                        AspectType.END_TIME);
1199:                start = Math.max(start, minStart);
1200:                if ((start >= end) || (start >= endTime - 1)) {
1201:                    // task is not in this interval
1202:                    return 0.0;
1203:                }
1204:                // get the time spanned (if any) for this task within the specified bucket
1205:                long interval_start = Math.max(start, startTime);
1206:                long interval_end = Math.min(end, endTime);
1207:                long time_spanned = interval_end - interval_start;
1208:                // add quantity for overlapping timespan
1209:                Rate rate = getRate(task, interval_start, interval_end);
1210:                try {
1211:                    Scalar scalar = (Scalar) rate.computeNumerator(Duration
1212:                            .newMilliseconds((double) time_spanned));
1213:                    return getDouble(scalar);
1214:                } catch (Exception e) {
1215:                    if (logger.isErrorEnabled()) {
1216:                        logger.error(taskDesc(task) + " Start: "
1217:                                + (new Date(start)) + " time_spanned: "
1218:                                + time_spanned);
1219:                    }
1220:                    return 0.0;
1221:                }
1222:            }
1223:
1224:            public Collection getDailyQuantities(Task task) {
1225:                if (task == null) {
1226:                    return null;
1227:                }
1228:
1229:                long startTime = -1;
1230:                if (getPreferenceBest(task, AspectType.START_TIME) != null) {
1231:                    startTime = getStartTime(task);
1232:                }
1233:
1234:                long endTime = getEndTime(task);
1235:                if (startTime == -1) {
1236:                    startTime = endTime - 1;
1237:                }
1238:
1239:                double dailyRate = 0.0d;
1240:
1241:                if (!isProjection(task)) {
1242:                    dailyRate = getQuantity(task);
1243:                } else {
1244:                    Rate rate = null;
1245:
1246:                    PrepositionalPhrase pp_rate = task
1247:                            .getPrepositionalPhrase(Constants.Preposition.DEMANDRATE);
1248:                    if (pp_rate != null) {
1249:                        Object indObj = pp_rate.getIndirectObject();
1250:                        if (indObj instanceof  Schedule) {
1251:                            Schedule sched = (Schedule) indObj;
1252:                            Collection rate_elems = sched
1253:                                    .getOverlappingScheduleElements(startTime,
1254:                                            endTime);
1255:                            int n = (rate_elems == null ? 0 : rate_elems.size());
1256:                            if (n == 1) {
1257:                                ObjectScheduleElement ose = (ObjectScheduleElement) rate_elems
1258:                                        .iterator().next();
1259:                                rate = (Rate) ose.getObject();
1260:                            } else if (n > 1) {
1261:                                // return a schedule of daily rates
1262:                                List ret = new ArrayList(n);
1263:                                for (Iterator iter = rate_elems.iterator(); iter
1264:                                        .hasNext();) {
1265:                                    ObjectScheduleElement ose = (ObjectScheduleElement) iter
1266:                                            .next();
1267:                                    Rate r = (Rate) ose.getObject();
1268:                                    double d = getDailyQuantity(r);
1269:                                    ScheduleElement se = new QuantityScheduleElementImpl(
1270:                                            ose.getStartTime(), ose
1271:                                                    .getEndTime(), d);
1272:                                    ret.add(se);
1273:                                }
1274:                                return ret;
1275:                            }
1276:                        }
1277:                    }
1278:
1279:                    if (rate == null) {
1280:                        AspectValue best = getPreferenceBest(task,
1281:                                AlpineAspectType.DEMANDRATE);
1282:                        if (best != null) {
1283:                            rate = ((AspectRate) best).getRateValue();
1284:                        }
1285:                    }
1286:
1287:                    if (rate != null) {
1288:                        dailyRate = getDailyQuantity(rate);
1289:                    }
1290:                }
1291:
1292:                ScheduleElement se = new QuantityScheduleElementImpl(startTime,
1293:                        endTime, dailyRate);
1294:                return Collections.singleton(se);
1295:            }
1296:
1297:            public Collection getReportedDailyQuantities(Task task) {
1298:                if (task == null) {
1299:                    return null;
1300:                }
1301:                PlanElement pe = task.getPlanElement();
1302:                if (pe == null) {
1303:                    return null;
1304:                }
1305:                AllocationResult ar = pe.getReportedResult();
1306:                if (ar == null) {
1307:                    ar = pe.getEstimatedResult();
1308:                }
1309:                if (ar == null) {
1310:                    return null;
1311:                }
1312:                return getReportedDailyQuantities(task, ar);
1313:            }
1314:
1315:            // This function is based heavily off of logAllocationResult in the
1316:            // LogisticsInventoryFormatter
1317:            public Collection getReportedDailyQuantities(Task task,
1318:                    AllocationResult ar) {
1319:                if (!ar.isSuccess()) {
1320:                    // logger.warn("Allocation Result was failure. Not returning.");
1321:                    return null;
1322:                }
1323:
1324:                if (!ar.isPhased()) {
1325:                    long endTime = (long) getEndTime(ar);
1326:                    long startTime = 0;
1327:
1328:                    if (isProjection(task)) {
1329:                        startTime = (long) getStartTime(ar);
1330:                        if (startTime == endTime) {
1331:                            startTime = endTime - 1;
1332:                        }
1333:                    } else {
1334:                        // if supply or withdraw task then we don't have a start time
1335:                        startTime = endTime - 1;
1336:                    }
1337:                    if (startTime == endTime) {
1338:                        startTime = endTime - 1;
1339:                    }
1340:
1341:                    double quantity = 0;
1342:                    try {
1343:                        quantity = getQuantity(task, ar);
1344:                    } catch (RuntimeException re) {
1345:                        throw re;
1346:                    }
1347:
1348:                    return Collections
1349:                            .singleton(new QuantityScheduleElementImpl(
1350:                                    startTime, endTime, quantity));
1351:                }
1352:
1353:                Collection returnQSEs = new HashSet();
1354:
1355:                int[] ats = ar.getAspectTypes();
1356:                int qtyInd = -1;
1357:                if (isProjection(task)) {
1358:                    qtyInd = LogisticsInventoryFormatter.getIndexForType(ats,
1359:                            AlpineAspectType.DEMANDRATE);
1360:                } else {
1361:                    qtyInd = LogisticsInventoryFormatter.getIndexForType(ats,
1362:                            AspectType.QUANTITY);
1363:                }
1364:                int startInd = LogisticsInventoryFormatter.getIndexForType(ats,
1365:                        AspectType.START_TIME);
1366:                int endInd = LogisticsInventoryFormatter.getIndexForType(ats,
1367:                        AspectType.END_TIME);
1368:                Enumeration phasedResults = ar.getPhasedResults();
1369:                while (phasedResults.hasMoreElements()) {
1370:                    double[] results = (double[]) phasedResults.nextElement();
1371:                    long startTime = 0;
1372:                    if (startInd != -1) {
1373:                        startTime = (long) results[startInd];
1374:                    }
1375:                    long endTime = 0;
1376:                    if (endInd == -1) {
1377:                        /** MWD The following line of code which replaces the
1378:                         *  allocation result end time with the task end time
1379:                         *  is only due to a current error in the
1380:                         *  UniversalAllocator.   The UA is only setting
1381:                         *  the start time in the allocation result. There
1382:                         *  is a bug in and when the UA is fixed this line
1383:                         *  of code should be removed. If there is no end time
1384:                         *  in the allocation result, none should be appended.
1385:                         *  GUI needs the end
1386:                         *  times for the rates.
1387:                         */
1388:                        endTime = getEndTime(task);
1389:                    } else {
1390:                        endTime = (long) results[endInd];
1391:                    }
1392:                    if ((qtyInd < 0) || (qtyInd >= results.length)) {
1393:                        // logger.error("qtyInd is " + qtyInd + " - No Qty in this phase of allocation results:");
1394:                        continue;
1395:                    }
1396:                    double dailyRate = convertResultsToDailyRate(task,
1397:                            results[qtyInd]);
1398:                    double quantity = dailyRate;
1399:
1400:                    if (startTime == 0) {
1401:                        startTime = endTime - 1;
1402:                    }
1403:                    if (startTime > endTime) {
1404:                        // logger.error("Error - start time can't be later than end time");
1405:                        continue;
1406:                    }
1407:                    // logger.warn("2nd Method adding (" + startTime + ", " + endTime + ", " + quantity + ")");
1408:                    returnQSEs.add(new QuantityScheduleElementImpl(startTime,
1409:                            endTime, quantity));
1410:                }
1411:                // logger.warn("AR Was Null. Result of " + returnQSEs.size() + " is alternate method");
1412:                return returnQSEs;
1413:            }
1414:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.