001: /*
002: * <copyright>
003: *
004: * Copyright 2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.community.util;
027:
028: import java.io.IOException;
029: import java.io.PrintWriter;
030: import java.io.StringReader;
031: import java.io.StringWriter;
032: import java.util.Date;
033: import java.util.Hashtable;
034:
035: import javax.servlet.Servlet;
036: import javax.servlet.http.HttpServlet;
037: import javax.servlet.http.HttpServletRequest;
038: import javax.servlet.http.HttpServletResponse;
039: import javax.xml.transform.Transformer;
040: import javax.xml.transform.TransformerFactory;
041: import javax.xml.transform.stream.StreamResult;
042: import javax.xml.transform.stream.StreamSource;
043:
044: import org.cougaar.core.blackboard.BlackboardClient;
045: import org.cougaar.core.service.AgentIdentificationService;
046: import org.cougaar.core.service.LoggingService;
047: import org.cougaar.core.service.community.Community;
048: import org.cougaar.core.service.community.CommunityResponse;
049: import org.cougaar.core.service.community.CommunityResponseListener;
050: import org.cougaar.core.service.community.CommunityService;
051: import org.cougaar.core.servlet.BaseServletComponent;
052: import org.cougaar.core.servlet.ServletUtil;
053: import org.cougaar.util.UnaryPredicate;
054:
055: import org.cougaar.community.util.Semaphore;
056:
057: import java.util.*;
058:
059: /**
060: * A servlet for viewing community state.
061: * Load into any agent:
062: * plugin = org.cougaar.community.util.CommunityViewerServlet
063: */
064: public class CommunityViewerServlet extends BaseServletComponent
065: implements BlackboardClient {
066:
067: private CommunityService cs;
068: private static LoggingService log;
069: private PrintWriter out;
070: private String agentId;
071:
072: /**
073: * Hard-coded servlet path.
074: * @return Servlet path
075: */
076: protected String getPath() {
077: return "/communityViewer";
078: }
079:
080: public void setCommunityService(CommunityService cs) {
081: this .cs = cs;
082: }
083:
084: /**
085: * Create the servlet.
086: * @return Servlet
087: */
088: protected Servlet createServlet() {
089: log = (LoggingService) serviceBroker.getService(this ,
090: LoggingService.class, null);
091: AgentIdentificationService ais = (AgentIdentificationService) serviceBroker
092: .getService(this , AgentIdentificationService.class,
093: null);
094: if (ais != null) {
095: this .agentId = ais.getMessageAddress().toString();
096: serviceBroker.releaseService(this ,
097: AgentIdentificationService.class, ais);
098: }
099: log = org.cougaar.core.logging.LoggingServiceWithPrefix.add(
100: log, agentId + ": ");
101: return new MyServlet();
102: }
103:
104: private class MyServlet extends HttpServlet {
105: public void doGet(HttpServletRequest req,
106: HttpServletResponse res) throws IOException {
107: out = res.getWriter();
108: parseParams(req);
109: }
110: }
111:
112: private String format = "", currentXML = "", communityShown;
113: private String command = "", target = "";
114:
115: private void parseParams(HttpServletRequest request)
116: throws IOException {
117: format = "html";
118: command = "";
119: target = "";
120: // create a URL parameter visitor
121: ServletUtil.ParamVisitor vis = new ServletUtil.ParamVisitor() {
122: public void setParam(String name, String value) {
123: if (name.equalsIgnoreCase("format"))
124: format = value;
125: if (name.equalsIgnoreCase("community")) {
126: command = "showCommunity";
127: target = value;
128: communityShown = value;
129: }
130: if (name.equals("attributes")) {
131: command = "showAttributes";
132: target = value;
133: }
134: }
135: };
136: // visit the URL parameters
137: ServletUtil.parseParams(vis, request);
138: if (command.equals(""))
139: showFrontPage();
140: else {
141: displayParams(command, target);
142: }
143: }
144:
145: Collection pcomms = new ArrayList();
146:
147: //The first page when user call this servlet will show all communities who are
148: //direct parents of calling agent.
149: private void showFrontPage() {
150: final Semaphore s = new Semaphore(0);
151: cs.listAllCommunities(new CommunityResponseListener() {
152: public void getResponse(CommunityResponse resp) {
153: pcomms = (Collection) resp.getContent();
154: s.release();
155: }
156: });
157: Collection local = cs.listParentCommunities(agentId.toString(),
158: "(CommunityType=*)", null);
159:
160: out.print("<html><title>communityViewer</title>\n");
161: out.print("<body>\n<h3>Local community:</h3><ol>\n");
162: for (Iterator it = local.iterator(); it.hasNext();) {
163: String name = (String) it.next();
164: out.print("<li><a href=./communityViewer?community=" + name
165: + ">" + name + "</a>\n");
166: }
167: out.print("</ol><br><br><h3>Remote community:</h3><ol>\n");
168: for (Iterator it = pcomms.iterator(); it.hasNext();) {
169: String name = (String) it.next();
170: if (!local.contains(name))
171: out.print("<li><a href=./communityViewer?community="
172: + name + ">" + name + "</a>\n");
173: }
174: out.print("</body>\n</html>\n");
175:
176: }
177:
178: private static Hashtable table = new Hashtable();
179:
180: private void displayParams(String command, String value) {
181: try {
182: Community community = null;
183: final Semaphore s = new Semaphore(0);
184: community = cs.getCommunity(communityShown,
185: new CommunityResponseListener() {
186: public void getResponse(CommunityResponse resp) {
187: communityChangeNotification((Community) resp
188: .getContent());
189: s.release();
190: }
191: });
192: if (community != null) {
193: communityChangeNotification(community);
194: } else {
195: try {
196: s.acquire();
197: } catch (InterruptedException e) {
198: }
199: }
200: community = (Community) table.get(communityShown);
201: currentXML = community.toXml();
202: if (format.equals("xml"))
203: out.write(currentXML);
204: else {
205: if (command.equals("showCommunity")) {
206: out.print(getHTMLFromXML(currentXML,
207: communityViewer));
208: } else {
209: String xml = "";
210: if (value.equals(communityShown)) {
211: //make sure this element do have attributes
212: int temp1 = currentXML.indexOf("<Attributes>");
213: int temp2 = currentXML.indexOf("<", currentXML
214: .indexOf("Community"));
215: if (temp1 == temp2) {
216: xml = currentXML.substring(0, currentXML
217: .indexOf("</Attributes>"));
218: xml += "</Attributes></Community>";
219: } else {
220: xml = "<Community Name=\"" + communityShown
221: + "\"></Community>";
222: }
223: } else {
224: String temp = "name=\"" + value + "\"";
225: int index = currentXML.indexOf(temp);
226: int firstIndex = currentXML.substring(0, index)
227: .lastIndexOf("<");
228: int temp1 = currentXML.indexOf("<Attributes",
229: firstIndex);
230: int temp2 = currentXML.indexOf("<",
231: firstIndex + 1);
232: if (temp1 == temp2) {
233: index = currentXML.indexOf("</Attributes>",
234: firstIndex);
235: int lastIndex = currentXML.indexOf(">",
236: index + 13);
237: xml = currentXML.substring(firstIndex,
238: lastIndex + 1);
239: } else {
240: index = currentXML
241: .indexOf("</", firstIndex);
242: int lastIndex = currentXML.indexOf(">",
243: index);
244: xml = currentXML.substring(firstIndex,
245: lastIndex + 1);
246: }
247: }
248: out.print(getHTMLFromXML(xml, attributesViewer));
249: }
250: }
251: } catch (Exception e) {
252: e.printStackTrace();
253: }
254: }
255:
256: public static void communityChangeNotification(Community community) {
257: if (table.containsKey(community.getName())) {
258: table.remove(community.getName());
259: table.put(community.getName(), community);
260: } else {
261: table.put(community.getName(), community);
262: }
263: }
264:
265: /**
266: * Using xsl file to transform a xml file into html file.
267: * @param xml given xml string
268: * @param xsl name of xsl file
269: * @return the html string
270: */
271: private String getHTMLFromXML(String xml, String xsl) {
272: String html = "";
273: try {
274: TransformerFactory tFactory = TransformerFactory
275: .newInstance();
276: //File xslf = ConfigFinder.getInstance().locateFile(xsl);
277: //xsl = "/configs/common/" + xsl;
278: //InputStream in = CommunityViewerServlet.class.getResourceAsStream(xsl);
279: //Transformer transformer = tFactory.newTransformer(new StreamSource(in));
280: Transformer transformer = tFactory
281: .newTransformer(new StreamSource(new StringReader(
282: xsl)));
283: StringWriter writer = new StringWriter();
284: transformer.transform(new StreamSource(
285: new StringReader(xml)), new StreamResult(writer));
286: html = writer.toString();
287: } catch (Exception e) {
288: log.error(e.getMessage());
289: }
290: return html;
291: }
292:
293: /**
294: * Selects CommunityDescriptors that are sent by remote community manager
295: * agent.
296: */
297: private UnaryPredicate communityPredicate = new UnaryPredicate() {
298: public boolean execute(Object o) {
299: return (o instanceof Community);
300: }
301: };
302:
303: // BlackboardClient method:
304: public String getBlackboardClientName() {
305: return toString();
306: }
307:
308: // unused BlackboardClient method:
309: public long currentTimeMillis() {
310: return new Date().getTime();
311: }
312:
313: // unused BlackboardClient method:
314: public boolean triggerEvent(Object event) {
315: return false;
316: }
317:
318: private static final String attributesViewer = "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
319: + "<xsl:output method=\"html\" indent=\"yes\"/>\n"
320: + "<xsl:template match=\"/\">\n"
321: + "<xsl:variable name=\"community\">"
322: + "<xsl:value-of select=\"//Community/@name\" /> "
323: + "</xsl:variable>"
324: + "<xsl:variable name=\"agent\">"
325: + "<xsl:value-of select=\"//Agent/@name\" />"
326: + "</xsl:variable>"
327: + "<xsl:variable name=\"communityLength\">"
328: + "<xsl:value-of select=\"string-length($community)\" />"
329: + "</xsl:variable>"
330: + "<xsl:variable name=\"agentLength\">"
331: + "<xsl:value-of select=\"string-length($agent)\" />"
332: + "</xsl:variable>"
333: + "<html><head><title><xsl:choose>"
334: + "<xsl:when test=\"$communityLength > 0\">"
335: + "<xsl:text>Community </xsl:text>"
336: + "<xsl:value-of select=\"$community\" />"
337: + "</xsl:when><xsl:otherwise>"
338: + "<xsl:text>Agent </xsl:text><xsl:value-of select=\"$agent\" />"
339: + "</xsl:otherwise></xsl:choose></title></head>"
340: + "<body><center><br /><H1><xsl:choose>"
341: + "<xsl:when test=\"$communityLength > 0\">"
342: + "<xsl:text>Community </xsl:text><xsl:value-of select=\"$community\" />"
343: + "</xsl:when><xsl:otherwise><xsl:text>Agent </xsl:text>"
344: + "<xsl:value-of select=\"$agent\" /></xsl:otherwise></xsl:choose></H1><br />"
345: + "<table border=\"1\" cellpadding=\"10\" cellspacing=\"0\">"
346: + "<th><xsl:text>Attribute Id</xsl:text></th>"
347: + "<th><xsl:text>Attribute Value</xsl:text></th>"
348: + "<xsl:apply-templates select=\"//Attributes\" />"
349: + "</table></center></body></html></xsl:template>"
350: + "<xsl:template match=\"Attributes\">"
351: + "<xsl:for-each select=\"//Attribute\">"
352: + "<xsl:variable name=\"count\"><xsl:value-of select=\"count(.//Value)\" /></xsl:variable>"
353: + "<xsl:variable name=\"id\"><xsl:value-of select=\"@id\" /></xsl:variable>"
354: + "<xsl:choose><xsl:when test=\"$count=1\">"
355: + "<tr><td><xsl:value-of select=\"$id\" /></td>"
356: + "<td><xsl:value-of select=\".//Value\" /></td></tr></xsl:when>"
357: + "<xsl:otherwise><xsl:for-each select=\".//Value\"><xsl:choose>"
358: + "<xsl:when test=\"position() = 1\">"
359: + "<tr><td><xsl:value-of select=\"$id\" /></td><td><xsl:value-of select=\".\" /></td>"
360: + "</tr></xsl:when><xsl:otherwise>"
361: + "<tr><td /><td><xsl:value-of select=\".\" /></td></tr>"
362: + "</xsl:otherwise></xsl:choose></xsl:for-each></xsl:otherwise></xsl:choose></xsl:for-each>"
363: + "</xsl:template></xsl:stylesheet>";
364:
365: private static final String communityViewer = "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">"
366: + "<xsl:output method=\"html\" indent=\"yes\"/>"
367: + "<xsl:template match=\"/\"><xsl:variable name=\"community\">"
368: + "<xsl:value-of select=\"//Community/@name\" /></xsl:variable>"
369: + "<html><head><title><xsl:text>Community </xsl:text><xsl:value-of select=\"$community\" />"
370: + "</title></head><body><br /><H1>"
371: + "<xsl:element name=\"a\"><xsl:attribute name=\"href\">"
372: + "<xsl:text>./communityViewer?attributes=</xsl:text>"
373: + "<xsl:value-of select=\"$community\" /></xsl:attribute>"
374: + "<xsl:text>Community </xsl:text><xsl:value-of select=\"$community\" />"
375: + "</xsl:element></H1><br /><ol>"
376: + "<xsl:for-each select=\"Community/Community\">"
377: + "<li><xsl:element name=\"a\"><xsl:attribute name=\"href\">"
378: + "<xsl:text>./communityViewer?community=</xsl:text>"
379: + "<xsl:value-of select=\"@name\" /></xsl:attribute>"
380: + "<xsl:text>Community </xsl:text><xsl:value-of select=\"@name\" />"
381: + "</xsl:element></li></xsl:for-each>"
382: + "<xsl:for-each select=\"//Agent\"><xsl:sort select=\"@name\" /><li>"
383: + "<xsl:element name=\"a\"><xsl:attribute name=\"href\">"
384: + "<xsl:text>./communityViewer?attributes=</xsl:text>"
385: + "<xsl:value-of select=\"@name\" /></xsl:attribute>"
386: + "<xsl:value-of select=\"@name\" /></xsl:element></li>"
387: + "</xsl:for-each></ol></body></html></xsl:template></xsl:stylesheet>";
388:
389: }
|