Annotation of java/classes/org/w3c/rdf/examples/SiRPACServlet.java, revision 1.20

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

Webmaster