001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.logistics.servlet;
028:
029: import java.io.IOException;
030: import java.io.PrintWriter;
031: import java.util.*;
032:
033: import javax.servlet.Servlet;
034: import javax.servlet.http.HttpServlet;
035: import javax.servlet.http.HttpServletRequest;
036: import javax.servlet.http.HttpServletResponse;
037:
038: import org.cougaar.core.mts.MessageAddress;
039: import org.cougaar.core.blackboard.BlackboardClient;
040: import org.cougaar.core.service.AgentIdentificationService;
041: import org.cougaar.core.service.BlackboardService;
042: import org.cougaar.core.servlet.BaseServletComponent;
043: import org.cougaar.core.util.UID;
044: import org.cougaar.util.UnaryPredicate;
045:
046: import org.cougaar.glm.ldm.oplan.Oplan;
047: import org.cougaar.glm.ldm.oplan.OplanCoupon;
048: import org.cougaar.glm.ldm.oplan.OrgActivity;
049: import org.cougaar.glm.ldm.oplan.TimeSpan;
050:
051: public class OplanEditServlet extends BaseServletComponent implements
052: BlackboardClient {
053: private static Comparator orgActivityComparator;
054: private static Comparator timeSpanComparator;
055:
056: static {
057: orgActivityComparator = new OrgActivityComparator();
058: timeSpanComparator = new TimeSpanComparator();
059: }
060:
061: private Oplan oplan = null;
062:
063: private ArrayList orgActivities = new ArrayList();
064:
065: private HashMap modifiedOrgActivities = new HashMap();
066: //private HashSet changedOplans = new HashSet();
067:
068: protected MessageAddress agentId;
069:
070: protected BlackboardService blackboard;
071:
072: /**
073: * Used to convert day offsets from dates to Date and back to offsets
074: */
075: private static Calendar formatter;
076: static {
077: formatter = Calendar.getInstance();
078: }
079:
080: public static final String ACTION_PARAM = "action";
081: public static final String SHOW_OPLAN = "show_oplan";
082: public static final String EDIT_ORGACTIVITY = "edit_orgactivity";
083: public static final String MODIFY_ORGACTIVITY = "modify_orgactivity";
084: public static final String PUBLISH = "Publish";
085: public static final String REFRESH = "Refresh";
086:
087: public static final String PARAM_SEPARATOR = "&";
088: public static final String OPTEMPO = "optempo";
089: public static final String ORG_ID = "org_ID";
090: public static final String ORG_UID = "org_UID";
091: public static final String START_OFFSET = "start_offset";
092: public static final String END_OFFSET = "end_offset";
093:
094: /** A zero-argument constructor is required for dynamically loaded PSPs,
095: required by Class.newInstance()
096: **/
097: public OplanEditServlet() {
098: super ();
099: }
100:
101: // odd BlackboardClient method:
102: public String getBlackboardClientName() {
103: return toString();
104: }
105:
106: // odd BlackboardClient method:
107: public long currentTimeMillis() {
108: throw new UnsupportedOperationException(this
109: + " asked for the current time???");
110: }
111:
112: // unused BlackboardClient method:
113: public boolean triggerEvent(Object event) {
114: // if we had Subscriptions we'd need to implement this.
115: //
116: // see "ComponentPlugin" for details.
117: throw new UnsupportedOperationException(this
118: + " only supports Blackboard queries, but received "
119: + "a \"trigger\" event: " + event);
120: }
121:
122: public void setBlackboardService(BlackboardService blackboard) {
123: this .blackboard = blackboard;
124: }
125:
126: public final void setAgentIdentificationService(
127: AgentIdentificationService ais) {
128: MessageAddress an;
129: if ((ais != null)
130: && ((an = ais.getMessageAddress()) instanceof MessageAddress)) {
131: this .agentId = (MessageAddress) an;
132: } else {
133: // FIXME: Log something?
134: }
135: }
136:
137: // release services:
138: public void unload() {
139: super .unload();
140: if (blackboard != null) {
141: serviceBroker.releaseService(this , BlackboardService.class,
142: blackboard);
143: blackboard = null;
144: }
145: }
146:
147: protected String getPath() {
148: return "/editOplan";
149: }
150:
151: protected MessageAddress getAgentID() {
152: return agentId;
153: }
154:
155: protected Servlet createServlet() {
156: // create inner class
157: return new MyServlet();
158: }
159:
160: protected boolean adjustAdjacent(OrgActivity orgActivity,
161: boolean adjustPrevious, boolean adjustSubsequent) {
162: int orgIndex = orgActivities.indexOf(orgActivity);
163: TimeSpan timeSpan = orgActivity.getTimeSpan();
164:
165: if ((adjustSubsequent)
166: && ((orgIndex + 1) < orgActivities.size())) {
167: OrgActivity nextOrgActivity = (OrgActivity) orgActivities
168: .get(orgIndex + 1);
169: if (nextOrgActivity.getOrgID().equals(
170: orgActivity.getOrgID())) {
171: ChangeInfo nextChangeInfo = getChangeInfo(nextOrgActivity);
172:
173: TimeSpan nextTimeSpan = nextChangeInfo
174: .getModifiedOrgActivity().getTimeSpan();
175: // next start == current end so
176: // make sure that we're not going to create an invalid timespan
177: if (timeSpan.getEndDate().getTime() >= nextTimeSpan
178: .getEndDate().getTime()) {
179: return false;
180: }
181: nextTimeSpan.setStartDate(timeSpan.getEndDate());
182: }
183: }
184:
185: if ((adjustPrevious) && ((orgIndex > 0))) {
186: OrgActivity previousOrgActivity = (OrgActivity) orgActivities
187: .get(orgIndex - 1);
188: if (previousOrgActivity.getOrgID().equals(
189: orgActivity.getOrgID())) {
190: ChangeInfo previousChangeInfo = getChangeInfo(previousOrgActivity);
191:
192: TimeSpan previousTimeSpan = previousChangeInfo
193: .getModifiedOrgActivity().getTimeSpan();
194: // Previous end == current start so
195: // make sure that we're not going to create an invalid timespan
196: if (timeSpan.getStartDate().getTime() <= previousTimeSpan
197: .getStartDate().getTime()) {
198: return false;
199: }
200:
201: previousTimeSpan.setEndDate(timeSpan.getStartDate());
202: }
203: }
204:
205: return true;
206: }
207:
208: /**
209: * changeOrgActivity - apply changes to specified OrgActivity
210: */
211: protected boolean changeOrgActivity(OrgActivity orgActivity,
212: HttpServletRequest request) {
213: String startOffset;
214: String endOffset;
215: String select = " ";
216: ChangeInfo changeInfo = getChangeInfo(orgActivity);
217: boolean adjustPrevious = true;
218: boolean adjustSubsequent = true;
219:
220: // Make sure we change the copy so we can refresh if required.
221: // Don't want our changes on the blackboard until we publish
222: OrgActivity modifiedOrgActivity = changeInfo
223: .getModifiedOrgActivity();
224:
225: select = request.getParameter(OPTEMPO);
226: startOffset = request.getParameter(START_OFFSET);
227: endOffset = request.getParameter(END_OFFSET);
228:
229: if ((select != null) && (select.length() > 0)) {
230: modifiedOrgActivity.setOpTempo(select);
231: }
232:
233: Date startDate;
234: if ((startOffset != null) && (startOffset.length() > 0)) {
235: startDate = getRelativeDate(oplan.getCday(), startOffset);
236:
237: // adjust end of previous
238: adjustPrevious = true;
239: } else {
240: startDate = orgActivity.getTimeSpan().getStartDate();
241: }
242:
243: Date endDate;
244: if ((endOffset != null) && (endOffset.length() > 0)) {
245: endDate = getRelativeDate(oplan.getCday(), endOffset);
246: } else {
247: endDate = orgActivity.getTimeSpan().getEndDate();
248:
249: //adjust start of Subsequent
250: adjustSubsequent = true;
251: }
252:
253: // Make sure start is before end
254: if (!startDate.before(endDate)) {
255: return false;
256: }
257:
258: modifiedOrgActivity.getTimeSpan().setStartDate(startDate);
259: modifiedOrgActivity.getTimeSpan().setEndDate(endDate);
260:
261: if (adjustPrevious || adjustSubsequent) {
262: return adjustAdjacent(modifiedOrgActivity, adjustPrevious,
263: adjustSubsequent);
264: }
265:
266: return true;
267: }
268:
269: protected void displayOplanNotFound(PrintWriter out) {
270: printHtmlBegin(out);
271: out.println("<font size=+1>Oplan not found</font>");
272: printHtmlEnd(out);
273: }
274:
275: protected void displayExceptionFailure(PrintWriter out, Exception e) {
276: printHtmlBegin(out);
277: out.println("<font size=+1>Failed due to Exception</font><p>");
278: out.println(e);
279: out.println("<p><pre>");
280: e.printStackTrace(out);
281: out.println("</pre>");
282: printHtmlEnd(out);
283: }
284:
285: protected void displayPostSuccess(PrintWriter out) {
286: out.println("<html>");
287: out.println("<head>");
288: out.println("<title>Untitled Document</title>");
289: out.print("<meta http-equiv=\"refresh\" content=\" 1;URL=");
290: out.print("/$" + getAgentID() + getPath());
291: out.print("\">");
292: out.println("</head>");
293: out.println("<body bgcolor=\"#FFFFFF\">");
294: out.println("<H3><CENTER>Submit Successful !!</CENTER></H3>");
295: printHtmlEnd(out);
296: }
297:
298: protected void displayPostFailure(PrintWriter out) {
299: out.println("<html>");
300: out.println("<head>");
301: out.println("<title>Untitled Document</title>");
302: out.print("<meta http-equiv=\"refresh\" content=\" 2;URL=");
303: out.print("/$" + getAgentID() + getPath());
304: out.println("\">");
305: out.println("</head>");
306: out.println("<body bgcolor=\"#FFFFFF\">");
307: out
308: .println("<H3><CENTER> !!ERROR !! Start Date is bigger than End Date</CENTER></H3>");
309: printHtmlEnd(out);
310: }
311:
312: protected void displayOplanEdit(PrintWriter out, boolean refresh) {
313: try {
314: if ((orgActivities.size() == 0) || (refresh == true)) {
315: blackboard.openTransaction();
316: orgActivities = new ArrayList(blackboard
317: .query(orgActivitiesForOplanPred(oplan)));
318: blackboard.closeTransaction();
319:
320: Collections.sort(orgActivities, orgActivityComparator);
321: }
322:
323: printHtmlBegin(out);
324:
325: out
326: .println("<p align=\"center\"><b><font size=\"5\">OPLAN EDITOR</font></b></p>");
327: printPublishChanges(out);
328:
329: out.println("<table width=\"100%\" border=\"1\">");
330: out.println("<tr>");
331: out.println("<td><b>Organization</b></td>");
332: out.println("</tr>");
333:
334: String previousOrgID = " ";
335:
336: for (Iterator iterator = orgActivities.iterator(); iterator
337: .hasNext();) {
338: OrgActivity org = (OrgActivity) iterator.next();
339:
340: if (!(org.getOrgID().equals(previousOrgID))) {
341: previousOrgID = org.getOrgID();
342: out.println("</tr>");
343: out.println("<td>" + org.getOrgID() + "</td>");
344: }
345:
346: out.println("<td><a href=\"/$"
347: + getAgentID()
348: + getPath()
349: + "?"
350: + ACTION_PARAM
351: + "="
352: + EDIT_ORGACTIVITY
353: + PARAM_SEPARATOR
354: + ORG_ID
355: + "="
356: + org.getOrgID()
357: + PARAM_SEPARATOR
358: + ORG_UID
359: + "="
360: + org.getUID()
361: + "\">"
362: + org.getActivityType()
363: + " C+"
364: + getRelativeOffsetDays(oplan.getCday(), org
365: .getTimeSpan().getStartDate())
366: + " To C+"
367: + getRelativeOffsetDays(oplan.getCday(), org
368: .getTimeSpan().getEndDate())
369: + "</a></td>");
370: }
371:
372: out.println("</table>");
373: printHtmlEnd(out);
374: out.flush();
375: } catch (Exception e) {
376: out.println("</table>");
377: printHtmlEnd(out);
378: e.printStackTrace();
379: }
380: }
381:
382: protected void displayOrgNotFound(PrintWriter out, String orgID,
383: String orgUID) {
384: printHtmlBegin(out);
385: out.println("<font size=+1>OrgActivity not found:<p><ul>");
386: if (orgID != null) {
387: out.print("<li><b>OrgID</b>: ");
388: out.print(orgID);
389: out.println("</li>");
390: }
391: out.print("<li><b>UID</b>: ");
392: out.print(orgUID);
393: out.println("</li>");
394: out.println("</ul>");
395: printHtmlEnd(out);
396: }
397:
398: protected void displayOrgActivity(PrintWriter out, OrgActivity org) {
399: printHtmlBegin(out);
400: out.println("<p align=\"center\"><b><font size=\"5\">"
401: + org.getOrgID() + "</font></b></p>");
402: out.println("<form method=\"get\" action=\"/$" + getAgentID()
403: + getPath() + "\">");
404: out.println("<table width=\"90%\" border=\"1\">");
405:
406: out.println("<tr>");
407: out.println("<td colspan=\"2\"><b>Activity Type</b></td>");
408: out.println("<td colspan=\"2\"> </td>");
409: out.println("</tr>");
410:
411: out.println("<tr>");
412: out.println("<td colspan=\"2\"> " + org.getActivityType()
413: + "</td>");
414: if (org.getActivityName() == null) {
415: out.println("<td colspan=\"2\"> " + " " + "</td>");
416: } else {
417: out.println("<td colspan=\"2\"> "
418: + org.getActivityName() + "</td>");
419: }
420: out.println("</tr>");
421:
422: out.println("<tr>");
423: out.println("<td colspan=\"2\"><b>OpTempo</b></td>");
424: out.println("<td colspan=\"2\">");
425:
426: printHtmlSelectOption(out, org.getOpTempo());
427:
428: out.println("</td>");
429: out.println("</tr>");
430:
431: out.println("<tr>");
432: out.println("<td colspan=\"4\"> </td>");
433: out.println("</tr>");
434:
435: out.println("<tr>");
436: out.println("<td colspan=\"4\"><b>TimeSpan</b></td>");
437: out.println("</tr>");
438:
439: out.println("<tr>");
440: out.println("<td colspan=\"2\"> </td>");
441: out.println("<td><b>Start Time</b></td>");
442: out.println("<td><b>End Time</b></td>");
443: out.println("</tr>");
444:
445: out.println("<tr>");
446: out.println("<td> </td>");
447: out.println("<td>");
448: out.println("<div align=\"right\"><b>C-Time</b></div>");
449: out.println("</td>");
450: out.println("<td>C+ <input type=\"text\" name=\""
451: + START_OFFSET
452: + "\" value=\""
453: + getRelativeOffsetDays(oplan.getCday(), org
454: .getTimeSpan().getStartDate())
455: + "\" size=\"6\"> </td>");
456: out.println("<td>C+ <input type=\"text\" name=\""
457: + END_OFFSET
458: + "\" value=\""
459: + getRelativeOffsetDays(oplan.getCday(), org
460: .getTimeSpan().getEndDate())
461: + "\" size=\"6\"></td>");
462:
463: out.println("<tr>");
464: out.println("<td> </td>");
465: out.println("<td>");
466: out.println("<div align=\"right\"><b>Absolute Time</b></div>");
467: out.println("</td>");
468: out.println("<td>"
469: + org.getTimeSpan().getStartDate().toGMTString()
470: + "</td>");
471: out.println("<td>"
472: + org.getTimeSpan().getEndDate().toGMTString()
473: + "</td>");
474: out.println("</tr>");
475:
476: out.println("<tr>");
477: out.println("<td colspan=\"2\"> </td>");
478: out.println("<td> </td>");
479: out.println("<td> </td>");
480: out.println("</tr>");
481:
482: out.println("<tr>");
483: out
484: .println("<td colspan=\"2\"><b>Geographic Location</b></td>");
485: out.println("<td> </td>");
486: out.println("<td> </td>");
487: out.println("</tr>");
488:
489: out.println("<tr>");
490: out.println("<td colspan=\"2\"> </td>");
491: out.println("<td><b>Name</b></td>");
492: out.println("<td>" + org.getGeoLoc().getName() + "</td>");
493: out.println("</tr>");
494:
495: out.println("<tr>");
496: out.println("<td colspan=\"2\"> </td>");
497: out.println("<td><b>Code</b></td>");
498: out.println("<td>" + org.getGeoLoc().getGeolocCode() + "</td>");
499: out.println("</tr>");
500:
501: out.println("<tr>");
502: out.println("<td colspan=\"2\"> </td>");
503: out.println("<td><b>Latitude</b></td>");
504: out.println("<td>" + org.getGeoLoc().getLatitude().getDegrees()
505: + "</td>");
506: out.println("</tr>");
507:
508: out.println("<tr>");
509: out.println("<td colspan=\"2\"> </td>");
510: out.println("<td><b>Longitude</b></td>");
511: out
512: .println("<td>"
513: + org.getGeoLoc().getLongitude().getDegrees()
514: + "</td>");
515: out.println("</tr>");
516:
517: out.println("<tr>");
518: out.println("<input type=\"hidden\" name=\"" + ACTION_PARAM
519: + "\" value=\"" + MODIFY_ORGACTIVITY + "\">\n");
520: out.println("<input type=\"hidden\" name=\"" + ORG_ID
521: + "\" value=\"" + org.getOrgID() + "\">\n");
522: out.println("<input type=\"hidden\" name=\"" + ORG_UID
523: + "\" value=\"" + org.getUID() + "\">\n");
524: out.println("<td colspan=\"4\">");
525: out.println("<div align=\"center\">");
526: out
527: .println("<input type=\"submit\" name=\"save_changes\" value=\"Save\">\n");
528: out.println("</div>");
529: out.println("</td>");
530: out.println("</tr>");
531:
532: out.println("</table>");
533: out.println("</form>");
534: out.println("<p> </p>");
535:
536: printHtmlEnd(out);
537: }
538:
539: protected void printHtmlBegin(PrintWriter out) {
540: out.println("<html>");
541: out.println("<head>");
542: out.println("<title>Oplan Editor</title>");
543: out
544: .println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">");
545: out.println("</head>");
546: out.println("<body bgcolor=\"#FFFFFF\">");
547: }
548:
549: protected void printHtmlEnd(PrintWriter out) {
550: out.println("</body>");
551: out.println("</html>");
552: }
553:
554: protected void printPublishChanges(PrintWriter out) {
555: out.println("<form method=\"get\" action=\"/$" + getAgentID()
556: + getPath() + "\">");
557: out.println("<tr>");
558: out.println("<td colspan=\"4\">");
559: out.println("<div align=\"center\">");
560: out.println("<input type=\"submit\" name=\"" + ACTION_PARAM
561: + "\" value=\"" + PUBLISH + "\">\n");
562: out.println("<input type=\"submit\" name=\"" + ACTION_PARAM
563: + "\" value=\"" + REFRESH + "\">\n");
564: out.println("</div>");
565: out.println("</td>");
566: out.println("</tr>");
567: out.println("</form>");
568: }
569:
570: protected void printHtmlSelectOption(PrintWriter out,
571: String opTempoValue) {
572: if (opTempoValue != null) {
573: out.println("<select name=\"" + OPTEMPO + "\">");
574: if (opTempoValue.equals("High")) {
575: out
576: .println("<option value=\"High\" selected>High</option>");
577: out.println("<option value=\"Medium\">Medium</option>");
578: out.println("<option value=\"Low\">Low</option>");
579: } else if (opTempoValue.equals("Medium")) {
580: out.println("<option value=\"High\">High</option>");
581: out
582: .println("<option value=\"Medium\" selected>Medium</option>");
583: out.println("<option value=\"Low\">Low</option>");
584: } else {
585: out.println("<option value=\"High\">High</option>");
586: out.println("<option value=\"Medium\">Medium</option>");
587: out
588: .println("<option value=\"Low\" selected>Low</option>");
589: }
590: out.println("</select>");
591: } else {
592: out.println("<td> </td>");
593: }
594: }
595:
596: protected void publish(PrintWriter out) {
597: blackboard.openTransaction();
598:
599: Collection changes = modifiedOrgActivities.values();
600:
601: for (Iterator iterator = changes.iterator(); iterator.hasNext();) {
602: ChangeInfo changeInfo = (ChangeInfo) iterator.next();
603: OrgActivity orgActivity = changeInfo.getOrigOrgActivity();
604: OrgActivity modifiedOrgActivity = changeInfo
605: .getModifiedOrgActivity();
606:
607: // Apply changes - currently only supporting changes to the op tempo,
608: // start and end times.
609: orgActivity.setOpTempo(modifiedOrgActivity.getOpTempo());
610: orgActivity.setTimeSpan(modifiedOrgActivity.getTimeSpan());
611:
612: blackboard.publishChange(orgActivity);
613: /*
614: System.out.println("Publish status of " + status + " for " + orgActivity);
615: System.out.println(orgActivity.getUID() + " " + orgActivity.getOpTempo() + " " +
616: orgActivity.getTimeSpan().getStartDate() + " " +
617: orgActivity.getTimeSpan().getEndDate());
618: */
619: }
620: /*
621: * KLUDGE - Don't publish the coupon because the GLSInitServlet will
622: * do it for us.
623: Collection coupons =
624: blackboard.query(new CouponPredicate(plan.getUID()));
625:
626: for (Iterator couponIt = coupons.iterator(); couponIt.hasNext();) {
627: System.out.println("OplanEditServlet: publishChanging OplanCoupon");
628: blackboard.publishChange(couponIt.next());
629: }
630: */
631:
632: displayPostSuccess(out);
633:
634: blackboard.closeTransactionDontReset();
635: modifiedOrgActivities.clear();
636: orgActivities.clear();
637:
638: displayOplanEdit(out, true);
639: }
640:
641: protected UnaryPredicate orgActivitiesForOplanPred(final Oplan oplan) {
642: return new UnaryPredicate() {
643: public boolean execute(Object o) {
644: if (o instanceof OrgActivity) {
645: OrgActivity orgActivity = (OrgActivity) o;
646: return orgActivity.getOplanUID().equals(
647: oplan.getUID());
648: } else {
649: return false;
650: }
651: }
652: };
653: }
654:
655: protected OrgActivity findOrg(UID orgUID) {
656:
657: for (Iterator iterator = orgActivities.iterator(); iterator
658: .hasNext();) {
659: OrgActivity next = (OrgActivity) iterator.next();
660: if (next.getUID().equals(orgUID)) {
661: return next;
662: }
663: }
664:
665: throw new IllegalArgumentException("OrgActivity UID - "
666: + orgUID
667: + " - not found in current set of OrgActivities.");
668: }
669:
670: protected ChangeInfo getChangeInfo(OrgActivity orgActivity) {
671: ChangeInfo changeInfo = (ChangeInfo) modifiedOrgActivities
672: .get(orgActivity.getUID());
673:
674: if (changeInfo == null) {
675: // replace copy in orgActivities so we display the changes
676: // assume that modifications will not change the sort order
677: OrgActivity copyOrgActivity = (OrgActivity) orgActivity
678: .clone();
679: int index = orgActivities.indexOf(orgActivity);
680: if (index >= 0) {
681: orgActivities.set(index, copyOrgActivity);
682: } else {
683: throw new IllegalArgumentException(
684: "OrgActivity - "
685: + orgActivity
686: + " - not found in current set of OrgActivities.");
687: }
688:
689: // Keep orig and current set of changes for publish
690: changeInfo = new ChangeInfo(orgActivity, copyOrgActivity);
691: modifiedOrgActivities.put(orgActivity.getUID(), changeInfo);
692: }
693:
694: return changeInfo;
695: }
696:
697: private static class OrgActivityComparator implements Comparator {
698: public int compare(Object o1, Object o2) {
699: if (o1 == null) {
700: if (o2 == null) {
701: return 0;
702: } else {
703: return -1;
704: }
705: } else if (o2 == null) {
706: return 1;
707: } else if (o1.equals(o2)) {
708: return 0;
709: }
710:
711: OrgActivity orgActivity1 = (OrgActivity) o1;
712: OrgActivity orgActivity2 = (OrgActivity) o2;
713:
714: String orgID1 = orgActivity1.getOrgID();
715: String orgID2 = orgActivity2.getOrgID();
716:
717: int idCompare = orgID1.compareTo(orgID2);
718:
719: if (idCompare != 0) {
720: return idCompare;
721: } else {
722: return timeSpanComparator.compare(orgActivity1,
723: orgActivity2);
724: }
725: }
726: }
727:
728: private static class TimeSpanComparator implements Comparator {
729: public int compare(Object o1, Object o2) {
730: if (o1 == null) {
731: if (o2 == null) {
732: return 0;
733: } else {
734: return -1;
735: }
736: } else if (o2 == null) {
737: return 1;
738: } else if (o1.equals(o2)) {
739: return 0;
740: }
741:
742: TimeSpan timeSpan1 = ((OrgActivity) o1).getTimeSpan();
743: TimeSpan timeSpan2 = ((OrgActivity) o2).getTimeSpan();
744:
745: long diff = timeSpan1.getStartTime()
746: - timeSpan2.getStartTime();
747:
748: // Compare starts
749: if (diff > 0L) {
750: return 1;
751: } else if (diff < 0L) {
752: return -1;
753: }
754:
755: // Compare ends
756: diff = timeSpan1.getEndTime() - timeSpan2.getEndTime();
757: if (diff > 0L) {
758: return 1;
759: } else if (diff < 0L) {
760: return -1;
761: }
762:
763: // Start and end are equal
764: return System.identityHashCode(timeSpan1)
765: - System.identityHashCode(timeSpan2);
766: }
767: }
768:
769: private static class CouponPredicate implements UnaryPredicate {
770: UID _oplanUID;
771:
772: public CouponPredicate(UID oplanUID) {
773: _oplanUID = oplanUID;
774: }
775:
776: public boolean execute(Object o) {
777: if (o instanceof OplanCoupon) {
778: if (((OplanCoupon) o).getOplanUID().equals(_oplanUID)) {
779: return true;
780: }
781: }
782: return false;
783: }
784: }
785:
786: protected void initOplan(PrintWriter out) {
787: // get the oplan and cdate
788: blackboard.openTransaction();
789: Collection oplans = blackboard.query(allOplansPredicate);
790: blackboard.closeTransaction();
791:
792: if ((oplans == null) || (oplans.size() == 0)) {
793: displayOplanNotFound(out);
794: return;
795: }
796:
797: // No provision for handling multiple oplans so pick the first one
798: for (Iterator iterator = oplans.iterator(); iterator.hasNext();) {
799: oplan = (Oplan) iterator.next();
800: break;
801: }
802:
803: // Reset all existing oplan related info.
804: orgActivities.clear();
805: modifiedOrgActivities.clear();
806: }
807:
808: // Predicate for all Oplans
809: private static UnaryPredicate allOplansPredicate = new UnaryPredicate() {
810: public boolean execute(Object o) {
811: return (o instanceof Oplan);
812: }
813: };
814:
815: private static Date getRelativeDate(Date baseDate, int offsetDays) {
816: formatter.setTime(baseDate);
817: formatter.add(formatter.DATE, offsetDays);
818: return formatter.getTime();
819: }
820:
821: private static Date getRelativeDate(Date baseDate,
822: String sOffsetDays) {
823: return getRelativeDate(baseDate, Integer.parseInt(sOffsetDays));
824: }
825:
826: private static int getRelativeOffsetDays(Date baseDate,
827: Date offsetDate) {
828: try {
829: return (int) ((offsetDate.getTime() - baseDate.getTime()) / (1000 * 60 * 60 * 24));
830: } catch (Exception e) {
831: return 0;
832: }
833: }
834:
835: private class MyServlet extends HttpServlet {
836:
837: public void doGet(HttpServletRequest req,
838: HttpServletResponse resp) throws IOException {
839: MyWorker mw = new MyWorker(req, resp);
840: mw.execute();
841: }
842:
843: private class MyWorker {
844:
845: // from the "doGet(..)":
846: private HttpServletRequest request;
847: private HttpServletResponse response;
848:
849: public MyWorker(HttpServletRequest req,
850: HttpServletResponse resp) {
851: request = req;
852: response = resp;
853: }
854:
855: public void execute() throws IOException {
856: PrintWriter out = response.getWriter();
857:
858: // make sure we have an oplan
859: if (oplan == null) {
860: initOplan(out);
861: }
862:
863: String action = request.getParameter(ACTION_PARAM);
864:
865: try {
866: // Default to displaying oplan editor
867: if ((action == null) || (action.equals(SHOW_OPLAN))) {
868: displayOplanEdit(out, false);
869: } else if (action.equals(EDIT_ORGACTIVITY)) {
870: editOrgActivity(out);
871: } else if (action.equals(MODIFY_ORGACTIVITY)) {
872: modifyOrgActivity(out);
873: } else if (action.equals(PUBLISH)) {
874: publish(out);
875: } else if (action.equals(REFRESH)) {
876: refreshOrgActivities(out);
877: }
878: } catch (Exception topLevelException) {
879: displayExceptionFailure(out, topLevelException);
880: }
881: }
882:
883: protected void editOrgActivity(PrintWriter out) {
884:
885: String orgID = request.getParameter(ORG_ID);
886: String orgUID = request.getParameter(ORG_UID);
887:
888: if ((orgID == null) || (orgUID == null)) {
889: throw new IllegalArgumentException("Malformed "
890: + EDIT_ORGACTIVITY + " request. "
891: + " Must include " + ORG_ID + " and "
892: + ORG_UID + " values.");
893: }
894:
895: OrgActivity orgActivity = findOrg(UID.toUID(orgUID));
896:
897: // display it
898: if (orgActivity != null) {
899: displayOrgActivity(out, orgActivity);
900: } else {
901: displayOrgNotFound(out, orgID, orgUID);
902: }
903: }
904:
905: protected void modifyOrgActivity(PrintWriter out) {
906: String orgID = request.getParameter(ORG_ID);
907: String orgUID = request.getParameter(ORG_UID);
908:
909: if ((orgID == null) || (orgUID == null)) {
910: throw new IllegalArgumentException("Malformed "
911: + MODIFY_ORGACTIVITY + " request. "
912: + " Must include " + ORG_ID + " and "
913: + ORG_UID + " values.");
914: }
915:
916: OrgActivity orgActivity = findOrg(UID.toUID(orgUID));
917:
918: if (changeOrgActivity(orgActivity, request)) {
919: displayPostSuccess(out);
920: } else {
921: displayPostFailure(out);
922: }
923: }
924:
925: protected void refreshOrgActivities(PrintWriter out) {
926: // Forget about all previous edits
927: modifiedOrgActivities.clear();
928: displayOplanEdit(out, true);
929: }
930: }
931: }
932:
933: private static class ChangeInfo {
934: private OrgActivity myOrigOrgActivity;
935: private OrgActivity myModifiedOrgActivity;
936:
937: public ChangeInfo(OrgActivity origOrgActivity,
938: OrgActivity modifiedOrgActivity) {
939: myOrigOrgActivity = origOrgActivity;
940: myModifiedOrgActivity = modifiedOrgActivity;
941: }
942:
943: public OrgActivity getOrigOrgActivity() {
944: return myOrigOrgActivity;
945: }
946:
947: public OrgActivity getModifiedOrgActivity() {
948: return myModifiedOrgActivity;
949: }
950: }
951:
952: } // end of class
|