Source Code Cross Referenced for HistoryServlet.java in  » Science » Cougaar12_4 » org » cougaar » pizza » servlet » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /*
0002:         *  
0003:         *  Copyright 2002-2004 BBNT Solutions, LLC
0004:         *  under sponsorship of the Defense Advanced Research Projects
0005:         *  Agency (DARPA).
0006:         * 
0007:         *  You can redistribute this software and/or modify it under the
0008:         *  terms of the Cougaar Open Source License as published on the
0009:         *  Cougaar Open Source Website (www.cougaar.org).
0010:         * 
0011:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0012:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0013:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0014:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0015:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0016:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0017:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0018:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0019:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0020:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0021:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0022:         *  
0023:         * </copyright>
0024:         */
0025:
0026:        package org.cougaar.pizza.servlet;
0027:
0028:        import org.cougaar.community.CommunityDescriptor;
0029:        import org.cougaar.community.manager.Request;
0030:        import org.cougaar.core.blackboard.Claimable;
0031:        import org.cougaar.core.blackboard.IncrementalSubscription;
0032:        import org.cougaar.core.component.ServiceBroker;
0033:        import org.cougaar.core.mts.MessageAddress;
0034:        import org.cougaar.core.plugin.ComponentPlugin;
0035:        import org.cougaar.core.relay.Relay;
0036:        import org.cougaar.core.service.LoggingService;
0037:        import org.cougaar.core.service.ServletService;
0038:        import org.cougaar.core.service.community.Community;
0039:        import org.cougaar.core.service.community.CommunityResponse;
0040:        import org.cougaar.core.util.UID;
0041:        import org.cougaar.core.util.UniqueObject;
0042:        import org.cougaar.multicast.AttributeBasedAddress;
0043:        import org.cougaar.planning.ldm.asset.Asset;
0044:        import org.cougaar.planning.ldm.asset.Entity;
0045:        import org.cougaar.planning.ldm.plan.*;
0046:        import org.cougaar.util.Arguments;
0047:        import org.cougaar.util.UnaryPredicate;
0048:
0049:        import javax.servlet.Servlet;
0050:        import javax.servlet.ServletException;
0051:        import javax.servlet.http.HttpServlet;
0052:        import javax.servlet.http.HttpServletRequest;
0053:        import javax.servlet.http.HttpServletResponse;
0054:        import java.io.IOException;
0055:        import java.io.PrintWriter;
0056:        import java.net.URLEncoder;
0057:        import java.text.FieldPosition;
0058:        import java.text.SimpleDateFormat;
0059:        import java.util.*;
0060:
0061:        /**
0062:         * Generic debugging servlet/plugin that displays all Adds/Changes/Removes
0063:         * on Blackboard objects, accessed at "/history".
0064:         * <p/>
0065:         * Specifically tracks changes on Relays, Tasks, PlanElements, Assets,
0066:         * UniqueObjects, and implementations of {@link HistoryServletFriendly}.
0067:         * For every event, attempts to explain the event.
0068:         * For instance, when a Relay is first published, it shows which Agent
0069:         * the Relay is being sent to.
0070:         * <p/>
0071:         * The Servlet lets the user sort events by time, then by uid, or by uid
0072:         * only.  Sorting by uid shows the complete lifecycle of a Blackboard
0073:         * object; especially useful for transient objects that live on the
0074:         * Blackboard only a short time.  When sorting by time, each group of
0075:         * changes that happens in the same execute cycle is drawn with
0076:         * the same background color.  When sorting by uid, each distinct
0077:         * object is drawn with the same background color.
0078:         * <p/>
0079:         * The servlet has a "show details" link which will show the toString for
0080:         * the blackboard object at that time. This is a spot where developers
0081:         * can tune how this servlet displays their objects.
0082:         * <p/>
0083:         * The "Meaning" column uses the HistoryServletFriendly's toHTML() method
0084:         * to fill in content when available.
0085:         * <p/>
0086:         * Also shows which plugin initially published an object to the Blackboard
0087:         * if that information is available (for Claimables).
0088:         * <p/>
0089:         * <p/>
0090:         * Try it in any Cougaar Application! Simply add this as a Plugin
0091:         * in any Agent!
0092:         * <p/>
0093:         * Has a default limit of 1000 events, but this can be set by the
0094:         * MAX_EVENTS_REMEMBERED component argument to the servlet.
0095:         * E.g. :
0096:         * &lt;argument&gt;MAX_EVENTS_REMEMBERED=5000&lt;/argument&gt;
0097:         * <p> Another limit: 5 RoleSchedule elements displayed by default,
0098:         * set with MAX_ROLE_SCHEDULE_ELEMENTS argument.
0099:         * And a default of 5 child Tasks shown per Expansion, changed with the
0100:         * MAX_CHILD_TASKS argument.
0101:         * <p/>
0102:         * Note that this Servlet is actually a Plugin, so that it can subscribe
0103:         * to all the blackboard changes, and keeps a SortedSet of these Events,
0104:         * ready for display. It then provides an inner Servlet to the ServletService,
0105:         * so a user can view the pre-collected Events Set.
0106:         * <p/>
0107:         * Note that this Servlet has heavy Planning dependencies. It has minor
0108:         * Community dependencies, to allow printing details in the Meaning column.
0109:         * By commenting out those items, this dependency could be removed.
0110:         */
0111:        public class HistoryServlet extends ComponentPlugin {
0112:            // Some defaults
0113:            protected final int INITIAL_MAX_ENTRIES = 1000; // Default max # events to track
0114:            protected final int INITIAL_MAX_ROLE_SCHEDULE_ELEMENTS = 5;
0115:            protected final int INITIAL_MAX_CHILD_TASKS = 5;
0116:
0117:            // Actual value of parametrized preferences
0118:            private int maxEvents;
0119:            private int maxRoleScheduleElements;
0120:            private int maxChildTasks;
0121:
0122:            /**
0123:             * initialize args to the empty instance
0124:             */
0125:            private Arguments args = Arguments.EMPTY_INSTANCE;
0126:            protected MessageAddress localAgent;
0127:
0128:            protected LoggingService logger;
0129:            private ServletService servletService;
0130:
0131:            // Subscribe to various kinds of objects
0132:            private IncrementalSubscription relaysSubscription;
0133:            private IncrementalSubscription tasksSubscription;
0134:            private IncrementalSubscription planElementsSubscription;
0135:            private IncrementalSubscription assetsSubscription;
0136:            // Note that this is an everything-but-the-above subscription
0137:            private IncrementalSubscription uniqueObjectsSubscription;
0138:
0139:            protected static SimpleDateFormat format = new SimpleDateFormat(
0140:                    "MM-dd hh:mm:ss,SSS");
0141:            protected String encAgentName;
0142:
0143:            /**
0144:             * The actual Blackboard history we collect
0145:             */
0146:            protected SortedSet events = new TreeSet();
0147:
0148:            // Has the events list been trimmed?
0149:            private boolean didDropOldEntries = false;
0150:
0151:            // User preferences
0152:            boolean showChangeReport = false;
0153:            boolean sortByUID = false;
0154:            boolean showDetails = false;
0155:
0156:            private SimpleDateFormat myDateFormat = new SimpleDateFormat(
0157:                    "MM_dd_yyyy_h:mma");
0158:            private Date myDateInstance = new Date();
0159:            private FieldPosition myFieldPos = new FieldPosition(
0160:                    SimpleDateFormat.YEAR_FIELD);
0161:
0162:            // what are we looking at?
0163:            public static final int TASK = 0;
0164:            public static final int PLAN_ELEMENT = 1;
0165:            public static final int ASSET = 2;
0166:            public static final int UNIQUE_OBJECT = 3;
0167:            public static final int DIRECT_OBJECT = 4;
0168:
0169:            // What kind of event was this?
0170:            public static final int ADDED = 0;
0171:            public static final int CHANGED = 1;
0172:            public static final int REMOVED = 2;
0173:
0174:            private UnaryPredicate relayPredicate = new UnaryPredicate() {
0175:                public boolean execute(Object o) {
0176:                    return (o instanceof  Relay);
0177:                }
0178:            };
0179:
0180:            private UnaryPredicate taskPredicate = new UnaryPredicate() {
0181:                public boolean execute(Object o) {
0182:                    return (o instanceof  Task);
0183:                }
0184:            };
0185:
0186:            private UnaryPredicate allocationPredicate = new UnaryPredicate() {
0187:                public boolean execute(Object o) {
0188:                    return (o instanceof  PlanElement);
0189:                }
0190:            };
0191:
0192:            private UnaryPredicate assetPredicate = new UnaryPredicate() {
0193:                public boolean execute(Object o) {
0194:                    return (o instanceof  Asset);
0195:                }
0196:            };
0197:
0198:            // Subscribe to anything not in the above subscriptions
0199:            private UnaryPredicate uniqueObjectPredicate = new UnaryPredicate() {
0200:                public boolean execute(Object o) {
0201:                    return (!(o instanceof  Relay) && !(o instanceof  Task)
0202:                            && !(o instanceof  PlanElement)
0203:                            && !(o instanceof  Asset) && (o instanceof  UniqueObject));
0204:                }
0205:            };
0206:
0207:            /**
0208:             * Only called if a plugin has parameters.
0209:             * We over-ride this to use the Arguments utility, since all our
0210:             * arguments are NAME=VALUE format.
0211:             */
0212:            public void setParameter(Object o) {
0213:                args = new Arguments(o);
0214:            }
0215:
0216:            /**
0217:             * Get the ServletService via reflection
0218:             */
0219:            public void setServletService(ServletService servletService) {
0220:                this .servletService = servletService;
0221:            }
0222:
0223:            public void load() {
0224:                super .load();
0225:                ServiceBroker sb = getServiceBroker();
0226:                logger = (LoggingService) sb.getService(this ,
0227:                        LoggingService.class, null);
0228:                if (logger == null)
0229:                    logger = LoggingService.NULL;
0230:
0231:                encAgentName = encodeAgentName(agentId.getAddress());
0232:
0233:                // when plugin is added to agent you can set this to a smaller or
0234:                // larger value depending on how much of the heap you want
0235:                // to fill up with events
0236:                maxEvents = args.getInt("MAX_EVENTS_REMEMBERED",
0237:                        INITIAL_MAX_ENTRIES);
0238:                maxRoleScheduleElements = args.getInt(
0239:                        "MAX_ROLE_SCHEDULE_ELEMENTS",
0240:                        INITIAL_MAX_ROLE_SCHEDULE_ELEMENTS);
0241:                maxChildTasks = args.getInt("MAX_CHILD_TASKS",
0242:                        INITIAL_MAX_CHILD_TASKS);
0243:                if (logger.isInfoEnabled()) {
0244:                    logger.info("max events "
0245:                            + args.getInt("MAX_EVENTS_REMEMBERED", 55));
0246:                    logger.info("args is " + args);
0247:                }
0248:            }
0249:
0250:            // Every load() should be matched with an unload() 
0251:            public void unload() {
0252:                if (servletService != null) {
0253:                    getServiceBroker().releaseService(this ,
0254:                            ServletService.class, servletService);
0255:                    servletService = null;
0256:                }
0257:                if (logger != LoggingService.NULL) {
0258:                    getServiceBroker().releaseService(this ,
0259:                            LoggingService.class, logger);
0260:                    logger = null;
0261:                }
0262:
0263:                super .unload();
0264:            }
0265:
0266:            /*
0267:             * Create subscriptions to all the BBoard changes, and register the servlet.
0268:             */
0269:            protected void setupSubscriptions() {
0270:                relaysSubscription = (IncrementalSubscription) blackboard
0271:                        .subscribe(relayPredicate);
0272:                tasksSubscription = (IncrementalSubscription) blackboard
0273:                        .subscribe(taskPredicate);
0274:                planElementsSubscription = (IncrementalSubscription) blackboard
0275:                        .subscribe(allocationPredicate);
0276:                assetsSubscription = (IncrementalSubscription) blackboard
0277:                        .subscribe(assetPredicate);
0278:                uniqueObjectsSubscription = (IncrementalSubscription) blackboard
0279:                        .subscribe(uniqueObjectPredicate);
0280:
0281:                // register with servlet service
0282:                try {
0283:                    servletService.register(getPath(), createServlet());
0284:                } catch (Exception e) {
0285:                    if (logger.isWarnEnabled())
0286:                        logger.warn("could not register servlet?", e);
0287:                }
0288:
0289:            }
0290:
0291:            /**
0292:             * Load this servlet at "/history"
0293:             */
0294:            protected String getPath() {
0295:                return "/history";
0296:            }
0297:
0298:            /**
0299:             * Get a new {@link HistoryWorker} to be the Servlet
0300:             */
0301:            protected Servlet createServlet() {
0302:                return new HistoryWorker();
0303:            }
0304:
0305:            /**
0306:             * Whenever a BBoard item changes, it adds that event to the list of Events
0307:             * (trimming the set if we reach the MAX size). Then when a user invokes
0308:             * the servlet, the set of events is ready for quick display.
0309:             */
0310:            public void execute() {
0311:                // Grab the time with which to mark the events. Note that this time
0312:                // is not when the event appeneded therefore, but when this plugin saw it.
0313:                // If the agent were busy (persistence?), this could be much later.
0314:                long now = currentTimeMillis(); // this is scenario time.
0315:
0316:                try {
0317:                    // Look at our subscriptions for changes, adding to our 
0318:                    // set of known events if necessary. This actually builds of the EventInfo
0319:                    // objects (see definition toward the bottom) which contain some HTML
0320:                    // strings -- making the later servlet viewing quicker, but taking
0321:                    // up more memory
0322:
0323:                    // synchronized prevents servlet from iterating over events
0324:                    // and adding to list of known events at same time
0325:                    synchronized (events) {
0326:                        checkTasks(now);
0327:                        checkPlanElements(now);
0328:                        checkRelays(now);
0329:                        checkAssets(now);
0330:                        checkUniqueObjects(now);
0331:                    }
0332:                } catch (Exception e) {
0333:                    if (logger.isWarnEnabled())
0334:                        logger.warn("Got exception adding to events list: ", e);
0335:                }
0336:
0337:                // Print the current set of Events...
0338:                if (logger.isDebugEnabled()) {
0339:                    StringBuffer buf = new StringBuffer();
0340:                    synchronized (events) {
0341:                        for (Iterator iter = events.iterator(); iter.hasNext();) {
0342:                            buf.append(iter.next() + "\n");
0343:                        }
0344:                    }
0345:
0346:                    logger.debug("Current events: \n" + buf);
0347:                }
0348:            }
0349:
0350:            /////////////////
0351:            // Below are all the helper methods to collect the Events....
0352:
0353:            public String encodeAgentName(String name) {
0354:                try {
0355:                    return URLEncoder.encode(name, "UTF-8");
0356:                } catch (java.io.UnsupportedEncodingException e) {
0357:                    // should never happen
0358:                    throw new RuntimeException("Unable to encode to UTF-8?");
0359:                }
0360:            }
0361:
0362:            protected String encode(String s) {
0363:                try {
0364:                    return URLEncoder.encode(s, "UTF-8");
0365:                } catch (Exception e) {
0366:                    throw new IllegalArgumentException("Unable to encode URL ("
0367:                            + s + ")");
0368:                }
0369:            }
0370:
0371:            /**
0372:             * Generate a link to the PlanView (/tasks) servlet
0373:             * for full details on the objet.
0374:             */
0375:            protected String getURL(UID uid, int which) {
0376:                int mode = 0;//PlanViewServlet.MODE_FRAME;
0377:                switch (which) {
0378:                case TASK:
0379:                    mode = 3;//PlanViewServlet.MODE_TASK_DETAILS;
0380:                    break;
0381:                case PLAN_ELEMENT:
0382:                    mode = 5;//PlanViewServlet.MODE_PLAN_ELEMENT_DETAILS;
0383:                    break;
0384:                case ASSET:
0385:                    mode = 7;//PlanViewServlet.MODE_PLAN_ELEMENT_DETAILS;
0386:                    break;
0387:                case UNIQUE_OBJECT:
0388:                    mode = 10;//PlanViewServlet.MODE_XML_HTML_DETAILS;
0389:                    break;
0390:                case DIRECT_OBJECT:
0391:                    mode = 15;//PlanViewServlet.MODE_XML_HTML_DETAILS;
0392:                    break;
0393:                }
0394:
0395:                StringBuffer buf = new StringBuffer();
0396:                buf.append("<a href=\"/$");
0397:                buf.append(encAgentName);
0398:                buf.append("/tasks");
0399:                buf.append("?" + "mode" + //PlanViewServlet.MODE+
0400:                        "=" + mode + "&" + "uid" + //PlanViewServlet.ITEM_UID+
0401:                        "=");
0402:                buf.append(encode(uid.toString()));
0403:                //        buf.append("\" target=\"itemFrame\">");
0404:                buf.append("\" target=\"_blank\">");
0405:                //    buf.append("\"");
0406:                buf.append(uid);
0407:                buf.append("</a>");
0408:
0409:                return buf.toString();
0410:            }
0411:
0412:            // Keep a running counter of events seen
0413:            // Can later be used to number the rows for readability.
0414:            private int eventNum = 0;
0415:
0416:            /**
0417:             * Get the next number for a new Event
0418:             */
0419:            protected int nextEventNum() {
0420:                return eventNum++;
0421:            }
0422:
0423:            /**
0424:             * Check the Tasks subscription, adding any new events to the list
0425:             */
0426:            protected void checkTasks(long now) {
0427:                // If there were any Task events
0428:                if (tasksSubscription.hasChanged()) {
0429:                    // First look at Added Tasks
0430:                    Collection added = tasksSubscription.getAddedCollection();
0431:                    // For each
0432:                    for (Iterator iter = added.iterator(); iter.hasNext();) {
0433:                        Task task = (Task) iter.next();
0434:                        // Basic description is the UID, verb, publisher
0435:                        String event = "Task " + getURL(task.getUID(), TASK)
0436:                                + " - " + task.getVerb();
0437:                        event += getClaimerString((Claimable) task);
0438:
0439:                        // Add the event to the set
0440:                        addEvent(new EventInfo(ADDED, nextEventNum(), task
0441:                                .getUID().toString(), event, now,
0442:                                getAddedTaskComment(task), encodeHTML(task
0443:                                        .toString())));
0444:                    }
0445:
0446:                    // Now the Changed tasks
0447:                    Collection changed = tasksSubscription
0448:                            .getChangedCollection();
0449:                    for (Iterator iter = changed.iterator(); iter.hasNext();) {
0450:                        Task task = (Task) iter.next();
0451:                        addEvent(new EventInfo(CHANGED, nextEventNum(), task
0452:                                .getUID().toString(), "Task "
0453:                                + getURL(task.getUID(), TASK), now, "",
0454:                                tasksSubscription.getChangeReports(task),
0455:                                encodeHTML(task.toString())));
0456:                    }
0457:
0458:                    // Now the removed tasks
0459:                    Collection removed = tasksSubscription
0460:                            .getRemovedCollection();
0461:                    for (Iterator iter = removed.iterator(); iter.hasNext();) {
0462:                        Task task = (Task) iter.next();
0463:                        addEvent(new EventInfo(REMOVED, nextEventNum(), task
0464:                                .getUID().toString(), "Task "
0465:                                + getURL(task.getUID(), TASK), now, ""));
0466:                    }
0467:                }
0468:            }
0469:
0470:            /**
0471:             * description of an added Task shows the Verb, DirectObject, and Preferences.
0472:             */
0473:            protected String getAddedTaskComment(Task task) {
0474:                StringBuffer buf = new StringBuffer();
0475:
0476:                buf.append(task.getVerb());
0477:                buf.append(" Task, ");
0478:                if (task.getDirectObject() != null) {
0479:                    buf.append(" with Direct Object ");
0480:                    buf.append(getTypeAndItemInfo(task.getDirectObject()));
0481:                    buf.append(".");
0482:                }
0483:                buf.append(getTaskPreferences(task));
0484:
0485:                return buf.toString();
0486:            }
0487:
0488:            /**
0489:             * Print out the Claimer of a Claimable, if any.
0490:             */
0491:            private String getClaimerString(Claimable cl) {
0492:                if (cl == null)
0493:                    return "";
0494:
0495:                Object claimer = cl.getClaim();
0496:                if (claimer != null && !claimer.toString().trim().equals(""))
0497:                    return "<br/>was published by " + claimer.toString();
0498:                else
0499:                    return "";
0500:            }
0501:
0502:            /**
0503:             * Add any PlanElement events to the Set
0504:             */
0505:            protected void checkPlanElements(long now) {
0506:                if (planElementsSubscription.hasChanged()) {
0507:                    Collection added = planElementsSubscription
0508:                            .getAddedCollection();
0509:                    for (Iterator iter = added.iterator(); iter.hasNext();) {
0510:                        PlanElement planElement = (PlanElement) iter.next();
0511:                        String event = "" + getClassName(planElement) + " "
0512:                                + getURL(planElement.getUID(), PLAN_ELEMENT)
0513:                                + "<br/>of Task "
0514:                                + getURL(planElement.getTask().getUID(), TASK)
0515:                                + getClaimerString(planElement.getClaimable());
0516:
0517:                        addEvent(new EventInfo(ADDED, nextEventNum(),
0518:                                planElement.getUID().toString(), event, now,
0519:                                getAddedPEComment(planElement),
0520:                                encodeHTML(planElement.toString())));
0521:                    }
0522:
0523:                    Collection changed = planElementsSubscription
0524:                            .getChangedCollection();
0525:                    for (Iterator iter = changed.iterator(); iter.hasNext();) {
0526:                        PlanElement planElement = (PlanElement) iter.next();
0527:                        String event = getClassName(planElement) + " "
0528:                                + getURL(planElement.getUID(), PLAN_ELEMENT);
0529:
0530:                        addEvent(new EventInfo(CHANGED, nextEventNum(),
0531:                                planElement.getUID().toString(), event, now,
0532:                                getChangedPEComment(planElement),
0533:                                planElementsSubscription
0534:                                        .getChangeReports(planElement),
0535:                                encodeHTML(planElement.toString())));
0536:                    }
0537:
0538:                    Collection removed = planElementsSubscription
0539:                            .getRemovedCollection();
0540:                    for (Iterator iter = removed.iterator(); iter.hasNext();) {
0541:                        PlanElement planElement = (PlanElement) iter.next();
0542:                        String event = getClassName(planElement) + " "
0543:                                + getURL(planElement.getUID(), PLAN_ELEMENT);
0544:
0545:                        addEvent(new EventInfo(REMOVED, nextEventNum(),
0546:                                planElement.getUID().toString(), event, now,
0547:                                // Alternative to empty comment would be getAddedPEComment(planElement)
0548:                                "&nbsp;", planElementsSubscription
0549:                                        .getChangeReports(planElement),
0550:                                encodeHTML(planElement.toString())));
0551:                    }
0552:                }
0553:            }
0554:
0555:            /**
0556:             * Add any Relay events
0557:             */
0558:            protected void checkRelays(long now) {
0559:                if (relaysSubscription.hasChanged()) {
0560:                    Collection added = relaysSubscription.getAddedCollection();
0561:                    for (Iterator iter = added.iterator(); iter.hasNext();) {
0562:                        Relay relay = (Relay) iter.next();
0563:                        addEvent(new EventInfo(ADDED, nextEventNum(), relay
0564:                                .getUID().toString(), "Relay "
0565:                                + getURL(relay.getUID(), UNIQUE_OBJECT), now,
0566:                                getAddedRelayComment(relay), encodeHTML(relay
0567:                                        .toString())));
0568:                    }
0569:
0570:                    Collection changed = relaysSubscription
0571:                            .getChangedCollection();
0572:                    for (Iterator iter = changed.iterator(); iter.hasNext();) {
0573:                        Relay relay = (Relay) iter.next();
0574:                        addEvent(new EventInfo(CHANGED, nextEventNum(), relay
0575:                                .getUID().toString(), "Relay "
0576:                                + getURL(relay.getUID(), UNIQUE_OBJECT), now,
0577:                                getChangedRelayComment(relay),
0578:                                relaysSubscription.getChangeReports(relay),
0579:                                encodeHTML(relay.toString())));
0580:                    }
0581:
0582:                    Collection removed = relaysSubscription
0583:                            .getRemovedCollection();
0584:                    for (Iterator iter = removed.iterator(); iter.hasNext();) {
0585:                        Relay relay = (Relay) iter.next();
0586:                        addEvent(new EventInfo(REMOVED, nextEventNum(), relay
0587:                                .getUID().toString(), "Relay "
0588:                                + getURL(relay.getUID(), UNIQUE_OBJECT), now,
0589:                                "Relay removed from blackboard.",
0590:                                relaysSubscription.getChangeReports(relay),
0591:                                encodeHTML(relay.toString())));
0592:                    }
0593:                }
0594:            }
0595:
0596:            /**
0597:             * Add any Asset events to the Set
0598:             */
0599:            protected void checkAssets(long now) {
0600:                if (assetsSubscription.hasChanged()) {
0601:                    Collection added = assetsSubscription.getAddedCollection();
0602:                    for (Iterator iter = added.iterator(); iter.hasNext();) {
0603:                        Asset asset = (Asset) iter.next();
0604:                        addEvent(new EventInfo(ADDED, nextEventNum(), asset
0605:                                .getUID().toString(), "Asset "
0606:                                + getURL(asset.getUID(), ASSET), now,
0607:                                getAddedAssetComment(asset), encodeHTML(asset
0608:                                        .toString())));
0609:                    }
0610:
0611:                    Collection changed = assetsSubscription
0612:                            .getChangedCollection();
0613:                    for (Iterator iter = changed.iterator(); iter.hasNext();) {
0614:                        Asset asset = (Asset) iter.next();
0615:                        addEvent(new EventInfo(CHANGED, nextEventNum(), asset
0616:                                .getUID().toString(), "Asset "
0617:                                + getURL(asset.getUID(), ASSET), now,
0618:                                getChangedAssetComment(asset), encodeHTML(asset
0619:                                        .toString())));
0620:                    }
0621:
0622:                    Collection removed = assetsSubscription
0623:                            .getRemovedCollection();
0624:                    for (Iterator iter = removed.iterator(); iter.hasNext();) {
0625:                        Asset asset = (Asset) iter.next();
0626:                        addEvent(new EventInfo(REMOVED, nextEventNum(), asset
0627:                                .getUID().toString(), "Asset "
0628:                                + getURL(asset.getUID(), ASSET), now, ""));
0629:                    }
0630:                }
0631:            }
0632:
0633:            /**
0634:             * Get the ChangedAssetComment
0635:             */
0636:            protected String getAddedAssetComment(Asset asset) {
0637:                return getChangedAssetComment(asset);
0638:            }
0639:
0640:            /**
0641:             * Show the asset class, typeID, ItemID, if an Entity then any Roles, Relationships, RoleSchedule, and the HistoryServletFriendly content
0642:             */
0643:            protected String getChangedAssetComment(Asset asset) {
0644:                StringBuffer buf = new StringBuffer();
0645:
0646:                buf.append(getClassName(asset));
0647:                buf.append(": <b>");
0648:                buf.append(getTypeAndItemInfo(asset));
0649:                buf.append("</b><br/>");
0650:
0651:                if (asset instanceof  Entity) {
0652:                    Entity entity = (Entity) asset;
0653:
0654:                    if (!entity.getEntityPG().getRoles().isEmpty()) {
0655:                        buf.append(" with Roles : ");
0656:                    }
0657:
0658:                    for (Iterator iter = entity.getEntityPG().getRoles()
0659:                            .iterator(); iter.hasNext();) {
0660:                        buf.append("<font size=small color=mediumblue>"
0661:                                + "<li>");
0662:                        Object obj = iter.next();
0663:                        buf.append(getClassName(obj) + " - " + obj);
0664:                        buf.append("</li>" + "</font>\n");
0665:                    } // end of loop over roles
0666:                } // end of block for Entity
0667:
0668:                if (asset instanceof  HasRelationships) {
0669:                    HasRelationships entity = (HasRelationships) asset;
0670:
0671:                    Collection relationships = entity.getRelationshipSchedule()
0672:                            .getMatchingRelationships(new UnaryPredicate() {
0673:                                public boolean execute(Object o) {
0674:                                    return true;
0675:                                }
0676:                            });
0677:
0678:                    if (!relationships.isEmpty()) {
0679:                        buf.append("<br/>with Relationships : ");
0680:                    }
0681:
0682:                    for (Iterator iter = relationships.iterator(); iter
0683:                            .hasNext();) {
0684:                        buf.append("<font size=small color=mediumblue>"
0685:                                + "<li>");
0686:
0687:                        Object obj = iter.next();
0688:                        // buf.append (getClassName(obj) + " - " + obj);
0689:                        if (obj instanceof  Relationship) {
0690:                            Relationship relation = (Relationship) obj;
0691:                            buf.append(relation.getRoleA().toString());
0692:                            buf.append("=");
0693:
0694:                            if (relation.getA() instanceof  Asset) {
0695:                                buf.append(getTypeAndItemInfo((Asset) relation
0696:                                        .getA()));
0697:                            }
0698:
0699:                            buf
0700:                                    .append("<br/>"
0701:                                            + relation.getRoleB().toString());
0702:                            buf.append("=");
0703:
0704:                            if (relation.getB() instanceof  Asset) {
0705:                                buf.append(getTypeAndItemInfo((Asset) relation
0706:                                        .getB()));
0707:                            }
0708:                        }
0709:
0710:                        buf.append("</li>" + "</font>\n");
0711:                    } // end of loop over relationships
0712:
0713:                } // end of HasRelationships
0714:
0715:                buf.append(getRoleSchedule(asset));
0716:
0717:                if (asset instanceof  HistoryServletFriendly) {
0718:                    buf
0719:                            .append(((HistoryServletFriendly) asset)
0720:                                    .toHTML(CHANGED));
0721:                }
0722:
0723:                return buf.toString();
0724:            } // end of getChangedAssetComment
0725:
0726:            /**
0727:             * Print the RoleSchedule of the Asset if any, up to the
0728:             * maxRoleScheduleElements
0729:             */
0730:            protected String getRoleSchedule(Asset asset) {
0731:                StringBuffer buf = new StringBuffer();
0732:
0733:                if (asset.getRoleSchedule().getRoleScheduleElements()
0734:                        .hasMoreElements()) {
0735:                    buf.append("<br/>which has Role Schedule: ");
0736:                }
0737:
0738:                int numShown = 0;
0739:                for (Enumeration en = asset.getRoleSchedule()
0740:                        .getRoleScheduleElements(); en.hasMoreElements(); numShown++) {
0741:                    buf.append("<font size=small color=mediumblue>" + "<li>");
0742:                    Object elem = en.nextElement();
0743:                    if (numShown >= maxRoleScheduleElements) {
0744:                        buf.append("... (more than ");
0745:                        buf.append(maxRoleScheduleElements);
0746:                        buf.append(")");
0747:                        buf.append("</li>" + "</font>\n");
0748:                        break;
0749:                    } else {
0750:                        if (elem instanceof  Allocation) {
0751:                            buf.append("Allocation to "
0752:                                    + getTypeAndItemInfo(((Allocation) elem)
0753:                                            .getAsset()));
0754:                        } else if (elem instanceof  PlanElement) {
0755:                            buf.append(getAddedPEComment((PlanElement) elem));
0756:                        } else {
0757:                            buf.append(en.nextElement());
0758:                        }
0759:                    }
0760:
0761:                    buf.append("</li>" + "</font>\n");
0762:                }
0763:
0764:                return buf.toString();
0765:            }
0766:
0767:            /**
0768:             * Add any added/changed/removed UniqueObjects
0769:             */
0770:            protected void checkUniqueObjects(long now) {
0771:                if (uniqueObjectsSubscription.hasChanged()) {
0772:                    Collection added = uniqueObjectsSubscription
0773:                            .getAddedCollection();
0774:                    for (Iterator iter = added.iterator(); iter.hasNext();) {
0775:                        UniqueObject uniqueObject = (UniqueObject) iter.next();
0776:                        addEvent(new EventInfo(ADDED, nextEventNum(),
0777:                                uniqueObject.getUID().toString(),
0778:                                "UniqueObject "
0779:                                        + getURL(uniqueObject.getUID(),
0780:                                                UNIQUE_OBJECT), now,
0781:                                getAddedUniqueObjectComment(uniqueObject),
0782:                                encodeHTML(uniqueObject.toString())));
0783:                    }
0784:
0785:                    Collection changed = uniqueObjectsSubscription
0786:                            .getChangedCollection();
0787:                    for (Iterator iter = changed.iterator(); iter.hasNext();) {
0788:                        UniqueObject uniqueObject = (UniqueObject) iter.next();
0789:                        addEvent(new EventInfo(CHANGED, nextEventNum(),
0790:                                uniqueObject.getUID().toString(),
0791:                                "UniqueObject "
0792:                                        + getURL(uniqueObject.getUID(),
0793:                                                UNIQUE_OBJECT) + " changed.",
0794:                                now,
0795:                                getChangedUniqueObjectComment(uniqueObject),
0796:                                encodeHTML(uniqueObject.toString())));
0797:                    }
0798:
0799:                    Collection removed = uniqueObjectsSubscription
0800:                            .getRemovedCollection();
0801:                    for (Iterator iter = removed.iterator(); iter.hasNext();) {
0802:                        UniqueObject uniqueObject = (UniqueObject) iter.next();
0803:                        addEvent(new EventInfo(REMOVED, nextEventNum(),
0804:                                uniqueObject.getUID().toString(),
0805:                                "UniqueObject "
0806:                                        + getURL(uniqueObject.getUID(),
0807:                                                UNIQUE_OBJECT)
0808:                                        + " was removed.", now,
0809:                                getRemovedUniqueObjectComment(uniqueObject)));
0810:                    }
0811:                }
0812:            }
0813:
0814:            /**
0815:             * For an Added unique object, print it's name, and any
0816:             * HistoryServletFriendly content
0817:             */
0818:            protected String getAddedUniqueObjectComment(UniqueObject unique) {
0819:                StringBuffer buf = new StringBuffer();
0820:
0821:                buf.append("A ");
0822:                buf.append(getClassName(unique));
0823:                buf.append(" object.<br/>");
0824:
0825:                if (unique instanceof  HistoryServletFriendly) {
0826:                    buf.append(((HistoryServletFriendly) unique).toHTML(ADDED));
0827:                }
0828:
0829:                return buf.toString();
0830:            }
0831:
0832:            /**
0833:             * Changed/Removed unique objects use the same comment as for Add
0834:             */
0835:            protected String getChangedUniqueObjectComment(UniqueObject unique) {
0836:                return getAddedUniqueObjectComment(unique);
0837:            }
0838:
0839:            /**
0840:             * Changed/Removed unique objects use the same comment as for Add
0841:             */
0842:            protected String getRemovedUniqueObjectComment(UniqueObject unique) {
0843:                return getAddedUniqueObjectComment(unique);
0844:            }
0845:
0846:            /**
0847:             * Get the non-Package name of the Class
0848:             */
0849:            protected String getClassName(Object obj) {
0850:                String classname = obj.getClass().getName();
0851:                int index = classname.lastIndexOf(".");
0852:                classname = classname.substring(index + 1, classname.length());
0853:                return classname;
0854:            }
0855:
0856:            /**
0857:             * For a Source: show the target addresses, any community content or request, and the
0858:             * relay's Content.
0859:             * <p/>
0860:             * For a Target, show any community info, the relay Source, and any HistoryServletFriendly content.
0861:             */
0862:            protected String getAddedRelayComment(Relay relay) {
0863:                StringBuffer buf = new StringBuffer();
0864:
0865:                if (relay instanceof  Relay.Source) {
0866:                    buf.append("Sent new ");
0867:                    Relay.Source sourceRelay = (Relay.Source) relay;
0868:                    buf.append(showTargetAddresses(sourceRelay));
0869:
0870:                    // Special case community relays
0871:                    if (sourceRelay.getContent() instanceof  CommunityDescriptor) {
0872:                        CommunityDescriptor response = (CommunityDescriptor) sourceRelay
0873:                                .getContent();
0874:                        Community community = null;
0875:                        if (response != null)
0876:                            community = (Community) response.getCommunity();
0877:                        if (buf.length() != 0)
0878:                            buf.append("<br/>");
0879:                        buf
0880:                                .append(getCommunityText(
0881:                                        "Relay Source sending Description: ",
0882:                                        community));
0883:                    } else if (sourceRelay.getContent() instanceof  Request) {
0884:                        if (buf.length() != 0)
0885:                            buf.append("<br/>");
0886:                        buf.append("Community Request: ");
0887:                        Request request = (Request) sourceRelay.getContent();
0888:                        buf.append(request.getRequestTypeAsString(request
0889:                                .getRequestType()));
0890:                        buf.append("<br/>Source: ");
0891:                        buf.append(request.getSource());
0892:                        buf.append("<br/>Entity: ");
0893:                        buf.append(request.getEntity());
0894:                    } else {
0895:                        if (buf.length() != 0)
0896:                            buf.append("<br/>");
0897:                        buf.append("Content: ");
0898:                        buf.append(encodeHTML(sourceRelay.getContent()
0899:                                .toString()));
0900:                    }
0901:                    buf.append("<br/>");
0902:                }
0903:
0904:                if (relay instanceof  Relay.Target) {
0905:                    Relay.Target targetRelay = (Relay.Target) relay;
0906:                    //    buf.append("instanceof " + getClassName(targetRelay.getResponse()) + " ");
0907:                    if (targetRelay.getResponse() instanceof  CommunityResponse) {
0908:                        CommunityResponse response = (CommunityResponse) targetRelay
0909:                                .getResponse();
0910:                        Community community = null;
0911:                        if (response != null)
0912:                            community = (Community) response.getContent();
0913:
0914:                        buf.append("Entity "
0915:                                + targetRelay.getSource()
0916:                                + " registers with Community "
0917:                                + (community != null ? community.getName()
0918:                                        : "[null]"));
0919:                    } else {
0920:                        // Other than community relays, no good general way to print
0921:                        // the relay response
0922:                        String targetSource = "-NO SOURCE SET-";
0923:
0924:                        if (targetRelay.getSource() != null) {
0925:                            targetSource = targetRelay.getSource().toString();
0926:                        }
0927:
0928:                        buf.append("Received Relay Target from Source  : "
0929:                                + encodeHTML(targetSource));
0930:                    }
0931:                }
0932:
0933:                if (relay instanceof  HistoryServletFriendly) {
0934:                    buf.append(((HistoryServletFriendly) relay).toHTML(ADDED));
0935:                }
0936:
0937:                return buf.toString();
0938:            }
0939:
0940:            /**
0941:             * Show the target(s) of a relay, including ABAs
0942:             */
0943:            protected String showTargetAddresses(Relay.Source sourceRelay) {
0944:                StringBuffer buf = new StringBuffer();
0945:
0946:                if (!sourceRelay.getTargets().isEmpty()) {
0947:                    buf.append("Relay Source with Targets: ");
0948:                    for (Iterator iter = sourceRelay.getTargets().iterator(); iter
0949:                            .hasNext();) {
0950:                        buf.append("<font size=small color=mediumblue>"
0951:                                + "<li>");
0952:                        MessageAddress address = (MessageAddress) iter.next();
0953:                        if (address instanceof  AttributeBasedAddress) {
0954:                            AttributeBasedAddress aba = (AttributeBasedAddress) address;
0955:                            buf
0956:                                    .append("AttributeBasedAddress: Broadcast to Community=");
0957:                            buf.append(aba.getCommunityName());
0958:                            buf.append(" attribute type=");
0959:                            buf.append(aba.getAttributeType());
0960:                            buf.append(" value=");
0961:                            buf.append(aba.getAttributeValue());
0962:                        } else {
0963:                            buf.append(address);
0964:                        }
0965:                        // buf.append (encodeHTML(address.toString()));
0966:                        buf.append("</li>" + "</font>\n");
0967:                    }
0968:                }
0969:
0970:                return buf.toString();
0971:            }
0972:
0973:            /**
0974:             * For a Source, show any community specific information, the Content.
0975:             * <p/>
0976:             * For a Target, show any community specific information, and the response, and
0977:             * any HistoryServletFriendly content.
0978:             */
0979:            protected String getChangedRelayComment(Relay relay) {
0980:                StringBuffer buf = new StringBuffer();
0981:                if (relay instanceof  Relay.Source) {
0982:                    buf.append("Response Returned</br>");
0983:
0984:                    Relay.Source sourceRelay = (Relay.Source) relay;
0985:                    if (!(sourceRelay.getContent() instanceof  Relay))
0986:                        buf.append("Relay Source's Query    : "
0987:                                + encodeHTML(sourceRelay.getContent()
0988:                                        .toString()) + "<br/>");
0989:
0990:                    if (sourceRelay.getContent() instanceof  CommunityDescriptor) {
0991:                        CommunityDescriptor response = (CommunityDescriptor) sourceRelay
0992:                                .getContent();
0993:                        Community community = null;
0994:                        if (response != null)
0995:                            community = (Community) response.getCommunity();
0996:                        buf.append(getCommunityText(
0997:                                "Relay Source received Response: ", community));
0998:                    }
0999:                }
1000:
1001:                if (relay instanceof  Relay.Target) {
1002:                    Relay.Target targetRelay = (Relay.Target) relay;
1003:                    //  buf.append("instanceof " + getClassName(targetRelay.getResponse()) + " ");
1004:                    if (targetRelay.getResponse() instanceof  CommunityResponse) {
1005:                        CommunityResponse response = (CommunityResponse) targetRelay
1006:                                .getResponse();
1007:                        Community community = null;
1008:                        if (response != null)
1009:                            community = (Community) response.getContent();
1010:                        buf.append(getCommunityText(
1011:                                "Relay Target sent Response: ", community));
1012:                    } else if (targetRelay.getResponse() instanceof  CommunityDescriptor) {
1013:                        CommunityDescriptor response = (CommunityDescriptor) targetRelay
1014:                                .getResponse();
1015:                        Community community = null;
1016:                        if (response != null)
1017:                            community = (Community) response.getCommunity();
1018:                        buf.append(getCommunityText(
1019:                                "Relay Target sent Response: ", community));
1020:                    } else {
1021:                        buf.append("Relay Target sent Response: "
1022:                                + encodeHTML(targetRelay.getResponse()
1023:                                        .toString()));
1024:                    }
1025:                }
1026:
1027:                if (relay instanceof  HistoryServletFriendly) {
1028:                    buf
1029:                            .append(((HistoryServletFriendly) relay)
1030:                                    .toHTML(CHANGED));
1031:                }
1032:
1033:                return buf.toString();
1034:            }
1035:
1036:            /**
1037:             * Describe this Community by name, entities
1038:             */
1039:            protected String getCommunityText(String prefix, Community community) {
1040:                if (community == null)
1041:                    return "[empty response]";
1042:
1043:                StringBuffer buf = new StringBuffer();
1044:                buf.append(prefix);
1045:                buf.append(" Community <b>" + community.getName()
1046:                        + "</b> with members : ");
1047:                for (Iterator iter = community.getEntities().iterator(); iter
1048:                        .hasNext();) {
1049:                    buf.append("<font size=small color=mediumblue>" + "<li>");
1050:                    buf.append(iter.next());
1051:                    buf.append("</li>" + "</font>\n");
1052:                }
1053:                return buf.toString();
1054:            }
1055:
1056:            /**
1057:             * Show the results on the PE
1058:             */
1059:            protected String getChangedPEComment(PlanElement planElement) {
1060:                StringBuffer buf = new StringBuffer();
1061:
1062:                if (planElement.getEstimatedResult() != null) {
1063:                    buf.append(getAllocResult("Estimated", planElement
1064:                            .getEstimatedResult()));
1065:                }
1066:
1067:                if (planElement.getReportedResult() != null) {
1068:                    buf.append(getAllocResult("Reported", planElement
1069:                            .getReportedResult()));
1070:                    buf.append("<br/>");
1071:                    if (!planElement.getReportedResult().isSuccess()) {
1072:                        if (planElement.getTask().getPreferences()
1073:                                .hasMoreElements()) {
1074:                            buf
1075:                                    .append("<br>Failed because reported Aspect Values did not satisfy Task Preferences:");
1076:                            buf
1077:                                    .append(getTaskPreferences(planElement
1078:                                            .getTask()));
1079:                        } else {
1080:                            buf
1081:                                    .append("<br>Failed because one or more Child Tasks failed.");
1082:                        }
1083:                    }
1084:                }
1085:
1086:                return buf.toString();
1087:            }
1088:
1089:            /**
1090:             * Get an HTML table of these Aspect Values (id'd by the prefix)
1091:             */
1092:            protected String getAspectValues(AspectValue[] values, String prefix) {
1093:                StringBuffer buf = new StringBuffer();
1094:                buf.append("<table>");
1095:                buf.append("<tr><td>");
1096:                buf.append(prefix + " Aspect Values:");
1097:                buf.append("</td></tr>");
1098:                for (int i = 0; i < values.length; i++) {
1099:                    buf.append("<tr><td>");
1100:                    buf.append("Type ");
1101:                    buf.append(AspectValue.aspectTypeToString(values[i]
1102:                            .getType()));
1103:                    buf.append(" - Value ");
1104:                    buf.append(values[i].getValue());
1105:                    buf.append("</td></tr>");
1106:                }
1107:                buf.append("</table>");
1108:                return buf.toString();
1109:            }
1110:
1111:            /**
1112:             * Get String representation of these Aspect Values
1113:             */
1114:            protected String getAspectValues2(AspectValue[] values) {
1115:                StringBuffer buf = new StringBuffer();
1116:                // for all (type, result) pairs
1117:                for (int i = 0; i < values.length; i++) {
1118:                    AspectValue avi = values[i];
1119:                    buf.append(getAspectValue(avi));
1120:                }
1121:                return buf.toString();
1122:            }
1123:
1124:            /**
1125:             * Get a String representation of this AspectValue
1126:             */
1127:            protected String getAspectValue(AspectValue avi) {
1128:                StringBuffer buf = new StringBuffer();
1129:                buf.append("<font size=small color=mediumblue>" + "<li>");
1130:                // show type
1131:                buf.append(AspectValue.aspectTypeToString(avi.getType()));
1132:                buf.append("= ");
1133:                // show value
1134:                if (avi instanceof  TimeAspectValue) {
1135:                    // print the date in our format
1136:                    long time = ((TimeAspectValue) avi).timeValue();
1137:                    buf.append(getTimeString(time));
1138:                } else {
1139:                    buf.append(avi.getValue());
1140:                }
1141:                buf.append("</li>" + "</font>\n");
1142:                return buf.toString();
1143:            }
1144:
1145:            /**
1146:             * Formats long millis time to Date Format String.
1147:             */
1148:            protected String getTimeString(long time) {
1149:                synchronized (myDateFormat) {
1150:                    myDateInstance.setTime(time);
1151:                    return myDateFormat.format(myDateInstance,
1152:                            new StringBuffer(20), myFieldPos).toString();
1153:                }
1154:            }
1155:
1156:            /**
1157:             * Get a String HTML table of the Task's preferences
1158:             */
1159:            protected String getTaskPreferences(Task task) {
1160:                Enumeration prefs = task.getPreferences();
1161:                StringBuffer buf = new StringBuffer();
1162:                boolean hasPrefs = false;
1163:                buf.append("<table>");
1164:                buf.append("<tr><td>");
1165:                buf.append("Preferences: ");
1166:                buf.append("</td></tr>");
1167:                while (prefs.hasMoreElements()) {
1168:                    Preference pref = (Preference) prefs.nextElement();
1169:                    hasPrefs = true;
1170:                    AspectValue prefav = pref.getScoringFunction().getBest()
1171:                            .getAspectValue();
1172:                    buf.append("<tr><td>");
1173:                    buf.append(getAspectValue(prefav));
1174:                    /*
1175:                    buf.append ("Type ");
1176:                    buf.append (AspectValue.aspectTypeToString(prefav.getType()));
1177:                    buf.append (" - Value");
1178:                    buf.append (prefav.getValue());
1179:                     */
1180:                    buf.append("</td></tr>");
1181:                }
1182:                buf.append("</table>");
1183:
1184:                if (!hasPrefs)
1185:                    return "";
1186:                else
1187:                    return buf.toString();
1188:            }
1189:
1190:            /**
1191:             * Return HTML of the success or failure (with Aspect Values) of the given AllocationResult
1192:             */
1193:            private String getAllocResult(String type, AllocationResult ar) {
1194:                if (ar == null)
1195:                    return "";
1196:
1197:                StringBuffer buf = new StringBuffer();
1198:                AspectValue[] values = ar.getAspectValueResults();
1199:                boolean success = ar.isSuccess();
1200:                String prefix = "<br/>"
1201:                        + type
1202:                        + " Allocation Result - "
1203:                        + (success ? "<font color=\"green\">Success</font>"
1204:                                : "<font color=\"red\">Failure</font>");
1205:                buf.append(prefix + "<br/>");
1206:                buf.append(getAspectValues2(values));
1207:
1208:                return buf.toString();
1209:            }
1210:
1211:            /**
1212:             * If it's an Allocation, show the Task Verb and the allocated Asset's Type
1213:             * and ItemID, RoleSchedule.
1214:             * For an Expansion, show the child tasks (up to the MAX).
1215:             * For an AssetTransfer, show the moving Asset and destination.
1216:             * For an Aggregation, show just the count of parent tasks.
1217:             * For a Disposition, show whether it succeed or failed.
1218:             * Also show any Annotation, Estimated Result, and Reported Result.
1219:             */
1220:            protected String getAddedPEComment(PlanElement planElement) {
1221:                StringBuffer buf = new StringBuffer();
1222:
1223:                if (planElement instanceof  Allocation) {
1224:                    Allocation allocation = (Allocation) planElement;
1225:
1226:                    if (allocation.getAsset() != null) {
1227:                        buf.append("Satisfy ");
1228:                        buf.append(allocation.getTask().getVerb());
1229:                        buf.append(" Task with ");
1230:                        if (allocation.getAsset() instanceof  Entity) {
1231:                            buf.append(" <i>remote Agent</i> ");
1232:                        }
1233:                        buf.append(getTypeAndItemInfo(allocation.getAsset()));
1234:                        buf.append("<br/>");
1235:                        buf.append(getRoleSchedule(allocation.getAsset()));
1236:                    }
1237:                } else if (planElement instanceof  Expansion) {
1238:                    Expansion expansion = (Expansion) planElement;
1239:
1240:                    buf.append("<table>");
1241:                    buf.append("<tr><td>");
1242:                    buf.append("Expansion's Child Tasks are:");
1243:                    buf.append("</td></tr>");
1244:
1245:                    int numShown = 0;
1246:                    for (Enumeration e = expansion.getWorkflow().getTasks(); e
1247:                            .hasMoreElements(); numShown++) {
1248:                        Task task = (Task) e.nextElement();
1249:                        buf.append("<tr><td>");
1250:
1251:                        if (numShown >= maxChildTasks) {
1252:                            buf.append("... (more than ");
1253:                            buf.append(maxChildTasks);
1254:                            buf.append(")");
1255:                            buf.append("</td></tr>");
1256:                            break;
1257:                        } else {
1258:                            buf.append("Task " + getURL(task.getUID(), TASK)
1259:                                    + " " + task.getVerb());
1260:
1261:                            if (task.getDirectObject() != null) {
1262:                                buf.append(" with Direct Object ");// + getURL(task.getDirectObject().getUID(), DIRECT_OBJECT) + " ");
1263:                                buf.append(getTypeAndItemInfo(task
1264:                                        .getDirectObject()));
1265:                                buf.append(".");
1266:                            }
1267:
1268:                            buf.append("</td></tr>");
1269:                        }
1270:                    }
1271:
1272:                    buf.append("</table>");
1273:                } else if (planElement instanceof  AssetTransfer) {
1274:                    AssetTransfer transfer = (AssetTransfer) planElement;
1275:                    buf.append("Transfer of <b>");
1276:                    buf.append(getTypeAndItemInfo(transfer.getAsset()));
1277:                    buf.append("</b> from <b>");
1278:                    buf.append(transfer.getAssignor());
1279:                    buf.append("</b> to <b>");
1280:                    buf.append(getTypeAndItemInfo(transfer.getAssignee()));
1281:                    buf.append("</b>");
1282:                } else if (planElement instanceof  Aggregation) {
1283:                    buf.append("Aggregation of ");
1284:                    buf.append(((Aggregation) planElement).getComposition()
1285:                            .getParentTasks().size());
1286:                    buf.append(" parent tasks.");
1287:                } else if (planElement instanceof  Disposition) {
1288:                    boolean suc = ((Disposition) planElement).isSuccess();
1289:                    buf.append("Disposition as ");
1290:                    if (suc)
1291:                        buf.append("<font color=green>Success</font>");
1292:                    else
1293:                        buf.append("<font color=red>Failure</font>");
1294:                }
1295:
1296:                if (planElement.getAnnotation() != null) {
1297:                    buf
1298:                            .append("<br>Annotation: "
1299:                                    + planElement.getAnnotation());
1300:                }
1301:
1302:                if (planElement.getEstimatedResult() != null) {
1303:                    buf.append(getAllocResult("Estimated", planElement
1304:                            .getEstimatedResult()));
1305:                }
1306:                if (planElement.getReportedResult() != null) {
1307:                    buf.append(getAllocResult("Reported", planElement
1308:                            .getReportedResult()));
1309:                }
1310:
1311:                return buf.toString();
1312:            }
1313:
1314:            /**
1315:             * Get the type & item ID of an Asset -- to ID it in the display
1316:             */
1317:            protected String getTypeAndItemInfo(Asset asset) {
1318:                StringBuffer buf = new StringBuffer();
1319:
1320:                if (asset.getTypeIdentificationPG() != null) {
1321:                    buf.append(asset.getTypeIdentificationPG()
1322:                            .getTypeIdentification()
1323:                            + " - ");
1324:                }
1325:                if (asset.getItemIdentificationPG() != null) {
1326:                    buf.append(asset.getItemIdentificationPG()
1327:                            .getItemIdentification());
1328:                }
1329:
1330:                return buf.toString();
1331:            }
1332:
1333:            // End of the various methods to fill the Events Set during plugin Execution
1334:            /////////////////////////////////////////////////////////////////
1335:            /////////////////////////////////////////////////////////////////
1336:            // Now, the methods to handle the Servlet:
1337:
1338:            /**
1339:             * Inner-class that's registered as the servlet.
1340:             */
1341:            protected class HistoryWorker extends HttpServlet {
1342:                public void doGet(HttpServletRequest request,
1343:                        HttpServletResponse response) throws IOException,
1344:                        ServletException {
1345:                    doPost(request, response);
1346:                }
1347:
1348:                public void doPost(HttpServletRequest request,
1349:                        HttpServletResponse response) throws IOException,
1350:                        ServletException {
1351:                    // returns a new instance with each query. Perhaps inefficient?
1352:                    new HistoryFormatter(request, response);
1353:                }
1354:            }
1355:
1356:            /**
1357:             * Add a new event to the list
1358:             */
1359:            protected void addEvent(EventInfo newEvent) {
1360:                events.add(newEvent);
1361:
1362:                // If we've reached the Max, trim the oldest event
1363:                if (events.size() > maxEvents) {
1364:                    // if the events are sorted by uid, we want to sort them
1365:                    // by time first and then remove the oldest entry
1366:                    if (sortByUID) {
1367:                        // switch back to sorting by time, then uid
1368:                        sortByUID = false;
1369:
1370:                        SortedSet set = new TreeSet();
1371:                        set.addAll(events);
1372:                        setEvents(set);
1373:                    }
1374:
1375:                    if (logger.isInfoEnabled()) {
1376:                        logger.info("removing " + events.first()
1377:                                + " since more than max " + events.size()
1378:                                + " elements.");
1379:                    }
1380:
1381:                    // Drop the oldest event
1382:                    events.remove(events.first());
1383:                    didDropOldEntries = true;
1384:                }
1385:            }
1386:
1387:            /**
1388:             * Reset the stored event list -- used when we've resorted the list.
1389:             */
1390:            protected void setEvents(SortedSet events) {
1391:                this .events = events;
1392:            }
1393:
1394:            /**
1395:             * The inner class used by the servlet to format the request results.
1396:             */
1397:            protected class HistoryFormatter {
1398:                public static final int FORMAT_DATA = 0;
1399:                public static final int FORMAT_XML = 1;
1400:                public static final int FORMAT_HTML = 2;
1401:
1402:                private int format = FORMAT_HTML;
1403:
1404:                public HistoryFormatter(HttpServletRequest request,
1405:                        HttpServletResponse response) throws IOException,
1406:                        ServletException {
1407:                    // Handle the parameters to the request
1408:                    processParams(request);
1409:                    // Then print the resulting page
1410:                    execute(response);
1411:                }
1412:
1413:                /**
1414:                 * Interpret the Format requested (only HTML supported),
1415:                 * sort the events as requested before we do printing.
1416:                 */
1417:                protected void processParams(HttpServletRequest request) {
1418:                    // Set page format. Default is HTML
1419:                    String formatParam = request.getParameter("format");
1420:                    if ("data".equals(formatParam)) {
1421:                        format = FORMAT_DATA;
1422:                    } else if ("xml".equals(formatParam)) {
1423:                        format = FORMAT_XML;
1424:                    } else {
1425:                        format = FORMAT_HTML;
1426:                    }
1427:
1428:                    // Does the user want the detailed toString column?
1429:                    String showDetailsParam = request
1430:                            .getParameter("showDetails");
1431:                    // Note the pattern below -- do the .equals on the constant,
1432:                    // avoiding the need to check for null in the variable String
1433:                    showDetails = "true".equals(showDetailsParam);
1434:
1435:                    // Re-sort the events if necessary.
1436:                    String sortByUIDParam = request.getParameter("sortByUID");
1437:                    boolean oldValue = sortByUID;
1438:                    sortByUID = "true".equals(sortByUIDParam);
1439:
1440:                    if (sortByUID != oldValue) {
1441:                        if (sortByUID) {
1442:                            if (logger.isInfoEnabled()) {
1443:                                logger.info("sorting by uid, then time.");
1444:                            }
1445:                            sortByUIDThenTime();
1446:                        } else {
1447:                            SortedSet set = new TreeSet();
1448:                            set.addAll(events);
1449:                            //logger.warn ("events before " + events.size() + " vs now "+ set.size());
1450:                            setEvents(set);
1451:                        }
1452:                    }
1453:                } // done processParams
1454:
1455:                /**
1456:                 * Execute the request - print the web page
1457:                 */
1458:                public void execute(HttpServletResponse response)
1459:                        throws IOException {
1460:                    if (format == FORMAT_HTML) {
1461:                        response.setContentType("text/html");
1462:
1463:                        PrintWriter out = response.getWriter();
1464:                        String sortLink = "<a href=\"/$" + encAgentName
1465:                                + getPath() + "?";
1466:
1467:                        if (sortByUID) {
1468:                            sortLink = sortLink + "sortByUID=false"
1469:                                    + "\">Sort by time</a>";
1470:                        } else {
1471:                            sortLink = sortLink + "sortByUID=true"
1472:                                    + "\">Sort by uid</a>";
1473:                        }
1474:
1475:                        String detailsLink = "<a href=\"/$" + encAgentName
1476:                                + getPath() + "?";
1477:
1478:                        if (showDetails) {
1479:                            detailsLink = detailsLink + "showDetails=false"
1480:                                    + "\">hide object details</a>";
1481:                        } else {
1482:                            detailsLink = detailsLink + "showDetails=true"
1483:                                    + "\">Show object details</a>";
1484:                        }
1485:
1486:                        // Now print the actual page
1487:                        out.print("<html><head><title>"
1488:                                + "History Servlet for " + agentId.getAddress()
1489:                                + "</title></head>" + "<body>"
1490:                                + "<p><center><h1>" + agentId.getAddress()
1491:                                + " Blackboard History</h1></center>" + "<p>" +
1492:
1493:                                "<center>" + sortLink + "&nbsp;&nbsp;&nbsp;"
1494:                                + detailsLink + "</center>" +
1495:                                // Here we print the actual table of events
1496:                                getHtmlForState() + "</body>" + "</html>\n");
1497:                        out.flush();
1498:                    }
1499:                    // FIXME: Add support for FORMAT_XML and FORMAT_DATA
1500:                } // end of execute()
1501:
1502:                /**
1503:                 * Print the actual table of events
1504:                 */
1505:                protected String getHtmlForState() {
1506:                    StringBuffer buf = new StringBuffer();
1507:
1508:                    // First we print the Table header....
1509:                    if (didDropOldEntries) {
1510:                        buf
1511:                                .append("<center>Note: Too many changes have occurred; only newest ");
1512:                        buf.append(maxEvents);
1513:                        buf.append(" are shown.</center><br/>");
1514:                    }
1515:
1516:                    // tell user what the gray-white highlighting means
1517:                    buf
1518:                            .append("<center>Gray-white alternation indicates different ");
1519:
1520:                    if (sortByUID) {
1521:                        buf.append("blackboard objects.");
1522:                    } else {
1523:                        buf.append("plugin execute cycles.");
1524:                    }
1525:                    buf.append("<br/>Time shown is scenario time.</center>");
1526:
1527:                    buf.append("<table border=1 align=center>");
1528:                    buf.append("<tr>");
1529:                    buf.append("<th>");
1530:                    // Event Number
1531:                    // Note that this may never appear in order, since the table is 
1532:                    // sorted by the comparator
1533:                    buf.append("#");
1534:                    buf.append("</th>");
1535:                    buf.append("<th>");
1536:                    buf.append("When"); // Scenario time
1537:                    buf.append("</th>");
1538:                    buf.append("<th>");
1539:                    buf.append("Type"); // Add/Change/Remove
1540:                    buf.append("</th>");
1541:                    buf.append("<th>");
1542:                    buf.append("Event"); // Basic summary
1543:                    buf.append("</th>");
1544:                    if (showChangeReport) {
1545:                        buf.append("<th>");
1546:                        buf.append("Change Report");
1547:                        buf.append("</th>");
1548:                    }
1549:                    buf.append("<th>");
1550:                    buf.append("Comment"); // Human readable descriptio in context
1551:                    buf.append("</th>");
1552:
1553:                    if (showDetails) {
1554:                        buf.append("<th>");
1555:                        buf.append("Object Details"); // Full toString
1556:                        buf.append("</th>");
1557:                    }
1558:
1559:                    buf.append("</tr>");
1560:                    long lastTime = -1;
1561:                    String lastUID = "";
1562:                    boolean colorRowGrey = false;
1563:
1564:                    // Now Loop over the events and print them
1565:                    synchronized (events) {
1566:                        for (Iterator iter = events.iterator(); iter.hasNext();) {
1567:                            EventInfo event = (EventInfo) iter.next();
1568:
1569:                            // Alternate colors in rows
1570:                            if (sortByUID) {
1571:                                // Alternate based on changing UID
1572:                                if (!event.uid.equals(lastUID)) {
1573:                                    colorRowGrey = !colorRowGrey;
1574:                                    lastUID = event.uid;
1575:                                }
1576:                            } else {
1577:                                // Alternate based on changing timestamp
1578:                                if (event.timeStamp != lastTime
1579:                                        && event.timeStamp != -1) {
1580:                                    colorRowGrey = !colorRowGrey;
1581:                                    lastTime = event.timeStamp;
1582:                                }
1583:                            }
1584:
1585:                            // Add the next Event
1586:                            buf.append(event.toHTML(colorRowGrey,
1587:                                    showChangeReport, showDetails));
1588:                            buf.append("\n");
1589:                        }
1590:                    }
1591:                    buf.append("</table>");
1592:                    return buf.toString();
1593:                } // end of getHTMLForState helper method, called by execute()
1594:            } // end of HistoryFormatter inner class
1595:
1596:            /**
1597:             * Sort the events collection by UID and then time. Then type, then meaning.
1598:             * Updates the single events collection Set
1599:             */
1600:            protected void sortByUIDThenTime() {
1601:                SortedSet events2 = new TreeSet(new Comparator() {
1602:                    public int compare(Object o1, Object o2) {
1603:                        EventInfo e1 = (EventInfo) o1;
1604:                        EventInfo e2 = (EventInfo) o2;
1605:                        int comp = e1.uid.compareTo(e2.uid);
1606:
1607:                        if (comp == 0) {
1608:                            if (e1.timeStamp < e2.timeStamp) {
1609:                                comp = -1;
1610:                            } else if (e1.timeStamp > e2.timeStamp) {
1611:                                comp = 1;
1612:                            }
1613:                        }
1614:
1615:                        if (comp == 0) {
1616:                            comp = e1.type - e2.type;
1617:                        }
1618:
1619:                        if (comp == 0) {
1620:                            comp = e1.meaning.compareTo(e2.meaning);
1621:                        }
1622:
1623:                        if (comp == 0) {
1624:                            if (logger.isInfoEnabled()) {
1625:                                logger.info(e1 + "\nequals\n" + e2);
1626:                            }
1627:                        }
1628:
1629:                        return comp;
1630:                    }
1631:                });
1632:
1633:                events2.addAll(events);
1634:                setEvents(events2);
1635:            }
1636:
1637:            /**
1638:             * Encodes a string that may contain HTML syntax-significant
1639:             * characters.
1640:             */
1641:            protected String encodeHTML(String s) {
1642:                if (s == null)
1643:                    return "";
1644:
1645:                boolean noBreakSpaces = true;
1646:                // Commenting out sawEquals for now -- a broken
1647:                // attempt to break up long lines....
1648:                //      boolean sawEquals = false;
1649:                StringBuffer buf = null; // In case we need to edit the string
1650:                int ix = 0; // Beginning of uncopied part of s
1651:                for (int i = 0, n = s.length(); i < n; i++) {
1652:                    String replacement = null;
1653:                    switch (s.charAt(i)) {
1654:                    case '"':
1655:                        replacement = "&quot;";
1656:                        break;
1657:                    //case '[': replacement = "["; break;
1658:                    case '<':
1659:                        if (i != 0 && s.charAt(i - 1) == ' ')
1660:                            replacement = "<br/>&nbsp;&lt;";
1661:                        else
1662:                            replacement = "&lt;";
1663:                        break;
1664:                    case '>':
1665:                        // put in a line break after '> ' as in the toString of many objects
1666:                        if (i + 1 < n && s.charAt(i + 1) == ' ')
1667:                            replacement = "&gt;<br/>";
1668:                        else
1669:                            replacement = "&gt;";
1670:                        break;
1671:                    case ',':
1672:                        // put in a line break after '>,' as in the toString of ServiceContractRelays
1673:                        if (i > 0 && i + 1 < n && s.charAt(i - 1) == '>'
1674:                                && s.charAt(i + 1) == ' ')
1675:                            replacement = ",<br/>";
1676:                        else
1677:                            replacement = ",";
1678:                        break;
1679:                    case '&':
1680:                        replacement = "&amp;";
1681:                        break;
1682:                    //	case '=': sawEquals = true; break;
1683:                    case ' ':
1684:                        //	  if (sawEquals && (i+1 < n) && s.charAt(i+1) != '>') {
1685:                        //	    replacement = "<br/>";
1686:                        //	  }
1687:                        //else if (noBreakSpaces) {
1688:                        if (noBreakSpaces) {
1689:                            replacement = "&nbsp;";
1690:                        }
1691:                        //sawEquals=false;
1692:                        break;
1693:                    }
1694:                    if (replacement != null) {
1695:                        if (buf == null)
1696:                            buf = new StringBuffer();
1697:                        buf.append(s.substring(ix, i));
1698:                        buf.append(replacement);
1699:                        ix = i + 1;
1700:                    }
1701:                }
1702:                if (buf != null) {
1703:                    buf.append(s.substring(ix));
1704:                    return buf.toString();
1705:                } else {
1706:                    return s;
1707:                }
1708:            }
1709:
1710:            /**
1711:             * This is the class that stores the information about an event
1712:             * Basic information about a particular event in a Transaction
1713:             */
1714:            private static class EventInfo implements  Comparable {
1715:                public int num; // Event number
1716:                public String uid; // The UID of the object
1717:                public String event; // Summary descripton of the event
1718:                public long timeStamp; // The scenario time of the event
1719:
1720:                // Goes in the Comment column - basic
1721:                // human readable description of the Event
1722:                public String meaning = "&nbsp;";
1723:                public Set changeReports = null; // Any ChangeReports
1724:                public String toStringResult = "&nbsp;"; // Full toString of the Event
1725:                public int type; // Add, Change, or Remove
1726:
1727:                public EventInfo(int type, int num, String uid, String event,
1728:                        long timeStamp, String meaning) {
1729:                    this .type = type;
1730:                    this .num = num;
1731:                    this .uid = uid;
1732:                    this .event = event;
1733:                    this .timeStamp = timeStamp;
1734:                    this .meaning = meaning;
1735:                }
1736:
1737:                public EventInfo(int type, int num, String uid, String event,
1738:                        long timeStamp, String meaning, Set changeReports) {
1739:                    this (type, num, uid, event, timeStamp, meaning);
1740:                    this .changeReports = changeReports;
1741:                }
1742:
1743:                public EventInfo(int type, int num, String uid, String event,
1744:                        long timeStamp, String meaning, String toStringResult) {
1745:                    this (type, num, uid, event, timeStamp, meaning);
1746:                    this .toStringResult = toStringResult;
1747:                }
1748:
1749:                public EventInfo(int type, int num, String uid, String event,
1750:                        long timeStamp, String meaning, Set changeReports,
1751:                        String toStringResult) {
1752:                    this (type, num, uid, event, timeStamp, meaning,
1753:                            changeReports);
1754:                    this .toStringResult = toStringResult;
1755:                }
1756:
1757:                /**
1758:                 * compare first by timestamp, and withing that, by UID
1759:                 * Then by type (A/C/R), and finally by the String meaning.
1760:                 */
1761:                public int compareTo(Object other) {
1762:                    EventInfo otherEvent = (EventInfo) other;
1763:
1764:                    if (timeStamp < otherEvent.timeStamp)
1765:                        return -1;
1766:                    if (timeStamp > otherEvent.timeStamp)
1767:                        return 1;
1768:
1769:                    int uidComp = uid.compareTo(otherEvent.uid);
1770:                    if (uidComp != 0)
1771:                        return uidComp;
1772:
1773:                    int val = type - otherEvent.type;
1774:
1775:                    if (val != 0)
1776:                        return val;
1777:
1778:                    val = meaning.compareTo(otherEvent.meaning);
1779:
1780:                    return val;
1781:                }
1782:
1783:                public String toString() {
1784:                    StringBuffer buf = new StringBuffer();
1785:                    buf.append("<EventInfo " + num + " at ");
1786:                    buf.append(format.format(new Date(timeStamp)));
1787:                    String typeS = " Added ";
1788:                    if (type == CHANGED)
1789:                        typeS = " Changed ";
1790:                    else if (type == REMOVED)
1791:                        typeS = " Removed ";
1792:                    buf.append(typeS);
1793:                    buf.append(meaning);
1794:                    buf.append(">");
1795:                    return buf.toString();
1796:                }
1797:
1798:                /**
1799:                 * Produce HTML for the Servlet display. "odd" boolean used to alternate colors for rows
1800:                 */
1801:                public String toHTML(boolean odd, boolean showChangeReport,
1802:                        boolean showDetails) {
1803:                    String color = odd ? "#FFFFFF" : "#c0c0c0";
1804:                    StringBuffer buf = new StringBuffer();
1805:                    buf.append("<tr BGCOLOR=" + color + ">");
1806:                    buf.append("<td>" + num + "</td>");
1807:                    buf.append("<td>" + format.format(new Date(timeStamp))
1808:                            + "</td>");
1809:                    String typeString = "<font color=green>Added</font>";
1810:                    if (type == CHANGED)
1811:                        typeString = "<font color=blue>Changed</font>";
1812:                    else if (type == REMOVED)
1813:                        typeString = "<font color=red>Removed</font>";
1814:
1815:                    buf.append("<td>" + typeString + "</td>");
1816:                    buf.append("<td>" + event + "</td>");
1817:
1818:                    if (showChangeReport) {
1819:                        buf.append("<td>");
1820:
1821:                        if (changeReports != null) {
1822:                            buf.append(htmlForChangeReport());
1823:                        }
1824:
1825:                        buf.append("</td>");
1826:                    }
1827:
1828:                    if (meaning != null) {
1829:                        buf.append("<td>" + meaning + "</td>");
1830:                    }
1831:
1832:                    if (showDetails) {
1833:                        buf.append("<td>" + toStringResult + "</td>");
1834:                    }
1835:
1836:                    buf.append("</tr>");
1837:
1838:                    return buf.toString();
1839:                }
1840:
1841:                /**
1842:                 * Produce pretty HTML to show the ChangeReports on a Transaction
1843:                 *
1844:                 * @return HTML Table of ChangeReport data
1845:                 */
1846:                public String htmlForChangeReport() {
1847:                    StringBuffer buf = new StringBuffer();
1848:                    buf.append("<table>");
1849:
1850:                    for (Iterator iter = changeReports.iterator(); iter
1851:                            .hasNext();) {
1852:                        Object obj = iter.next();
1853:                        buf.append("<tr><td>" + obj + "</td></tr>");
1854:                    }
1855:
1856:                    buf.append("</table>");
1857:
1858:                    return buf.toString();
1859:                }
1860:            } // end of EventInfo class 
1861:        } // end of HistoryServlet
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.