001: /*
002: *
003: * <copyright>
004: *
005: * Copyright 1997-2004 BBNT Solutions, LLC
006: * under sponsorship of the Defense Advanced Research Projects
007: * Agency (DARPA).
008: *
009: * You can redistribute this software and/or modify it under the
010: * terms of the Cougaar Open Source License as published on the
011: * Cougaar Open Source Website (www.cougaar.org).
012: *
013: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
014: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
015: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
016: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
017: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
018: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
019: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
020: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
021: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
022: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
023: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
024: *
025: * </copyright>
026: */
027:
028: package org.cougaar.planning.servlet;
029:
030: import java.io.FilterWriter;
031: import java.io.IOException;
032: import java.io.InputStream;
033: import java.io.PrintWriter;
034: import java.io.Writer;
035: import java.lang.reflect.Method;
036: import java.net.URLDecoder;
037: import java.net.URLEncoder;
038: import java.text.SimpleDateFormat;
039: import java.util.ArrayList;
040: import java.util.Arrays;
041: import java.util.Calendar;
042: import java.util.Collection;
043: import java.util.Collections;
044: import java.util.Comparator;
045: import java.util.Date;
046: import java.util.Enumeration;
047: import java.util.HashMap;
048: import java.util.Iterator;
049: import java.util.List;
050:
051: import javax.servlet.ServletException;
052: import javax.servlet.http.HttpServlet;
053: import javax.servlet.http.HttpServletRequest;
054: import javax.servlet.http.HttpServletResponse;
055:
056: import org.cougaar.core.blackboard.Blackboard;
057: import org.cougaar.core.blackboard.UniqueObjectSet;
058: import org.cougaar.core.mts.MessageAddress;
059: import org.cougaar.core.servlet.ComponentServlet;
060: import org.cougaar.core.service.BlackboardQueryService;
061: import org.cougaar.core.util.UID;
062: import org.cougaar.core.util.UniqueObject;
063: import org.cougaar.planning.ldm.LogPlan;
064: import org.cougaar.planning.ldm.asset.AggregateAsset;
065: import org.cougaar.planning.ldm.asset.Asset;
066: import org.cougaar.planning.ldm.asset.AssetGroup;
067: import org.cougaar.planning.ldm.asset.ClusterPG;
068: import org.cougaar.planning.ldm.asset.ItemIdentificationPG;
069: import org.cougaar.planning.ldm.asset.LocationSchedulePG;
070: import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
071: import org.cougaar.planning.ldm.lps.ConsistencyChecker;
072: import org.cougaar.planning.ldm.measure.AbstractMeasure;
073: import org.cougaar.planning.ldm.plan.Aggregation;
074: import org.cougaar.planning.ldm.plan.Allocation;
075: import org.cougaar.planning.ldm.plan.AllocationResult;
076: import org.cougaar.planning.ldm.plan.AllocationforCollections;
077: import org.cougaar.planning.ldm.plan.AspectScorePoint;
078: import org.cougaar.planning.ldm.plan.AspectScoreRange;
079: import org.cougaar.planning.ldm.plan.AspectType;
080: import org.cougaar.planning.ldm.plan.AspectValue;
081: import org.cougaar.planning.ldm.plan.AssetAssignment;
082: import org.cougaar.planning.ldm.plan.AssetTransfer;
083: import org.cougaar.planning.ldm.plan.Composition;
084: import org.cougaar.planning.ldm.plan.Disposition;
085: import org.cougaar.planning.ldm.plan.Expansion;
086: import org.cougaar.planning.ldm.plan.ItineraryElement;
087: import org.cougaar.planning.ldm.plan.Location;
088: import org.cougaar.planning.ldm.plan.LocationRangeScheduleElement;
089: import org.cougaar.planning.ldm.plan.LocationScheduleElement;
090: import org.cougaar.planning.ldm.plan.MPTask;
091: import org.cougaar.planning.ldm.plan.Plan;
092: import org.cougaar.planning.ldm.plan.PlanElement;
093: import org.cougaar.planning.ldm.plan.PlanElementSet;
094: import org.cougaar.planning.ldm.plan.Preference;
095: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
096: import org.cougaar.planning.ldm.plan.Role;
097: import org.cougaar.planning.ldm.plan.RoleSchedule;
098: import org.cougaar.planning.ldm.plan.Schedule;
099: import org.cougaar.planning.ldm.plan.ScheduleElement;
100: import org.cougaar.planning.ldm.plan.ScoringFunction;
101: import org.cougaar.planning.ldm.plan.Task;
102: import org.cougaar.planning.ldm.plan.TimeAspectValue;
103: import org.cougaar.planning.ldm.plan.Verb;
104: import org.cougaar.planning.ldm.plan.Workflow;
105: import org.cougaar.planning.plugin.util.PluginHelper;
106: import org.cougaar.util.ConfigFinder;
107: import org.cougaar.util.PropertyTree;
108: import org.cougaar.util.Sortings;
109: import org.cougaar.util.TimeSpan;
110: import org.cougaar.util.UnaryPredicate;
111: import org.cougaar.util.log.Logger;
112: import org.cougaar.util.log.LoggerAdapter;
113: import org.w3c.dom.Document;
114: import org.w3c.dom.Element;
115:
116: /**
117: * A <code>Servlet</code> that checks the blackboard for plan
118: * object consistency, such as checking that the blackboard
119: * contains the parent tasks.
120: * <p>
121: * Load in all agents & nodes as:<pre>
122: * <component class="org.cougaar.planning.servlet.ConsistencyCheckServlet">
123: * <argument>/consistency</argument>
124: * </component>
125: * </pre>
126: */
127: public class ConsistencyCheckServlet extends ComponentServlet {
128:
129: private BlackboardQueryService blackboard;
130:
131: public void setBlackboardQueryService(
132: BlackboardQueryService blackboard) {
133: this .blackboard = blackboard;
134: }
135:
136: public void doGet(HttpServletRequest request,
137: HttpServletResponse response) throws IOException,
138: ServletException {
139: (new Worker(request, response)).execute();
140: }
141:
142: /** This inner class does all the work. */
143: private class Worker {
144: // from the "doGet(..)":
145: private HttpServletRequest request;
146: private HttpServletResponse response;
147:
148: // TBA url parameters
149:
150: // writer from the request
151: private PrintWriter out;
152:
153: private UniqueObjectSet taskSet;
154: private PlanElementSet planElementSet;
155:
156: private Logger logger;
157: private LogPlan logplan;
158:
159: public Worker(HttpServletRequest request,
160: HttpServletResponse response) {
161: this .request = request;
162: this .response = response;
163: }
164:
165: public void execute() throws IOException {
166: parseParams();
167: writeResponse();
168: }
169:
170: private void parseParams() {
171: // no parameters for now
172: //value = getParameter("name", "default");
173: }
174:
175: private String getParameter(String name, String defaultValue) {
176: String value = request.getParameter(name);
177: if (value != null) {
178: value = value.trim();
179: if (value.length() == 0) {
180: value = null;
181: }
182: }
183: if (value == null) {
184: value = defaultValue;
185: }
186: return value;
187: }
188:
189: private void writeResponse() throws IOException {
190: response.setContentType("text/html");
191: this .out = response.getWriter();
192:
193: String title = getEncodedAgentName()
194: + " Consistency Checker";
195: out.println("<html><head><title>" + title
196: + "</title></head><body bgcolor=\"white\">"
197: + "<h1>" + title + "</h1><p>");
198:
199: out.println("<h2>Validating Tasks[" + getTaskCount()
200: + "]:</h2><hr>");
201: boolean tasksOkay = validateTasks();
202: out.println("<br><hr><p>");
203:
204: out.println("<h2>Validating PlanElements["
205: + getPlanElementCount() + "]:</h2><hr>");
206: boolean planElementsOkay = validatePlanElements();
207: out.println("<br><hr>");
208:
209: boolean allOkay = (tasksOkay && planElementsOkay);
210:
211: out.println("<h2>" + (allOkay ? "All" : "Not")
212: + " Consistent</h2>");
213:
214: String color = (allOkay ? "green" : "red");
215: out.println("<table width=\"100%\" bgcolor=\"" + color
216: + "\"><tr><td> </td></tr></table>");
217:
218: out.println("</body></html>");
219: }
220:
221: private void findTasks() {
222: if (taskSet != null) {
223: return;
224: }
225: UnaryPredicate taskP = new UnaryPredicate() {
226: public boolean execute(Object o) {
227: return (o instanceof Task);
228: }
229: };
230: Collection col = blackboard.query(taskP);
231: taskSet = new UniqueObjectSet();
232: taskSet.addAll(col);
233: }
234:
235: private int getTaskCount() {
236: findTasks();
237: return taskSet.size();
238: }
239:
240: private Task findTask(UID uid) {
241: findTasks();
242: return (Task) taskSet.findUniqueObject(uid);
243: }
244:
245: private void findPlanElements() {
246: if (planElementSet != null) {
247: return;
248: }
249: UnaryPredicate planElementP = new UnaryPredicate() {
250: public boolean execute(Object o) {
251: return (o instanceof PlanElement);
252: }
253: };
254: Collection col = blackboard.query(planElementP);
255: planElementSet = new PlanElementSet();
256: planElementSet.addAll(col);
257: }
258:
259: private int getPlanElementCount() {
260: findPlanElements();
261: return planElementSet.size();
262: }
263:
264: private PlanElement findPlanElement(Task task) {
265: findPlanElements();
266: return planElementSet.findPlanElement(task);
267: }
268:
269: private boolean validateTasks() {
270: boolean ret = true;
271: for (Iterator iter = taskSet.iterator(); iter.hasNext();) {
272: Task t = (Task) iter.next();
273: if (!validateTask(t)) {
274: ret = false;
275: }
276: }
277: return ret;
278: }
279:
280: private boolean validateTask(Task t) {
281: return ConsistencyChecker.isTaskConsistent(
282: getAgentIdentifier(), getLogger(), getLogPlan(), t,
283: "Task found");
284: }
285:
286: private boolean validatePlanElements() {
287: boolean ret = true;
288: for (Iterator iter = planElementSet.iterator(); iter
289: .hasNext();) {
290: PlanElement pe = (PlanElement) iter.next();
291: if (!validatePlanElement(pe)) {
292: ret = false;
293: }
294: }
295: return ret;
296: }
297:
298: private boolean validatePlanElement(PlanElement pe) {
299: return ConsistencyChecker.isPlanElementConsistent(
300: getAgentIdentifier(), getLogger(), getLogPlan(),
301: pe, true);
302: }
303:
304: private Logger getLogger() {
305: if (logger != null) {
306: return logger;
307: }
308: logger = new LoggerAdapter() {
309: public boolean isEnabledFor(int level) {
310: return true;
311: }
312:
313: public void log(int level, String message, Throwable t) {
314: out.println("<b>" + convertIntToString(level)
315: + "</b>" + " - "
316: + encodeHTML(message, false));
317: if (t != null) {
318: out.println("<pre>");
319: t.printStackTrace(out);
320: out.println("</pre>");
321: }
322: out.println("<br>");
323: }
324:
325: public void printDot(String dot) {
326: }
327:
328: private String convertIntToString(int level) {
329: switch (level) {
330: case Logger.DETAIL:
331: return "DETAIL";
332: case Logger.DEBUG:
333: return "DEBUG";
334: case Logger.INFO:
335: return "INFO";
336: case Logger.WARN:
337: return "WARN";
338: case Logger.ERROR:
339: return "ERROR";
340: case Logger.SHOUT:
341: return "SHOUT";
342: case Logger.FATAL:
343: return "FATAL";
344: default:
345: return null;
346: }
347: }
348: };
349: return logger;
350: }
351:
352: private LogPlan getLogPlan() {
353: if (logplan != null) {
354: return logplan;
355: }
356: logplan = new LogPlan() {
357: public PlanElement findPlanElement(Task task) {
358: return Worker.this .findPlanElement(task);
359: }
360:
361: public Task findTask(UID uid) {
362: return Worker.this .findTask(uid);
363: }
364:
365: public Task findTask(Task task) {
366: return (Task) taskSet.findUniqueObject(task
367: .getUID());
368: }
369:
370: // unsupported operations:
371: private void die() {
372: throw new UnsupportedOperationException();
373: }
374:
375: public void setupSubscriptions(Blackboard blackboard) {
376: die();
377: }
378:
379: public PlanElement findPlanElement(String task) {
380: die();
381: return null;
382: }
383:
384: public PlanElement findPlanElement(UID uid) {
385: die();
386: return null;
387: }
388:
389: public Task findTask(String id) {
390: die();
391: return null;
392: }
393:
394: public Asset findAsset(Asset asset) {
395: die();
396: return null;
397: }
398:
399: public Asset findAsset(String id) {
400: die();
401: return null;
402: }
403:
404: public void incAssetCount(int inc) {
405: die();
406: }
407:
408: public void incPlanElementCount(int inc) {
409: die();
410: }
411:
412: public void incTaskCount(int inc) {
413: die();
414: }
415:
416: public void incWorkflowCount(int inc) {
417: die();
418: }
419: };
420: return logplan;
421: }
422: }
423:
424: private static String encodeHTML(String s, boolean noBreakSpaces) {
425: StringBuffer buf = null; // In case we need to edit the string
426: int ix = 0; // Beginning of uncopied part of s
427: for (int i = 0, n = s.length(); i < n; i++) {
428: String replacement = null;
429: switch (s.charAt(i)) {
430: case '"':
431: replacement = """;
432: break;
433: case '<':
434: replacement = "<";
435: break;
436: case '>':
437: replacement = ">";
438: break;
439: case '&':
440: replacement = "&";
441: break;
442: case ' ':
443: if (noBreakSpaces)
444: replacement = " ";
445: break;
446: }
447: if (replacement != null) {
448: if (buf == null)
449: buf = new StringBuffer();
450: buf.append(s.substring(ix, i));
451: buf.append(replacement);
452: ix = i + 1;
453: }
454: }
455: if (buf != null) {
456: buf.append(s.substring(ix));
457: return buf.toString();
458: } else {
459: return s;
460: }
461: }
462: }
|