001: /*
002: * <copyright>
003: * Copyright 1997-2003 BBNT Solutions, LLC
004: * under sponsorship of the Defense Advanced Research Projects Agency (DARPA).
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the Cougaar Open Source License as published by
008: * DARPA on the Cougaar Open Source Website (www.cougaar.org).
009: *
010: * THE COUGAAR SOFTWARE AND ANY DERIVATIVE SUPPLIED BY LICENSOR IS
011: * PROVIDED 'AS IS' WITHOUT WARRANTIES OF ANY KIND, WHETHER EXPRESS OR
012: * IMPLIED, INCLUDING (BUT NOT LIMITED TO) ALL IMPLIED WARRANTIES OF
013: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND WITHOUT
014: * ANY WARRANTIES AS TO NON-INFRINGEMENT. IN NO EVENT SHALL COPYRIGHT
015: * HOLDER BE LIABLE FOR ANY DIRECT, SPECIAL, INDIRECT OR CONSEQUENTIAL
016: * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE OF DATA OR PROFITS,
017: * TORTIOUS CONDUCT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
018: * PERFORMANCE OF THE COUGAAR SOFTWARE.
019: * </copyright>
020: */
021:
022: package org.cougaar.logistics.servlet;
023:
024: import java.util.*;
025:
026: import org.cougaar.planning.ldm.plan.*;
027: import org.cougaar.planning.ldm.asset.Asset;
028: import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
029: import org.cougaar.planning.ldm.asset.ItemIdentificationPG;
030: import org.cougaar.logistics.ldm.Constants;
031: import org.cougaar.glm.ldm.asset.Organization;
032: import org.cougaar.glm.ldm.plan.GeolocLocation;
033: import org.cougaar.glm.ldm.plan.AlpineAspectType;
034: import org.cougaar.planning.ldm.plan.AspectValue;
035: import org.cougaar.planning.ldm.measure.*;
036: import org.cougaar.logistics.plugin.inventory.MaintainedItem;
037: import org.cougaar.logistics.plugin.inventory.TaskUtils;
038: import org.cougaar.logistics.plugin.inventory.TimeUtils;
039: import org.cougaar.util.log.Logger;
040: import org.cougaar.util.Random;
041: import java.io.PrintWriter;
042:
043: /**
044: * The LocalLevel2Mapper expands a Level2Task into it's adjusted
045: * (by Level6 tasks) equivilent
046: *
047: * @see Level2TranslatorPlugin
048: * @see Level2TranslatorModule
049: **/
050:
051: public class MapperPrinter {
052:
053: protected HashMap level2To6Map;
054: protected HashMap endTimeMap;
055: protected TreeMap supplyTaskMap;
056: protected TreeMap projTaskMap;
057:
058: protected transient Logger logger;
059: protected transient TaskUtils taskUtils;
060:
061: protected MapperServlet servlet;
062: protected PrintWriter writer;
063: protected String supplyType;
064:
065: public MapperPrinter(MapperServlet aServlet) {
066: level2To6Map = new HashMap();
067: endTimeMap = new HashMap();
068: supplyTaskMap = new TreeMap();
069: projTaskMap = new TreeMap();
070: servlet = aServlet;
071: logger = (Logger) servlet.getLoggingService(this );
072: }
073:
074: public void printDemandStats(Collection level2Tasks,
075: Collection level6Tasks, Collection supplyTasks,
076: String aSupplyType, String org, PrintWriter out) {
077:
078: writer = out;
079: supplyType = aSupplyType;
080:
081: mapSupplyTasks(supplyTasks);
082: mapProjTasks(level6Tasks);
083:
084: double totalL2Qty = getTotalProjectionQty(level2Tasks);
085: double totalL6ProjQty = getTotalProjectionQty(level6Tasks);
086: double totalL6ActualQty = getTotalSupplyQty(supplyTasks);
087: double countedL6ProjQty = getCountedProjectionQty(level6Tasks);
088: double countedL2ProjQty = getCountedProjectionQty(level2Tasks);
089:
090: /* MWD Remove
091: if(!level2Tasks.isEmpty())
092: writer.println("Level 2 Item key :" + getTaskKey((Task)level2Tasks.iterator().next()));
093: */
094:
095: writer.println("<head>");
096: writer.println("<title> Total Demand for " + org + "</title>");
097: writer.println("<body><p><h4> Total Demand for " + org
098: + "</h4><p>");
099:
100: writer.println("On "
101: + getTimeUtils()
102: .dateString(servlet.currentTimeMillis())
103: + ". At Agent: " + org + " - " + supplyType + "<br>");
104: writer.println(" - Total Actual Demand:" + totalL6ActualQty
105: + "<br>");
106: writer.println(" - Total L6 Projected Demand:"
107: + totalL6ProjQty + "<br>");
108: writer.println(" - Total Level 2 Demand: " + totalL2Qty
109: + "<br>");
110: writer.println(" - Total Counted L6 Projected Demand: "
111: + countedL6ProjQty + "<br>");
112: writer.println(" - Total Counted L2 Projected Demand: "
113: + countedL2ProjQty + "<br>");
114:
115: writer.println("</p><p><br><b> Actuals </b><p>");
116: printSupplyTasksByCustDodic();
117: writer
118: .println("</p><p><br><b> Counted Projected Demand </b><p>");
119: printProjTasksByCustDodic();
120: writer.println("</body>");
121:
122: }
123:
124: public void printSupplyTasksByCustDodic() {
125: Set entries = supplyTaskMap.entrySet();
126: Iterator entryIt = entries.iterator();
127: while (entryIt.hasNext()) {
128: Map.Entry entry = (Map.Entry) entryIt.next();
129: Collection supplyTasks = (Collection) entry.getValue();
130: double totalDOQty = getTotalSupplyQty(supplyTasks);
131: writer.println("Actual: " + entry.getKey() + " -: "
132: + totalDOQty + "<br>");
133: }
134: }
135:
136: public void printProjTasksByCustDodic() {
137: Set entries = projTaskMap.entrySet();
138: Iterator entryIt = entries.iterator();
139: while (entryIt.hasNext()) {
140: Map.Entry entry = (Map.Entry) entryIt.next();
141: Collection projTasks = (Collection) entry.getValue();
142: double totalDOQty = getCountedProjectionQty(projTasks);
143: writer.println("Proj: " + entry.getKey() + " -: "
144: + totalDOQty + "<br>");
145: }
146: }
147:
148: protected long getCountedStartTime(Task task) {
149: long start = getTaskUtils().getStartTime(task);
150: long legalProjectionStart = start;
151: Long custLastActual = (Long) endTimeMap.get(getTaskKey(task));
152: if (custLastActual != null) {
153: legalProjectionStart = custLastActual.longValue()
154: + getTimeUtils().MSEC_PER_DAY;
155: }
156: return Math.max(start, legalProjectionStart);
157: }
158:
159: public double getCountedProjectionQty(Collection projTasks) {
160: Iterator projTaskIt = projTasks.iterator();
161: double totalQty = 0.0;
162: while (projTaskIt.hasNext()) {
163: Task projTask = (Task) projTaskIt.next();
164: long countedStartTime = getCountedStartTime(projTask);
165: long end = getTaskUtils().getEndTime(projTask);
166: if (end > countedStartTime) {
167: totalQty += deriveTotalQty(countedStartTime, end,
168: projTask);
169: }
170: }
171: return totalQty;
172: }
173:
174: public double getTotalProjectionQty(Collection projTasks) {
175: Iterator projTaskIt = projTasks.iterator();
176: double totalQty = 0.0;
177: while (projTaskIt.hasNext()) {
178: Task projTask = (Task) projTaskIt.next();
179: long start = getTaskUtils().getStartTime(projTask);
180: long end = getTaskUtils().getEndTime(projTask);
181: totalQty += deriveTotalQty(start, end, projTask);
182: }
183: return totalQty;
184: }
185:
186: public double getTotalSupplyQty(Collection supplyTasks) {
187: Iterator supplyTaskIt = supplyTasks.iterator();
188: double totalQty = 0.0;
189: while (supplyTaskIt.hasNext()) {
190: Task supplyTask = (Task) supplyTaskIt.next();
191: long end = getTaskUtils().getEndTime(supplyTask);
192: //logger.warn("MapperSupplyTask: " + getTaskUtils().taskDesc(supplyTask));
193: totalQty += getTaskUtils().getQuantity(supplyTask);
194: }
195: return totalQty;
196: }
197:
198: protected TaskUtils getTaskUtils() {
199: return servlet.getTaskUtils();
200: }
201:
202: protected TimeUtils getTimeUtils() {
203: return servlet.getTimeUtils();
204: }
205:
206: protected void mapCustomerEndTimes(Collection supplyTasks) {
207: endTimeMap.clear();
208: Iterator supplyTaskIt = supplyTasks.iterator();
209: while (supplyTaskIt.hasNext()) {
210: Task supplyTask = (Task) supplyTaskIt.next();
211: long endTime = getTaskUtils().getEndTime(supplyTask);
212: Object org = getTaskUtils().getCustomer(supplyTask);
213: if (org != null) {
214: Long lastActualSeen = (Long) endTimeMap.get(org);
215: if ((lastActualSeen == null)
216: || (endTime > lastActualSeen.longValue())) {
217: endTimeMap.put(org, new Long(endTime));
218: }
219: }
220: }
221: }
222:
223: protected String getTaskKey(Task task) {
224: Object org = getTaskUtils().getCustomer(task);
225: String taskItem = getTaskUtils().getTaskItemName(task);
226: String key = taskItem + org.toString();
227: return key;
228: }
229:
230: protected String getLevel2TaskKey(Task task) {
231: Object org = getTaskUtils().getCustomer(task);
232: String assetName = "Level2" + supplyType;
233: String taskItem = assetName + "(" + assetName + " asset)";
234: String key = taskItem + org.toString();
235: return key;
236: }
237:
238: protected void mapSupplyTasks(Collection supplyTasks) {
239: endTimeMap.clear();
240: supplyTaskMap.clear();
241:
242: Iterator supplyTaskIt = supplyTasks.iterator();
243: while (supplyTaskIt.hasNext()) {
244: Task supplyTask = (Task) supplyTaskIt.next();
245: long endTime = getTaskUtils().getEndTime(supplyTask);
246: String key = getTaskKey(supplyTask);
247: if (key != null) {
248: Long lastActualSeen = (Long) endTimeMap.get(key);
249: if ((lastActualSeen == null)
250: || (endTime > lastActualSeen.longValue())) {
251: endTimeMap.put(key, new Long(endTime));
252: }
253: HashSet tasks = (HashSet) supplyTaskMap.get(key);
254: if (tasks == null) {
255: tasks = new HashSet();
256: supplyTaskMap.put(key, tasks);
257: }
258: tasks.add(supplyTask);
259: }
260: String l2Key = getLevel2TaskKey(supplyTask);
261: Long lastL2ActualSeen = (Long) endTimeMap.get(l2Key);
262: if ((lastL2ActualSeen == null)
263: || (endTime > lastL2ActualSeen.longValue())) {
264: endTimeMap.put(l2Key, new Long(endTime));
265: }
266: }
267: }
268:
269: protected void mapProjTasks(Collection projTasks) {
270: projTaskMap.clear();
271: Iterator projTaskIt = projTasks.iterator();
272: while (projTaskIt.hasNext()) {
273: Task projTask = (Task) projTaskIt.next();
274: String key = getTaskKey(projTask);
275: if (key != null) {
276: HashSet tasks = (HashSet) projTaskMap.get(key);
277: if (tasks == null) {
278: tasks = new HashSet();
279: projTaskMap.put(key, tasks);
280: }
281: tasks.add(projTask);
282: }
283: }
284: }
285:
286: protected void mapLevel2ToLevel6(Collection level2s,
287: Collection level6s) {
288: //alreadyMapped is only here to print out the error below. This turns out
289: //to be a nominal case where level 6s overlap more than one level2. Commented
290: //out the debug code for right now. Can uncomment if any need to re-examine.
291: //HashSet alreadyMapped = new HashSet();
292: level2To6Map.clear();
293: Iterator level2It = level2s.iterator();
294: while (level2It.hasNext()) {
295: Task level2Task = (Task) level2It.next();
296: long l2StartTime = getTaskUtils().getStartTime(level2Task);
297: long l2EndTime = getTaskUtils().getEndTime(level2Task);
298: Object l2Cust = getTaskUtils().getCustomer(level2Task);
299: Iterator level6It = level6s.iterator();
300: ArrayList mappedL6s = new ArrayList();
301: while (level6It.hasNext()) {
302: Task level6Task = (Task) level6It.next();
303: long l6StartTime = getTaskUtils().getStartTime(
304: level6Task);
305: long l6EndTime = getTaskUtils().getEndTime(level6Task);
306: Object l6Cust = getTaskUtils().getCustomer(level2Task);
307: if ((l6StartTime < l2EndTime)
308: && (l6EndTime > l2StartTime)) {
309: if (l2Cust.equals(l6Cust)) {
310: mappedL6s.add(level6Task);
311: /**
312: if ((alreadyMapped.contains(level6Task)) &&
313: logger.isWarnEnabled()) {
314: //Apparently lots overlap commented out alreadyMapped and all debug related code.
315: logger.warn("The following task has already been mapped: " + level6Task.getUID() + " startTime: " +
316: new Date(l6StartTime) + " endTime: " +
317: new Date(l6EndTime) + ". And the new overlapping L2 Task startTime " + new Date(l2StartTime) +
318: " and endTime is:" + new Date(l2EndTime));
319: } else {
320: alreadyMapped.add(level6Task);
321: }
322: **/
323: } else {
324: logger
325: .error("Unexpected Customer of level2Task "
326: + l2Cust
327: + " differs from level6 cust:"
328: + l6Cust);
329: }
330: }
331: }
332: level2To6Map.put(level2Task, mappedL6s);
333: }
334: }
335:
336: protected double deriveTotalQty(long bucketStart, long bucketEnd,
337: Collection projTasks) {
338: Iterator tasksIt = projTasks.iterator();
339: double totalQty = 0.0;
340: while (tasksIt.hasNext()) {
341: Task projTask = (Task) tasksIt.next();
342: double qty = deriveTotalQty(bucketStart, bucketEnd,
343: projTask);
344: totalQty += qty;
345: }
346: return totalQty;
347: }
348:
349: protected double deriveTotalQty(long bucketStart, long bucketEnd,
350: Task projTask) {
351:
352: long taskStart = getTaskUtils().getStartTime(projTask);
353: long taskEnd = getTaskUtils().getEndTime(projTask);
354: long start = Math.max(taskStart, bucketStart);
355: long end = Math.min(taskEnd, bucketEnd);
356: double qty = 0.0;
357: //duration in seconds
358: if (start < end) {
359: double duration = ((end - start) / 1000);
360: Rate rate = getTaskUtils().getRate(projTask);
361: qty = (getBaseUnitPerSecond(rate) * duration);
362: }
363: return qty;
364: }
365:
366: protected static double getBaseUnitPerSecond(Rate rate) {
367: if (rate instanceof CostRate) {
368: return ((CostRate) rate).getDollarsPerSecond();
369: } else if (rate instanceof CountRate) {
370: return ((CountRate) rate).getEachesPerSecond();
371: } else if (rate instanceof FlowRate) {
372: return ((FlowRate) rate).getGallonsPerSecond();
373: } else if (rate instanceof MassTransferRate) {
374: return ((MassTransferRate) rate).getShortTonsPerSecond();
375: } else if (rate instanceof TimeRate) {
376: return ((TimeRate) rate).getHoursPerSecond();
377: } // if
378: return 0.0;
379: }
380:
381: protected Rate newRateFromUnitPerSecond(Rate rate,
382: double unitsPerSecond) {
383: if (rate instanceof CostRate) {
384: return (CostRate.newDollarsPerSecond(unitsPerSecond));
385: } else if (rate instanceof CountRate) {
386: return (CountRate.newEachesPerSecond(unitsPerSecond));
387: } else if (rate instanceof FlowRate) {
388: return (FlowRate.newGallonsPerSecond(unitsPerSecond));
389: } else if (rate instanceof MassTransferRate) {
390: return (MassTransferRate
391: .newShortTonsPerSecond(unitsPerSecond));
392: } else if (rate instanceof TimeRate) {
393: return (TimeRate.newHoursPerSecond(unitsPerSecond));
394: } // if
395:
396: if (logger.isErrorEnabled()) {
397: logger.error("Unknown rate type");
398: }
399: return (CountRate.newEachesPerSecond(unitsPerSecond));
400: }
401:
402: }
|