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