Sourcecode Listing of
NeumesXSLTServlet.java
Color Key : [•] XML code
[•] string literal
Line
0001 /**
0002 * @(#)NeumesXSLTServlet.java
0003 * @version 1.2, 10 April 2006
0004 * @author Louis W. G. Barton
0005 * University of Oxford
0006 * e-mail: louis.barton.je.77@aya.yale.edu
0007 * @author Tillman Weyde
0008 *
0009 * Abstract:
0010 * For the NEUMES Project
0011 * (Neumed and Ecphonetic Universal Manuscript Encoding Standard).
0012 *
0013 * A. Background
0014 * - The content of medieval chant manuscripts are transcribed to
0015 * NeumesXML file format. Such files can be used for a variety of
0016 * purposes, one of which is visualization.
0017 * - In principle, a NeumesXML file can be directly accessed on the Web
0018 * by its URL. In such cases, the client-side browser performs the
0019 * 'parse/validation' of the file, then invokes an XSLT transformation,
0020 * which pushes a plain HTML visualization of the transcription to the
0021 * client's browser.
0022 * - The NeumesXML DTD and XSLT files reside on the Scribe server and
0023 * are addressed in a NeumesXML file by their respective URIs.
0024 * - In practice, however, many browsers in the field do not support
0025 * XSLT, or they do the parsing and transformation in a manner not
0026 * consistent with current standards.
0027 * - In order to make transcriptions available for viewing by the greatest
0028 * number of users, the NeumesXSLTServlet class performs these XML functions
0029 * for the user on the www.scribeserver.com server, and simply pushes the
0030 * resulting HTML output to the client.
0031 * - This Java program runs on the Scribe server as a servlet within the
0032 * Tomcat or JRun servlet service.
0033 *
0034 * B. Functionality
0035 * - From an HTML menu page on the NEUMES Web site, the user is given a
0036 * choice of three processing options:
0037 * 1. View a transcription on the Scribe server (such as the Aquitanian
0038 * "Dextera domini fecit virtutem") by attempting the 'parse/validate" and
0039 * XSLT transformation in the client browser (in which case this servlet
0040 * is not invoked).
0041 * 2. View a transcription on the Scribe server (such as the Aquitanian
0042 * "Dextera domini fecit virtutem") by having this servlet do the
0043 * 'parse/validate' and XSLT transformation, then push the resulting
0044 * HTML page to the client browser.
0045 * 3. Upload a NeumesXML transcription from user's local disk to the
0046 * Scribe server for processing, which results in an HTML visualization
0047 * of that transcription being pushed to the user's browser.
0048 * - The servlet checks to see whether there is an HTTP request parameter
0049 * called "com" and whether its value is "transfer_upload".
0050 * - If true, then the servlet attempts to retrieve the uploaded file
0051 * and submit it for 'parse/validation' and XSLT transformation here.
0052 *
0053 * Acknowledgments:
0054 * - This program was derived from SimpleXSLTServlet.java, which is a
0055 * sample program provided with Xalan-Java2 (http://www.apache.org/).
0056 * - The Xalan class package (javax.xml.transform.*) for 'parse/validate' of
0057 * XML files and XSLT transformation is Copyright
0058 * (c) 1999 The Apache Software Foundation:
0059 * "The end-user documentation included with the redistribution,
0060 * if any, must include the following acknowledgment:
0061 * 'This product includes software developed by the
0062 * Apache Software Foundation (http://www.apache.org/).'
0063 * Alternately, this acknowledgment may appear in the software itself,
0064 * if and wherever such third-party acknowledgments normally appear."
0065 * - The MultipartRequest class package (com.oreilly.servlet.*) for handling
0066 * file uploads is Copyright (C) 2001-2002 by Jason Hunter:
0067 * "Permission is granted to use these packages in the development of any
0068 * non-commercial project. For this use you are granted a non-exclusive,
0069 * non-transferable limited license at no cost," provided the distribution
0070 * includes copyright notice as follows:
0071 * "The source code, object code, and documentation in the
0072 * com.oreilly.servlet package is copyright and owned by Jason Hunter."
0073 *
0074 * Implementation Notes:
0075 * - Processing of a NeumesXML file that resides on the server is done
0076 * by invoking the doGet() method in this servlet. Example:
0077 * http://www.scribeserver.com/servlet/NeumesXML.NeumesXSLTServlet?filepath=
0078 * http://www.scribeserver.com/SCRIBE/NEUMES/xml/transcriptions/Dextera_Aq_2.xml
0079 * - Processing of an uploaded NeumesXML file is done by invoking the
0080 * doPost() method in this servlet. Example:
0081 * <FORM
0082 * ACTION="http://www.scribeserver.com/servlet/NeumesXML.NeumesXSLTServlet"
0083 * METHOD="POST" ENCTYPE="multipart/form-data">
0084 * <INPUT TYPE=HIDDEN NAME="com" VALUE="transfer_upload" MAXLENGTH=200>
0085 * <INPUT TYPE=FILE SIZE=30 NAME="thefile" MAXLENGTH=400
0086 * ACCEPT="text/*; charset=UTF-8"><BR>
0087 * <INPUT TYPE=SUBMIT VALUE="Upload File">
0088 * </FORM>
0089 * - The MultipartRequest classes were designed to have no maximum upload
0090 * size limit, but for your server's protection the constructor allows you
0091 * to set a maximum POST size to accept. Any upload larger than the limit
0092 * is halted. The default maximum is 1MB.
0093 * - Xalan is the standard XML processor integrated in Java2 version 1.4.
0094 * And so, it is not really necessary to use the external library if the
0095 * servlet engine uses JDK 1.4.
0096 *
0097 * Revision History:
0098 * - Version 1.2 (10 April 2006). [LB:] added "NEUMES." to package name.
0099 * - LB, 24 February 2004:
0100 * Changed "NeumesXSL.xsl" to "NeumesXML.xsl".
0101 * Changed "neumesFO.xsl" to "NeumesXML_FO.xsl".
0102 * Added to doGet() two parameters: 'testing' and 'format'.
0103 * Added: xslt_filepath_testing; xslFO_filepath_testing.
0104 * - 01/03; minor changes added by TW to handle error conditions.
0105 * - version, 1.1, 31 December 2002.
0106 * - 12/02: code added by Tillman Weyde to allow client to upload
0107 * file for parse/validate and XSLT transformation.
0108 * - This source code was decompiled by TW from NeumesXSLTServlet.class.
0109 *
0110 * Copyright Notice:
0111 * Copyright 2003-2004 by Louis W. G. Barton.
0112 * Copyright 2002 by the President and Fellows of Harvard College;
0113 * contains software or other intellectual property licensed from
0114 * Louis W. G. Barton, copyright 1995-2001 by Louis W. G. Barton.
0115 */
0116
0117 package NEUMES.NeumesXML;
0118
0119 import java.io.*; // for CharArrayReader, CharArrayWriter, IOException,
0120 // InputStreamReader, ObjectInputStream, PrintStream,
0121 // PrintWriter, Reader.
0122 import java.net.*; // for MalformedURLException, URL.
0123 import java.util.*; // for Enumeration, Hashtable, Vector.
0124 import javax.servlet.*; // for ServletConfig, ServletException;
0125 import javax.servlet.http.*; // for HttpServlet, HttpServletRequest,
0126 // HttpServletResponse.
0127 import javax.xml.transform.*; // for Result, Source, Transformer,
0128 // TransformerFactory;
0129 import javax.xml.transform.sax.*; // for SAXResult
0130 import javax.xml.transform.stream.*; // for StreamResult, StreamSource
0131 import org.apache.avalon.framework.logger.*; // for ConsoleLogger, Logger
0132 import org.apache.fop.apps.*; // for Driver, XSLTInputHandler
0133 import org.apache.fop.messaging.*; // for MessageHandler
0134 import com.oreilly.servlet.multipart.*; // for FilePart, MultipartParser,
0135 // ParamPart, Part
0136
0137
0138 public class NeumesXSLTServlet extends HttpServlet {
0139 public static final String copyright =
0140 "Copyright 2003-2006 by Louis W. G. Barton.\n"
0141 + "Copyright 2002 by the President and Fellows of Harvard College;\n"
0142 + "contains software or other intellectual property licensed from "
0143 + "Louis W. G. Barton,\n copyright 1995-2001 by Louis W. G. Barton.\n"
0144 + "e-mail: louis.barton.je.77@aya.yale.edu.\n";
0145
0146 // Flag indicating where ther servlet is installed:
0147 static final int SCRIBE = 0; // Scribe server
0148 static final int MUSITECH = 1;
0149 static final int LOUIS = 2; // laptop computer, loop-back
0150 static final int TILLMAN = 3;
0151 static final int LOCATION = SCRIBE;
0152
0153 // Maximum size constraint on uploaded NeumesXML file is to protect server
0154 // (size of a NeumesXML file is expected typically around 10kB):
0155 private final int MAXLENGTH = 0x80000; // = 524,288 bytes (decimal)
0156
0157 // Output format:
0158 static final int HTML_OUT = 0;
0159 static final int PDF_OUT = 1;
0160 private int outputType; // the requested format for output
0161 // Test mode:
0162 private boolean testing = false; // for non-production testing
0163
0164 // Transcription file locations:
0165 private String default_infilepath; // default transcription
0166 private String xslt_filepath; // normal stylesheet
0167 private String xslFO_filepath; // Formating Objects stylesheet
0168 private String xslt_filepath_testing; // stylesheet, testing
0169 private String xslFO_filepath_testing; // formating objects, testing
0170 private URL xslFileURL; // address of the XSLT file
0171
0172
0173 /**
0174 * constructor
0175 *
0176 */
0177 public NeumesXSLTServlet() {
0178 } //end, constructor
0179
0180 /**
0181 * init()
0182 *
0183 */
0184 public final void init(ServletConfig config) throws ServletException {
0185 super.init(config); // super must be called
0186 } //end, init()
0187
0188 /**
0189 * setURLs()
0190 *
0191 * Selects filepaths depending on the platform being used in production/debug.
0192 */
0193 private final void setURLs(int choice) {
0194 switch (choice) {
0195 case MUSITECH :
0196 default_infilepath =
0197 "http://musitech.fmt.uni-osnabrueck.de:8080/neumes/NeumesExample.xml";
0198 // XSLT files:
0199 xslt_filepath =
0200 "http://musitech.fmt.uni-osnabrueck.de:8080/neumes/NeumesXSL.xsl";
0201 xslFO_filepath =
0202 "http://musitech.fmt.uni-osnabrueck.de:8080/neumes/neumesFO.xsl";
0203 break;
0204 case LOUIS :
0205 // For use on laptop computer w/ Personal Web Server and loopback URL:
0206 default_infilepath =
0207 "file:/D:/inetpub/wwwroot/NEUMES/xml/transcriptions/NeumesExample.xml";
0208 xslt_filepath =
0209 "file:/D:/inetpub/wwwroot/NEUMES/xml/NeumesXML.xsl";
0210 xslFO_filepath =
0211 "file:/D:/inetpub/wwwroot/NEUMES/xml/NeumesXML_FO.xsl";
0212 break;
0213 case TILLMAN :
0214 default_infilepath =
0215 "file:///C:/EigeneDateien/neumes/NeumesXML/NeumesExample.xml";
0216 xslt_filepath =
0217 "file:///C:/EigeneDateien/neumes/NeumesXML/NeumesXML.xsl";
0218 xslFO_filepath =
0219 "file:///C:/EigeneDateien/neumes/NeumesXML/neumesFO.xsl";
0220 break;
0221 case SCRIBE :
0222 default :
0223 // Default transcription file:
0224 default_infilepath =
0225 "http://purl.oclc.org/NEUMES/ref/transcriptions/NeumesExample.xml";
0226 // XSLT files:
0227 xslt_filepath = "http://purl.oclc.org/NEUMES/ref/NeumesXML.xsl";
0228 xslFO_filepath = "http://purl.oclc.org/NEUMES/ref/NeumesXML_FO.xsl";
0229 // XSLT files for testing:
0230 xslt_filepath_testing =
0231 "http://www.scribeserver.com/NEUMES/xml/test/NeumesXML.xsl";
0232 xslFO_filepath_testing =
0233 "http://www.scribeserver.com/NEUMES/xml/test/NeumesXML_FO.xsl";
0234 break;
0235 } //end, switch
0236 } //end, setURLs()
0237
0238 /**
0239 * doGet()
0240 *
0241 * doGet Responds to HTTP GET requests from browsers.
0242 * For processing a NeumesXML file of which client sends the file's URL.
0243 * Results of the XSLT transformation are pushed back to client.
0244 * If no filename is sent, then use the default example file.
0245 */
0246 public final void doGet(HttpServletRequest req, HttpServletResponse res)
0247 throws MalformedURLException, IOException, ServletException {
0248 setURLs(LOCATION); // choose between production and debug mode
0249 String inFilepath = null; // filepath of the input NeumesXML file
0250 String inDisplayMode = null; // display mode for visualization
0251 URL inFileURL = null; // URL of the NeumesXML file
0252 Source xmlSource = null; // for Xalan
0253 Source xslSource = null; // for Xalan
0254
0255 res.setContentType("text/html; charset=UTF-8");
0256 // Output goes to the response PrintWriter:
0257 PrintStream out = new PrintStream(res.getOutputStream());
0258 //Debug: printParameters(req, out); // show the GET request parameter list
0259
0260 // Get URL of input NeumesXML file:
0261 try {
0262 inFilepath = req.getParameter("filepath");
0263 if (inFilepath == null) {
0264 inFilepath = default_infilepath;
0265 } //end, if
0266 inFileURL = new URL(inFilepath);
0267 } catch (Exception e) {
0268 printErrorAndClose(out, "Invalid NeumesXML filepath specified.", e);
0269 return;
0270 } //end, try/catch, input file URL
0271
0272 // Get display mode:
0273 try {
0274 inDisplayMode = req.getParameter("testing");
0275 //Debug: out.println("inDisplayMode, testing = '" + inDisplayMode + "'.<BR>");
0276 if (inDisplayMode == null) {
0277 testing = false;
0278 } else if (inDisplayMode.equalsIgnoreCase("true")) {
0279 testing = true;
0280 } else {
0281 testing = false;
0282 } //end, if testing
0283
0284 inDisplayMode = req.getParameter("format");
0285 //Debug: out.println("inDisplayMode, format = '" + inDisplayMode + "'.<BR>");
0286 if (inDisplayMode == null) {
0287 outputType = HTML_OUT;
0288 } else if (inDisplayMode.equalsIgnoreCase("pdf")) {
0289 outputType = PDF_OUT;
0290 } else {
0291 outputType = HTML_OUT;
0292 } //end, if format
0293 } catch (Exception e) {
0294 printErrorAndClose(out,
0295 "Unable to read parameter(s) of servlet GET call.", e);
0296 return;
0297 } //end, try/catch, display mode
0298
0299 // Get URL of the appropriate XSL Transformation file:
0300 try {
0301 if (testing == true) {
0302 if (outputType == PDF_OUT) {
0303 xslFileURL = new URL(xslFO_filepath_testing);
0304 } else {
0305 xslFileURL = new URL(xslt_filepath_testing);
0306 } //end, if PDF
0307 } //end, if testing
0308 else {
0309 if (outputType == PDF_OUT) {
0310 xslFileURL = new URL(xslFO_filepath);
0311 } else {
0312 xslFileURL = new URL(xslt_filepath);
0313 } //end, if PDF
0314 } //end, if not testing
0315 } catch (Exception e) {
0316 printErrorAndClose(out, "Unable to get URL of XSLT file.", e);
0317 return;
0318 } //end, try,catch, XSLT URL
0319
0320 //Debug: out.println("Got Transformation URL.<BR/>");
0321
0322 try {
0323 TransformerFactory tFactory = TransformerFactory.newInstance();
0324 // Get the NeumesXML input document:
0325 xmlSource = new StreamSource(inFileURL.openStream());
0326 //Debug: out.println("Got inFile Stream.<BR/>");
0327 // Get the stylesheet:
0328 xslSource = new StreamSource(xslFileURL.openStream());
0329 //Debug: out.println("Got the Stylesheet.<BR/>");
0330 // Generate the transformer:
0331 Transformer transformer = tFactory.newTransformer(xslSource);
0332 // Perform the transformation, sending the output to the response:
0333 transformer.transform(xmlSource, new StreamResult(out));
0334 } catch (Exception e) {
0335 printErrorAndClose(out, "NeumesXML XSLT transformation Exception.<BR>", e);
0336 return;
0337 } //end, try/catch
0338
0339 out.close();
0340 } //end, doGet()
0341
0342 /**
0343 * doPost()
0344 *
0345 * Responds to HTTP POST requests from browsers.
0346 * For uploading a NeumesXML file to be processed here.
0347 * Results of the XSLT transformation are delivered back to client.
0348 *
0349 * @see javax.servlet.http.HttpServlet#doPost(
0350 * javax.servlet.http.HttpServletRequest,
0351 * javax.servlet.http.HttpServletResponse)
0352 */
0353 public final void doPost(HttpServletRequest req, HttpServletResponse res)
0354 throws IOException, ServletException {
0355 int length; // length of the uploaded file
0356 int filePartCount = 0; // number of fileParts read
0357 char fileData[] = null; // the updloaded file's data
0358 Source xmlSource = null; // the NeumesXML source document
0359 Source xslSource = null; // the NeumesXML transformation document
0360 MultipartParser mp = null; // multipart parser (new)
0361 Part part; // temp, part of the multipart
0362 String partName; // temp, name of the part
0363 Hashtable parameters = new Hashtable(); // Parameters. A clean hashtable
0364 Vector comVals; // Vector of parameter values
0365
0366 setURLs(LOCATION); // choose between production and debug mode
0367 res.setContentType("text/html; charset=UTF-8");
0368 // Output goes to the response PrintWriter:
0369 PrintStream out = new PrintStream(res.getOutputStream());
0370 length = req.getContentLength();
0371 // fileData[0] = 'a';
0372 if (length > MAXLENGTH) {
0373 printErrorAndClose(out,
0374 "Uploaded file exceeds maximum allowed filesize of "
0375 + MAXLENGTH + " bytes.");
0376 out.close();
0377 return;
0378 } //end, if > MAXLENGTH
0379
0380 /*Debug:
0381 Display information about this HTTP request:
0382 out.write("Content type = '" + req.getContentType() + "'.<BR/>");
0383 out.write("Character encoding is = " + req.getCharacterEncoding() + "<BR/>");
0384 out.write("<BR/>Query string = '" + req.getHeader("QUERY_STRING") + "'<BR/>");
0385 out.write("Uploaded file length = " + length + "<BR/>");
0386 Enumeration attribnames = req.getAttributeNames();
0387 out.write("<BR/>Attribute Names:<BR/>");
0388 while(attribnames.hasMoreElements()) {
0389 out.write("Attribute Name: '" + attribnames.nextElement() + "'<BR/>");
0390 } //end, while
0391 out.write("==END==<BR/>");
0392 printParameters(req, out); // local method: display the Parameter list
0393 [end, Debug] */
0394
0395 // Catch runtime exceptions while reading multipart messages:
0396 try {
0397 String contentType = req.getContentType();
0398 if (contentType.equals("application/x-java-serialized-object")) {
0399 String fileString;
0400 try {
0401 ObjectInputStream ois = new ObjectInputStream(req.getInputStream());
0402 fileString = (String) ois.readObject();
0403 } catch (Exception e) {
0404 printErrorAndClose(out, "Could not deserialize Java String object.");
0405 return;
0406 } // end try/catch
0407 fileData = fileString.toCharArray();
0408 comVals = new Vector(1);
0409 comVals.add(req.getHeader("com"));
0410 } //end, if Java coded data
0411 else {
0412 // not a coded Java object; should be MultiPart, then get the parser:
0413 try {
0414 mp = new MultipartParser(req, MAXLENGTH); // maxlength is settable
0415 } catch (IOException e) {
0416 out.print("This servlet's POST method can only be used with " +
0417 "multipart encoding.");
0418 out.close();
0419 return;
0420 } //end, try/catch, new MultipartParser
0421
0422 // read all parts of the multipart message:
0423 while ((part = mp.readNextPart()) != null) {
0424 partName = part.getName();
0425 if (part.isParam()) {
0426 // It's a parameter part:
0427 ParamPart paramPart = (ParamPart) part;
0428 String paramValue = paramPart.getStringValue();
0429 /*Debug:
0430 out.println("<BR>Parameter name = '" + partName +
0431 "', value = '" + paramValue + "'.");
0432 */
0433
0434 // Store any query parameters in a Hashtable:
0435 if (parameters.get(partName) == null) {
0436 Vector vec = new Vector();
0437 vec.add(paramValue);
0438 parameters.put(partName, vec);
0439 } else {
0440 Vector vec = (Vector) parameters.get(partName);
0441 vec.add(paramValue);
0442 } //end, if/else, add to hashtable
0443
0444 } else if (part.isFile()) {
0445 // It's a file part:
0446 filePartCount++;
0447 // Was more than one file sent?
0448 if (filePartCount > 1) {
0449 // If so, then this is an error
0450 break; // break the multipart loop
0451 } // end if filepartcount > 1
0452 FilePart filePart = (FilePart) part;
0453 // Get the NeumesXML input document:
0454 // create Writer and Reader:
0455 CharArrayWriter writer = new CharArrayWriter();
0456 Reader reader = new InputStreamReader(filePart.getInputStream());
0457 int numChar;
0458 // get that data
0459 char readBuffer[] = new char[512]; // Q: Assumption? (declare it)
0460 while ((numChar = reader.read(readBuffer)) != -1) {
0461 writer.write(readBuffer, 0, numChar);
0462 }
0463 reader.close();
0464 writer.close();
0465 // Save the data as a char array:
0466 fileData = writer.toCharArray();
0467 } //end, if/else part is Param or File
0468 } //end, while more parts
0469
0470 // Verify the correct request parameters for file upload:
0471 comVals = (Vector) parameters.get("com");
0472
0473 // Check the file out of the multiple parts:
0474 if (filePartCount > 1) {
0475 out.print("Only one upload file may be transmitted.");
0476 out.close();
0477 return;
0478 }
0479 if (filePartCount < 1) {
0480 printErrorAndClose(out, "No upload file received.");
0481 return;
0482 } //end, if
0483 // file param ok if we got here
0484 } //end, if/else Multipart
0485
0486 // Error checking:
0487 if (comVals == null) {
0488 printErrorAndClose(out, "Missing required 'com' parameter in HTTP "
0489 + "POST request.");
0490 return;
0491 } //end, if no com parameter
0492 if (comVals.size() > 1) {
0493 printErrorAndClose(out,
0494 "'com' parameter in HTTP POST request must only have one value.");
0495 return;
0496 }
0497 String com = (String) comVals.get(0);
0498 if (com.equalsIgnoreCase("transfer_upload")) {
0499 outputType = HTML_OUT;
0500 } else if (com.equalsIgnoreCase("transfer_upload_pdf")) {
0501 outputType = PDF_OUT;
0502 } //end, if mutliple com parameters
0503 else {
0504 printErrorAndClose(out, "Invalid com parameter value in HTTP POST "
0505 + "request. Only 'transfer_upload' and 'transfer_upload:pdf' are "
0506 + "allowed.");
0507 return;
0508 } //end, if not transfer_upload
0509 // com parameter is ok if we got here.
0510
0511 // xmlSource = new StreamSource(tempFile);
0512 xmlSource = new StreamSource(new CharArrayReader(fileData));
0513
0514 if (outputType == PDF_OUT) {
0515 xslFileURL = new URL(xslFO_filepath);
0516 // Construct driver:
0517 Driver driver = new Driver();
0518
0519 // Setup logger:
0520 Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
0521 driver.setLogger(logger);
0522 MessageHandler.setScreenLogger(logger);
0523
0524 // Setup Renderer (output format):
0525 driver.setRenderer(Driver.RENDER_PDF);
0526
0527 // Setup output:
0528 try {
0529 driver.setOutputStream(out);
0530
0531 // Setup XSLT:
0532 TransformerFactory factory = TransformerFactory.newInstance();
0533 Transformer transformer =
0534 factory.newTransformer(new StreamSource(xslFileURL.openStream()));
0535
0536 // Setup input for XSLT transformation:
0537 Source src = new StreamSource(new CharArrayReader(fileData));
0538
0539 // Resulting SAX events (the generated FO) must be piped to FOP:
0540 Result result = new SAXResult(driver.getContentHandler());
0541 res.setContentType("application/pdf");
0542
0543 // Start XSLT transformation and FOP processing:
0544 transformer.transform(src, result);
0545 } catch (Exception e) {
0546 printErrorAndClose(out, "PDF creation failed", e);
0547 } // end try/catch
0548 out.close(); // close flushes automatically
0549 return;
0550 } //end, if PDF
0551
0552 // Get URL of the XSLT transformation file:
0553 try {
0554 if (outputType == PDF_OUT) {
0555 xslFileURL = new URL(xslFO_filepath);
0556 } else if (outputType == HTML_OUT) {
0557 xslFileURL = new URL(xslt_filepath);
0558 }
0559 } catch (Exception e) {
0560 out.print("Unable to get URL of XSLT file.");
0561 out.close();
0562 return;
0563 } //end, try,catch, XSLT URL
0564 //Debug: System.out.println("Getting Factory.");
0565
0566 // The Transformer Factory
0567 TransformerFactory tFactory = TransformerFactory.newInstance();
0568 if (tFactory == null) {
0569 printErrorAndClose(out,
0570 "Could not get an instance of TransformerFactory.");
0571 return;
0572 } //end, if
0573
0574 // Get the XSLT stylesheet:
0575 xslSource = new StreamSource(xslFileURL.openStream());
0576 //Debug: System.out.println("got the xsl file");
0577
0578 // Generate the transformer:
0579 Transformer transformer = tFactory.newTransformer(xslSource);
0580 //Debug: System.out.println("before transform");
0581 // Perform the transformation, pushing the output to the client:
0582 transformer.transform(xmlSource, new StreamResult(out));
0583 // client needs not wait for cleaning up
0584
0585 } catch (Exception e) {
0586 printErrorAndClose(out,
0587 "NeumesXML XSLT transformation Exception. Unable to proceed.<BR>", e);
0588 return;
0589 } //end, try/catch, multipart
0590 out.close(); // close flushes automatically
0591 } //end, doPost()
0592
0593 /**
0594 * renderXML()
0595 *
0596 * Renders an XML file into a PDF file by applying a stylesheet
0597 * that converts the XML to XSL:FO. The PDF is written
0598 * directly to the response object's OutputStream
0599 */
0600 public final void renderXML(XSLTInputHandler input,
0601 HttpServletResponse response) throws ServletException {
0602 // if (log == null) {
0603 // log = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
0604 // MessageHandler.setScreenLogger(log);
0605 // }
0606 // try {
0607 // ByteArrayOutputStream out = new ByteArrayOutputStream();
0608 // Driver driver = new Driver();
0609 // driver.setRenderer(Driver.RENDER_PDF);
0610 // driver.setOutputStream(out);
0611 // XMLReader parser = input.getParser();
0612 // driver.render(parser, input.getInputSource());
0613 // response.setContentType("application/pdf");
0614 // byte[] content = out.toByteArray();
0615 // response.setContentLength(content.length);
0616 // response.getOutputStream().write(content);
0617 // response.getOutputStream().flush();
0618 // } catch (Exception ex) {
0619 // throw new ServletException(ex);
0620 // }
0621 } //end, renderXML()
0622
0623 /**
0624 * printErrorAndClose()
0625 *
0626 * Print an error message in HTML format and
0627 * close the stream.
0628 * @param out The PrintWriter to write to.
0629 * @param errMsg The errMsg to print.
0630 */
0631 private final void printErrorAndClose(PrintStream out, String errMsg) {
0632 printErrorAndClose(out, errMsg, null,
0633 "An error occured in NEUMES XSLT servlet, process terminated.");
0634 } //end, printErrorAndClose()
0635
0636 /**
0637 * printErrorAndClose(Exception)
0638 *
0639 * Print an error message in HTML format and
0640 * close the stream.
0641 * @param out The PrintWriter to write to.
0642 * @param errMsg The errMsg to print.
0643 * @param e The Ecxception causing the error.
0644 */
0645 private final void printErrorAndClose(PrintStream out, String errMsg,
0646 Exception e) {
0647 printErrorAndClose(out, errMsg, e,
0648 "An error occured in NEUMES XSLT servlet, process terminated.");
0649 } //end, printErrorAndClose(Exception)
0650
0651 /**
0652 * printErrorAndClose(errTitle)
0653 *
0654 * Print an error message in HTML format and close the writer.
0655 * @param out The PrintWriter to write to.
0656 * @param errMsg The errMsg to print.
0657 * @param e The Ecxception causing the error.
0658 * @param errTitle The title for the message.
0659 */
0660 private final void printErrorAndClose(PrintStream out, String errMsg,
0661 Exception e, String errTitle) {
0662 if (errMsg != null) {
0663 out.println("<HTML>");
0664 out.println("<HEAD>");
0665 out.println("<meta " +
0666 "http-equiv='content-type' content='text/html; charset=ISO-8859-1'>" +
0667 "</HEAD>");
0668 out.println("<TITLE>");
0669 out.println(errTitle);
0670 out.println("</TITLE>");
0671 out.println("<BODY>");
0672 out.println("<H2>" + errTitle + "</H2>\n<BR>Reason: ");
0673 out.println(errMsg);
0674 if (e != null) {
0675 out.println("MSG: " + e.getMessage() + "<BR>");
0676 out.println("STR: " + e.toString() + "<BR>");
0677 out.println("<BR><PRE>");
0678 e.printStackTrace(out);
0679 out.println("</PRE><BR>");
0680 }
0681 out.println("</BODY>");
0682 out.println("</HTML>");
0683 } //end, non-null error
0684 out.close();
0685 } //end, printErrorAndClose(errTitle)
0686
0687 /**
0688 * printParameters()
0689 *
0690 * For debugging: Displays a TABLE with the parameter names and their values.
0691 * @param request The request to process.
0692 * @param out The PrintWriter to write to.
0693 */
0694 private final void printParameters(HttpServletRequest request,
0695 PrintStream out) {
0696 Enumeration paramNames; // parameter names
0697 String paramName; // temp holder for parameter name
0698 String[] paramValues; // temp, values of the parameter
0699 int i; // temp index
0700
0701 // Make an HTML TABLE:
0702 out.println(
0703 "<TABLE BORDER=1 ALIGN=CENTER>\n"
0704 + "<TR BGCOLOR="#FFAD00">\n"
0705 + "<TH>Parameter Name</TH><TH>Parameter Value(s)</TH>");
0706 paramNames = request.getParameterNames();
0707 while (paramNames.hasMoreElements()) {
0708 paramName = (String) paramNames.nextElement();
0709 out.println("<TR><TD>" + paramName + "</TD>\n<TD>");
0710 paramValues = request.getParameterValues(paramName);
0711 if (paramValues.length == 1) {
0712 String paramValue = paramValues[0];
0713 if (paramValue.length() == 0) {
0714 out.print("<I>No Value</I>");
0715 } else {
0716 out.print(paramValue);
0717 } //end, if/else (paramValue.length)
0718 } else {
0719 out.println("<UL>");
0720 for (i = 0; i < paramValues.length; i++) {
0721 out.println("<LI>" + paramValues[i]);
0722 } //end, for (i)
0723 out.println("</UL>");
0724 } //end, if/else
0725 out.println("</TD></TR>");
0726 } //end, while
0727 out.println("</TABLE><BR clear='left'/>");
0728 } //end, printParameters()
0729
0730 } //end, class NeumesXSLTServlet
0731 //end, NeumesXSLTServlet.java