Annotation of java/classes/org/w3c/rdf/examples/SiRPACServlet.java, revision 1.20
1.1 barstow 1: /**
2: * SiRPACServlet - Simple RDF Parser & Compiler Servlet wrapper
3: *
4: * Copyright © World Wide Web Consortium, (Massachusetts Institute of
5: * Technology, Institut National de Recherche en Informatique et en
6: * Automatique, Keio University).
7: *
8: * All Rights Reserved.
9: *
10: * Please see the full Copyright clause at
11: * <http://www.w3.org/Consortium/Legal/copyright-software.html>
12: *
1.3 barstow 13: * This servlet is a wrapper for the SiRPAC RDF parser. The servlet
1.7 barstow 14: * expects the following variables through the POST method:
1.3 barstow 15: *
1.19 barstow 16: * RDF - the RDF in an XML syntax
17: *
18: * BAGS - if "on", each Description should have its own Bag;
19: * the default is not to do this.
20: *
21: * STREAM - if "on", the stream mode is turned off so that aboutEach
22: * and aboutEachPrefix are supported. It is off by default.
23: *
24: * SAVE_DOT_FILE - if "on", the DOT file is saved and a link to the
25: * file is provided to the user
26: *
27: * SAVE_RDF - if "on", the RDF will be copied to a file.
28: *
29: * URI - the URI to parse [instead of the RDF]; may not be specified
30: *
31: * ORIENTATION - the graph's orientation (left to right or top to
32: * bottom
33: *
34: * FONT_SIZE - the font size to use [10, 12, 14, 16 and 20 are supported]
35: *
36: * GRAPH_FORMAT - the graph's output format. Supported values are:
37: *
38: * GIF_EMBED - embed the graph as a GIF [the default]
39: * GIF_LINK - don't embed the GIF but create a link for it
40: * SVG_LINK - create the graph in SVG format and create a link to the file
1.20 ! barstow 41: * PNG_EMBED - create the graph in PNG format and embed the graph in the
! 42: * document that is returned
! 43: * PNG_LINK - create the graph in PNG format and create a link to the file
1.19 barstow 44: * PS_LINK - create a PostScript image of the file and a link to the file
45: * HP_PCL_LINK - create a HPGL/2 - PCL (Laserwriter) image of the file
46: * and a link to the file
47: * HP_GL_LINK - create a HPGL - PCL (pen plotter) image of the file and
48: * a link to the file
49: * NO_GRAPH - do not generate a graph
1.1 barstow 50: *
1.7 barstow 51: * @author Art Barstow <barstow@w3.org>
1.1 barstow 52: *
1.7 barstow 53: * The graphics package is AT&T's GraphVis tool.
1.1 barstow 54: */
55:
56: package org.w3c.rdf.examples;
57:
58: import java.io.*;
1.16 barstow 59: import java.net.MalformedURLException;
60: import java.net.URL;
1.1 barstow 61: import java.util.StringTokenizer;
62: import java.util.Enumeration;
63: import javax.servlet.*;
64: import javax.servlet.http.*;
65:
66: import org.xml.sax.InputSource;
67: import org.xml.sax.Parser;
68: import org.xml.sax.SAXException;
69: import org.xml.sax.helpers.*;
70:
71: import org.w3c.rdf.model.*;
72: import org.w3c.rdf.syntax.*;
73: import org.w3c.rdf.syntax.RDFConsumer;
74: import org.w3c.rdf.util.xml.DumpConsumer;
75: import org.w3c.rdf.util.xml.ErrorStore;
1.16 barstow 76: import org.w3c.rdf.util.xml.GenericParser;
1.1 barstow 77: import org.w3c.rdf.implementation.model.StatementImpl;
78: import org.w3c.rdf.implementation.model.NodeFactoryImpl;
79: import org.w3c.rdf.implementation.syntax.sirpac.*;
80:
81: public class SiRPACServlet extends HttpServlet
82: {
1.20 ! barstow 83: final static public String REVISION = "$Id: SiRPACServlet.java,v 1.19 2001/02/20 18:23:42 barstow Exp $";
1.1 barstow 84:
1.7 barstow 85: // The email address for bug reports
1.4 barstow 86: private static final String MAIL_TO = "barstow@w3.org";
1.10 barstow 87:
1.19 barstow 88: // Names of the POST parameters (described above) and their
89: // defaults
90: private static final String TEXT = "RDF";
91: private static final String BAG = "BAGS";
92: private static final String STREAM_MODE = "STREAM";
93: private static final String SAVE_DOT_FILE = "SAVE_DOT_FILE";
94: private static final String SAVE_RDF = "SAVE_RDF";
95: private static final String URI = "URI";
1.3 barstow 96:
1.6 barstow 97: private static final String NODE_COLOR = "NODE_COLOR";
98: private static final String DEFAULT_NODE_COLOR = "black";
99:
100: private static final String NODE_TEXT_COLOR = "NODE_TEXT_COLOR";
101: private static final String DEFAULT_NODE_TEXT_COLOR = "black";
102:
103: private static final String EDGE_COLOR = "EDGE_COLOR";
104: private static final String DEFAULT_EDGE_COLOR = "black";
105:
106: private static final String EDGE_TEXT_COLOR = "EDGE_TEXT_COLOR";
107: private static final String DEFAULT_EDGE_TEXT_COLOR = "black";
108:
109: private static final String ORIENTATION = "ORIENTATION";
110: private static final String DEFAULT_ORIENTATION = "TB"; // Top to Bottom
111:
112: private static final String FONT_SIZE = "FONT_SIZE";
113: private static final String DEFAULT_FONT_SIZE = "10";
114:
1.19 barstow 115: private static final String FORMAT = "FORMAT";
116: private static final String FORMAT_GIF_EMBED = "GIF_EMBED";
117: private static final String FORMAT_GIF_LINK = "GIF_LINK";
118: private static final String FORMAT_SVG_LINK = "SVG_LINK";
1.20 ! barstow 119: private static final String FORMAT_PNG_EMBED = "PNG_EMBED";
! 120: private static final String FORMAT_PNG_LINK = "PNG_LINK";
1.19 barstow 121: private static final String FORMAT_PS_LINK = "PS_LINK";
122: private static final String FORMAT_HP_PCL_LINK = "HP_PCL_LINK";
123: private static final String FORMAT_HP_GL_LINK = "HP_GL_LINK";
124: private static final String FORMAT_NO_GRAPH = "NO_GRAPH";
125:
1.6 barstow 126: // Fonts are not currently configurable
127: private static final String DEFAULT_FONT = "arial";
128:
1.19 barstow 129: // Names of the servlet's parameters - for Jigsaw web server
130: private static final String SIRPAC_TMP_DIR = "SIRPAC_TMP_DIR";
131: private static final String GRAPH_VIZ_ROOT = "GRAPH_VIZ_ROOT";
132: private static final String GRAPH_VIZ_PATH = "GRAPH_VIZ_PATH";
133: private static final String GRAPH_VIZ_LIB_DIR = "GRAPH_VIZ_LIB_DIR";
134: private static final String GRAPH_VIZ_FONT_DIR = "GRAPH_VIZ_FONT_DIR";
135:
136: // Variables for the servlet's parameters
137: private static String m_SiRPACTmpDir = null;
138: private static String m_GraphVizPath = null;
139: private static String m_GraphVizFontDir = null;
140: private static String m_GraphVizLibDir = null;
141:
142: // Names of environment variable need by GraphVis
143: private static String DOTFONTPATH = "DOTFONTPATH";
144: private static String LD_LIBRARY_PATH = "LD_LIBRARY_PATH";
145:
146: // Names used for temporary files
147: private static final String TMP_FILE_PREFIX = "sirpac_";
148: private static final String SUFFIX_TMP_DIR = ".tmp";
149: private static final String SUFFIX_DOT = ".dot";
150: private static final String SUFFIX_RDF = ".rdf";
151:
152: // Names used for file suffixes and for GraphViz's command line
153: // option
154: private static final String NAME_GIF = "gif";
155: private static final String NAME_HPGL = "hpgl";
156: private static final String NAME_PCL = "pcl";
1.20 ! barstow 157: private static final String NAME_PNG = "png";
1.19 barstow 158: private static final String NAME_PS = "ps";
159: private static final String NAME_SVG = "svg";
160:
161: // Default GraphViz parameter names and their default values
1.8 barstow 162: // Servlet name
163: private static final String SERVLET_NAME = "SiRPACServlet";
164:
1.3 barstow 165: /*
1.4 barstow 166: * Create a File object in the m_SiRPACTmpDir directory
1.3 barstow 167: *
1.4 barstow 168: *@param directory the file's directory
169: *@param prefix the file's prefix name (not its directory)
170: *@param suffix the file's suffix or extension name
171: *@return a File object if a temporary file is created; null otherwise
1.3 barstow 172: */
1.4 barstow 173: private File createTempFile (String directory, String prefix, String suffix) {
174: File f;
175: try {
176: File d = new File(directory);
177: f = File.createTempFile(prefix, suffix, d);
178: } catch (Exception e) {
179: return null;
180: }
181: return f;
182: }
183:
1.14 barstow 184:
185: /*
186: * Copy the given string of RDF to a file in the given directory
187: *
188: *@param dir the file's directory
189: *@param rdf the string of RDF
190: *@return void
191: */
192:
193: private void copyRDFStringToFile(String tmpDir, String rdf)
194: {
195: try {
196: // Generate a unique file name
1.19 barstow 197: File tmpFile = createTempFile(tmpDir, TMP_FILE_PREFIX, SUFFIX_RDF);
1.14 barstow 198: if (tmpFile == null) {
199: // Not really a critical error, just return
200: return;
201: }
202:
203: // Create a PrintWriter for the GraphViz consumer
204: FileWriter fw = new FileWriter(tmpFile);
205: PrintWriter pw = new PrintWriter(fw);
206:
207: pw.println(rdf);
208: pw.close();
209: } catch (Exception e) {
210: // Just return - not critical
211: return;
212: }
213: }
214:
1.4 barstow 215: /*
1.19 barstow 216: * Given the graph's format option, return either the corresponding
217: * command line option for that option or the file name suffix for
218: * the graph option. For example GIF files have ".gif" for its
219: * suffix and GraphViz uses "-Tgif" for the command line.
220: *
221: * NOTE: default is GIF.
222: *
223: *@param graphFormat the graph's output format
224: *@param suffix. If true, the name returned is for the graph's
225: * file name suffix; otherwise, the name returned is for the
226: * graph's command line option.
227: *@return the suffix to use for the graph's output file
228: */
229: private String getFormatName(String graphFormat, boolean suffix) {
230:
231: String name = (suffix) ? "." : "-T";
232:
1.20 ! barstow 233: if (graphFormat.equals(FORMAT_PNG_EMBED)) return name + NAME_PNG;
! 234: if (graphFormat.equals(FORMAT_PNG_LINK)) return name + NAME_PNG;
1.19 barstow 235: if (graphFormat.equals(FORMAT_SVG_LINK)) return name + NAME_SVG;
236: if (graphFormat.equals(FORMAT_PS_LINK)) return name + NAME_PS;
237: if (graphFormat.equals(FORMAT_HP_GL_LINK)) return name + NAME_HPGL;
238: if (graphFormat.equals(FORMAT_HP_PCL_LINK)) return name + NAME_PCL;
239:
240: return name + NAME_GIF;
241: }
242:
243: /*
1.20 ! barstow 244: * Invokes the GraphVis program to create a graph image from the
1.4 barstow 245: * the given DOT data file
246: *
247: *@param dotFileName the name of the DOT data file
1.20 ! barstow 248: *@param outputFileName the name of the output data file
1.4 barstow 249: *@return true if success; false if any failure occurs
250: */
1.19 barstow 251: private boolean generateOutputFile(String dotFileName, String outputFileName, String graphFormat) {
1.5 barstow 252: String environment[] = {DOTFONTPATH + "=" + m_GraphVizFontDir,
253: LD_LIBRARY_PATH + "=" + m_GraphVizLibDir};
1.4 barstow 254:
1.19 barstow 255: String formatOption = getFormatName(graphFormat, false);
256:
257: String cmdArray[] = {m_GraphVizPath, formatOption, "-o", outputFileName, dotFileName};
1.4 barstow 258:
259: Runtime rt = Runtime.getRuntime();
260: try {
261: Process p = rt.exec(cmdArray, environment);
262: p.waitFor();
263: } catch (Exception e) {
264: return false;
265: }
266:
267: return true;
1.3 barstow 268: }
1.1 barstow 269:
1.3 barstow 270: /*
1.6 barstow 271: * Returns a parameter from a request or the parameter's default
272: * value.
273: *
274: *@param req a Servlet request
275: *@return if the request contains the specfied parameter its value
276: * in the request is returned; otherwise its default value is
277: * returned
278: */
279: private String getParameter(HttpServletRequest req, String param, String defString) {
280: String s = req.getParameter(param);
281: return (s == null) ? defString : s;
282: }
283:
284: /*
285: * If the request contains any graph-related parameters, pass them
286: * to the graph consumer for handling
287: *
288: *@param req the response
289: *@param consumer the GraphViz consumer
290: */
291: private void processGraphParameters (HttpServletRequest req, GraphVizDumpConsumer consumer) {
292: // Look for colors
293:
294: String s;
295:
296: String nodeColor = getParameter (req, NODE_COLOR, DEFAULT_NODE_COLOR);
297: String nodeTextColor = getParameter (req, NODE_TEXT_COLOR, DEFAULT_NODE_TEXT_COLOR);
298: String edgeColor = getParameter (req, EDGE_COLOR, DEFAULT_EDGE_COLOR);
299: String edgeTextColor = getParameter (req, EDGE_TEXT_COLOR, DEFAULT_EDGE_TEXT_COLOR);
300: String fontSize = getParameter (req, FONT_SIZE, DEFAULT_FONT_SIZE);
301:
302: // Orientation must be either
303: String orientation = req.getParameter (ORIENTATION);
1.19 barstow 304: if (orientation.equals("LR"))
1.6 barstow 305: orientation = "LR";
306: else
307: orientation = DEFAULT_ORIENTATION;
308:
309: // Add an attribute for all of the graph's nodes
310: consumer.addGraphAttribute("node [fontname=" + DEFAULT_FONT +
311: ",fontsize=" + fontSize +
312: ",color=" + nodeColor +
313: ",fontcolor=" + nodeTextColor + "]");
314:
315: // Add an attribute for all of the graph's edges
316: consumer.addGraphAttribute("edge [fontname=" + DEFAULT_FONT +
317: ",fontsize=" + fontSize +
318: ",color=" + edgeColor +
319: ",fontcolor=" + edgeTextColor + "]");
320:
321: // Add an attribute for the orientation
322: consumer.addGraphAttribute("rankdir=" + orientation + ";");
323: }
324:
325: /*
1.3 barstow 326: * Generate a graph of the RDF data model
327: *
1.4 barstow 328: *@param out the servlet's output stream
1.6 barstow 329: *@param rdf the RDF text
330: *@param req a Servlet request
1.19 barstow 331: *@param source the name of input source
332: *@param graphFormat the graph's format
333: *@param saveRDF the RDF can be cached [saved to the file system]
334: *@param saveDOTFile the DOT file should be cached
335: *@param createBags the parser should create a bag for each Description
336: *@param streamMode the parser's stream mode setting
1.3 barstow 337: */
1.19 barstow 338: private void generateGraph (ServletOutputStream out, String rdf, HttpServletRequest req, String source, String graphFormat, boolean saveRDF, boolean saveDOTFile, boolean createBags, boolean streamMode) {
1.2 barstow 339: try {
340: out.println("<hr title=\"visualisation\">");
1.3 barstow 341: out.println("<h3>Graph of the data model</h3>");
342:
1.4 barstow 343: // Stop if any of the parameters are missing
1.19 barstow 344: if (m_SiRPACTmpDir == null ||
345: m_GraphVizPath == null ||
346: m_GraphVizFontDir == null ||
347: m_GraphVizLibDir == null) {
1.8 barstow 348:
349: // Put the paths in a comment in the returned content
350: out.println("<!-- SIRPAC TMP = " + m_SiRPACTmpDir);
351: out.println("GRAPH VIZ = " + m_GraphVizPath);
352: out.println("GRAPH LIB = " + m_GraphVizLibDir);
353: out.println("GRAPH FON = " + m_GraphVizFontDir + " -->");
354:
1.3 barstow 355: out.println("Servlet initialization failed. A graph cannot be generated.");
356: return;
357: }
358:
1.4 barstow 359: // The temporary directory
360: String tmpDir = m_SiRPACTmpDir;
1.3 barstow 361:
1.4 barstow 362: // Must generate a unique file name that the DOT consumer
363: // will use
1.19 barstow 364: File dotFile = createTempFile(tmpDir, TMP_FILE_PREFIX, SUFFIX_DOT);
1.4 barstow 365: if (dotFile == null) {
366: out.println("Failed to create a temporary DOT file. A graph cannot be generated.");
1.3 barstow 367: return;
368: }
369:
370: // Create a PrintWriter for the GraphViz consumer
1.4 barstow 371: FileWriter fw = new FileWriter(dotFile);
1.3 barstow 372: PrintWriter pw = new PrintWriter(fw);
373:
374: // Run the parser using the DOT consumer to capture
375: // the output in a file
376: StringReader sr = new StringReader (rdf);
377: InputSource is = new InputSource (sr);
378: GraphVizDumpConsumer consumer = new GraphVizDumpConsumer(pw);
379:
1.6 barstow 380: // Process any graph-related parameters in the request
381: processGraphParameters(req, consumer);
1.15 barstow 382:
383: // Reinitialize the parser's genid counter so the genids
384: // of the triple will match the genids of the graph
1.18 barstow 385: SiRPAC sirpac = new SiRPAC();
386: ErrorStore errorHandler = new ErrorStore();
387:
388: sirpac.setErrorHandler(errorHandler);
389: sirpac.createBags (createBags);
390: sirpac.setStreamMode (streamMode);
391: sirpac.setSource(source);
1.6 barstow 392:
1.3 barstow 393: try {
1.18 barstow 394: sirpac.parse(is, consumer);
1.3 barstow 395: } catch (Exception e) {
396: out.println("An attempt to generate the graph data failed ("
397: + e.getMessage() + ").");
1.4 barstow 398: pw.close();
399: dotFile.delete();
1.3 barstow 400: return;
401: }
402:
1.4 barstow 403: // Must close the DOT input file so the GraphViz can
404: // open and read it
405: pw.close();
406:
1.20 ! barstow 407: // Must generate a unique file name for the output file
1.4 barstow 408: // that will be created
1.19 barstow 409: String suffix = getFormatName(graphFormat, true);
410: File outputFile = createTempFile(tmpDir, TMP_FILE_PREFIX, suffix);
411: if (outputFile == null) {
412: out.println("Failed to create a temporary file for the graph. A graph cannot be generated.");
1.4 barstow 413: dotFile.delete();
414: return;
415: }
416:
1.3 barstow 417: // Pass the DOT data file to the GraphViz dot program
1.20 ! barstow 418: // so it can create a graph image of the data model
1.4 barstow 419: String dotFileName = dotFile.getAbsolutePath();
1.19 barstow 420: String outputFileName = outputFile.getAbsolutePath();
1.4 barstow 421:
1.19 barstow 422: if (!generateOutputFile(dotFileName, outputFileName, graphFormat)) {
1.4 barstow 423: out.println("An attempt to create a graph failed.");
424: dotFile.delete();
1.19 barstow 425: outputFile.delete();
1.4 barstow 426: return;
427: }
1.3 barstow 428:
1.19 barstow 429: // Handle the DOT file
430: if (saveDOTFile) {
431: // Make the DOT file link'able if so requested
432: String dotPath = SERVLET_NAME + SUFFIX_TMP_DIR +
433: File.separator + dotFile.getName();
434: out.println("<a href=\"" + dotPath + "\">Get the DOT file.</a><br /><br />");
435: }
436: else {
437: // Delete it ...
438: dotFile.delete();
439: }
1.3 barstow 440:
1.20 ! barstow 441: // NOTE: Cannot delete the output file here because its
1.9 barstow 442: // pathname is returned to the client
1.19 barstow 443: String imagePath = SERVLET_NAME + SUFFIX_TMP_DIR + File.separator +
444: outputFile.getName();
445:
446: // Handle the embedded image formats first
1.20 ! barstow 447: if (graphFormat.equals(FORMAT_GIF_EMBED) ||
! 448: graphFormat.equals(FORMAT_PNG_EMBED)) {
1.19 barstow 449: if (outputFile.length() > 0)
450: out.println("<img src=\"" + imagePath + "\"/>");
451: else
452: out.println("The graph image file is empty.");
453: } else {
454: if (outputFile.length() > 0)
455: out.println("<a href=\"" + imagePath + "\">Get/view the graph's image file (" + suffix + ").</a><br /><br />");
456: else
457: out.println("The graph image file is empty.");
458: }
1.2 barstow 459:
1.14 barstow 460: // One last thing to do before exiting - copy the RDF to a file
461: if (saveRDF)
462: copyRDFStringToFile(tmpDir, rdf);
463:
1.2 barstow 464: } catch (Exception e) {
465: System.err.println("Exception: " + e.getMessage());
466: }
467: }
468:
469: /*
1.3 barstow 470: * Search the given string for substring "key"
1.2 barstow 471: * and if it is found, replace it with string "replacement"
472: *
1.4 barstow 473: *@param input the input string
474: *@param key the string to search for
475: *@param replacement the string to replace all occurences of "key"
1.2 barstow 476: *@return if no substitutions are done, input is returned; otherwise
477: * a new string is returned.
478: */
1.12 barstow 479: public static String replaceString(String input, String key, String replacement) {
1.2 barstow 480: StringBuffer sb = new StringBuffer("");
481: StringTokenizer st = new StringTokenizer(input, key);
482:
483: // Must handle the case where the input string begins with the key
484: if (input.startsWith(key))
485: sb = sb.append(replacement);
486: while (st.hasMoreTokens()) {
487: sb = sb.append(st.nextToken());
488: if (st.hasMoreTokens())
489: sb = sb.append(replacement);
490: }
491: if (sb.length() >= 1)
492: return sb.toString();
493: else
494: return input;
495: }
496:
1.3 barstow 497: /*
498: * Print the document's header info
499: *
500: *@param out the servlet's output stream
501: */
1.1 barstow 502: private void printDocumentHeader (ServletOutputStream out) {
503:
504: try {
505:
506: out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"");
507: out.println(" \"http://www.w3.org/TR/REC-html40/loose.dtd\">");
508: out.println("<HTML><HEAD>");
509: out.println("<TITLE>RDF creation</TITLE>");
510: out.println("<LINK HREF=\"rdf.css\" REL=\"stylesheet\">");
511: out.println("</HEAD>");
512: out.println("<BODY>");
513:
514: } catch (Exception e) {
1.2 barstow 515: System.err.println("Exception: " + e.getMessage());
1.1 barstow 516: }
517: }
518:
1.3 barstow 519: /*
520: * Print the rdf listing
521: *
522: *@param out the servlet's output stream
523: *@param rdf the RDF code
524: */
1.16 barstow 525: private void printListing (ServletOutputStream out, String rdf, boolean needCR) {
1.1 barstow 526: try {
527: out.println("<hr title=\"original source\">");
528: out.println("<h3>The original RDF/XML document</h3>");
529: out.println("<pre>");
530:
1.2 barstow 531: String s = replaceString(rdf, "<", "<");
532: StringTokenizer st = new StringTokenizer(s, "\n");
1.1 barstow 533:
534: // Now output the RDF one line at a time with line numbers
535: int lineNum = 1;
536: while (st.hasMoreTokens()) {
1.16 barstow 537: if (needCR)
538: out.print ("<a name=\"" + lineNum + "\">" + lineNum +
539: "</a>: " + st.nextToken() + "\n");
540: else
541: out.print ("<a name=\"" + lineNum + "\">" + lineNum +
542: "</a>: " + st.nextToken());
1.1 barstow 543: lineNum++;
544: }
545:
546: out.println("</pre>");
547: } catch (Exception e) {
548: System.err.println("Exception: " + e.getMessage());
549: }
550: }
551:
1.3 barstow 552: /*
553: * Print the header for the triple listing
554: *
555: *@param out the servlet's output stream
556: */
1.17 barstow 557: private void printTripleTableHeader (ServletOutputStream out) {
1.1 barstow 558: try {
559: out.println("<hr title=\"triples\">");
560: out.println("<h3>Triples of the data model</h3>");
1.17 barstow 561: out.println("<table border><tr>" +
562: "<td><b>Number</b></td>" +
563: "<td><b>Subject</b></td>" +
564: "<td><b>Predicate</b></td>" +
565: "<td><b>Object</b></td>" +
566: "</tr>");
1.1 barstow 567: } catch (Exception e) {
568: System.err.println("Exception: " + e.getMessage());
569: }
570: }
571:
1.3 barstow 572: /*
573: * Print the footer info for the triple listing
574: *
575: *@param out the servlet's output stream
576: */
1.17 barstow 577: private void printTripleTableFooter (ServletOutputStream out, SiRPACServletDumpConsumer consumer) {
1.1 barstow 578: try {
1.17 barstow 579: out.println("</table>");
1.14 barstow 580: if (consumer != null)
581: out.println("<p>The number of triples = " + consumer.getNumStatements() + "</p>");
1.1 barstow 582: } catch (Exception e) {
583: System.err.println("Exception: " + e.getMessage());
584: }
585: }
1.3 barstow 586:
587: /*
588: * Print the document's footer info
589: *
590: *@param out the servlet's output stream
591: *@param rdf the RDF code
592: */
1.1 barstow 593: private void printDocumentFooter (ServletOutputStream out, String rdf) {
594: try {
595:
596: out.println("<hr title=\"Problem reporting\">");
597: out.println("<h3>Feedback</h3>");
1.2 barstow 598: out.println("<p>If you suspect that SiRPAC produced an error, please enter an explanation below and then press the <b>Submit problem report</b> button, to mail the report (and listing) to <i>" + MAIL_TO + "</i></p>");
1.1 barstow 599: out.println("<form enctype=\"text/plain\" method=\"post\" action=\"mailto:" + MAIL_TO + "\">");
600: out.println("<textarea cols=\"60\" rows=\"4\" name=\"report\"></textarea>");
1.2 barstow 601: out.println("<p><input type=\"hidden\" name=\"RDF\" value=\"<?xml version="1.0"?>");
1.1 barstow 602:
1.2 barstow 603: // The listing is being passed as a parameter so the '<'
604: // and '"' characters must be replaced with < and ",
605: // respectively
1.16 barstow 606: if (rdf != null) {
607: String s1 = replaceString(rdf, "<", "<");
608: String s2 = replaceString(s1, "\"", """);
609: out.println(s2 + "\">");
610: }
1.1 barstow 611:
612: out.println("<input type=\"submit\" value=\"Submit problem report\">");
613: out.println("</form>");
1.13 barstow 614: out.println("<hr/>");
1.1 barstow 615: out.println("</BODY>");
616: out.println("</HTML>");
617:
618: } catch (Exception e) {
1.2 barstow 619: System.err.println("Exception: " + e.getMessage());
1.1 barstow 620: }
621:
622: }
623:
1.3 barstow 624: /*
1.16 barstow 625: * Given a URI string, open it, read its contents into a String
626: * and return the String
627: *
628: *@param uri the URI to open
629: *@return the content at the URI or null if any error occurs
630: */
631: private String getByteStream (String uri) {
632: try {
633: URL url = new URL(uri);
634: InputStream is = url.openStream();
635: String s = new String("");
636:
637: int c;
638: int numRead = 0;
639:
640: while ((c = is.read()) != -1) {
641: s += (char)c;
642: if (numRead == 15) {
643: // A server could return content but not the RDF/XML that
644: // we need. Check the beginning of s and if it looks like
645: // a generic HTML message, return an error.
646: if (s.startsWith("<!DOCTYPE HTML"))
647: return null;
648: }
649: numRead++;
650: }
651:
652: if (s.equals(""))
653: // Nothing was returned
654: return null;
655:
656: return s;
657:
658: } catch (Exception e) {
659: return null;
660: }
661: }
662:
663: /*
1.3 barstow 664: * Servlet's get info method
665: */
1.1 barstow 666: public String getServletInfo () {
667: return "Servlet Wrapper for SiRPAC. This is revision " + REVISION;
668: }
669:
1.3 barstow 670: /*
671: * Servlet's init method
672: *
673: *@param config the servlet's configuration object
674: */
1.1 barstow 675: public void init(ServletConfig config) throws ServletException {
676: super.init (config);
677:
1.3 barstow 678: // Cache the parameters
679: m_SiRPACTmpDir = config.getInitParameter(SIRPAC_TMP_DIR);
1.5 barstow 680:
681: // All of the Graph Viz paths extend from GRAPH_VIZ_ROOT
682: String GraphVizRoot = config.getInitParameter(GRAPH_VIZ_ROOT);
683:
684: m_GraphVizPath = GraphVizRoot + "/" + config.getInitParameter(GRAPH_VIZ_PATH);
685: m_GraphVizFontDir = GraphVizRoot + "/" + config.getInitParameter(GRAPH_VIZ_FONT_DIR);
686: m_GraphVizLibDir = GraphVizRoot + "/" + config.getInitParameter(GRAPH_VIZ_LIB_DIR);
1.1 barstow 687: }
688:
1.3 barstow 689: /*
690: * Servlet's destroy info method
691: */
1.1 barstow 692: public void destroy () {
693: super.destroy ();
694: }
695:
1.3 barstow 696: /*
1.4 barstow 697: * Servlet's doGet info method - NOT supported
1.3 barstow 698: *
699: *@param req the request
700: *@param res the response
701: */
1.1 barstow 702: public void doGet (HttpServletRequest req, HttpServletResponse res)
703: throws ServletException, IOException {
1.3 barstow 704:
1.1 barstow 705: ServletOutputStream out = res.getOutputStream ();
706:
707: res.setContentType ("text/html");
708:
1.3 barstow 709: out.println ("<h1>GET is NOT supported!</h1>\n\n<p>Please send RDF through POST!</p>\n");
1.1 barstow 710: }
711:
1.3 barstow 712: /*
713: * Servlet's doPost method
714: *
715: *@param req the request
716: *@param res the response
717: */
1.1 barstow 718: public void doPost (HttpServletRequest req, HttpServletResponse res)
719: throws ServletException, IOException {
720:
721: ServletOutputStream out = res.getOutputStream ();
722:
1.19 barstow 723: String sRDF = req.getParameter (TEXT);
724: String sBags = req.getParameter (BAG);
725: String sStreamMode = req.getParameter (STREAM_MODE);
726: String sSaveRDF = req.getParameter (SAVE_RDF);
727: String sSaveDOTFile = req.getParameter (SAVE_DOT_FILE);
728: String sURI = req.getParameter (URI);
729: String sFormat = req.getParameter (FORMAT);
1.16 barstow 730:
1.18 barstow 731: SiRPAC sirpac = new SiRPAC();
732: ErrorStore errorHandler = new ErrorStore();
1.16 barstow 733: InputSource is = null;
734: boolean error = false;
735: String sError = null;
736:
1.1 barstow 737: SiRPACServletDumpConsumer consumer = new SiRPACServletDumpConsumer();
1.9 barstow 738:
1.18 barstow 739: // Initialize the parser
740: sirpac.setErrorHandler(errorHandler);
1.1 barstow 741:
1.16 barstow 742: // If a URI was sent in the request, it takes precedence
743: if (sURI != null && sURI.length() >= 1) {
744: try {
745: is = GenericParser.getInputSource(sURI);
746: sRDF = getByteStream(sURI);
747: if (sRDF == null)
748: sError = "An attempt to load the RDF from URI '" + sURI + "' failed. (The file may not exist or the server is down.)";
1.18 barstow 749: sirpac.setSource(sURI);
1.16 barstow 750: } catch (MalformedURLException e) {
751: sError = "An attempt to load URI '" + sURI
752: + "' produced a MalforedURL Exception.\n["
753: + e.getMessage() + "]";
754: } catch (IOException e) {
755: sError = "An attempt to load URI '" + sURI
756: + "' produced an IO Exception.\n["
757: + e.getMessage() + "]";
758: }
759: } else {
760: StringReader sr = new StringReader (sRDF);
761: is = new InputSource (sr);
1.18 barstow 762: sirpac.setSource("online:#");
1.16 barstow 763: }
764:
765: if (sError != null) {
766: printDocumentHeader (out);
767: out.println ("<h1>" + sError + "</h1>\n");
768: printDocumentFooter(out, null);
769: return;
770: }
771:
1.1 barstow 772: printDocumentHeader (out);
1.16 barstow 773: printListing (out, sRDF, sURI != null && sURI.length() >= 1);
1.17 barstow 774: printTripleTableHeader (out);
1.1 barstow 775:
776: try {
1.3 barstow 777: // Override the default triple output handler
1.1 barstow 778: consumer.setOutputStream(out);
779:
1.18 barstow 780: // Create a bag per Description element? [off by default]
1.1 barstow 781: if (sBags != null && sBags.equals ("on"))
1.18 barstow 782: sirpac.createBags (true);
1.10 barstow 783:
1.18 barstow 784: // Set parser's streaming mode [on by default]
1.11 barstow 785: if (sStreamMode != null && sStreamMode.equals ("on"))
1.18 barstow 786: sirpac.setStreamMode (false);
1.1 barstow 787:
1.18 barstow 788: sirpac.parse(is, consumer);
1.1 barstow 789:
1.17 barstow 790: printTripleTableFooter(out, consumer);
1.12 barstow 791:
1.19 barstow 792: if (sFormat != null && !sFormat.equals(FORMAT_NO_GRAPH)) {
793: generateGraph(out,
794: sRDF,
795: req,
796: sirpac.source(),
797: sFormat,
798: (sSaveRDF != null) ? true : false,
799: (sSaveDOTFile != null && sSaveDOTFile.equals ("on") ? true : false),
800: (sBags != null && sBags.equals ("on") ? true : false),
801: (sStreamMode != null && sStreamMode.equals ("on") ? false : true));
802: }
1.2 barstow 803:
1.1 barstow 804: } catch (SAXException e) {
1.3 barstow 805: error = true;
1.1 barstow 806: } catch (Exception e) {
1.3 barstow 807: error = true;
1.1 barstow 808: e.printStackTrace ();
809: }
810:
811: res.setContentType ("text/html");
1.3 barstow 812:
813: if (error) {
1.17 barstow 814: printTripleTableFooter(out, null);
1.1 barstow 815: out.println ("<h1>Errors during parsing</h1>\n");
816: out.println ("<pre>\n");
1.2 barstow 817:
818: // Make the line number a link to the listing
1.18 barstow 819: out.println ("Fatal error: " + errorHandler.getErrorMessage());
1.1 barstow 820: out.println (" (Line number = " + "<a href=\"#" +
1.18 barstow 821: errorHandler.getLineNumber() + "\">" +
822: errorHandler.getLineNumber() + "</a>" +
1.1 barstow 823: ", Column number = " +
1.18 barstow 824: errorHandler.getColumnNumber() + ")");
1.1 barstow 825:
826: out.println ("</pre>\n\n");
827: }
828:
829: printDocumentFooter(out, sRDF);
830: }
831: }
Webmaster