Annotation of java/classes/org/w3c/rdf/examples/ARPServlet.java, revision 1.52

1.16      barstow     1: /***********************************************************************
                      2:  *
                      3:  * ARPServlet - this servlet implements an RDF Validation service.  As
                      4:  *  of this writing, the following RDF validation service used this
                      5:  *  servlet:
                      6:  *
                      7:  *   http://www.w3.org/RDF/Validator/
                      8:  *
                      9:  ***********************************************************************
1.1       barstow    10:  *
                     11:  * Copyright © World Wide Web Consortium, (Massachusetts Institute of
                     12:  * Technology, Institut National de Recherche en Informatique et en
                     13:  * Automatique, Keio University).
                     14:  *
                     15:  * All Rights Reserved.
                     16:  *
                     17:  * Please see the full Copyright clause at
                     18:  * <http://www.w3.org/Consortium/Legal/copyright-software.html>
                     19:  *
1.16      barstow    20:  ***********************************************************************
                     21:  *
                     22:  * This servlet is a wrapper for the ARP RDF parser.  See the following
                     23:  * for information about the ARP RDF parser:
                     24:  *
                     25:  *  http://www.hpl.hp.co.uk/people/jjc/arp/
                     26:  *
                     27:  ***********************************************************************
                     28:  *
                     29:  * Implementation notes:
                     30:  *
                     31:  * o This servlet supports the HTTP POST operation; it does not 
                     32:  *  support the HTTP GET operation
                     33:  *
                     34:  * o Depending upon the parameters given to the servlet it may 
                     35:  *  invoke a GraphViz suprocess to generate a graph of the RDF.  
                     36:  *  See the following for more information about GraphViz:
1.1       barstow    37:  *
1.16      barstow    38:  *   http://www.research.att.com/sw/tools/graphviz/
1.1       barstow    39:  *
1.16      barstow    40:  *  The servlet assumes version 1.7.4 of GraphViz.
1.1       barstow    41:  *
1.16      barstow    42:  * o Depending upon the parameters given to the servlet, the RDF
                     43:  *  to be validated may be copied to a file.  The name of the file
                     44:  *  is automatically generated via Java's temporary file APIs.  The
                     45:  *  location of the directory where the file is stored is configured
                     46:  *  via the serverlet's init() method.  See below for more information.
                     47:  *
                     48:  * o See the section on Server Initialization for more information.
                     49:  *
                     50:  ***********************************************************************
                     51:  *
                     52:  * HTTP POST parameters - the servlet expects/assumes the following 
                     53:  *  variables are defined via the HTTP POST request:
                     54:  *
                     55:  * RDF - the RDF (assumed to be in RDF/XML syntax) to be validated
                     56:  *
                     57:  * SAVE_DOT_FILE - if "on", the GraphViz DOT file is saved and a 
                     58:  *   link to the file is returned; otherwise the DOT file is not saved
                     59:  *
                     60:  * SAVE_RDF - if "on", the RDF will be copied to a file; otherwise
                     61:  *   the RDF is not copied to a file
1.1       barstow    62:  *
1.10      barstow    63:  * EMBEDDED_RDF - if "on", then the RDF is not enclosed in <RDF>...</RDF>
1.30      duerst     64:  *   tags; otherwise it assumed that the RDF is enclosed in these tags.
1.10      barstow    65:  *
1.16      barstow    66:  * URI - the URI of the RDF to validate; this parameter may not be 
                     67:  *   specified; if this parameter and the RDF parameter are both 
                     68:  *   specified, this parameter takes precedence
1.1       barstow    69:  *
                     70:  * ORIENTATION - the graph's orientation (left to right or top to
1.16      barstow    71:  *   bottom); default is left to right
1.1       barstow    72:  *
1.16      barstow    73:  * FONT_SIZE - the font size to use (10, 12, 14, 16 and 20 are 
                     74:  *   supported); the default is 10
1.1       barstow    75:  *
1.16      barstow    76:  * ANON_NODES_EMPTY - if "on", anonymous nodes are not labeled; otherwise
                     77:  *   anonymous nodes are labeled;
1.12      barstow    78:  *
                     79:  * TRIPLES_AND_GRAPH - support values are:
                     80:  *
1.16      barstow    81:  *     PRINT_BOTH - display triples and a graph (the default)
                     82:  *     PRINT_TRIPLES - only display the triples
                     83:  *     PRINT_GRAPH - only display the graph
1.12      barstow    84:  *
1.1       barstow    85:  * GRAPH_FORMAT - the graph's output format.  Supported values are:
                     86:  *
1.16      barstow    87:  *     GIF_EMBED - embed the graph as a GIF (the default)
1.1       barstow    88:  *     GIF_LINK - don't embed the GIF but create a link for it
                     89:  *     SVG_LINK - create the graph in SVG format and create a link to the file
                     90:  *     PNG_EMBED - create the graph in PNG format and embed the graph in the 
                     91:  *       document that is returned
                     92:  *     PNG_LINK - create the graph in PNG format and create a link to the file
                     93:  *     PS_LINK - create a PostScript image of the file and a link to the file
                     94:  *     HP_PCL_LINK - create a HPGL/2 - PCL (Laserwriter) image of the file 
                     95:  *       and a link to the file
                     96:  *     HP_GL_LINK - create a HPGL - PCL (pen plotter) image of the file and 
                     97:  *       a link to the file
                     98:  *
                     99:  * NTRIPLES if "on" the tabular output will be in the NTriples format;
                    100:  *  otherwise a table of Subject, Predicate, Objects will be generated
                    101:  *
1.16      barstow   102:  ***********************************************************************
                    103:  *
                    104:  * Server Initialization - this servlet requires the following 
                    105:  *  parameters be set in the servlet's init() method - via the
                    106:  *  ServletConfig object:
1.1       barstow   107:  *
1.16      barstow   108:  * GRAPH_VIZ_ROOT - the absolute path of the top-level directory containing
                    109:  *   GraphViz's binary distribution
                    110:  *
                    111:  * GRAPH_VIZ_PATH - the relative path (based on GRAPH_VIZ_ROOT) of
                    112:  *   the DOT executable (e.g. dotneato/dot) - the program used to generate
                    113:  *   a graph from a DOT file.
                    114:  *
                    115:  * GRAPH_VIZ_FONT_DIR - the relative path (based on GRAPH_VIZ_ROOT) of
                    116:  *   the fonts directory used by GraphViz (e.g. Fonts)
                    117:  *
                    118:  * SERVLET_TMP_DIR - the absolute path of the directory to be used to
                    119:  *   store temporary files used by the servlet and GraphViz.  This 
                    120:  *   directory must be writable by the servlet.  
                    121:  *
                    122:  *   NOTE - Some files created by the servlet are not removed by 
                    123:  *     servlet (e.g. graph image files).
                    124:  *
                    125:  * If any of these parameters are not defined, the servlet will NOT 
                    126:  * validate the RDF.
                    127:  *
                    128:  ***********************************************************************
                    129:  *
                    130:  * Dependencies - this servlet requires the following Java packages
                    131:  *   as well as GraphViz (described above):
                    132:  *
                    133:  * ARP RDF parser: http://www.hpl.hp.co.uk/people/jjc/arp/download.html
                    134:  *
                    135:  * SAX-based XML parser: e.g. Xerces at http://xml.apache.org/
                    136:  *
                    137:  * Java servlet package: http://java.sun.com/products/servlet/archive.html
                    138:  *
                    139:  * Apache Regular Expression: http://jakarta.apache.org/builds/jakarta-regexp/release/v1.2/
                    140:  *
                    141:  ***********************************************************************
                    142:  *
                    143:  * Author: Art Barstow <barstow@w3.org>
1.30      duerst    144:  * Author (internationalization): Martin J. Duerst <duerst@w3.org>
1.16      barstow   145:  *
1.52    ! duerst    146:  * $Id: ARPServlet.java,v 1.34 2002/08/06 02:32:26 duerst Exp $
1.16      barstow   147:  *
                    148:  ***********************************************************************/
1.1       barstow   149: 
1.16      barstow   150: // http://dev.w3.org/cvsweb/java/classes/org/w3c/rdf/examples/
                    151: package org.w3c.rdf.examples; 
1.1       barstow   152: 
                    153: import java.io.*;
                    154: import java.net.MalformedURLException;
                    155: import java.net.URL;
1.33      duerst    156: import java.net.URLConnection;
1.1       barstow   157: import java.util.StringTokenizer;
                    158: import java.util.Enumeration;
1.14      barstow   159: import java.util.Hashtable;
1.16      barstow   160: 
                    161: // http://java.sun.com/products/servlet/2.2/javadoc/javax/servlet/package-summary.html
                    162: import javax.servlet.*;         
1.1       barstow   163: import javax.servlet.http.*;
1.32      duerst    164: import javax.mail.internet.ContentType;
1.1       barstow   165: 
1.16      barstow   166: // http://xml.apache.org/apiDocs/org/xml/sax/package-summary.html
                    167: import org.xml.sax.InputSource;        
1.1       barstow   168: import org.xml.sax.Parser;
                    169: import org.xml.sax.SAXException;
                    170: import org.xml.sax.SAXParseException;
                    171: import org.xml.sax.ErrorHandler;
                    172: import org.xml.sax.helpers.*;
                    173: 
1.16      barstow   174: // http://jakarta.apache.org/regexp/apidocs/org/apache/regexp/RE.html
1.3       barstow   175: import org.apache.regexp.RE;
                    176: 
1.16      barstow   177: // http://www.hpl.hp.co.uk/people/jjc/arp/apidocs/index.html
                    178: import com.hp.hpl.jena.rdf.arp.*; 
1.1       barstow   179: 
                    180: public class ARPServlet extends HttpServlet
                    181: {
1.52    ! duerst    182:     final static public String REVISION = "$Id: ARPServlet.java,v 1.34 2002/08/06 02:32:26 duerst Exp $";
1.1       barstow   183: 
                    184:     // The email address for bug reports
1.6       barstow   185:     private static final String MAIL_TO = "www-rdf-validator@w3.org";
1.1       barstow   186: 
                    187:     // Names of the POST parameters (described above) and their
1.12      barstow   188:     // defaults (if applicable)
                    189:     private static final String TEXT              = "RDF";
                    190:     private static final String SAVE_DOT_FILE     = "SAVE_DOT_FILE";
                    191:     private static final String SAVE_RDF          = "SAVE_RDF";
                    192:     private static final String EMBEDDED_RDF      = "EMBEDDED_RDF";
                    193:     private static final String URI               = "URI";
                    194:     private static final String NTRIPLES          = "NTRIPLES";
                    195:     private static final String ANON_NODES_EMPTY  = "ANON_NODES_EMPTY";
1.1       barstow   196:  
                    197:     private static final String NODE_COLOR         = "NODE_COLOR";
                    198:     private static final String DEFAULT_NODE_COLOR = "black";
                    199: 
                    200:     private static final String NODE_TEXT_COLOR         = "NODE_TEXT_COLOR";
                    201:     private static final String DEFAULT_NODE_TEXT_COLOR = "black";
                    202: 
                    203:     private static final String EDGE_COLOR         = "EDGE_COLOR";
                    204:     private static final String DEFAULT_EDGE_COLOR = "black";
                    205: 
                    206:     private static final String EDGE_TEXT_COLOR         = "EDGE_TEXT_COLOR";
                    207:     private static final String DEFAULT_EDGE_TEXT_COLOR = "black";
                    208: 
                    209:     private static final String ORIENTATION         = "ORIENTATION";
                    210:     private static final String DEFAULT_ORIENTATION = "TB";  // Top to Bottom
                    211: 
                    212:     private static final String FONT_SIZE         = "FONT_SIZE";
                    213:     private static final String DEFAULT_FONT_SIZE = "10";
                    214: 
1.12      barstow   215:     // Print graph and/or triples
                    216:     private static final String TRIPLES_AND_GRAPH = "TRIPLES_AND_GRAPH";
                    217:     private static final String PRINT_BOTH        = "PRINT_BOTH";
                    218:     private static final String PRINT_TRIPLES     = "PRINT_TRIPLES";
                    219:     private static final String PRINT_GRAPH       = "PRINT_GRAPH";
                    220: 
                    221:     // Graph formats
1.1       barstow   222:     private static final String FORMAT              = "FORMAT";
                    223:     private static final String FORMAT_GIF_EMBED    = "GIF_EMBED";
                    224:     private static final String FORMAT_GIF_LINK     = "GIF_LINK";
                    225:     private static final String FORMAT_SVG_LINK     = "SVG_LINK";
                    226:     private static final String FORMAT_PNG_EMBED    = "PNG_EMBED";
                    227:     private static final String FORMAT_PNG_LINK     = "PNG_LINK";
                    228:     private static final String FORMAT_PS_LINK      = "PS_LINK";
                    229:     private static final String FORMAT_HP_PCL_LINK  = "HP_PCL_LINK";
                    230:     private static final String FORMAT_HP_GL_LINK   = "HP_GL_LINK";
                    231: 
                    232:     // Fonts are not currently configurable
                    233:     private static final String DEFAULT_FONT = "arial";
                    234: 
                    235:     // Names of the servlet's parameters - for Jigsaw web server
                    236:     private static final String SERVLET_TMP_DIR    = "SERVLET_TMP_DIR";
                    237:     private static final String GRAPH_VIZ_ROOT     = "GRAPH_VIZ_ROOT";
                    238:     private static final String GRAPH_VIZ_PATH     = "GRAPH_VIZ_PATH";
                    239:     private static final String GRAPH_VIZ_FONT_DIR = "GRAPH_VIZ_FONT_DIR";
                    240: 
                    241:     // Variables for the servlet's parameters
                    242:     private static String m_ServletTmpDir   = null;
                    243:     private static String m_GraphVizPath    = null;
                    244:     private static String m_GraphVizFontDir = null;
                    245: 
1.30      duerst    246:     // Names of environment variable needed by GraphVis
1.1       barstow   247:     private static String DOTFONTPATH     = "DOTFONTPATH";
                    248:     private static String LD_LIBRARY_PATH = "LD_LIBRARY_PATH";
                    249: 
                    250:     // Names used for temporary files
                    251:     private static final String TMP_FILE_PREFIX = "servlet_";
                    252:     private static final String SUFFIX_TMP_DIR  = ".tmp";
                    253:     private static final String SUFFIX_DOT      = ".dot";
                    254:     private static final String SUFFIX_RDF      = ".rdf";
                    255: 
                    256:     // Names used for file suffixes and for GraphViz's command line
                    257:     // option
                    258:     private static final String NAME_GIF      = "gif";
                    259:     private static final String NAME_HPGL     = "hpgl";
                    260:     private static final String NAME_PCL      = "pcl";
                    261:     private static final String NAME_PNG      = "png";
                    262:     private static final String NAME_PS       = "ps";
                    263:     private static final String NAME_SVG      = "svg";
                    264: 
                    265:     // Default GraphViz parameter names and their default values
                    266:     // Servlet name
                    267:     private static final String SERVLET_NAME = "ARPServlet";
                    268: 
                    269:     // Name for the DOT file title
                    270:     private static final String DOT_TITLE = "dotfile";
                    271: 
1.30      duerst    272:     // The string to use to prefix anonymous nodes.
1.14      barstow   273:     private static final String ANON_NODE = "genid:";
                    274: 
1.1       barstow   275:     // The string to use for a namespace name when no
                    276:     // namespace is available - e.g. for the RDF that is
                    277:     // directly entered into the input form.
1.14      barstow   278:     private static final String DEFAULT_NAMESPACE = "online:";
1.1       barstow   279: 
                    280:     /*
1.14      barstow   281:      * Create a File object from the given directory and file names
1.1       barstow   282:      *
                    283:      *@param directory the file's directory
                    284:      *@param prefix the file's prefix name (not its directory)
                    285:      *@param suffix the file's suffix or extension name
                    286:      *@return a File object if a temporary file is created; null otherwise
                    287:      */
1.4       barstow   288:     private File createTempFile (String directory, String prefix, String suffix) 
                    289:     {
1.1       barstow   290:         File f;
                    291:         try {
                    292:             File d = new File(directory);
                    293:             f = File.createTempFile(prefix, suffix, d);
                    294:         } catch (Exception e) {
                    295:             return null;
                    296:         }
                    297:         return f;
                    298:     }
                    299: 
                    300:     /*
                    301:      * Given a URI string, open it, read its contents into a String
                    302:      * and return the String
                    303:      *
                    304:      *@param uri the URI to open
                    305:      *@return the content at the URI or null if any error occurs
                    306:      */
1.42      duerst    307:     private String getRDFfromURI (String uri) 
1.4       barstow   308:     {
1.1       barstow   309:         try {
1.52    ! duerst    310:            /* add this code here, to allow reading from a file:
        !           311:                 File ff = new File(uri);
        !           312:                 in = new FileInputStream(ff);
        !           313:            */
1.1       barstow   314:             URL url = new URL(uri);
1.32      duerst    315:            URLConnection con = url.openConnection();
1.34      duerst    316:             con.setRequestProperty("Accept", "application/rdf+xml");
1.32      duerst    317:             con.connect();
                    318:            String contentT = con.getContentType();
1.52    ! duerst    319:            String charset = null;
1.33      duerst    320:            if (contentT != null) {
1.52    ! duerst    321:                 ContentType contentType = new ContentType(con.getContentType());
        !           322:                charset = contentType.getParameter("charset");
1.32      duerst    323:            }
                    324: 
1.52    ! duerst    325:             InputStream is = con.getInputStream();
        !           326:             String s = new String("");
1.35      duerst    327: 
1.1       barstow   328:             int c;
                    329:             int numRead = 0;
                    330: 
1.52    ! duerst    331:             while ((c = is.read()) != -1) {
1.1       barstow   332:                 s += (char)c;
1.52    ! duerst    333:                 if (numRead == 15) {
        !           334:                     // A server could return content but not the RDF/XML that
        !           335:                     // we need.  Check the beginning of s and if it looks like
        !           336:                     // a generic HTML message, return an error.
        !           337:                     if (s.startsWith("<!DOCTYPE"))
        !           338:                         return null;
        !           339:                 }
        !           340:                 numRead++;
1.46      duerst    341:             }
1.35      duerst    342: 
1.52    ! duerst    343:             if (s.equals(""))
        !           344:                 // Nothing was returned 
1.35      duerst    345:                 return null;
                    346: 
1.1       barstow   347:             return s;
                    348: 
1.52    ! duerst    349:         } catch (Exception e) {
        !           350:             return null;
1.1       barstow   351:         }
                    352:     }
                    353: 
                    354:     /*
1.4       barstow   355:      * Copy the given string of RDF to a file in the given directory.
                    356:      * This is only done if the servlet is explictly asked to save
                    357:      * the RDF to a file.
1.1       barstow   358:      *
1.14      barstow   359:      *@param tmpDir the file's directory
1.1       barstow   360:      *@param rdf the string of RDF
                    361:      */
                    362:     private void copyRDFStringToFile(String tmpDir, String rdf) 
                    363:     {
                    364:         try {
                    365:             // Generate a unique file name 
                    366:             File tmpFile = createTempFile(tmpDir, TMP_FILE_PREFIX, SUFFIX_RDF);
                    367:             if (tmpFile == null) {
                    368:                 // Not really a critical error, just return
                    369:                 return;
                    370:             }
                    371: 
                    372:             // Create a PrintWriter for the GraphViz consumer
                    373:             FileWriter fw = new FileWriter(tmpFile);
                    374:             PrintWriter pw = new PrintWriter(fw);
                    375: 
                    376:             pw.println(rdf);
                    377:             pw.close();
                    378:         } catch (Exception e) {
1.4       barstow   379:             System.err.println(SERVLET_NAME + ": error occured trying to save RDF to file '" + tmpDir + TMP_FILE_PREFIX + SUFFIX_RDF + "'.");
1.1       barstow   380:             return;
                    381:         }
                    382:     }
                    383: 
                    384:     /*
                    385:      * Given the graph's format option, return either the corresponding
                    386:      * command line option for that option or the file name suffix for
                    387:      * the graph option.  For example GIF files have ".gif" for its
                    388:      * suffix and GraphViz uses "-Tgif" for the command line.
                    389:      *
                    390:      * NOTE: default is GIF.
                    391:      *
                    392:      *@param graphFormat the graph's output format
                    393:      *@param suffix.  If true, the name returned is for the graph's
                    394:      * file name suffix; otherwise, the name returned is for the
                    395:      * graph's command line option.
                    396:      *@return the suffix to use for the graph's output file
                    397:      */
                    398:     private String getFormatName(String graphFormat, boolean suffix) {
                    399: 
                    400:         String name = (suffix) ? "." : "-T";
                    401: 
1.4       barstow   402:         if (graphFormat.equals(FORMAT_PNG_EMBED))   return name + NAME_PNG;
                    403:         if (graphFormat.equals(FORMAT_PNG_LINK))    return name + NAME_PNG;
                    404:         if (graphFormat.equals(FORMAT_SVG_LINK))    return name + NAME_SVG;
                    405:         if (graphFormat.equals(FORMAT_PS_LINK))     return name + NAME_PS;
                    406:         if (graphFormat.equals(FORMAT_HP_GL_LINK))  return name + NAME_HPGL;
1.1       barstow   407:         if (graphFormat.equals(FORMAT_HP_PCL_LINK)) return name + NAME_PCL;
                    408:         
                    409:         return name + NAME_GIF;
                    410:     }
                    411: 
                    412:     /*
                    413:      * Invokes the GraphVis program to create a graph image from the
                    414:      * the given DOT data file
                    415:      *
                    416:      *@param dotFileName the name of the DOT data file
                    417:      *@param outputFileName the name of the output data file 
1.14      barstow   418:      *@param graphFormat the graph's format
1.1       barstow   419:      *@return true if success; false if any failure occurs
                    420:      */
1.8       barstow   421:     private boolean generateGraphFile(String dotFileName, 
1.4       barstow   422:        String outputFileName, String graphFormat) 
                    423:     {
1.16      barstow   424:         String environment[] = {DOTFONTPATH + "=" + m_GraphVizFontDir};
1.1       barstow   425: 
                    426:         String formatOption = getFormatName(graphFormat, false);
                    427: 
                    428:         String cmdArray[] = {m_GraphVizPath, formatOption, "-o", outputFileName, dotFileName};
                    429:         Runtime rt = Runtime.getRuntime();
                    430:         try {
                    431:             Process p = rt.exec(cmdArray, environment);
                    432:             p.waitFor();
1.10      barstow   433: 
1.1       barstow   434:         } catch (Exception e) {
                    435:             System.err.println("Error: generating OutputFile.");
                    436:             return false;
                    437:         }
                    438:         return true;
                    439:     }
                    440: 
                    441:     /*
                    442:      * Returns a parameter from a request or the parameter's default
                    443:      * value.
                    444:      *
                    445:      *@param req a Servlet request
1.14      barstow   446:      *@param param the name of the parameter
                    447:      *@param defString the string returned if the param is not found
1.1       barstow   448:      *@return if the request contains the specfied parameter its value
                    449:      *  in the request is returned; otherwise its default value is
                    450:      *  returned
                    451:      */
                    452:     private String getParameter(HttpServletRequest req, String param, 
                    453:         String defString) 
                    454:     {
                    455:         String s = req.getParameter(param);
                    456:         return (s == null) ? defString : s;
                    457:     }
                    458: 
                    459:     /*
                    460:      * If the request contains any graph-related parameters, pass them
                    461:      * to the graph consumer for handling
                    462:      *
                    463:      *@param req the response
1.14      barstow   464:      *@param pw the PrintWriter
1.1       barstow   465:      *@param consumer the GraphViz consumer
                    466:      */
1.14      barstow   467:     private void processGraphParameters (HttpServletRequest req, PrintWriter pw)
1.1       barstow   468:     {
1.4       barstow   469:        // Print the graph header
                    470:         pw.println("digraph " + DOT_TITLE + "{ " );
1.1       barstow   471: 
                    472:         // Look for colors
1.4       barstow   473:         String nodeColor     = getParameter(req, NODE_COLOR, 
                    474:                                            DEFAULT_NODE_COLOR);
                    475:         String nodeTextColor = getParameter(req, NODE_TEXT_COLOR, 
                    476:                                            DEFAULT_NODE_TEXT_COLOR);
                    477:         String edgeColor     = getParameter(req, EDGE_COLOR, 
                    478:                                            DEFAULT_EDGE_COLOR);
                    479:         String edgeTextColor = getParameter(req, EDGE_TEXT_COLOR, 
                    480:                                            DEFAULT_EDGE_TEXT_COLOR);
                    481:         String fontSize      = getParameter(req, FONT_SIZE, 
                    482:                                            DEFAULT_FONT_SIZE);
1.1       barstow   483: 
                    484:         // Orientation must be either 
                    485:         String orientation = req.getParameter (ORIENTATION);
                    486:         if (orientation.equals("LR"))
                    487:             orientation = "LR";
                    488:         else
                    489:             orientation = DEFAULT_ORIENTATION;
                    490: 
                    491:         // Add an attribute for all of the graph's nodes
                    492:         pw.println("node [fontname=" + DEFAULT_FONT + 
1.7       barstow   493:                    ",fontsize="  + fontSize +
                    494:                    ",color="     + nodeColor +
1.12      barstow   495:                    ",fontcolor=" + nodeTextColor + "];");
1.1       barstow   496: 
                    497:         // Add an attribute for all of the graph's edges
                    498:         pw.println("edge [fontname=" + DEFAULT_FONT + 
1.8       barstow   499:                    ",fontsize="  + fontSize +
                    500:                    ",color="     + edgeColor +
                    501:                    ",fontcolor=" + edgeTextColor + "];");
1.1       barstow   502: 
                    503:         // Add an attribute for the orientation
                    504:         pw.println("rankdir=" + orientation + ";");
                    505:     }
                    506: 
                    507:     private static class SaxErrorHandler implements org.xml.sax.ErrorHandler
                    508:     { 
1.22      duerst    509:         PrintWriter out;
1.1       barstow   510:         boolean silent = false;
1.5       barstow   511:        String fatalErrors = "";
                    512:        String errors = "";
                    513:        String warnings = "";
1.1       barstow   514: 
                    515:         /*
                    516:          * Constructuor for a SaxErrorHandler 
                    517:          *
1.22      duerst    518:         *@param out the servlet's PrintWriter
1.1       barstow   519:         *@param silent if false, output is suprressed
                    520:          */
1.22      duerst    521:         public SaxErrorHandler(PrintWriter out, boolean silent) 
1.1       barstow   522:         {
                    523:             this.out = out;
                    524:             this.silent = silent;
                    525:         }
                    526: 
                    527:         /*
                    528:          * Create a formatted string from the exception's message
                    529:          *
1.5       barstow   530:         *@param e the SAX Parse Exception
1.1       barstow   531:         *@return a formatted string
                    532:          */
                    533:         private static String format(org.xml.sax.SAXParseException e) 
                    534:         {
                    535:             String msg = e.getMessage();
                    536:             if (msg == null)
                    537:                 msg = e.toString();
                    538:             return msg + "[Line = " + e.getLineNumber() + ", Column = " + e.getColumnNumber() + "]";
                    539:         }
                    540: 
                    541:         /*
                    542:          * Handle a parse error
                    543:          *
1.5       barstow   544:         *@param e the SAX Parse Exception
1.1       barstow   545:         */
                    546:         public void error(org.xml.sax.SAXParseException e) 
                    547:             throws org.xml.sax.SAXException 
                    548:         {
                    549:             if (this.silent) return;
                    550: 
1.5       barstow   551:            this.errors += "Error: " + format(e) + "<br />";
1.1       barstow   552:         }
                    553:     
                    554:         /*
                    555:          * Handle a fatal parse error
                    556:          *
1.5       barstow   557:         *@param e the SAX Parse Exception
1.1       barstow   558:         */
                    559:         public void fatalError(org.xml.sax.SAXParseException e) 
                    560:             throws org.xml.sax.SAXException 
                    561:         {
                    562:             if (this.silent) return;
                    563: 
1.5       barstow   564:            this.fatalErrors += "FatalError: " + format(e) + "<br />";
1.1       barstow   565:         }
                    566:     
                    567:         /*
                    568:          * Handle a parse warning
                    569:          *
1.5       barstow   570:         *@param e the SAX Parse Exception
1.1       barstow   571:         */
                    572:         public void warning(org.xml.sax.SAXParseException e) 
                    573:             throws org.xml.sax.SAXException 
                    574:         {
                    575:             if (this.silent) return;
                    576: 
1.5       barstow   577:            this.warnings += "Warning: " + format(e) + "<br />";
1.1       barstow   578:         }
1.5       barstow   579: 
                    580:         /*
                    581:          * Return the error messages
                    582:          *
                    583:         *@return the error messages or an empty string if there are
                    584:         * no messages
                    585:         */
                    586:        public String getErrors()
                    587:        {
                    588:           return this.errors;
                    589:        }
                    590: 
                    591:         /*
                    592:          * Return the fatal error messages
                    593:          *
                    594:         *@return the fatal error messages or an empty string if there are
                    595:         * no messages
                    596:         */
                    597:        public String getFatalErrors()
                    598:        {
                    599:           return this.fatalErrors;
                    600:        }
                    601: 
                    602:         /*
                    603:          * Return the warning messages
                    604:          *
                    605:         *@return the warning messages or an empty string if there are
                    606:         * no messages
                    607:         */
                    608:        public String getWarnings()
                    609:        {
                    610:           return this.warnings;
                    611:        }
1.1       barstow   612:     } 
                    613: 
                    614:     /*
                    615:      * Generate a graph of the RDF data model
                    616:      *
                    617:      *@param out the servlet's output stream
1.4       barstow   618:      *@param pw the graph file's PrintWriter
                    619:      *@param dotFile the File handle for the graph file
1.1       barstow   620:      *@param rdf the RDF text
                    621:      *@param req a Servlet request
                    622:      *@param graphFormat the graph's format
                    623:      *@param saveRDF the RDF can be cached [saved to the file system]
                    624:      *@param saveDOTFile the DOT file should be cached
                    625:      */
1.22      duerst    626:     private void generateGraph(PrintWriter out, PrintWriter pw,
1.4       barstow   627:        File dotFile, String rdf, HttpServletRequest req, String graphFormat, 
1.1       barstow   628:         boolean saveRDF, boolean saveDOTFile) 
                    629:     {
                    630:         try {
                    631:             out.println("<hr title=\"visualisation\">");
                    632:             out.println("<h3>Graph of the data model</h3>");
                    633: 
                    634:             // The temporary directory
                    635:             String tmpDir = m_ServletTmpDir;
                    636: 
                    637:             // Add the graph footer
                    638:             pw.println( " }");
                    639: 
1.4       barstow   640:             // Close the DOT input file so the GraphViz can
1.1       barstow   641:             // open and read it
                    642:             pw.close();
                    643: 
                    644:             // Generate a unique file name for the output file
                    645:             // that will be created
                    646:             String suffix = getFormatName(graphFormat, true);
                    647:             File outputFile = createTempFile(tmpDir, TMP_FILE_PREFIX, suffix);
                    648:             if (outputFile == null) {
                    649:                 out.println("Failed to create a temporary file for the graph. A graph cannot be generated.");
                    650:                 dotFile.delete();
                    651:                 return;
                    652:             }
                    653: 
                    654:             // Pass the DOT data file to the GraphViz dot program
                    655:             // so it can create a graph image of the data model
                    656:             String dotFileName = dotFile.getAbsolutePath();
                    657:             String outputFileName = outputFile.getAbsolutePath();
                    658: 
1.8       barstow   659:             if (!generateGraphFile(dotFileName, outputFileName, graphFormat)) {
1.1       barstow   660:                 out.println("An attempt to create a graph failed.");
                    661:                 dotFile.delete();
                    662:                 outputFile.delete();
                    663:                 return;
                    664:             }
                    665:             // Handle the DOT file
                    666:             if (saveDOTFile) {
                    667:                 // Make the DOT file link'able if so requested
                    668:                 String dotPath = SERVLET_NAME + SUFFIX_TMP_DIR + 
                    669:                                  File.separator + dotFile.getName();
                    670:                 out.println("<a href=\"" + dotPath + "\">Download the DOT file.</a><br /><br />");
                    671:             }
                    672:             else {
                    673:                 // Delete it ...
                    674:                 dotFile.delete();
                    675:             }
                    676: 
                    677:             // NOTE: Cannot delete the output file here because its
                    678:             // pathname is returned to the client
                    679:             String imagePath = SERVLET_NAME + SUFFIX_TMP_DIR + File.separator + 
                    680:                                outputFile.getName();
                    681: 
                    682:             // Handle the embedded image formats first
                    683:             if (graphFormat.equals(FORMAT_GIF_EMBED) ||
                    684:                 graphFormat.equals(FORMAT_PNG_EMBED)) {
                    685:                 if (outputFile.length() > 0)
                    686:                     out.println("<img src=\"" + imagePath + "\"/>");
                    687:                 else
                    688:                     out.println("The graph image file is empty.");
                    689:             } else {
                    690:                 if (outputFile.length() > 0)
                    691:                     out.println("<a href=\"" + imagePath + "\">Get/view the graph's image file (" + suffix + ").</a><br /><br />");
                    692:                 else
                    693:                     out.println("The graph image file is empty.");
                    694:             }
                    695: 
                    696:             // One last thing to do before exiting - copy the RDF to a file
                    697:             if (saveRDF)
                    698:                 copyRDFStringToFile(tmpDir, rdf);
                    699: 
                    700:         } catch (Exception e) {
                    701:             System.err.println("Exception generating graph: " + e.getMessage());
                    702:         }
                    703:     }
                    704: 
                    705:     /*
                    706:      * Search the given string for substring "key"
                    707:      * and if it is found, replace it with string "replacement"
                    708:      *
                    709:      *@param input the input string
                    710:      *@param key the string to search for
                    711:      *@param replacement the string to replace all occurences of "key"
1.3       barstow   712:      *@return if no substitutions are done, input is returned; otherwise
1.1       barstow   713:      * a new string is returned.
                    714:      */
                    715:     public static String replaceString(String input, String key, 
                    716:         String replacement) 
                    717:     {
1.3       barstow   718:         try {
                    719:             RE re = new RE(key);
                    720:             return re.subst(input, replacement);
1.52    ! duerst    721:         } catch (Exception e) {
1.3       barstow   722:             return input;
1.1       barstow   723:         }
                    724:     }
                    725: 
                    726:     /*
                    727:      * Print the document's header info
                    728:      *
                    729:      *@param out the servlet's output stream
                    730:      */
1.22      duerst    731:     private void printDocumentHeader (PrintWriter out) 
1.1       barstow   732:     {
                    733:         try {
                    734: 
1.6       barstow   735:             out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"" +
                    736:                 "      \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" +
                    737:                 "<html><head>" +
                    738:                 "<title>RDF Validator</title>" +
                    739:                 "<link href='http://www.w3.org/StyleSheets/base.css' rel='stylesheet' type='text/css'/>" +
                    740:                "<style type='text/css'>" +
                    741:                "  TD {" +
                    742:                "    background:#EEEEEE;" +
                    743:                "    font-family:'courier new',courier,serif;" +
                    744:                "  }" +
                    745:                "</style>" +
                    746:                 "</head>" +
                    747:                 "<body>");
1.1       barstow   748: 
                    749:         } catch (Exception e) {
1.8       barstow   750:             System.err.println("Exception (printDocumentHeader): " + e.getMessage());
1.1       barstow   751:         }
                    752:     }
                    753: 
                    754:     /*
                    755:      * Print the rdf listing
                    756:      *
                    757:      *@param out the servlet's output stream
                    758:      *@param rdf the RDF code
1.14      barstow   759:      *@param needCR if true, add a CarriageReturn to the output; if false,
                    760:      * do not add it
1.1       barstow   761:      */
1.22      duerst    762:     private void printListing (PrintWriter out, String rdf, 
1.1       barstow   763:         boolean needCR) 
                    764:     {
                    765:         try {
1.8       barstow   766:             out.println("<hr title=\"original source\">" +
1.29      duerst    767:                         "<h3>The original RDF/XML document</h3>" +
1.8       barstow   768:                         "<pre>");
1.1       barstow   769: 
                    770:             String s = replaceString(rdf, "<", "&lt;");
                    771:             
                    772:             // Now output the RDF one line at a time with line numbers
                    773:             int lineNum = 1;
                    774:             int nl = 0;
                    775:             String terminator = needCR?"\n":"";
                    776:             do {
                    777:                 String tok;
                    778:                 nl = s.indexOf('\n');
                    779:                 if ( nl == -1 ) {
                    780:                     tok = s;
                    781:                 } else {
                    782:                     tok = s.substring(0,nl);
                    783:                     s = s.substring(nl+1);
                    784:                 }
1.8       barstow   785:                 out.print("<a name=\"" + lineNum + "\">" + lineNum +
                    786:                           "</a>: " + tok + terminator);
1.1       barstow   787:                 lineNum++;
                    788:             } while ( nl != -1 );
                    789: 
                    790:             out.println("</pre>");
                    791:         } catch (Exception e) {
1.8       barstow   792:             System.err.println("Exception (printListing): " + e.getMessage());
1.1       barstow   793:         }
                    794:     }
                    795: 
                    796:     /*
                    797:      * Print the header for the triple listing
                    798:      *
                    799:      *@param out the servlet's output stream
1.14      barstow   800:      *@param nTriples if true, output is N-Triples syntax
1.1       barstow   801:      */
1.22      duerst    802:     private void printTripleTableHeader (PrintWriter out, boolean nTriples) 
1.1       barstow   803:     {
                    804:         try {
                    805:             if (nTriples) {
1.6       barstow   806:                 out.println("<h3>Triples of the Data Model in " +
                    807:                    "<a href=\"http://www.w3.org/2001/sw/RDFCore/ntriples/\">" +
                    808:                    "N-Triples</a> Format (Sub, Pred, Obj)</h3>" +
                    809:                    "<pre>");
1.1       barstow   810:             } else {
                    811:                 out.println("<hr title=\"triples\">");
                    812:                 out.println("<h3>Triples of the Data Model</h3>");
                    813:                 out.println("<table border><tr>" +
                    814:                            "<td><b>Number</b></td>" +
                    815:                            "<td><b>Subject</b></td>" +
                    816:                            "<td><b>Predicate</b></td>" +
                    817:                            "<td><b>Object</b></td>" +
                    818:                            "</tr>");
                    819:             }
                    820:         } catch (Exception e) {
1.8       barstow   821:             System.err.println("Exception (printTripleTableHeader): " + e.getMessage());
1.1       barstow   822:         }
                    823:     }
                    824: 
                    825:     /*
                    826:      * Print the footer info for the triple listing
                    827:      *
                    828:      *@param out the servlet's output stream
1.14      barstow   829:      *@param nTriples if true, output is N-Triples syntax
1.1       barstow   830:      */
1.22      duerst    831:     private void printTripleTableFooter (PrintWriter out, 
1.1       barstow   832:         boolean nTriples) 
                    833:     {
                    834:         try {
                    835:             if (nTriples)
                    836:                 out.println("</pre>");
                    837:             else
                    838:                 out.println("</table>");
                    839:         } catch (Exception e) {
1.8       barstow   840:             System.err.println("Exception (printTripleTableFooter): " + e.getMessage());
1.1       barstow   841:         }
                    842:     }
                    843:     
                    844:     /*
                    845:      * Print the document's footer info
                    846:      *
                    847:      *@param out the servlet's output stream
                    848:      *@param rdf the RDF code
                    849:      */
1.22      duerst    850:     private void printDocumentFooter (PrintWriter out, String rdf) 
1.1       barstow   851:     {
                    852:         try {
                    853: 
1.8       barstow   854:             String s;
                    855: 
                    856:             s = "<hr title=\"Problem reporting\">" +
                    857:                 "<h3>Feedback</h3>" +
                    858:                 "<p>If you suspect the parser is in 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>" +
                    859:                 "<form enctype='text/plain' method='post' action='mailto:" + MAIL_TO + "'>" +
1.9       barstow   860:                 "<textarea cols='60' rows='4' name='report'></textarea>";
1.8       barstow   861:             out.println(s);
1.1       barstow   862: 
1.9       barstow   863:             out.println("<input type='hidden' name='RDF' value=\"&lt;?xml version=&quot;1.0&quot;&gt;");
                    864: 
1.1       barstow   865:             // The listing is being passed as a parameter so the '<' 
                    866:             // and '"' characters must be replaced with &lt; and &quot, 
                    867:             // respectively
                    868:             if (rdf != null) {
1.9       barstow   869:                 String s1;
                    870:                 s1 = replaceString(rdf, "<",  "&lt;");
1.11      barstow   871:                 s1 = replaceString(s1,  ">",  "&gt;");
1.9       barstow   872:                 s1 = replaceString(s1,  "\"", "&quot;");
                    873:                 out.println(s1);
1.1       barstow   874:             }
1.9       barstow   875:             out.println("\"\\>");
1.1       barstow   876: 
1.8       barstow   877:             out.println("<input type='submit' value='Submit problem report'\\>" +
1.9       barstow   878:                         "</form></body></html>");
1.1       barstow   879: 
                    880:         } catch (Exception e) {
1.8       barstow   881:             System.err.println("Exception (printDocumentFooter): " + e.getMessage());
1.1       barstow   882:         }
                    883:     }
                    884: 
                    885:     /*
                    886:      * Servlet's get info method
                    887:      */
                    888:     public String getServletInfo () {
                    889:        return "Servlet wrapper for the ARP RDF parser. This is revision " + REVISION;
                    890:     }
                    891: 
                    892:     /*
                    893:      * Servlet's init method
                    894:      *
                    895:      *@param config the servlet's configuration object
                    896:      *@throws ServletException
                    897:      */
                    898:     public void init(ServletConfig config) throws ServletException 
                    899:     {
                    900:        super.init (config);
                    901: 
                    902:         // Cache the parameters
                    903:         m_ServletTmpDir = config.getInitParameter(SERVLET_TMP_DIR);
                    904: 
                    905:         // All of the Graph Viz paths extend from GRAPH_VIZ_ROOT
                    906:         String GraphVizRoot = config.getInitParameter(GRAPH_VIZ_ROOT);
                    907: 
                    908:         m_GraphVizPath = GraphVizRoot + "/" + config.getInitParameter(GRAPH_VIZ_PATH);
                    909:         m_GraphVizFontDir = GraphVizRoot + "/" + config.getInitParameter(GRAPH_VIZ_FONT_DIR);
1.20      duerst    910: System.out.println("GRAPH_VIZ_ROOT   = " + GraphVizRoot);
                    911: System.out.println("GRAPH_VIZ_PATH   = " + m_GraphVizPath);
                    912: System.out.println("GRAPH_VIZ_FNTDIR = " + m_GraphVizFontDir);
                    913: System.out.println("SERVLET_TMP_DIR  = " + m_ServletTmpDir);
1.1       barstow   914: 
                    915:         if (m_ServletTmpDir == null || GraphVizRoot == null) {
                    916:            System.err.println (
                    917:                 "<html>" +
                    918:                 "<h1>Servlet Initialization Error</h1>" +
                    919:                 "<h2>One or more of the following parameters has not been initialized: " + 
                    920:                 SERVLET_TMP_DIR + "," + GRAPH_VIZ_ROOT + "," +
1.16      barstow   921:                 GRAPH_VIZ_FONT_DIR + "," + GRAPH_VIZ_PATH + "." +
1.1       barstow   922:                 "</h2>" +
                    923:                 "</html>");
                    924:         }
                    925:     }
                    926: 
                    927:     /*
                    928:      * Servlet's destroy info method
                    929:      */
                    930:     public void destroy () {
                    931:        super.destroy ();
                    932:     }
                    933: 
                    934:     /*
                    935:      * Servlet's doGet info method - NOT supported
                    936:      *
                    937:      *@param req the request
                    938:      *@param res the response
                    939:      *@throws ServletException, IOException
                    940:      */
                    941:     public void doGet (HttpServletRequest req, HttpServletResponse res)
                    942:         throws ServletException, IOException 
                    943:     {
                    944:         String sRDF = req.getParameter(TEXT);
                    945:        String sURI = req.getParameter(URI);
                    946: 
                    947:         if (sURI == null && sRDF == null) {
1.22      duerst    948:             res.setContentType ("text/html;charset=utf-8");
                    949:            PrintWriter out = res.getWriter ();
1.1       barstow   950: 
1.6       barstow   951:             out.println("<h1>Data Error</h1>" +
                    952:                 "Must specify the RDF (RDF is a string) or the URI parameter." +
                    953:                 "</h1>");
1.1       barstow   954:             return;
                    955:         }
                    956: 
1.20      duerst    957:        try {
                    958:             process(req, res, 
                    959:                     (sRDF != null) ? java.net.URLDecoder.decode(sRDF) : null, 
                    960:                     (sURI != null) ? java.net.URLDecoder.decode(sURI) : null);
                    961:        } catch (Exception e) {
                    962:             System.err.println("Exception: URLDecoder.decode()");
                    963:        }
1.1       barstow   964:     }
                    965: 
                    966:     /*
                    967:      * Servlet's doPost method
                    968:      *
                    969:      *@param req the request
                    970:      *@param res the response
1.17      duerst    971:      *@throws ServletException, IOException, java.io.UnsupportedEncodingException
1.1       barstow   972:      */
                    973:     public void doPost (HttpServletRequest req, HttpServletResponse res)
                    974:         throws ServletException, IOException 
                    975:     {
1.19      duerst    976:        // String encoding = req.getCharacterEncoding();
                    977:         // if (encoding == null) {
                    978:        //    req.setCharacterEncoding("UTF-8");
                    979:        // }
1.52    ! duerst    980:        String sRDF = new String(req.getParameter(TEXT).getBytes("iso-8859-1"), "utf-8");
1.35      duerst    981:        String sURI = new String(req.getParameter(URI).getBytes("iso-8859-1"), "utf-8");
1.1       barstow   982: 
                    983:         if (sURI == null && sRDF == null) {
1.22      duerst    984:             res.setContentType ("text/html;charset=utf-8");
                    985:            PrintWriter out = res.getWriter ();
1.1       barstow   986: 
                    987:             out.println("<h1>Neither the RDF or an URI was specified" + 
                    988:                         "and one of them must be specified.</h1>");
                    989:             return;
                    990:         }
                    991: 
                    992:         process(req,res,sRDF, sURI);
                    993:     }
                    994: 
                    995:     /*
                    996:      * Output a Resource in NTriples syntax
                    997:      *
                    998:      *@param out the servlet's output stream
                    999:      *@param r the Resource to output
                   1000:      */
1.22      duerst   1001:     static private void printResource(PrintWriter out, AResource r)
1.1       barstow  1002:     {
1.26      duerst   1003:         if (r.isAnonymous() )
                   1004:             out.print("_:j" + r.getAnonymousID() + " ");
                   1005:         else
                   1006:            out.print("&lt;" + r.getURI() + "&gt; ");
1.1       barstow  1007:     }
                   1008: 
                   1009:     /*
1.18      duerst   1010:      * Convert to Hex and padd left with zeroes
                   1011:      *
                   1012:      *@param in the integer to convert and padd
                   1013:      *@param in the length of the result
                   1014:      *@return the padded string
                   1015:      */
                   1016:      // MJD: is there an easier way to do this?
1.20      duerst   1017:     static private String hexPadd (int number, int length)
1.18      duerst   1018:     {
                   1019:        String t = Integer.toHexString(number).toUpperCase();
1.20      duerst   1020:        int hexlength = t.length();
1.18      duerst   1021: 
                   1022:         if ( hexlength > length ) {    // too long, truncate
                   1023:            hexlength = length;
                   1024:        }
                   1025: 
1.20      duerst   1026:        int zerolength = length - hexlength;
1.18      duerst   1027:        String r = "";
                   1028: 
                   1029:        for (int i=0; i < zerolength; i++) {
                   1030:            r += "0";
                   1031:        }
                   1032:        for (int i=0; i < hexlength; i++) {
1.24      duerst   1033:            r += t.charAt(i);
1.18      duerst   1034:        }
                   1035:        return r;
                   1036:     }
                   1037: 
                   1038:     /*
1.1       barstow  1039:      * Output a Literal in NTriples syntax
                   1040:      *
                   1041:      *@param out the servlet's output stream
                   1042:      *@param l the Literal to output
                   1043:      */
1.22      duerst   1044:     static private void printNTripleLiteral(PrintWriter out, ALiteral l) 
1.1       barstow  1045:     {
1.28      duerst   1046:         out.print("\"");
                   1047:         char ar[] = l.toString().toCharArray();
1.1       barstow  1048: 
1.28      duerst   1049:         for (int i=0;i<ar.length;i++) {
                   1050:             switch (ar[i]) {
                   1051:                 case '\\':
                   1052:                     out.print("\\\\");
                   1053:                     break;
                   1054:                 case '"':
                   1055:                     out.print("\\\"");
                   1056:                     break;
                   1057:                 case '\n':
                   1058:                     out.print("\\n");
                   1059:                     break;
                   1060:                 case '\r':
                   1061:                     out.print("\\r");
                   1062:                     break;
                   1063:                 case '\t':
                   1064:                     out.print("\\t");
                   1065:                     break;
                   1066:                 default:
                   1067:                     if ( ar[i] >= 32 && ar[i] <= 127 )
                   1068:                         out.print(ar[i]);
                   1069:                     else if ( ar[i] < 0xD800 || ar[i] >= 0xE000)
                   1070:                        out.print("\\u" + hexPadd(ar[i], 4) );
                   1071:                    else  {  // deal with surrogates
                   1072:                             // check for correct surrogate pair
                   1073:                              // this code should probably move somewhere else:
                   1074:                              // check when we get the input
                   1075:                         if ( ar[i] >= 0xDC00 ) {
                   1076:                            out.print("{{{error: lone low surrogate}}}");
1.18      duerst   1077:                        }
1.28      duerst   1078:                        else if ( ++i >= ar.length ) {
                   1079:                             out.print("{{{error: lone surrogate at end of string}}}");
                   1080:                        }
                   1081:                        else if ( ar[i] < 0xDC00 || ar[i] >= 0xE000 ) {
                   1082:                            out.print("{{{error: high surrogate not followed by low surrogate}}}");
                   1083:                        }
                   1084:                        // no errors, actually print
                   1085:                        else {
                   1086:                            int scalarvalue = 0x10000 + (ar[i-1] * 1024) + ar[i];
                   1087:                            out.print("\\U" + hexPadd(scalarvalue, 8) );
                   1088:                        }
                   1089:                    }
1.1       barstow  1090:             }
1.28      duerst   1091:         }
                   1092:         out.print("\" ");
1.1       barstow  1093:     }
                   1094: 
                   1095:     /*
                   1096:      * Control point for outputing an triple in NTriple syntax
                   1097:      *
                   1098:      *@param out the servlet's output stream
                   1099:      *@param subj the subject
                   1100:      *@param pred the predicate
                   1101:      *@param objRes the object as a Resource (may be null)
                   1102:      *@param objLit the object as a Literal (may be null)
                   1103:      */
1.22      duerst   1104:     static private void printNTriple(PrintWriter out, AResource subj, 
1.1       barstow  1105:         AResource pred, AResource objRes, ALiteral objLit) 
                   1106:     {
1.27      duerst   1107:         printResource(out, subj);
                   1108:         printResource(out, pred);
                   1109:         if (objRes != null)
                   1110:             printResource(out, objRes);
                   1111:         else
                   1112:             printNTripleLiteral(out, objLit);
                   1113:         out.println(".");
1.1       barstow  1114:     }
                   1115: 
                   1116:     /*
                   1117:      * Create a HTML anchor from the URI or anonNode of the
                   1118:      * given Resource
                   1119:      *
1.14      barstow  1120:      *@param r the Resource
1.1       barstow  1121:      *@return the string as an HTML anchor
                   1122:      */
                   1123:     static private String addAnchor(AResource r) 
                   1124:     {
                   1125:         if (r.isAnonymous())
1.14      barstow  1126:             return ANON_NODE + r.getAnonymousID();
1.1       barstow  1127:         else
                   1128:             return "<a href='" + r.getURI() + "'>" + r.getURI() + "</a>";
                   1129:     }
                   1130: 
                   1131:     /*
                   1132:      * Output a triple as a row in HTML
                   1133:      *
                   1134:      *@param out the servlet's output stream
                   1135:      *@param subj the subject
                   1136:      *@param pred the predicate
                   1137:      *@param objRes the object as a Resource (may be null)
                   1138:      *@param objLit the object as a Literal (may be null)
                   1139:      *@param num the statement number
                   1140:      */
1.22      duerst   1141:     static private void printTableRow(PrintWriter out, AResource subj, 
1.1       barstow  1142:         AResource pred, AResource objRes, ALiteral objLit, int num) 
                   1143:     {
1.27      duerst   1144:         out.println("<tr><td>" + num + "</td>");
                   1145:         out.println("<td>" + addAnchor(subj) + "</td>");
                   1146:         out.println("<td>" + addAnchor(pred) + "</td>");
                   1147:         if (objRes != null)
                   1148:             out.println("<td>" + addAnchor(objRes) + "</td>");
                   1149:         else {
                   1150:             out.println("<td>");
                   1151:             String s1 = objLit.toString().trim();
                   1152:             s1 = replaceString(s1, "<", "&lt;");
                   1153:             s1 = replaceString(s1, ">", "&gt;");
                   1154:             out.println(s1);
                   1155:             out.println("</td>");
                   1156:         }
                   1157:         out.println("</tr>");
1.1       barstow  1158:     }
                   1159: 
1.4       barstow  1160:     private static class SH implements StatementHandler 
1.1       barstow  1161:     {
1.22      duerst   1162:         PrintWriter out;
1.12      barstow  1163:         PrintWriter pw;
1.1       barstow  1164:         boolean isNTriples;
1.12      barstow  1165:         boolean printTriples;
                   1166:         boolean printGraph;
                   1167:         boolean anonNodesEmpty;
1.14      barstow  1168:         int numStatements;
                   1169:         int numLiterals;
                   1170:        Hashtable subjects;
                   1171:        int numSubjects;
1.1       barstow  1172:   
                   1173:         /*
1.4       barstow  1174:          * Constructuor for the StatementHandler.  The primary
                   1175:         * responsiblitly is to cache init variables
1.1       barstow  1176:          *
1.22      duerst   1177:         *@param out the servlet's PrintWriter
1.4       barstow  1178:         *@param pw the Dot file's PrintWriter
1.1       barstow  1179:         *  syntax; otherwise use HTML syntax
1.12      barstow  1180:         *@param isNTriples if true, output using the NTriples
                   1181:         *@param printTriples if true, print the triples
                   1182:         *@param printGraph if true, create the graph file
                   1183:         *@param printGraph if true, anonomyous nodes should be empty
1.1       barstow  1184:         */
1.22      duerst   1185:         public SH(PrintWriter out, PrintWriter pw, boolean isNTriples, 
1.12      barstow  1186:             boolean printTriples, boolean printGraph, boolean anonNodesEmpty)
1.1       barstow  1187:         {
                   1188:             this.out = out;
1.12      barstow  1189:             this.pw = pw;
1.1       barstow  1190:             this.isNTriples = isNTriples;
1.12      barstow  1191:             this.printTriples = printTriples;
                   1192:             this.printGraph = printGraph;
                   1193:             this.anonNodesEmpty = anonNodesEmpty;
1.14      barstow  1194: 
                   1195:             this.numStatements = 0;
                   1196:             this.numLiterals = 0;
                   1197: 
                   1198:            this.subjects = new Hashtable();
                   1199:            this.numSubjects = 0;
1.4       barstow  1200:         }
                   1201: 
                   1202:         /*
                   1203:          * Generic handler for a Resource/Resource/Resource triple (S/P/O).
                   1204:         * Dispatches to the methods that do the real work.
                   1205:          *
                   1206:         *@param subj the subject
                   1207:         *@param pred the predicate
                   1208:         *@param obj the object (as a Resource)
                   1209:         */
                   1210:         public void statement(AResource subj, AResource pred, AResource obj) 
                   1211:         {
1.12      barstow  1212:            if (printTriples)
                   1213:                 statementResource(subj, pred, obj);
                   1214:            if (printGraph)
                   1215:                statementDotResource(subj, pred, obj);
1.4       barstow  1216:         }
                   1217: 
                   1218:         /*
                   1219:          * Generic handler for a Resource/Resource/Resource triple (S/P/O).
                   1220:         * Dispatches to the methods that do the real work.
                   1221:          *
                   1222:         *@param subj the subject
                   1223:         *@param pred the predicate
                   1224:         *@param obj the object (as a Literal)
                   1225:         */
                   1226:         public void statement(AResource subj, AResource pred, ALiteral lit) 
                   1227:         {
1.13      barstow  1228:             numLiterals++;
                   1229: 
1.12      barstow  1230:            if (printTriples)
                   1231:                 statementLiteral(subj, pred, lit);
                   1232:            if (printGraph)
                   1233:                 statementDotLiteral(subj, pred, lit);
1.1       barstow  1234:         }
                   1235: 
                   1236:         /*
                   1237:          * Handler for a Resource/Resource/Resource triple (S/P/O)
                   1238:         * Outputs the given triple using NTriples or HTML syntax.
                   1239:          *
                   1240:         *@param subj the subject
                   1241:         *@param pred the predicate
                   1242:         *@param obj the object (as a Resource)
                   1243:         */
1.4       barstow  1244:         public void statementResource(AResource subj, AResource pred, AResource obj) 
1.1       barstow  1245:         {
                   1246:             numStatements++;
                   1247: 
                   1248:             if (this.isNTriples)
                   1249:                 printNTriple(out, subj, pred, obj, null);
                   1250:             else
                   1251:                 printTableRow(out, subj, pred, obj, null, this.numStatements);
                   1252:         }
1.4       barstow  1253: 
1.1       barstow  1254:         /*
                   1255:          * Handler for a Resource/Resource/Literal triple (S/P/O)
                   1256:         * Outputs the given triple using NTriples or HTML syntax.
                   1257:          *
                   1258:         *@param subj the subject
                   1259:         *@param pred the predicate
                   1260:         *@param obj the object (as a Literal)
                   1261:         */
1.4       barstow  1262:         public void statementLiteral(AResource subj, AResource pred, ALiteral lit) 
1.1       barstow  1263:         {
                   1264:             numStatements++;
                   1265: 
                   1266:             if (this.isNTriples)
                   1267:                 printNTriple(out, subj, pred, null, lit);
                   1268:             else
                   1269:                 printTableRow(out, subj, pred, null, lit, this.numStatements);
                   1270:         }
1.4       barstow  1271: 
1.12      barstow  1272:        /* 
                   1273:         * Print the first part of a triple's Dot file.  See below for
                   1274:         * more info.  This is the same regardless if the triple's
                   1275:         * object is a Resource or a Literal
                   1276:         *
                   1277:         *@param subj the subject
                   1278:         */
                   1279:         public void printFirstPart(AResource subj) 
                   1280:        {
1.14      barstow  1281:             if (subj.isAnonymous()) {
1.12      barstow  1282:                if (this.anonNodesEmpty) {
1.14      barstow  1283:                    Integer n = (Integer) subjects.get(subj.getAnonymousID());
                   1284:                    if (n == null) {
                   1285:                        this.numSubjects++;
                   1286:                        subjects.put(subj.getAnonymousID(), new Integer(this.numSubjects));
                   1287:                         this.pw.println("\"" + ANON_NODE + 
                   1288:                            subj.getAnonymousID() + "\" [label=\"   \"];");
                   1289:                    }
1.12      barstow  1290:                }
1.14      barstow  1291:                 this.pw.print("\"" + ANON_NODE + subj.getAnonymousID());
1.12      barstow  1292:             } else {
                   1293:                 this.pw.println("\"" + subj.getURI() + "\" [URL=\"" +
                   1294:                    subj.getURI() + "\"];");
                   1295:                 this.pw.print("\"" + subj.getURI());
                   1296:             }
                   1297:        }
                   1298: 
1.4       barstow  1299:         /*
                   1300:          * Handler for a Resource/Resource/Resource triple (S/P/O).
                   1301:         * Outputs the given triple using Dot syntax.
1.12      barstow  1302:         *
                   1303:         * Each triple will be output in three lines of DOT code as
                   1304:         * follows (not including the complication of anon nodes 
                   1305:         * and the possiblity that the anon nodes may be named 
                   1306:         * with an empty string):
                   1307:         *
                   1308:         *   1. "<subject>" [URL="<subject">];
                   1309:         *   2. "<subject>" -> "<object>" [label="<predicate>",URL="<predicate>"];
                   1310:         *   3. "<object>"  [URL="<object>"];
1.4       barstow  1311:          *
                   1312:         *@param subj the subject
                   1313:         *@param pred the predicate
                   1314:         *@param obj the object (as a Resource)
                   1315:         */
                   1316:         public void statementDotResource(AResource subj, AResource pred, AResource obj) 
                   1317:         {
                   1318:            if (this.pw == null) return;
                   1319: 
1.12      barstow  1320:            printFirstPart(subj);
                   1321:            
                   1322:             this.pw.print("\" -> ");
1.4       barstow  1323: 
1.7       barstow  1324:             if (obj.isAnonymous()) {
1.12      barstow  1325:                if (this.anonNodesEmpty) {
1.14      barstow  1326:                     this.pw.println("\"" + ANON_NODE + 
1.15      barstow  1327:                        obj.getAnonymousID() + 
                   1328:                        "\" [label=\"" + pred.getURI() + "\",URL=\"" + 
                   1329:                        pred.getURI() + "\"];");
1.12      barstow  1330:                } else {
1.15      barstow  1331:                     this.pw.println("\"" + ANON_NODE + obj.getAnonymousID() + 
                   1332:                        "\" [label=\"" + pred.getURI() + "\",URL=\"" + 
                   1333:                        pred.getURI() + "\"];");
1.12      barstow  1334:                }
1.7       barstow  1335:             } else {
1.14      barstow  1336:                 this.pw.println("\"" + obj.getURI() + "\" [label=\"" +
                   1337:                    pred.getURI() + "\",URL=\"" + pred.getURI() + "\"];");
1.12      barstow  1338:                this.pw.println("\"" + obj.getURI() + "\" [URL=\"" +
                   1339:                    obj.getURI() + "\"];");
1.14      barstow  1340:            }
1.4       barstow  1341:         }
                   1342: 
                   1343:         /*
                   1344:          * Handler for a Resource/Resource/Literal triple (S/P/O).
                   1345:         * Outputs the given triple using Dot syntax.
1.12      barstow  1346:         *
                   1347:         * Each triple will be output in three lines of DOT code as
                   1348:         * follows (not including the complication of anon nodes 
                   1349:         * and the possiblity that the anon nodes may be named 
                   1350:         * with an empty string):
                   1351:          *
                   1352:         *   1. "<subject>" [URL="<subject">];
                   1353:         *   2. "<subject>" -> "<literal>" [label="<predicate>",URL="<predicate>"];
                   1354:         *   3. "<literal>" [shape="box"];
1.4       barstow  1355:          *
                   1356:         *@param subj the subject
                   1357:         *@param pred the predicate
                   1358:         *@param obj the object (as a Literal)
                   1359:         */
                   1360:         public void statementDotLiteral(AResource subj, AResource pred, ALiteral lit) 
                   1361:         {
                   1362:            if (this.pw == null) return;
                   1363: 
1.12      barstow  1364:            printFirstPart(subj);  // Same as Res/Res/Res
1.4       barstow  1365: 
                   1366:             /*
                   1367:              * Before outputing the object (Literal) do the following:
                   1368:              *
                   1369:              * o GraphViz/DOT cannot handle embedded line terminators characters
                   1370:              *   so they must be replaced with spaces
                   1371:              * o Limit the number of chars to make the graph legible
                   1372:              * o Escape double quotes
                   1373:              */
                   1374:             String s1 = new String(lit.toString());
                   1375:             s1 = s1.replace('\n', ' ');
                   1376:             s1 = s1.replace('\f', ' ');
                   1377:             s1 = s1.replace('\r', ' ');
                   1378:             if (s1.indexOf('"') != -1)
                   1379:                 s1 = replaceString(s1, "\"", "\\\"");
                   1380: 
                   1381:             // Anything beyond 80 chars makes the graph too large
                   1382:             String tmpObject;
                   1383:             if (s1.length() >= 80)
                   1384:                 tmpObject = s1.substring(0, 80) + " ...";
                   1385:             else
                   1386:                 tmpObject = s1.substring(0, s1.length());
                   1387: 
1.13      barstow  1388:            // Create a temporary label for the literal so that if
                   1389:            // it is duplicated it will be unique in the graph and
                   1390:            // thus have its own node.
                   1391:            String tmpName = "Literal_" + Integer.toString(this.numLiterals);
                   1392:             this.pw.print("\" -> \"" + tmpName);
1.4       barstow  1393: 
1.14      barstow  1394:             this.pw.println("\" [label=\"" + pred.getURI() + 
                   1395:                            "\",URL=\""    + pred.getURI() + "\"];");
1.4       barstow  1396: 
1.13      barstow  1397:             this.pw.println("\"" + tmpName + "\" [shape=box,label=\"" + tmpObject + "\"];");
1.4       barstow  1398:         }
                   1399:     }
                   1400: 
1.22      duerst   1401:     private void printErrorMessages(PrintWriter out, SaxErrorHandler eh)
1.5       barstow  1402:     {
                   1403:        try {
                   1404:            String s;
                   1405: 
                   1406:            s = eh.getFatalErrors();
                   1407:            if (s != null && s.length() >= 1)
                   1408:                out.println("<h2>Fatal Error Messages</h2>" + s);
                   1409: 
                   1410:            s = eh.getErrors();
                   1411:            if (s != null && s.length() >= 1)
                   1412:                out.println("<h2>Error Messages</h2>" + s);
                   1413: 
                   1414:            s = eh.getWarnings();
                   1415:            if (s != null && s.length() >= 1)
                   1416:                out.println("<h2>Warning Messages</h2>" + s);
                   1417:        } catch (Exception e) {
                   1418:            System.err.println(SERVLET_NAME + ": Error printing error messages.");
                   1419:        }
                   1420:     }
                   1421: 
                   1422:     /*
                   1423:      * Initialize the graph output file.  If an error occurs, this
                   1424:      * function will print an error message.
                   1425:      *
                   1426:      *@param out the servlet's output stream
                   1427:      *@req the servlet request object
                   1428:      *@return the File object for the graph file; null if an error occurs
                   1429:      */
1.22      duerst   1430:     private File initGraphFile(PrintWriter out, 
1.4       barstow  1431:        HttpServletRequest req)
                   1432:     {
                   1433:         try {
                   1434:             // Stop if any of the parameters are missing
                   1435:             if (m_ServletTmpDir   == null || 
                   1436:                 m_GraphVizPath    == null || 
1.16      barstow  1437:                 m_GraphVizFontDir == null)
1.4       barstow  1438:            {
                   1439:                 // Put the paths in a comment in the returned content
                   1440:                 out.println("<!-- SERVLET_TMP_DIR = " + m_ServletTmpDir);
                   1441:                 out.println("GRAPH_VIZ_PATH = " + m_GraphVizPath);
                   1442:                 out.println("GRAPH_FONT_DIR  = " + m_GraphVizFontDir + " -->");
                   1443: 
1.12      barstow  1444:                 out.println("<h1>Servlet initialization failed</h1>");
                   1445:                out.println("Please send a message to <a href='mailto:" + MAIL_TO +  "'>" + MAIL_TO + "</a> and mention this problem.");
1.4       barstow  1446:                 return null;
                   1447:             } 
                   1448:        } catch (Exception e) {
                   1449:            System.err.println("Unable to create a temporary graph file. A graph cannot be generated.");
                   1450:            return null;
                   1451:        }
                   1452: 
                   1453:         File dotFile = null;
                   1454: 
1.27      duerst   1455:         // Must generate a unique file name that the DOT handler will use 
                   1456:         dotFile = createTempFile(m_ServletTmpDir, TMP_FILE_PREFIX, SUFFIX_DOT);
                   1457:         if (dotFile == null) {
                   1458:             out.println("<h1>Failed to create a temporary graph file. A graph cannot be generated.</h1>");
                   1459:             return null;
                   1460:         }
1.4       barstow  1461: 
                   1462:        return dotFile;
1.1       barstow  1463:     }
1.6       barstow  1464: 
                   1465:     /*
                   1466:      * Check if the given URI is supported or not
                   1467:      *
                   1468:      *@param out the servlet's output stream
                   1469:      *@param uri the URI to check
                   1470:      *@return true if the URI is supported; false otherwise
                   1471:      */
1.22      duerst   1472:     private boolean isURISupported(PrintWriter out, String uri)
1.6       barstow  1473:     {
                   1474:        try {
                   1475:            if (uri.length() >= 4 && uri.substring(0,4).equalsIgnoreCase("file")) {
                   1476:                out.println("<h1>file URI Schemes are NOT Supported</h1>");
                   1477:                out.println("URIs from the 'file' URI scheme are not supported by this servlet.");
                   1478:                return false;
                   1479:            }
                   1480:         } catch (Exception e) {
                   1481:            System.err.println("Exception in isURISupported.");
                   1482:            return false;
                   1483:        }
                   1484: 
                   1485:        return true;
                   1486:     }
1.1       barstow  1487:     
                   1488:     /*
                   1489:      * Handle the servlets doGet or doPut request
                   1490:      *
                   1491:      *@param req the servlet's request
                   1492:      *@param res the servlet's response
                   1493:      *@throws SevletException, IOException
                   1494:      */
                   1495:     private void process(HttpServletRequest req, HttpServletResponse res, 
1.52    ! duerst   1496:         String sRDF, String sURI) throws ServletException, IOException 
1.1       barstow  1497:     {
1.21      duerst   1498:         res.setContentType ("text/html;charset=utf-8");
1.52    ! duerst   1499:         PrintWriter out = res.getWriter ();
1.10      barstow  1500: 
1.12      barstow  1501:        String sSaveRDF         = req.getParameter (SAVE_RDF);
                   1502:        String sSaveDOTFile     = req.getParameter (SAVE_DOT_FILE);
                   1503:        String sFormat          = req.getParameter (FORMAT);
                   1504:        String sNTriples        = req.getParameter (NTRIPLES);
                   1505:        String sEmbedded        = req.getParameter (EMBEDDED_RDF);
                   1506:        String sTriplesAndGraph = req.getParameter (TRIPLES_AND_GRAPH);
                   1507:        String sAnonNodesEmpty  = req.getParameter (ANON_NODES_EMPTY);
                   1508: 
                   1509:         // Set the print flags
                   1510:         boolean printTriples = true;
                   1511:        boolean printGraph = true;
                   1512:        if (sTriplesAndGraph != null) {
                   1513:            if (sTriplesAndGraph.equals(PRINT_TRIPLES)) 
                   1514:                printGraph = false;
                   1515:            if (sTriplesAndGraph.equals(PRINT_GRAPH))
                   1516:                printTriples = false;
                   1517:        } 
1.1       barstow  1518: 
1.12      barstow  1519:        // Determine if printing the triples and/or graph
                   1520:         boolean anonNodesEmpty = (sAnonNodesEmpty != null) ? true : false;
1.1       barstow  1521:         boolean nTriples = (sNTriples != null) ? true : false;
1.12      barstow  1522: 
1.10      barstow  1523:         // ARP parser has embedded = true by default so if user
                   1524:         // wants embedding, must set it to false
                   1525:         boolean embedded = (sEmbedded != null) ? false : true;
1.1       barstow  1526: 
                   1527:         String sError = null;
                   1528:         String xmlBase = DEFAULT_NAMESPACE;
                   1529: 
                   1530:         printDocumentHeader (out);
                   1531:         
                   1532:         if (sURI != null && sURI.length() >= 1) {
1.6       barstow  1533: 
                   1534:            // First check for unsupported URIs
                   1535:            if (!isURISupported(out, sURI)) {
                   1536:                 printDocumentFooter(out, null);
                   1537:                 return;
                   1538:            }
                   1539: 
1.1       barstow  1540:             xmlBase = sURI;
1.52    ! duerst   1541:            sRDF = getRDFfromURI(sURI);
        !          1542:            if (sRDF == null)
        !          1543:                sError = "error";
        !          1544:         }
1.1       barstow  1545: 
                   1546:         if (sError != null) {
1.6       barstow  1547:             out.println("<h1>RDF Load Error</h1>");
1.52    ! duerst   1548:             out.println("An attempt to load the RDF from URI '" + sURI + "' failed.  (The URI may not exist or the server is down.)");
1.1       barstow  1549:             printDocumentFooter(out, null);
                   1550:             return;
                   1551:         }
1.4       barstow  1552:  
                   1553:        PrintWriter pw = null; // The writer for the graph file
                   1554:        File dotFile = null;   // The graph file
1.12      barstow  1555:         if (sFormat != null && printGraph) {
1.4       barstow  1556:            dotFile = initGraphFile(out, req);
                   1557:            if (dotFile == null)
                   1558:                // Assume error has been reported
                   1559:                return;
                   1560: 
                   1561:             // Create a PrintWriter for the DOT handler
1.52    ! duerst   1562:             FileWriter fw = new FileWriter(dotFile);
1.4       barstow  1563:            if (fw != null)
                   1564:                 pw = new PrintWriter(fw);
                   1565:            if (pw != null)
                   1566:                 // Add the graph header
                   1567:                 processGraphParameters (req, pw);
                   1568:        }
                   1569: 
                   1570:        // Create the StatementHandler - it will handle triples for
                   1571:        // the table/ntriples and the graph file
1.12      barstow  1572:         SH sh = new SH(out, pw, nTriples, printTriples, printGraph, anonNodesEmpty);
1.4       barstow  1573: 
                   1574:         // Create the ErrorHandler 
                   1575:         SaxErrorHandler errorHandler = new SaxErrorHandler(out, false);
                   1576: 
                   1577:         // Create and initialize the parser
                   1578:        ARP parser = new com.hp.hpl.jena.rdf.arp.ARP();
                   1579:         parser.setErrorHandler(errorHandler);
                   1580:         parser.setStatementHandler(sh);
1.10      barstow  1581:         parser.setEmbedding(embedded);
1.1       barstow  1582: 
                   1583:         printListing (out, sRDF, sURI != null && sURI.length() >= 1);
1.12      barstow  1584: 
                   1585:         if (printTriples)
                   1586:             printTripleTableHeader (out, nTriples);
1.1       barstow  1587: 
                   1588:         try {
1.52    ! duerst   1589:            StringReader  sr = new StringReader (sRDF);
        !          1590:            parser.load(sr, xmlBase);
1.1       barstow  1591:         } catch (Exception ex) {
                   1592:             sError = "Exception parsing: " + sURI + ": " + ex.toString();
                   1593:         }
                   1594: 
1.12      barstow  1595:         if (printTriples)
                   1596:             printTripleTableFooter(out, nTriples);
1.5       barstow  1597: 
                   1598:        printErrorMessages(out, errorHandler);
1.1       barstow  1599: 
                   1600:         if (sError != null) {
1.6       barstow  1601:            out.println ("<h1>Parser Loading Error</h1>");
                   1602:            out.println (sError);
1.1       barstow  1603:             printDocumentFooter(out, null);
                   1604:             return;
                   1605:         }
                   1606: 
1.52    ! duerst   1607:         res.flushBuffer();
1.12      barstow  1608:         if (sFormat != null && printGraph) {
1.4       barstow  1609:             generateGraph(out, pw, dotFile, sRDF, req, sFormat,
1.1       barstow  1610:                           (sSaveRDF != null) ? true : false,
                   1611:                           (sSaveDOTFile != null && sSaveDOTFile.equals ("on") ? true : false));
                   1612:         }
                   1613: 
                   1614: 
1.9       barstow  1615:         if (sURI != null && sURI.length() >= 1)
                   1616:             printDocumentFooter(out, null);
                   1617:         else
                   1618:             printDocumentFooter(out, sRDF);
1.1       barstow  1619:     }
                   1620: }

Webmaster