0001: /*
0002: *
0003: * <copyright>
0004: *
0005: * Copyright 1997-2004 BBNT Solutions, LLC
0006: * under sponsorship of the Defense Advanced Research Projects
0007: * Agency (DARPA).
0008: *
0009: * You can redistribute this software and/or modify it under the
0010: * terms of the Cougaar Open Source License as published on the
0011: * Cougaar Open Source Website (www.cougaar.org).
0012: *
0013: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0014: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0015: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0016: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0017: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0018: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0019: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0020: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0021: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0022: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0023: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0024: *
0025: * </copyright>
0026: */
0027:
0028: package org.cougaar.logistics.servlet;
0029:
0030: import java.io.IOException;
0031: import java.io.FileNotFoundException;
0032: import java.io.ObjectOutputStream;
0033: import java.io.InputStreamReader;
0034: import java.io.BufferedReader;
0035: import java.io.InputStream;
0036: import java.io.OutputStream;
0037: import java.io.OutputStreamWriter;
0038: import java.io.PrintWriter;
0039: import java.io.File;
0040: import java.io.BufferedReader;
0041: import java.io.FileReader;
0042: import java.io.StreamCorruptedException;
0043:
0044: import java.net.URLEncoder;
0045: import java.net.URL;
0046: import java.net.URLConnection;
0047: import java.util.ArrayList;
0048: import java.util.Arrays;
0049: import java.util.Collection;
0050: import java.util.Collections;
0051: import java.util.Date;
0052: import java.util.Iterator;
0053: import java.util.List;
0054: import java.util.Set;
0055: import java.util.SortedSet;
0056: import java.util.TreeSet;
0057: import java.util.Comparator;
0058: import java.util.TimeZone;
0059:
0060: import java.text.SimpleDateFormat;
0061: import java.text.DecimalFormat;
0062:
0063: import javax.servlet.Servlet;
0064: import javax.servlet.ServletException;
0065: import javax.servlet.http.HttpServlet;
0066: import javax.servlet.http.HttpServletRequest;
0067: import javax.servlet.http.HttpServletResponse;
0068:
0069: import org.cougaar.core.mts.MessageAddress;
0070: import org.cougaar.core.service.AgentIdentificationService;
0071: import org.cougaar.core.service.BlackboardQueryService;
0072: import org.cougaar.core.service.LoggingService;
0073: import org.cougaar.core.service.AlarmService;
0074: import org.cougaar.core.service.wp.WhitePagesService;
0075: import org.cougaar.core.servlet.BaseServletComponent;
0076: import org.cougaar.core.util.UID;
0077: import org.cougaar.core.wp.ListAllAgents;
0078:
0079: import org.cougaar.planning.ldm.plan.Task;
0080: import org.cougaar.planning.ldm.plan.Verb;
0081: import org.cougaar.planning.ldm.plan.Workflow;
0082: import org.cougaar.planning.ldm.plan.AllocationResult;
0083: import org.cougaar.planning.ldm.plan.PlanElement;
0084: import org.cougaar.planning.ldm.plan.AssetTransfer;
0085: import org.cougaar.planning.ldm.plan.Disposition;
0086: import org.cougaar.planning.ldm.plan.Aggregation;
0087: import org.cougaar.planning.ldm.plan.Expansion;
0088: import org.cougaar.planning.ldm.plan.Allocation;
0089: import org.cougaar.planning.servlet.data.xml.XMLWriter;
0090:
0091: import org.cougaar.logistics.servlet.data.shortfall.ShortfallShortData;
0092: import org.cougaar.logistics.servlet.data.shortfall.FullShortfallData;
0093: import org.cougaar.logistics.servlet.data.shortfall.ShortfallInventoryRule;
0094:
0095: import org.cougaar.util.UnaryPredicate;
0096: import org.cougaar.util.Filters;
0097: import org.cougaar.util.ConfigFinder;
0098:
0099: import org.cougaar.glm.ldm.oplan.Oplan;
0100: import org.cougaar.glm.ldm.oplan.OrgActivity;
0101: import org.cougaar.glm.ldm.plan.GeolocLocation;
0102:
0103: import org.cougaar.logistics.plugin.inventory.ShortfallSummary;
0104: import org.cougaar.logistics.plugin.inventory.ShortfallInventory;
0105: import org.cougaar.logistics.plugin.inventory.ShortfallPeriod;
0106: import org.cougaar.logistics.plugin.inventory.LogisticsInventoryFormatter;
0107: import org.cougaar.logistics.plugin.inventory.TimeUtils;
0108:
0109: /**
0110: * A <code>Servlet</code>, loaded by the
0111: * <code>SimpleServletComponent</code>, that generates
0112: * HTML, XML, and serialized-Object views of Task completion
0113: * information.
0114: */
0115: public class ShortfallAlertServlet extends BaseServletComponent {
0116: protected static final UnaryPredicate SHORTFALL_SUMMARY_PRED = new UnaryPredicate() {
0117: public boolean execute(Object o) {
0118: return (o instanceof ShortfallSummary);
0119: }
0120: };
0121:
0122: protected static UnaryPredicate OPLAN_PREDICATE = new UnaryPredicate() {
0123: public boolean execute(Object o) {
0124: return (o instanceof Oplan);
0125: }
0126: };
0127:
0128: protected static UnaryPredicate ORG_ACTIVITY_PREDICATE = new UnaryPredicate() {
0129: public boolean execute(Object o) {
0130: return (o instanceof OrgActivity);
0131: }
0132: };
0133:
0134: protected static final String[] iframeBrowsers = { "mozilla/5",
0135: "msie 5", "msie 6" };
0136:
0137: protected static final String RULE_CONFIG_FILE = "ShortfallAlertConfig.txt";
0138:
0139: protected static final String USER_MODE = "USER_MODE";
0140:
0141: public static final double DEFAULT_RED_THRESHOLD = 4;
0142:
0143: public static final double DEFAULT_YELLOW_THRESHOLD = 1;
0144:
0145: protected static final int MAX_AGENT_FRAMES = 18;
0146:
0147: protected static final int RED_PERCENT_SHORTFALL_THRESHOLD = 20;
0148:
0149: protected static final int YELLOW_PERCENT_SHORTFALL_THRESHOLD = 10;
0150:
0151: protected String path;
0152: //protected ArrayList rulesList=new ArrayList();
0153:
0154: protected MessageAddress localAgent;
0155:
0156: protected String encLocalAgent;
0157:
0158: protected AgentIdentificationService agentIdService;
0159: protected BlackboardQueryService blackboardQueryService;
0160: protected WhitePagesService whitePagesService;
0161:
0162: protected final Object lock = new Object();
0163: protected LoggingService logger;
0164:
0165: protected AlarmService alarmService;
0166:
0167: protected static boolean setTimeZone = false;
0168:
0169: protected static SimpleDateFormat dayFormat = new SimpleDateFormat(
0170: "MM/dd/yyyy");
0171: protected static SimpleDateFormat hourFormat = new SimpleDateFormat(
0172: "MM/dd/yyyy HH:mm");
0173:
0174: protected boolean userMode = false;
0175:
0176: public ShortfallAlertServlet() {
0177: super ();
0178: path = getDefaultPath();
0179: setTimeZonesInit();
0180: }
0181:
0182: protected void setTimeZonesInit() {
0183: if (!setTimeZone) {
0184: dayFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
0185: hourFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
0186: setTimeZone = true;
0187: }
0188: }
0189:
0190: public void setParameter(Object o) {
0191: if (o instanceof String) {
0192: path = (String) o;
0193: } else if (o instanceof List) {
0194: List l = (List) o;
0195: if (!(l.isEmpty())) {
0196: path = (String) l.iterator().next();
0197: }
0198: if (l.size() > 1) {
0199: Object o2 = l.get(1);
0200: if (!(o2 instanceof String)) {
0201: throw new IllegalArgumentException(
0202: "Expecting third optional argument as a string, not ("
0203: + o2 + ")");
0204: }
0205: String[] keyAndValue = ((String) o2).split("=");
0206: if ((keyAndValue.length == 2)
0207: && (keyAndValue[0].trim().equals(USER_MODE))
0208: && (!(keyAndValue[1].trim().equals("")))) {
0209: userMode = keyAndValue[1].trim().toLowerCase()
0210: .equals("true");
0211: } else {
0212: throw new IllegalArgumentException(
0213: "Optional second argument should be "
0214: + USER_MODE + "=<true or false>");
0215: }
0216: }
0217: } else if (o == null) {
0218: // ignore
0219: } else {
0220: throw new IllegalArgumentException("Invalid parameter: "
0221: + o);
0222: }
0223: }
0224:
0225: protected String getDefaultPath() {
0226: return "/shortfall";
0227: }
0228:
0229: protected String getPath() {
0230: return path;
0231: }
0232:
0233: protected Servlet createServlet() {
0234: return new ShortfallServlet();
0235: }
0236:
0237: public void setAgentIdentificationService(
0238: AgentIdentificationService agentIdService) {
0239: this .agentIdService = agentIdService;
0240: if (agentIdService == null) {
0241: // Revocation
0242: } else {
0243: this .localAgent = agentIdService.getMessageAddress();
0244: encLocalAgent = formURLEncode(localAgent.getAddress());
0245: }
0246: }
0247:
0248: public void setAlarmService(AlarmService anAlarmService) {
0249: this .alarmService = anAlarmService;
0250: }
0251:
0252: public void setBlackboardQueryService(
0253: BlackboardQueryService blackboardQueryService) {
0254: this .blackboardQueryService = blackboardQueryService;
0255: }
0256:
0257: public void setWhitePagesService(WhitePagesService whitePagesService) {
0258: this .whitePagesService = whitePagesService;
0259: }
0260:
0261: public void load() {
0262: super .load();
0263: logger = (LoggingService) serviceBroker.getService(this ,
0264: LoggingService.class, null);
0265:
0266: getAndParseRules();
0267: }
0268:
0269: public void unload() {
0270: super .unload();
0271: if (whitePagesService != null) {
0272: serviceBroker.releaseService(this , WhitePagesService.class,
0273: whitePagesService);
0274: whitePagesService = null;
0275: }
0276: if (blackboardQueryService != null) {
0277: serviceBroker.releaseService(this ,
0278: BlackboardQueryService.class,
0279: blackboardQueryService);
0280: blackboardQueryService = null;
0281: }
0282: if (agentIdService != null) {
0283: serviceBroker.releaseService(this ,
0284: AgentIdentificationService.class, agentIdService);
0285: agentIdService = null;
0286: }
0287: }
0288:
0289: protected void getAndParseRules() {
0290: File ruleFile = ConfigFinder.getInstance().locateFile(
0291: RULE_CONFIG_FILE);
0292: ArrayList rulesList = new ArrayList();
0293:
0294: BufferedReader ruleStrings = null;
0295:
0296: if (ruleFile == null) {
0297: logger.warn("Config file for ShortfallAlertServlet - "
0298: + RULE_CONFIG_FILE + " could not be located");
0299: return;
0300: }
0301:
0302: try {
0303: ruleStrings = new BufferedReader(new FileReader(ruleFile));
0304: } catch (FileNotFoundException ex) {
0305: logger.warn("Config file for ShortfallAlertServlet - "
0306: + RULE_CONFIG_FILE + " not found");
0307: return;
0308: }
0309:
0310: try {
0311:
0312: String currLine = ruleStrings.readLine();
0313: while (currLine != null) {
0314: if (!(currLine.startsWith("#"))) {
0315: ShortfallInventoryRule rule = ShortfallInventoryRule
0316: .parseConfigFileLine(currLine);
0317: if (rule != null) {
0318: rulesList.add(rule);
0319: }
0320: }
0321: currLine = ruleStrings.readLine();
0322: }
0323:
0324: ruleStrings.close();
0325:
0326: } catch (IOException ex) {
0327: throw new RuntimeException(
0328: "Error while trying to parse config file for ShortfallAlertServlet!",
0329: ex);
0330: }
0331:
0332: ShortfallShortData.setRulesList(rulesList);
0333: }
0334:
0335: protected List getAllEncodedAgentNames() {
0336: try {
0337: // do full WP list (deprecated!)
0338: Set s = ListAllAgents.listAllAgents(whitePagesService);
0339: // URLEncode the names and sort
0340: List l = ListAllAgents.encodeAndSort(s);
0341: return l;
0342: } catch (Exception e) {
0343: throw new RuntimeException("List all agents failed", e);
0344: }
0345: }
0346:
0347: protected List getAllAgentNames() {
0348: try {
0349: // do full WP list (deprecated!)
0350: List result = new ArrayList(ListAllAgents
0351: .listAllAgents(whitePagesService));
0352: Collections.sort(result);
0353: return result;
0354: } catch (Exception e) {
0355: throw new RuntimeException("List all agents failed", e);
0356: }
0357: }
0358:
0359: protected Collection queryBlackboard(UnaryPredicate pred) {
0360: return blackboardQueryService.query(pred);
0361: }
0362:
0363: protected String getEncodedAgentName() {
0364: return encLocalAgent;
0365: }
0366:
0367: protected String formURLEncode(String name) {
0368: try {
0369: return URLEncoder.encode(name, "UTF-8");
0370: } catch (java.io.UnsupportedEncodingException e) {
0371: // should never happen
0372: throw new RuntimeException("Unable to encode to UTF-8?");
0373: }
0374: }
0375:
0376: protected String getTitlePrefix() {
0377: return ""; // must not contain special URL characters
0378: }
0379:
0380: public static String createTimeString(long time, long bucketSize,
0381: long startC0Day) {
0382: return createTimeString(time, bucketSize, calcCBucket(time,
0383: bucketSize, startC0Day));
0384:
0385: }
0386:
0387: public static String createTimeString(long time, long bucketSize,
0388: int cBucket) {
0389: String timeString = "";
0390: if (bucketSize == TimeUtils.MSEC_PER_DAY) {
0391: timeString = dayFormat.format(new Date(time));
0392: } else if (bucketSize == TimeUtils.MSEC_PER_HOUR) {
0393: timeString = hourFormat.format(new Date(time));
0394: }
0395: timeString = timeString + " (C" + cBucket + ")";
0396: return timeString;
0397: }
0398:
0399: public static int calcCBucket(long time, long bucketSize, long c0Day) {
0400: int cBucket = ((int) ((time - c0Day) / bucketSize));
0401: return cBucket;
0402: }
0403:
0404: /**
0405: * Inner-class that's registered as the servlet.
0406: */
0407: protected class ShortfallServlet extends HttpServlet {
0408: public void doGet(HttpServletRequest request,
0409: HttpServletResponse response) throws IOException,
0410: ServletException {
0411: (new ShortfallChecker(request, response)).execute();
0412: }
0413:
0414: public void doPost(HttpServletRequest request,
0415: HttpServletResponse response) throws IOException,
0416: ServletException {
0417: (new ShortfallChecker(request, response)).execute();
0418: }
0419: }
0420:
0421: /**
0422: * Inner-class to hold state and generate the response.
0423: */
0424: protected class ShortfallChecker {
0425:
0426: public static final int FORMAT_DATA = 0;
0427: public static final int FORMAT_XML = 1;
0428: public static final int FORMAT_HTML = 2;
0429:
0430: protected int format;
0431: protected boolean showTables;
0432:
0433: protected HttpServletRequest request;
0434: private HttpServletResponse response;
0435:
0436: // writer from the request for HTML output
0437: protected PrintWriter out;
0438:
0439: // various form params
0440: protected double redThreshold;
0441: protected double yellowThreshold;
0442: protected int refreshInterval;
0443:
0444: protected Date startCDay = null;
0445:
0446: public ShortfallChecker(HttpServletRequest request,
0447: HttpServletResponse response) {
0448: this .request = request;
0449: this .response = response;
0450: }
0451:
0452: public void execute() throws IOException, ServletException {
0453: try {
0454: redThreshold = Double.parseDouble(request
0455: .getParameter("redThreshold"));
0456: } catch (Exception e) {
0457: redThreshold = DEFAULT_RED_THRESHOLD;
0458: }
0459: try {
0460: yellowThreshold = Double.parseDouble(request
0461: .getParameter("yellowThreshold"));
0462: } catch (Exception e) {
0463: yellowThreshold = DEFAULT_YELLOW_THRESHOLD;
0464: }
0465: try {
0466: refreshInterval = Integer.parseInt(request
0467: .getParameter("refreshInterval"));
0468: } catch (Exception e) {
0469: refreshInterval = 0;
0470: }
0471: String formatParam = request.getParameter("format");
0472: if (formatParam == null) {
0473: format = FORMAT_HTML; // default
0474: } else if ("data".equals(formatParam)) {
0475: format = FORMAT_DATA;
0476: } else if ("xml".equals(formatParam)) {
0477: format = FORMAT_XML;
0478: } else if ("html".equals(formatParam)) {
0479: format = FORMAT_HTML;
0480: } else {
0481: format = FORMAT_HTML; // other
0482: }
0483:
0484: String showTablesParam = request.getParameter("showTables");
0485: if (showTablesParam == null) {
0486: showTables = false; // default
0487: } else if ("true".equals(showTablesParam)) {
0488: showTables = true;
0489: } else {
0490: showTables = false; // other
0491: }
0492:
0493: String viewType = request.getParameter("viewType");
0494: if (viewType == null) {
0495: viewDefault(); // default
0496: } else if ("viewAgentSubmit".equals(viewType)) {
0497: viewAgentSubmit();
0498: } else if ("viewAgentBig".equals(viewType)) {
0499: viewAgentBig();
0500: } else if ("viewAllAgents".equals(viewType)) {
0501: viewAllAgents();
0502: } else if ("viewSelectedAgents".equals(viewType)) {
0503: viewSelectedAgents();
0504: } else if ("viewManyAgents".equals(viewType)) {
0505: viewManyAgents();
0506: } else if ("viewTitle".equals(viewType)) {
0507: viewTitle();
0508: } else if ("viewAgentSmall".equals(viewType)) {
0509: viewAgentSmall();
0510: } else if ("viewMoreLink".equals(viewType)) {
0511: viewMoreLink();
0512: } else if ("viewNumShortfall".equals(viewType)) {
0513: viewNumShortfall();
0514: } else {
0515: viewDefault(); // other
0516: }
0517:
0518: // done
0519: }
0520:
0521: protected void viewDefault() throws IOException {
0522: if (format == FORMAT_HTML) {
0523: // generate outer frame page:
0524: // top: select "/agent"
0525: // middle: "viewAgentSubmit" buttons
0526: // bottom: "viewAgentBig" frame
0527: //
0528: // Note that the top and middle frames must be on
0529: // the same host, due to javascript security. Only
0530: // the bottom frame is updated by the submit button.
0531: response.setContentType("text/html");
0532: this .out = response.getWriter();
0533: out
0534: .print("<html><head><title>"
0535: + getTitlePrefix()
0536: + "Shortfall Viewer</title></head>"
0537: + "<frameset rows=\"10%,12%,78%\">\n"
0538: + "<frame src=\""
0539: + "/agents?format=select&suffix="
0540: + getEncodedAgentName()
0541: + "\" name=\"agentFrame\">\n"
0542: + "<frame src=\"/$"
0543: + getEncodedAgentName()
0544: + getPath()
0545: + "?viewType=viewAgentSubmit\" name=\"viewAgentSubmit\">\n"
0546: + "<frame src=\"/$"
0547: + getEncodedAgentName()
0548: + getPath()
0549: + "?viewType=viewAgentBig\" name=\"viewAgentBig\">\n"
0550: + "</frameset>\n"
0551: + "<noframes>Please enable frame support</noframes>"
0552: + "</html>\n");
0553: out.flush();
0554: } else {
0555: // for other formats, just get the data
0556: viewAgentBig();
0557: }
0558: }
0559:
0560: protected void viewAgentSubmit() throws IOException {
0561: response.setContentType("text/html");
0562: this .out = response.getWriter();
0563: // javascript based on PlanViewServlet
0564: out
0565: .print("<html>\n"
0566: + "<script language=\"JavaScript\">\n"
0567: + "<!--\n"
0568: + "function mySubmit() {\n"
0569: + " var obj = top.agentFrame.document.agent.name;\n"
0570: + " var encAgent = obj.value;\n"
0571: + " if (encAgent.charAt(0) == '.') {\n"
0572: + " alert(\"Please select an agent name\")\n"
0573: + " return false;\n"
0574: + " }\n"
0575: + " document.myForm.target=\"viewAgentBig\"\n"
0576: + " document.myForm.action=\"/$\"+encAgent+\""
0577: + getPath()
0578: + "\"\n"
0579: + " return true\n"
0580: + "}\n"
0581: + "// -->\n"
0582: + "</script>\n"
0583: + "<head>\n"
0584: + "<title>"
0585: + getTitlePrefix()
0586: + "Shortfall"
0587: + "</title>"
0588: + "</head>\n"
0589: + "<body>"
0590: + "<form name=\"myForm\" method=\"get\" "
0591: + "onSubmit=\"return mySubmit()\">\n"
0592: + getTitlePrefix()
0593: + "Select an agent above, "
0594: + "<input type=\"hidden\""
0595: + " name=\"viewType\""
0596: + " value=\"viewAgentBig\" "
0597: + "<input type=\"checkbox\""
0598: + " name=\"showTables\""
0599: + " value=\"true\" ");
0600: if (showTables) {
0601: out.print("checked");
0602: }
0603: out
0604: .println("> show table, \n"
0605: + "<input type=\"submit\""
0606: + " name=\"formSubmit\""
0607: + " value=\"Submit\"><br>");
0608: out.println("<a href=\"/$" + getEncodedAgentName()
0609: + getPath() + "?viewType=viewAllAgents"
0610: + "\" target=\"_top\">Show all agents.</a>");
0611: out
0612: .println("<a href=\"/$"
0613: + getEncodedAgentName()
0614: + getPath()
0615: + "?viewType=viewManyAgents"
0616: + "\" target=\"_top\"> Show several selected agents.</a>");
0617: out.println("</form>");
0618: out.print("</body></html>");
0619: out.flush();
0620: }
0621:
0622: protected void viewAgentBig() {
0623: // get result
0624: ShortfallShortData result = getShortfallData();
0625:
0626: // write data
0627: try {
0628: if (format == FORMAT_HTML) {
0629: // html
0630: response.setContentType("text/html");
0631: this .out = response.getWriter();
0632: printShortfallDataAsHTML(result);
0633: } else {
0634: // unsupported
0635: if (format == FORMAT_DATA) {
0636: // serialize
0637: //response.setContentType("application/binary");
0638: OutputStream out = response.getOutputStream();
0639: ObjectOutputStream oos = new ObjectOutputStream(
0640: out);
0641: oos.writeObject(result);
0642: oos.flush();
0643: } else {
0644: // xml
0645: response.setContentType("text/plain");
0646: OutputStream out = response.getOutputStream();
0647: out.write(("<?xml version='1.0'?>\n")
0648: .getBytes());
0649: XMLWriter w = new XMLWriter(
0650: new OutputStreamWriter(out));
0651: result.toXML(w);
0652: w.flush();
0653: }
0654: }
0655: } catch (IOException e) {
0656: e.printStackTrace();
0657: }
0658: }
0659:
0660: private void viewMoreLink() throws IOException {
0661: response.setContentType("text/html");
0662: out = response.getWriter();
0663: format = FORMAT_HTML; // Force html format
0664: out.println("<html>\n" + "<head>\n" + "<title>"
0665: + getTitlePrefix()
0666: + "Shortfall of More Agents</title>\n"
0667: + "</head>\n" + "<body>");
0668: String firstAgent = request.getParameter("firstAgent");
0669: if (firstAgent != null) {
0670: out.println("<A href=\"/$" + getEncodedAgentName()
0671: + getPath()
0672: + "?viewType=viewAllAgents&refreshInterval="
0673: + refreshInterval + "&redThreshold="
0674: + redThreshold + "&yellowThreshold="
0675: + yellowThreshold + "&firstAgent=" + firstAgent
0676: + "\" + target=\"_top\">\n"
0677: + "<h2><center>More Agents</h2></center>\n"
0678: + "</A>");
0679: }
0680: out.println("</body>\n</html>");
0681: }
0682:
0683: private void viewTitle() throws IOException {
0684: String title = request.getParameter("title");
0685: response.setContentType("text/html");
0686: if (refreshInterval > 0) {
0687: response.setHeader("Refresh", String
0688: .valueOf(refreshInterval));
0689: }
0690: List agents = getSelectedAgents();
0691: out = response.getWriter();
0692: format = FORMAT_HTML; // Force html format
0693: out.println("<html>\n" + "<head>\n" + "<title>" + title
0694: + "</title>\n" + "</head>\n" + "<body>\n"
0695: + "<h2><center>" + title + "</h2></center>\n");
0696: int totalAgents = agents.size();
0697: int nPages = (totalAgents + MAX_AGENT_FRAMES - 1)
0698: / MAX_AGENT_FRAMES;
0699: String[] menu = null;
0700: if (nPages > 1) {
0701: menu = new String[nPages];
0702: for (int page = 0; page < nPages; page++) {
0703: int nagents;
0704: int agent0;
0705: agent0 = (page * totalAgents + nPages - 1) / nPages;
0706: nagents = (((page + 1) * totalAgents + nPages - 1) / nPages)
0707: - agent0;
0708: String item = "Agents "
0709: + ((String) agents.get(agent0))
0710: + " Through "
0711: + ((String) agents
0712: .get(agent0 + nagents - 1));
0713: menu[page] = item;
0714: }
0715: }
0716: String this Page = request.getParameter("thisPage");
0717: printThresholdAndRefreshForm(out, agents, menu, this Page);
0718: out.println("</body>\n" + "</html>");
0719: }
0720:
0721: private void printThresholdAndRefreshForm(PrintWriter out,
0722: List selectedAgents, String[] menu, String this Page) {
0723: out.println("<form name=\"viewTitle\" action=\"/$"
0724: + getEncodedAgentName() + getPath()
0725: + "\"method=\"post\" target=\"_top\">");
0726: out.println("<table>");
0727: out.print("<tr><td>");
0728: out.print("Red Threshold");
0729: out.print("</td><td>");
0730: out
0731: .print("<input name=\"redThreshold\" type=\"text\" value=\""
0732: + redThreshold + "\">");
0733: out.print("</td><td>");
0734: out.print("Yellow Threshold");
0735: out.print("</td><td>");
0736: out
0737: .print("<input name=\"yellowThreshold\" type=\"text\" value=\""
0738: + yellowThreshold + "\">");
0739: out.println("</td><td rowspan=3>");
0740: if (menu != null) {
0741: out
0742: .println("<select name=\"page\" size=3 onclick=\"document.viewTitle.submit()\">");
0743: for (int page = 0; page < menu.length; page++) {
0744: out
0745: .println("<option value=\""
0746: + page
0747: + "\" onclick=\"document.viewTitle.submit()\">");
0748: out.println(menu[page]);
0749: out.println("</option>");
0750: }
0751: out.println("</select>");
0752: }
0753: out.println("</td></tr>");
0754: out.print("<tr><td>");
0755: out.print("Refresh Interval");
0756: out.print("</td><td>");
0757: out
0758: .print("<input name=\"refreshInterval\" type=\"text\" value=\""
0759: + refreshInterval + "\">");
0760: out.print("</td><td>");
0761: out
0762: .print("<input type=\"submit\" name=\"submit\" value=\"Refresh\">");
0763: out.println("</td>");
0764: out.println("</tr>");
0765: out.println("</table>");
0766: out
0767: .println("<input type=\"hidden\" name=\"viewType\" value=\"viewSelectedAgents\">");
0768: for (int i = 0, n = selectedAgents.size(); i < n; i++) {
0769: String agentName = (String) selectedAgents.get(i);
0770: out
0771: .println("<input type=\"hidden\" name=\"selectedAgents\" value=\""
0772: + agentName + "\">");
0773: }
0774: out
0775: .println("<input type=\"hidden\" name=\"currentPage\" value=\""
0776: + this Page + "\">");
0777: out.println("</form>");
0778: }
0779:
0780: private class AgentShortfall {
0781:
0782: private String agent;
0783: private int numShortfall;
0784:
0785: public AgentShortfall(String agent, int numShortfall) {
0786: this .agent = agent;
0787: this .numShortfall = numShortfall;
0788: }
0789:
0790: public String getAgent() {
0791: return agent;
0792: }
0793:
0794: public int getNumShortfall() {
0795: return numShortfall;
0796: }
0797:
0798: }
0799:
0800: private class ShortfallComparator implements Comparator {
0801:
0802: public boolean equals(Object aComparator) {
0803: return aComparator instanceof ShortfallComparator;
0804: }
0805:
0806: public int compare(Object obj1, Object obj2) {
0807: AgentShortfall as1 = (AgentShortfall) obj1;
0808: AgentShortfall as2 = (AgentShortfall) obj2;
0809: return (as2.getNumShortfall() - as1.getNumShortfall());
0810: }
0811: }
0812:
0813: protected ArrayList getSortedShortfallAgents(List agents) {
0814: boolean VERBOSE = true;
0815: ArrayList filteredAS = new ArrayList();
0816: Iterator agentIt = agents.iterator();
0817: while (agentIt.hasNext()) {
0818: String agent = (String) agentIt.next();
0819: InputStream is = null;
0820: BufferedReader reader = null;
0821:
0822: try {
0823: // build URL for remote connection
0824: StringBuffer buf = new StringBuffer();
0825: buf.append(getBaseURL());
0826: buf.append("$");
0827: buf.append(formURLEncode(agent));
0828: buf.append(getPath());
0829: buf.append("?viewType=viewNumShortfall");
0830:
0831: //buf.append("http://");
0832: //buf.append(request.getServerName());
0833: //buf.append(":");
0834: //buf.append(request.getServerPort());
0835: //buf.append("/$");
0836: //buf.append(subOrgName);
0837: //buf.append(support.getPath());
0838:
0839: String url = buf.toString();
0840:
0841: if (VERBOSE) {
0842: logger.warn("URL is: " + url);
0843: }
0844:
0845: // open connection
0846: URL myURL = new URL(url);
0847: URLConnection myConnection = myURL.openConnection();
0848: is = myConnection.getInputStream();
0849:
0850: reader = new BufferedReader(new InputStreamReader(
0851: is));
0852:
0853: // read single HierarchyData Object from subordinate
0854:
0855: int numShortfall = Integer.parseInt(reader
0856: .readLine());
0857:
0858: if (numShortfall > 0) {
0859: filteredAS.add(new AgentShortfall(agent,
0860: numShortfall));
0861: }
0862: } catch (StreamCorruptedException sce) {
0863: if (VERBOSE) {
0864: System.err.println("In "
0865: + getEncodedAgentName()
0866: + " while hitting " + agent
0867: + ", got exception : ");
0868: sce.printStackTrace();
0869: }
0870: } catch (FileNotFoundException fnf) {
0871: if (VERBOSE) {
0872: System.err.println("In "
0873: + getEncodedAgentName()
0874: + " while hitting " + agent
0875: + ", got exception : ");
0876: fnf.printStackTrace();
0877: }
0878: } catch (Exception e) {
0879: System.err.println("In " + getEncodedAgentName()
0880: + " while hitting " + agent
0881: + ", got exception : ");
0882: e.printStackTrace();
0883: } finally {
0884: try {
0885: if (reader != null)
0886: reader.close();
0887: if (is != null)
0888: is.close();
0889: } catch (Exception e) {
0890: }
0891: }
0892: }
0893:
0894: Collections.sort(filteredAS, new ShortfallComparator());
0895:
0896: Iterator filteredIt = filteredAS.iterator();
0897: ArrayList filteredAgents = new ArrayList(filteredAS.size());
0898: while (filteredIt.hasNext()) {
0899: String agentWShortfall = ((AgentShortfall) filteredIt
0900: .next()).getAgent();
0901: filteredAgents.add(agentWShortfall);
0902: }
0903:
0904: return filteredAgents;
0905: }
0906:
0907: // Output a page showing summary info for all agents
0908: protected void viewAllAgents() throws IOException {
0909: ArrayList filteredAgents = getSortedShortfallAgents(getAllAgentNames());
0910: viewSelectedAgents(filteredAgents, "All");
0911: }
0912:
0913: protected void viewSelectedAgents() throws IOException {
0914: viewSelectedAgents(getSelectedAgents(), "Selected");
0915: }
0916:
0917: protected void viewSelectedAgents(List agents,
0918: String titleModifier) throws IOException {
0919: response.setContentType("text/html");
0920: if (refreshInterval > 0) {
0921: response.setHeader("Refresh", String
0922: .valueOf(refreshInterval));
0923: }
0924: out = response.getWriter();
0925: format = FORMAT_HTML; // Force html format
0926: String title = getTitlePrefix() + "Shortfall of "
0927: + titleModifier + " Agents";
0928: out.println("<html>\n" + "<head>\n" + "<title>" + title
0929: + "</title>\n" + "</head>");
0930: boolean use_iframes = false;
0931: String browser = request.getHeader("user-agent")
0932: .toLowerCase();
0933: if (browser != null) {
0934: for (int i = 0; i < iframeBrowsers.length; i++) {
0935: if (browser.indexOf(iframeBrowsers[i]) >= 0) {
0936: use_iframes = true;
0937: break;
0938: }
0939: }
0940: }
0941: if (use_iframes) {
0942: out.println("<body>\n" + "<h2><center>" + title
0943: + "</h2></center>");
0944: printThresholdAndRefreshForm(out, agents, null, null);
0945: if (agents.size() > 0) {
0946: for (int i = 0, n = agents.size(); i < n; i++) {
0947: String agentName = (String) agents.get(i);
0948: out
0949: .println("<iframe src=\"/$"
0950: + formURLEncode(agentName)
0951: + getPath()
0952: + "?viewType=viewAgentSmall&redThreshold="
0953: + redThreshold
0954: + "&yellowThreshold="
0955: + yellowThreshold
0956: + "\" scrolling=\"no\" width=300 height=151>"
0957: + agentName + "</iframe>");
0958: }
0959: } else {
0960: out.println(" No Agents with Shortfall.");
0961: }
0962: out.println("</body>");
0963: } else {
0964: int totalAgents = agents.size();
0965: int nPages = (totalAgents + MAX_AGENT_FRAMES - 1)
0966: / MAX_AGENT_FRAMES;
0967: int nagents;
0968: int agent0;
0969: int page;
0970: if (nPages > 1) {
0971: try {
0972: page = Integer.parseInt(request
0973: .getParameter("page"));
0974: } catch (Exception e) {
0975: try {
0976: page = Integer.parseInt(request
0977: .getParameter("currentPage"));
0978: } catch (Exception e1) {
0979: page = 0;
0980: }
0981: }
0982: agent0 = (page * totalAgents + nPages - 1) / nPages;
0983: nagents = (((page + 1) * totalAgents + nPages - 1) / nPages)
0984: - agent0;
0985: title = titleModifier
0986: + " Agents "
0987: + ((String) agents.get(agent0))
0988: + " Through "
0989: + ((String) agents
0990: .get(agent0 + nagents - 1));
0991: } else {
0992: agent0 = 0;
0993: nagents = totalAgents;
0994: title = "All Agents";
0995: page = 0;
0996: }
0997: int nrows = (nagents + 2) / 3;
0998: out.print("<frameset rows=\"100");
0999: for (int row = 0; row < nrows; row++) {
1000: out.print(",100");
1001: }
1002: out.print("\">\n" + " <frame src=\"/$"
1003: + getEncodedAgentName() + getPath()
1004: + "?viewType=viewTitle&title="
1005: + getTitlePrefix() + "Shortfall+of+"
1006: + formURLEncode(title) + "&refreshInterval="
1007: + refreshInterval + "&redThreshold="
1008: + redThreshold + "&yellowThreshold="
1009: + yellowThreshold + "&thisPage=" + page
1010: + "&nextPage=" + ((page + 1) % nPages));
1011: for (int i = 0; i < totalAgents; i++) {
1012: String agentName = (String) agents.get(i);
1013: out.print("&selectedAgents="
1014: + formURLEncode(agentName));
1015: }
1016: out.println("\" scrolling=\"no\">");
1017: for (int row = 0; row < nrows; row++) {
1018: out.println(" <frameset cols=\"300,300,300\">");
1019: for (int col = 0; col < 3; col++) {
1020: int agentn = agent0 + row * 3 + col;
1021: if (agentn < agent0 + nagents) {
1022: String agentName = (String) agents
1023: .get(agentn);
1024: out
1025: .println(" <frame src=\""
1026: + "/$"
1027: + formURLEncode(agentName)
1028: + getPath()
1029: + "?viewType=viewAgentSmall&redThreshold="
1030: + redThreshold
1031: + "&yellowThreshold="
1032: + yellowThreshold
1033: + "\" scrolling=\"no\">");
1034: } else if (agentn == agent0 + nagents) {
1035: }
1036: }
1037: out.println(" </frameset>");
1038: }
1039: out.println("</frameset>");
1040: }
1041: out.println("<html>");
1042: }
1043:
1044: private List getSelectedAgents() {
1045: String[] selectedAgents = request
1046: .getParameterValues("selectedAgents");
1047: if (selectedAgents != null) {
1048: List ret = new ArrayList(Arrays.asList(selectedAgents));
1049: Collections.sort(ret);
1050: return ret;
1051: } else {
1052: return Collections.EMPTY_LIST;
1053: }
1054: }
1055:
1056: protected String getTimeString(long time, long bucketSize) {
1057: return createTimeString(time, bucketSize, getCBucket(time,
1058: bucketSize));
1059: }
1060:
1061: protected int getCBucket(long time, long bucketSize) {
1062: long c0Day = startCDay.getTime();
1063: return calcCBucket(time, bucketSize, c0Day);
1064: }
1065:
1066: protected Date getStartDate() {
1067: Date startingCDay = null;
1068:
1069: // get oplan
1070:
1071: Collection oplanCollection = queryBlackboard(OPLAN_PREDICATE);
1072:
1073: if (!(oplanCollection.isEmpty())) {
1074: Iterator iter = oplanCollection.iterator();
1075: Oplan plan = (Oplan) iter.next();
1076: startingCDay = plan.getCday();
1077: }
1078: return startingCDay;
1079: }
1080:
1081: protected GeolocLocation getCurrentGeoLoc() {
1082: long currentTime = alarmService.currentTimeMillis();
1083:
1084: Collection orgActCollection = queryBlackboard(ORG_ACTIVITY_PREDICATE);
1085: Iterator iter = orgActCollection.iterator();
1086: while (iter.hasNext()) {
1087: OrgActivity currAct = (OrgActivity) iter.next();
1088: if ((currAct.getStartTime() <= currentTime)
1089: && (currAct.getEndTime() >= currentTime)) {
1090: return currAct.getGeoLoc();
1091: }
1092: }
1093: return null;
1094: }
1095:
1096: protected String getGeoLocString() {
1097: GeolocLocation geoLoc = getCurrentGeoLoc();
1098: if (geoLoc == null) {
1099: return "Unknown Location";
1100: } else {
1101: return (geoLoc.getName() + ", Lat: "
1102: + geoLoc.getLatitude() + ", Long: " + geoLoc
1103: .getLongitude());
1104: }
1105: }
1106:
1107: // Output a checkbox form allowing selection of multiple agents
1108: private void viewManyAgents() throws IOException {
1109: response.setContentType("text/html");
1110: out = response.getWriter();
1111: format = FORMAT_HTML; // Force html format
1112: SortedSet selectedAgents = new TreeSet(getSelectedAgents());
1113: boolean selectAll = false;
1114: boolean selectNone = false;
1115: String submit = request.getParameter("submit");
1116: if ("Show".equals(submit)) {
1117: viewSelectedAgents(new ArrayList(selectedAgents),
1118: "Selected");
1119: return;
1120: }
1121: if ("Select All".equals(submit)) {
1122: selectAll = true;
1123: } else if ("Select None".equals(submit)) {
1124: selectNone = true;
1125: }
1126: List l = getAllAgentNames();
1127: Collections.sort(l);
1128: String title = "Select Agents for Shortfall Display";
1129: out.println("<html>\n" + "<head>\n" + "<title>"
1130: + getTitlePrefix() + title + "</title>\n"
1131: + "</head>");
1132: out.println("<body>\n" + "<h2><center>" + title
1133: + "</h2></center>");
1134: out.println("<form method=\"post\" action=\"/$"
1135: + getEncodedAgentName() + getPath()
1136: + "\" target=\"_top\">");
1137: out
1138: .println("<input type=\"submit\" name=\"submit\" value=\"Select All\">");
1139: out
1140: .println("<input type=\"submit\" name=\"submit\" value=\"Select None\">");
1141: out
1142: .println("<input type=\"submit\" name=\"submit\" value=\"Show\">");
1143: out
1144: .println("<input type=\"hidden\" name=\"viewType\" value=\"viewManyAgents\">");
1145: out.println("<table><tr>");
1146: int nagents = l.size();
1147: int agent0 = 0;
1148: int NCOL = 4;
1149: for (int col = 0; col < NCOL; col++) {
1150: out.println("<td valign=\"top\">");
1151: int agent1 = ((col + 1) * nagents + NCOL - 1) / NCOL;
1152: for (; agent0 < agent1; agent0++) {
1153: String agentName = (String) l.get(agent0);
1154: String selected;
1155: if (selectAll
1156: || (!selectNone && selectedAgents
1157: .contains(agentName))) {
1158: selected = " checked=\"true\"";
1159: } else {
1160: selected = "";
1161: }
1162: out
1163: .println("<input type=\"checkbox\" name=\"selectedAgents\" value=\""
1164: + agentName
1165: + "\""
1166: + selected
1167: + ">"
1168: + agentName + "</input><br>");
1169: }
1170: out.println("</td>");
1171: agent0 = agent1;
1172: }
1173: out.println("</tr></table>");
1174: out.println("</form>");
1175: out.println("</body>");
1176: out.println("</html>");
1177: }
1178:
1179: /*** Moving to shortfall data
1180: protected int computeNumShortfallWithRules(ShortfallShortData result) {
1181: Collection summaries = result.getShortfallSummaries().values();
1182: Iterator summaryIT = summaries.iterator();
1183: int totalInvsWithShortfall=0;
1184: while(summaryIT.hasNext()) {
1185: ShortfallSummary summary = (ShortfallSummary) summaryIT.next();
1186: Iterator invIT = summary.getShortfallInventories().iterator();
1187: while(invIT.hasNext()) {
1188: boolean ruleMatch=false;
1189: ShortfallInventory shortInv = (ShortfallInventory)invIT.next();
1190: Iterator rulesIT = rulesList.iterator();
1191: while(rulesIT.hasNext()) {
1192: ShortfallInventoryRule rule = (ShortfallInventoryRule) rulesIT.next();
1193: ShortfallInventory newInv = rule.apply(getEncodedAgentName(),shortInv);
1194: if(newInv != null) {
1195: shortInv=newInv;
1196: ruleMatch=true;
1197: }
1198: }
1199: if(shortInv.getNumPermShortfall() > 0) {
1200: totalInvsWithShortfall++;
1201: }
1202: }
1203:
1204: }
1205: return totalInvsWithShortfall;
1206: }
1207: ***/
1208:
1209: // Output a small page showing summary info for one agent
1210: private void viewAgentSmall() throws IOException {
1211: response.setContentType("text/html");
1212: out = response.getWriter();
1213: format = FORMAT_HTML; // Force html format
1214: String agent = getEncodedAgentName();
1215: ShortfallShortData result = getShortfallData();
1216: int numShortfall = result.getNumberOfShortfallInventories();
1217:
1218: int numShortfallPeriodInvs = result
1219: .getNumberOfShortfallPeriodInventories();
1220:
1221: int numTempShortfall = result
1222: .getNumberOfTempShortfallInventories();
1223:
1224: int numUnexpectedShortfall = numShortfallPeriodInvs;
1225:
1226: if (!userMode) {
1227: numUnexpectedShortfall = result
1228: .getNumberOfUnexpectedShortfallInventories();
1229: }
1230: String bgcolor, fgcolor, lncolor;
1231: if ((numUnexpectedShortfall >= redThreshold)
1232: || ((userMode) && (result
1233: .hasPercentShortfallAbove(RED_PERCENT_SHORTFALL_THRESHOLD)))) {
1234: bgcolor = "#aa0000";
1235: fgcolor = "#ffffff";
1236: lncolor = "#ffff00";
1237: } else if ((numUnexpectedShortfall >= yellowThreshold)
1238: || ((userMode) && (result
1239: .hasPercentShortfallAbove(YELLOW_PERCENT_SHORTFALL_THRESHOLD)))) {
1240: bgcolor = "#ffff00";
1241: fgcolor = "#000000";
1242: lncolor = "#0000ff";
1243: } else {
1244: bgcolor = "#d0ffd0";
1245: fgcolor = "#000000";
1246: lncolor = "#0000ff";
1247: }
1248: out.println("<html>\n" + "<head>\n" + "</head>\n" + "<body"
1249: + " bgcolor=\"" + bgcolor + "\" text=\"" + fgcolor
1250: + "\" vlink=\"" + lncolor + "\" link=\"" + lncolor
1251: + "\">\n" + "<pre><a href=\"" + "/$" + agent
1252: + getPath() + "\" target=\"_top\">" + agent
1253: + "</a>");
1254: if (userMode) {
1255: out.println(formatLabel("Num Shortfall Items:")
1256: + " <b>" + numShortfallPeriodInvs + "</b>");
1257: } else {
1258: out.println(formatLabel("Num Shortfall Items:")
1259: + " <b>" + numShortfall + "</b>");
1260: out.println(formatLabel("Num Shortfall Period Items:")
1261: + " <b>" + numShortfallPeriodInvs + "</b>");
1262: out.println(formatLabel("Num Temp Shortfall Items:")
1263: + " <b>" + numTempShortfall + "</b>");
1264: out
1265: .println(formatLabel("Num Unexpected Shortfall Items:")
1266: + " <b>"
1267: + numUnexpectedShortfall
1268: + "</b>");
1269: }
1270: if (((userMode) && (numShortfallPeriodInvs > 0))
1271: || ((!userMode) && (numUnexpectedShortfall > 0))) {
1272: out.println(formatLabel("Effected Supply Types:\n")
1273: + result.getSupplyTypes());
1274: }
1275: out.println("</body>\n</html>");
1276: }
1277:
1278: // Output a small page showing summary info for one agent
1279: private void viewNumShortfall() throws IOException {
1280: response.setContentType("text/html");
1281: out = response.getWriter();
1282: format = FORMAT_HTML; // Force html format
1283: String agent = getEncodedAgentName();
1284: ShortfallShortData result = getShortfallData();
1285: int numShortfall = 0;
1286:
1287: //int numTempShortfall = result.getNumberOfTempShortfallInventories();
1288:
1289: if (!userMode) {
1290: numShortfall = result
1291: .getNumberOfUnexpectedShortfallInventories();
1292: } else {
1293: numShortfall = result
1294: .getNumberOfShortfallPeriodInventories();
1295: }
1296:
1297: out.println(Integer.toString(numShortfall));
1298:
1299: }
1300:
1301: private String formatLabel(String lbl) {
1302: int nchars = lbl.length();
1303: if (nchars > 24)
1304: return lbl;
1305: return lbl + " ".substring(nchars);
1306: }
1307:
1308: private String formatInteger(int n) {
1309: return formatInteger(n, 5);
1310: }
1311:
1312: private final String SPACES = " ";
1313: private final int NSPACES = SPACES.length();
1314:
1315: private String formatInteger(int n, int w) {
1316: if (w > NSPACES)
1317: w = NSPACES;
1318: String r = String.valueOf(n);
1319: int needed = w - r.length();
1320: if (needed <= 0)
1321: return r;
1322: return SPACES.substring(0, needed) + r;
1323: }
1324:
1325: private String formatPercent(double percent) {
1326: return formatInteger((int) (percent * 100.0), 3) + "%";
1327: }
1328:
1329: private String formatColorBar(String color) {
1330: return "<table width=\"100%\" bgcolor=\"" + color
1331: + "\"><tr><td> </td></tr></table>";
1332: }
1333:
1334: protected Collection getAllShortfallSummaries() {
1335: Collection col = queryBlackboard(SHORTFALL_SUMMARY_PRED);
1336: if (col == null)
1337: col = Collections.EMPTY_LIST;
1338: return col;
1339: }
1340:
1341: public Collection filterTasks(Collection allTasks,
1342: UnaryPredicate predicate) {
1343: return Filters.filter(allTasks, predicate);
1344: }
1345:
1346: protected ShortfallShortData getShortfallData() {
1347: // get tasks
1348: Collection summaries = getAllShortfallSummaries();
1349: long nowTime = System.currentTimeMillis();
1350: startCDay = getStartDate();
1351: long c0Time = startCDay.getTime();
1352:
1353: ShortfallShortData data;
1354: if (showTables) {
1355: data = new FullShortfallData(getEncodedAgentName(),
1356: getGeoLocString(), nowTime, c0Time, summaries,
1357: userMode);
1358: } else {
1359: data = new ShortfallShortData(getEncodedAgentName(),
1360: getGeoLocString(), nowTime, c0Time, summaries,
1361: userMode);
1362: }
1363: return data;
1364: }
1365:
1366: protected String getBaseURL() {
1367: String baseURL = request.getScheme() + "://"
1368: + request.getServerName() + ":"
1369: + request.getServerPort() + "/";
1370:
1371: return baseURL;
1372: }
1373:
1374: /**
1375: * Get the TASKS.PSP URL for the given UID String.
1376: *
1377: * Assumes that the TASKS.PSP URL is fixed at "/tasks".
1378: */
1379: protected String getTaskUID_URL(String clusterId,
1380: String sTaskUID) {
1381: /*
1382: // FIXME prefix with base URL?
1383:
1384: String baseURL =
1385: request.getScheme()+
1386: "://"+
1387: request.getServerName()+
1388: ":"+
1389: request.getServerPort()+
1390: "/";
1391: */
1392: return "/$" + clusterId + "/tasks?mode=3&uid=" + sTaskUID;
1393: }
1394:
1395: /**
1396: * Get a brief description of the given <code>PlanElement</code>.
1397: */
1398: protected String getPlanElement(PlanElement pe) {
1399: return (pe instanceof Allocation) ? "Allocation"
1400: : (pe instanceof Expansion) ? "Expansion"
1401: : (pe instanceof Aggregation) ? "Aggregation"
1402: : (pe instanceof Disposition) ? "Disposition"
1403: : (pe instanceof AssetTransfer) ? "AssetTransfer"
1404: : (pe != null) ? pe
1405: .getClass()
1406: .getName()
1407: : null;
1408: }
1409:
1410: /**
1411: * Write the given <code>ShortfallShortData</code> as formatted HTML.
1412: */
1413: protected void printShortfallDataAsHTML(
1414: ShortfallShortData result) {
1415: // javascript based on PlanViewServlet
1416: out.print("<html><body>\n" + "<h2><center>"
1417: + getTitlePrefix() + "Shortfall at "
1418: + getEncodedAgentName() + "</center></h2>\n");
1419: printCountersAsHTML(result);
1420: printTablesAsHTML(result);
1421: out.print("</body></html>");
1422: out.flush();
1423: }
1424:
1425: protected void printCountersAsHTML(ShortfallShortData result) {
1426: int numShortfall = result.getNumberOfShortfallInventories();
1427: int numShortfallPeriodInvs = result
1428: .getNumberOfShortfallPeriodInventories();
1429: int numTempShortfall = result
1430: .getNumberOfTempShortfallInventories();
1431: int numUnexpectedShortfall = numShortfallPeriodInvs;
1432:
1433: if (!userMode) {
1434: numUnexpectedShortfall = result
1435: .getNumberOfUnexpectedShortfallInventories();
1436: }
1437: String shortfallColor;
1438: if ((numUnexpectedShortfall >= redThreshold)
1439: || ((userMode) && (result
1440: .hasPercentShortfallAbove(RED_PERCENT_SHORTFALL_THRESHOLD)))) {
1441: shortfallColor = "red";
1442: } else if ((numUnexpectedShortfall >= yellowThreshold)
1443: || ((userMode) && (result
1444: .hasPercentShortfallAbove(YELLOW_PERCENT_SHORTFALL_THRESHOLD)))) {
1445: shortfallColor = "yellow";
1446: } else {
1447: shortfallColor = "#00d000";
1448: }
1449: out.print(formatColorBar(shortfallColor) + "<pre>\n"
1450: + "Time: <b>");
1451: long timeMillis = result.getTimeMillis();
1452: out.print(new Date(timeMillis));
1453: out.print("</b> (");
1454: out.print(timeMillis);
1455: if (userMode) {
1456: out.print(" MS)\n" + getTitlePrefix() + "Location: <b>"
1457: + getGeoLocString() + "</b>\n"
1458: + "Number of Shortfall Items: <b>"
1459: + numShortfallPeriodInvs + "</b>\n");
1460: } else {
1461: out.print(" MS)\n" + getTitlePrefix() + "Location: <b>"
1462: + getGeoLocString() + "</b>\n"
1463: + "Number of Shortfall Items: <b>"
1464: + numShortfall + "</b>\n");
1465: out.print("Number of Shortfall Period Items: <b>"
1466: + numShortfallPeriodInvs + "</b>\n");
1467: out.print("Number of Temporary Shortfall Items: <b>"
1468: + numTempShortfall + "</b>\n");
1469:
1470: out.print("Number of Unexpected Shortfall Items: <b>"
1471: + numUnexpectedShortfall + "</b>\n");
1472: }
1473: if (((userMode) && (numShortfallPeriodInvs > 0))
1474: || ((!userMode) && (numUnexpectedShortfall > 0))) {
1475: out.println(formatLabel("Effected Supply Types:")
1476: + ((result.getSupplyTypes()).replaceAll("\n",
1477: "")) + "\n");
1478: }
1479: out.print("</pre>\n");
1480: }
1481:
1482: protected void printTablesAsHTML(ShortfallShortData result) {
1483: int numShortfall = result.getNumberOfShortfallInventories();
1484: if (userMode) {
1485: numShortfall = result
1486: .getNumberOfShortfallPeriodInventories();
1487: }
1488: if (result instanceof FullShortfallData) {
1489: Iterator summaries = result.getShortfallSummaries()
1490: .values().iterator();
1491: while (summaries.hasNext()) {
1492: ShortfallSummary summary = (ShortfallSummary) summaries
1493: .next();
1494: int numSummaryShortfall = summary
1495: .getShortfallInventories().size();
1496:
1497: if (userMode) {
1498: numSummaryShortfall = summary
1499: .getNumShortfallPeriodInvs();
1500: }
1501:
1502: if (numSummaryShortfall > 0) {
1503: String supplyType = summary.getSupplyType();
1504:
1505: beginShortfallHTMLTable((supplyType
1506: + " shortfall items:["
1507: + numSummaryShortfall + "]"), "",
1508: summary.getUnit());
1509: printShortfallSummaryAsHTML(summary);
1510:
1511: endShortfallHTMLTable();
1512: }
1513: }
1514: } else {
1515: // no table data
1516: out.print("<p>" + "<a href=\"");
1517: out.print("/$");
1518: out.print(getEncodedAgentName());
1519: out.print(getPath());
1520: out
1521: .print("?showTables=true&viewType=viewAgentBig\" target=\"viewAgentBig\">"
1522: + "Full Listing of Shortfall Inventory Items (");
1523: out.print(numShortfall);
1524: out.println(" lines)</a><br>");
1525: }
1526: }
1527:
1528: /**
1529: * Begin a table of <tt>printShortfallSummaryAsHTML</tt> entries.
1530: */
1531: protected void beginShortfallHTMLTable(String title,
1532: String subTitle, String unit) {
1533: out
1534: .print("<table border=1 cellpadding=3 cellspacing=1 width=\"100%\">\n"
1535: + "<tr bgcolor=lightgrey>");
1536: if (userMode) {
1537: out.print("<th align=left colspan=10>");
1538: } else {
1539: out.print("<th align=left colspan=15>");
1540: }
1541: out.print(title);
1542: if (subTitle != null) {
1543: out.print(" <tt><i>");
1544: out.print(subTitle);
1545: out.print("</i></tt>");
1546: }
1547: out.print("</th></tr>\n" + "<tr>" + "<th></th>"
1548: + "<th>Inventory Item</th>");
1549: if (!userMode) {
1550: out.print("<th>Demand Shortfall</th>"
1551: + "<th>Refill Shortfall</th>"
1552: + "<th>Supply Shortfall</th>"
1553: + "<th>Temp Shortfall</th>"
1554: + "<th>ProjectSupply Shortfall</th>");
1555: }
1556: out.print("<th>Shortfall Start</th>"
1557: + "<th>Shortfall End</th>" + "<th>Num " + unit
1558: + "</th>" + "<th>Unit of Issue</th>"
1559: + "<th>Demand</th>" + "<th>Filled</th>"
1560: + "<th>Shortfall</th>"
1561: + "<th>Percent Shortfall</th>" + "</tr>\n");
1562: }
1563:
1564: /**
1565: * End a table of <tt>printShortfallSummaryAsHTML</tt> entries.
1566: */
1567: protected void endShortfallHTMLTable() {
1568: out.print("</table>\n" + "<p>\n");
1569: }
1570:
1571: /**
1572: * Write the given <code>AbstractTask</code> as formatted HTML.
1573: */
1574: protected void printShortfallSummaryAsHTML(
1575: ShortfallSummary summary) {
1576: Iterator inventoryItems = summary.getShortfallInventories()
1577: .iterator();
1578: int index = 0;
1579: while (inventoryItems.hasNext()) {
1580: ShortfallInventory inv = (ShortfallInventory) inventoryItems
1581: .next();
1582: String invItem = inv.getInvID();
1583: if (userMode
1584: && ((inv.getShortfallPeriods().isEmpty()) || (!inv
1585: .getUnexpected()))) {
1586: continue;
1587: }
1588: out.print("<tr align=left><td>");
1589: out.print(++index);
1590: out.print("</td><td>");
1591: out.print("<b>" + invItem + "</b>");
1592: if (!userMode) {
1593: out.print("</td><td>");
1594: out.print("<b>" + inv.getNumDemand() + "</b>");
1595: out.print("</td><td>");
1596: out.print("<b>" + inv.getNumRefill() + "</b>");
1597: out.print("</td><td>");
1598: out.print("<b>" + inv.getNumActual() + "</b>");
1599: out.print("</td><td>");
1600: out.print("<b>" + inv.getNumTempShortfall()
1601: + "</b>");
1602: out.print("</td><td>");
1603: out.print("<b>" + inv.getNumProjection() + "</b>");
1604: }
1605: if (inv.getShortfallPeriods().isEmpty()) {
1606: out
1607: .print("</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td>");
1608: out.print("</td></tr>\n");
1609: } else {
1610: Iterator shortfallPeriodIt = inv
1611: .getShortfallPeriods().iterator();
1612: ShortfallPeriod currPeriod = (ShortfallPeriod) shortfallPeriodIt
1613: .next();
1614: printShortfallPeriodAsHTML(currPeriod, inv
1615: .getUnitOfIssue(), summary
1616: .getMsecPerBucket());
1617: out.print("</td></tr>\n");
1618: while (shortfallPeriodIt.hasNext()) {
1619: currPeriod = (ShortfallPeriod) shortfallPeriodIt
1620: .next();
1621: index = printShortfallPeriodRowAsHTML(
1622: currPeriod, inv.getUnitOfIssue(),
1623: index, summary.getMsecPerBucket());
1624: }
1625: }
1626: }
1627: }
1628:
1629: protected int printShortfallPeriodRowAsHTML(
1630: ShortfallPeriod period, String unitOfIssue, int index,
1631: long bucketSize) {
1632: out.print("<tr align=left><td>");
1633: out.print(index);
1634: out.print("</td><td>");
1635: out.print("\'\'");
1636: if (!userMode) {
1637: out.print("</td><td>");
1638: out.print("</td><td>");
1639: out.print("</td><td>");
1640: out.print("</td><td>");
1641: out.print("</td><td>");
1642: }
1643: printShortfallPeriodAsHTML(period, unitOfIssue, bucketSize);
1644: out.print("</td></tr>\n");
1645: return index;
1646: }
1647:
1648: protected void printShortfallPeriodAsHTML(
1649: ShortfallPeriod period, String unitOfIssue,
1650: long bucketSize) {
1651:
1652: boolean roundToInt = !(unitOfIssue
1653: .equals(LogisticsInventoryFormatter.AMMUNITION_UNIT));
1654:
1655: out.print("</td><td>");
1656: out.print("<b>"
1657: + getTimeString(period.getStartTime(), bucketSize)
1658: + "</b>");
1659: out.print("</td><td>");
1660: out.print("<b>"
1661: + getTimeString(period.getEndTime(), bucketSize)
1662: + "</b>");
1663: out.print("</td><td>");
1664: out
1665: .print("<b>" + period.getNumBuckets(bucketSize)
1666: + "</b>");
1667: out.print("</td><td>");
1668: out.print("<b>" + unitOfIssue + "</b>");
1669: out.print("</td><td>");
1670: out.print("<b>" + period.getRoundedTotalDemand(roundToInt)
1671: + "</b>");
1672: out.print("</td><td>");
1673: out.print("<b>" + period.getRoundedTotalFilled(roundToInt)
1674: + "</b>");
1675: out.print("</td><td>");
1676: out.print("<b>" + period.getShortfallQty(roundToInt)
1677: + "</b>");
1678: out.print("</td><td>");
1679: out.print("<b>" + period.getPercentShortfall() + "%</b>");
1680: }
1681: }
1682: }
|