You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by dl...@locus.apache.org on 2000/08/02 19:14:09 UTC
cvs commit: xml-xalan/samples/Servlet ApplyXSLT.java ApplyXSLTException.java ApplyXSLTListener.java ApplyXSLTProperties.java DefaultApplyXSLTProperties.java ApplyXSL.java ApplyXSLException.java ApplyXSLListener.java ApplyXSLProperties.java DefaultApplyXSL.java DefaultApplyXSLProperties.java
dleslie 00/08/02 10:14:09
Added: samples/Servlet ApplyXSLT.java ApplyXSLTException.java
ApplyXSLTListener.java ApplyXSLTProperties.java
DefaultApplyXSLTProperties.java
Removed: samples/Servlet ApplyXSL.java ApplyXSLException.java
ApplyXSLListener.java ApplyXSLProperties.java
DefaultApplyXSL.java DefaultApplyXSLProperties.java
Log:
xalan-j 2.0 sample app.
Revision Changes Path
1.1 xml-xalan/samples/Servlet/ApplyXSLT.java
Index: ApplyXSLT.java
===================================================================
/*****************************************************************************************************
* $Id: ApplyXSLT.java,v 1.1 2000/08/02 17:14:08 dleslie Exp $
*
* Copyright (c) 1998-1999 Lotus Corporation, Inc. All Rights Reserved.
* This software is provided without a warranty of any kind.
*
* $State: Exp $
*****************************************************************************************************/
package samples.servlet;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLConnection;
import org.apache.xalan.templates.Constants;
import org.apache.xalan.templates.StylesheetRoot;
import org.apache.xalan.templates.OutputFormatExtended;
// SAX2 Imports
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.Locator;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.w3c.dom.*;
import trax.*;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xalan.stree.SourceTreeHandler;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XString;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.helpers.XMLFilterImpl;
// Imported Serializer classes
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.Serializer;
import org.apache.xml.serialize.SerializerFactory;
// Imported JAVA API for XML Parsing 1.0 classes
import javax.xml.parsers.ParserConfigurationException;
/*****************************************************************************************************
*
* ApplyXSLT supplies the basic
* functions for transforming XML data using XSL stylesheets.
*
* @author Spencer Shepard (sshepard@us.ibm.com)
* @author R. Adam King (rak@us.ibm.com)
* @author Tom Rowe (trowe@us.ibm.com)
* @author Don Leslie (donald_leslie@lotus.com)
*
*****************************************************************************************************/
public class ApplyXSLT extends HttpServlet
{
/**
* Operational parameters for this class.
* <p>Request-time values override init-time values which override class defaults.</p>
* @see #init
* @serial
*/
protected ApplyXSLTProperties ourDefaultParameters = null;
/**
* String representing the end of line characters for the System.
*/
public final static String EOL = System.getProperty("line.separator");
/**
* String representing the file separator characters for the System.
*/
public final static String FS = System.getProperty("file.separator");
/**
* String representing the current directory for properties files. See init().
*/
public final static String ROOT = System.getProperty("server.root");
public static String CURRENTDIR;
/**
* Initialize operational parameters from the configuration.
* @param config Configuration
* @exception ServletException Never thrown
*/
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
// If the server.root property --see above-- is null, use current working directory
// as default location for media.properties.
if (ROOT != null)
CURRENTDIR= ROOT + FS + "servlets" + FS;
else
CURRENTDIR = System.getProperty("user.dir")+ FS;
setDefaultParameters(config);
setMediaProps(config.getInitParameter("mediaURL"));
}
/**
* Sets the default parameters for the servlet from the configuration.
* Also sets required system properties until we figure out why servlet
* sometimess fails to read properties from properties files.
* @param config Configuration
*/
protected void setDefaultParameters(ServletConfig config)
{
ourDefaultParameters = new DefaultApplyXSLTProperties(config);
}
/**
* Loads the media properties file specified by the given string.
* @param mediaURLstring Location of the media properties file. Can be either a full URL or a path relative
* to the System's server.root /servlets directory. If this parameter is null,
* server.root/servlets/media.properties will be used.
* @see ApplyXSL#CURRENTDIR
*/
protected void setMediaProps(String mediaURLstring)
{
if (mediaURLstring != null)
{
URL url = null;
try
{
url = new URL(mediaURLstring);
}
catch (MalformedURLException mue1)
{
try
{
url = new URL("file", "", CURRENTDIR + mediaURLstring);
}
catch (MalformedURLException mue2)
{
writeLog("Unable to find the media properties file based on parameter 'mediaURL' = "
+ mediaURLstring, HttpServletResponse.SC_ACCEPTED, mue2);
url = null;
}
}
if (url != null)
{
try
{
ourMediaProps = new OrderedProps(url.openStream());
}
catch (IOException ioe1)
{
writeLog("Exception occurred while opening media properties file: " + mediaURLstring +
". Media table may be invalid.", HttpServletResponse.SC_ACCEPTED, ioe1);
}
}
}
else
{
String defaultProp = CURRENTDIR + "media.properties";
try
{
ourMediaProps = new OrderedProps(new FileInputStream(defaultProp));
}
catch (IOException ioe2)
{
writeLog("Default media properties file " + defaultProp + " not found.",
HttpServletResponse.SC_ACCEPTED, ioe2);
}
}
}
public String getMedia(HttpServletRequest request)
{
return ourMediaProps.getValue(request.getHeader(HEADER_NAME));
}
// doPost removed for security reasons due to the possibility of sending
// unsecure XML and XSL XSLTInputSources through the request input stream
/**
* HTTP Get method passed on to process().
* @param request The request
* @param response The response
* @see #process
* @exception ServletException Never thrown
* @exception IOException Never thrown
*/
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
try
{
Processor processor = Processor.newInstance("xslt");
process(processor, request, response);
}
catch (Exception e)
{
}
}
/**
* Coordinates applying an XSL stylesheet to XML data using operational parameters.
* <p>If successfully applied, the result tree will be streamed to the response object
* and the content type set according to the XSL stylesheet's <xsl:output> element(s).</p>
* <p>If there is a problem in parsing the XML/XSL or if there is a problem in applying
* the XSL to the XML, an exception will be streamed to the response object. The detail
* of the information returned in the response object will depend on whether we're
* running in debug mode or not.</p>
* @param processor implementation of TRaX processor
* @param request May contain information relevant to creating XML and XSL XSLTInputSource's
* @param response Where to write the transformation result
* @see #getDocument
* @see #getStylesheet
* @see #getContentType
* @see #displayException
* @see #setStylesheetParams
* @exception ServletException Never thrown
* @exception IOException Never thrown
*/
public void process(Processor processor,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException, SAXException
{
boolean debug = ourDefaultParameters.isDebug(request);
long time = 0;
if (debug)
time = System.currentTimeMillis();
// Listener to be used for all reporting
ApplyXSLTListener listener = new ApplyXSLTListener();
listener.out.println("debug is " + debug);
InputSource xmlSource = null;
InputSource xslSource = null;
try
{
if ((xmlSource = getDocument(request, listener)) == null)
throw new ApplyXSLTException("getDocument() returned null",
new NullPointerException(),
response.SC_NOT_FOUND);
}
catch (ApplyXSLTException axe)
{
axe.appendMessage(EOL + "getDocument() resulted in ApplyXSLTException" + EOL
+ listener.getMessage());
if (debug) writeLog(axe);
displayException(response, axe, debug);
xmlSource = null;
}
// creating XSL Stylesheet
if (xmlSource != null)
{
try
{
if ((xslSource = getStylesheet(processor, request, xmlSource, listener)) == null)
{
throw new ApplyXSLTException("getStylesheet() returned null",
new NullPointerException(),
response.SC_NOT_FOUND);
}
// For time being, must "reset" xmlSource after extracting stylesheet PI
xmlSource = getDocument(request, listener);
}
catch (ApplyXSLTException axe)
{
axe.appendMessage(EOL + "getStylesheet() resulted in ApplyXSLTException" + EOL
+ listener.getMessage());
if (debug) writeLog(axe);
displayException(response, axe, debug);
xslSource = null;
}
// perform Transformation
if ((xmlSource != null) && (xslSource != null))
{
try
{
listener.out.println("Performing transformation...");
Templates templates = processor.process(xslSource);
Transformer transformer = templates.newTransformer();
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
Document outNode = docBuilder.newDocument();
{
try
{
String contentType = null;
contentType = getContentType(templates);
if (contentType != null);
response.setContentType(contentType);
if (transformer instanceof TransformerImpl)
{
TransformerImpl transformerImpl = (TransformerImpl)transformer;
transformerImpl.setQuietConflictWarnings(ourDefaultParameters.isNoCW(request));
}
setStylesheetParams(transformer, request);
Node doc = docBuilder.parse(xmlSource);
transformer.transformNode(doc, new Result(outNode));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Result outBuffer = new Result(baos);
SerializerFactory sf = SerializerFactory.getSerializerFactory("xml");
Serializer serializer = sf.makeSerializer(baos, new OutputFormat());
serializer.asDOMSerializer().serialize(outNode);
baos.writeTo(response.getOutputStream());
if (debug)
writeLog(listener.getMessage(), response.SC_OK);
}
catch (Exception exc)
{
ApplyXSLTException axe = new ApplyXSLTException
("Exception occurred during Transformation:"
+ EOL + listener.getMessage() + EOL
+ exc.getMessage(),
exc,
response.SC_INTERNAL_SERVER_ERROR);
if (debug) writeLog(axe);
displayException(response, axe, debug);
}
finally
{
// transformer.reset();
} // end of try ... catch ... finally
}
}
catch (/*org.xml.sax.SAX*/Exception saxExc)
{
ApplyXSLTException axe = new ApplyXSLTException
("Exception occurred during ctor/Transformation:"
+ EOL + listener.getMessage() + EOL
+ saxExc.getMessage(),
saxExc,
response.SC_INTERNAL_SERVER_ERROR);
if (debug) writeLog(axe);
displayException(response, axe, debug);
} // end of new try ... catch
} // end of if((stylesheetRoot != null) ...
if (debug)
{
time = System.currentTimeMillis() - time;
writeLog(" No Conflict Warnings = " + ourDefaultParameters.isNoCW(request) +
" Transformation time: " + time + " ms", response.SC_OK);
}
}
}
/**
* Returns an XML XSLTInputSource DOM. Attempts will be make to create the DOM from the following
* sources:
* <ol>
* <li>A relative URL specified in the HTTP request's path information. This capability is intended
* for use by <b>servlet engines that map</b> some or all XML data to be processed at the server.</li>
* <li>A URL specified in the HTTP request's <code>URL=</code> parameter. This capability
* is intended for <b>clients wishing to selectively process</b> XML data at the server. For
* security reasons, this URL will be forced to the local IP host.</li>
* <li>The HTTP request's XML input stream. This capability is intended for use by chained servlets.</li>
* </ol>
* @param request May contain or point to the XML XSLTInputSource
* @param listener To record detailed parsing messages for possible return to requestor
* @return XML XSLTInputSource DOM, or null if the XSLTInputSource could not be parsed
* @exception ApplyXSLTException Thrown if exception occurs while handling request
*/
protected InputSource getDocument(HttpServletRequest request,
ApplyXSLTListener listener)
throws ApplyXSLTException
{
try
{
String xmlURL = null;
// document from PathInfo
if ((xmlURL = request.getPathInfo()) != null)
{
listener.out.println("Parsing XML Document from PathInfo: " + xmlURL);
return new InputSource(new URL("http", ((DefaultApplyXSLTProperties)
ourDefaultParameters).getLocalHost(),
xmlURL.replace('\\', '/')).openStream());
}
// document from Request parameter
if ((xmlURL = ourDefaultParameters.getXMLurl(request)) != null)
{
listener.out.println("Parsing XML Document from request parameter: " + xmlURL);
return new InputSource(new URL(xmlURL).openStream());
}
// document from chain
String contentType = request.getContentType();
if ((contentType != null) && contentType.startsWith("text/xml"))
{
listener.out.println("Parsing XML Document from request chain");
return new InputSource(request.getInputStream());
}
}
catch (IOException ioe)
{
throw new ApplyXSLTException(ioe, HttpServletResponse.SC_NOT_FOUND);
}
catch (Exception e)
{
throw new ApplyXSLTException(e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
return null;
}
/**
* Returns a Templates (StylesheetRoot) object. Attempts will be make to create the Stylesheet
* from the followingsources:
* <ol>
* <li>A URL specified in the HTTP request's <code>xslURL=</code> parameter. This capability
* is intended for clients wishing to selectively override the server algorithm for applying XSL
* stylesheets. For security reasons, this URL will be forced to the local IP host.</li>
* <li>XML association. XML documents may contain references to one or more stylesheets using
* <a HREF="http://www.w3.org/TR/1999/PR-xml-stylesheet-19990114">this</a> W3C proposed recommendation.
* If the XML document does contain such references, a best match will be chosen based on the browser
* type making the request and the default association. This capability enables relationships to be
* defined between client capabilities and stylesheets capable of acting on these capabilities.</li>
* <li>A configured default stylesheet URL</li>
* </ol>
* @param request May contain or point to the XSL XSLTInputSource
* @param xmlSource May point to the XSL XSLTInputSource
* @param listener To record detailed parsing messages for possible return to requestor
* @return XSL XSLTInputSource, or null if the request could not be parsed
* @see #makeDocument
* @see #getMedia
* @see #STYLESHEET_ATTRIBUTE
* @see #getXSLURLfromDoc
* @see #toAcceptLanguageConnection
* @exception ApplyXSLTException Thrown if exception occurs while handling request
*/
protected InputSource getStylesheet(Processor processor,
HttpServletRequest request,
InputSource xmlSource,
ApplyXSLTListener listener)
throws ApplyXSLTException
{
try
{
//stylesheet URL from request
String xslURL = ((DefaultApplyXSLTProperties) ourDefaultParameters).getXSLRequestURL(request);
if (xslURL != null)
listener.out.println("Parsing XSL Stylesheet Document from request parameter: "
+ xslURL);
else
{
// find stylesheet from XML Document, Media tag preference
if (xmlSource != null){
listener.out.println("calling getXSLURLfromDoc and getMedia " + getMedia(request) );
xslURL = getXSLURLfromDoc(xmlSource, STYLESHEET_ATTRIBUTE, getMedia(request), processor);
}
if (xslURL != null)
listener.out.println("Parsing XSL Stylesheet Document from XML Document tag: " + xslURL);
else
// Configuration Default
if ((xslURL = ourDefaultParameters.getXSLurl(null)) != null)
listener.out.println("Parsing XSL Stylesheet Document from configuration: " + xslURL);
}
return new InputSource(xslURL);
}
catch (IOException ioe)
{
throw new ApplyXSLTException(ioe, HttpServletResponse.SC_NOT_FOUND);
}
catch (Exception e)
{
throw new ApplyXSLTException(e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
/**
* Returns the response content type specified by the media-type and encoding attributes of
* the <xsl:output> element(s) of the stylesheet.
* @param xslSourceRoot XSL Stylesheet to be examined for <xsl:output> elements.
* @return The response content type (MIME type and charset) of the stylesheet output
* @see #process
*/
public String getContentType(Templates templates)
{
StylesheetRoot xslSourceRoot = (StylesheetRoot)templates;
OutputFormatExtended of = xslSourceRoot.getOutput();
String encoding = of.getEncoding();
String media = of.getMediaType();
if (encoding != null)
return media + "; charset=" + encoding;
return media;
}
/**
* Defines and sets select top-level XSL stylesheet variables from the HTTP request, which
* can be evaluated using <xsl:param-variable>. The following variables will be
* automatically set:
* <dl>
* <dt><i>ParameterName</i></dt>
* <dd>Each non-reserved request parameter returned from request.getParameterNames(). If a
* parameter contains more than a single value, only the first value is available.</dd>
* <dt>servlet-RemoteAddr</dt>
* <dd>Contains String output from request.getRemoteAddr(), which is the IP address
* of the client machine.</dd>
* <dt>servlet-RemoteHost</dt>
* <dd>Contains String output from request.getRemoteHost(), which is the host name
* of the client machine.</dd>
* <dt>servlet-RemoteUser</dt>
* <dd>Contains String output from request.getRemoteUser(), which was the user name
* accepted by the server to grant access to this servlet.</dd>
* <dt>servlet-Request</dt>
* <dd>Contains the request object.</dd>
* </dl>
* @param xslprocessor Where to register parameters to be set
* @param request Provides access to all meaningful parameters to set
* @see #process
*/
public void setStylesheetParams(Transformer transformer, HttpServletRequest request)
{
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements())
{
String paramName = (String) paramNames.nextElement();
try
{
String[] paramVals = request.getParameterValues(paramName);
if (paramVals != null)
transformer.setParameter(paramName, null,
new XString(paramVals[0]));
}
catch (Exception e)
{
}
}
try
{
transformer.setParameter("servlet-RemoteAddr", null,
new XString(request.getRemoteAddr()));
}
catch (Exception e)
{
}
try
{
transformer.setParameter("servlet-RemoteHost", null,
new XString(request.getRemoteHost()));
}
catch (Exception e)
{
}
try
{
transformer.setParameter("servlet-RemoteUser", null,
new XString(request.getRemoteUser()));
}
catch (Exception e)
{
}
}
/**
* Writes the following information to the servlet log:
* <ol>
* <li>HTTP status code</li>
* <li>Message</li>
* <li>Stack trace</li>
* </ol>
* @param axe Contains valid HTTP status code, message, and stack trace (optional)
*/
protected void writeLog(ApplyXSLTException axe)
{
writeLog(axe.getMessage(), axe.getStatusCode(), axe.getException());
}
/**
* Writes the following information to the servlet log:
* <ol>
* <li>HTTP status code</li>
* <li>Message</li>
* <li>Stack trace</li>
* </ol>
* @param msg Message to be logged
* @param statusCode Valid status code from javax.servlet.http.HttpServletResponse
* @param t Used to generate stack trace (may be =null to suppress stack trace)
*/
protected void writeLog(String msg, int statusCode, Throwable t)
{
if (t == null)
writeLog(msg, statusCode);
else
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(bytes, true);
System.out.println("Exception is " + t.getClass().getName());
t.printStackTrace(writer);
log("HTTP Status Code: " + statusCode + " - " + msg + EOL + bytes.toString());
}
}
/**
* Writes the following information to the servlet log:
* <ol>
* <li>HTTP status code</li>
* <li>Message</li>
* </ol>
* @param msg Message to be logged
* @param statusCode Valid status code from javax.servlet.http.HttpServletResponse
*/
protected void writeLog(String msg, int statusCode)
{
log("HTTP Status Code: " + statusCode + " - " + msg);
}
/**
* Invokes response.sendError setting an HTTP status code and optionally an error message
* as an HTML page.
* <p>If running in debug mode, also try to return a stack trace of the exception and
* and xml/xsl processor messages.</p>
* @param response Where to stream the exception to
* @param xse The wrapper which contains the exception and its HTTP status code
* @param debug Indicates whether to include stack trace, etc.
*/
protected void displayException(HttpServletResponse response, ApplyXSLTException xse, boolean debug)
{
String mesg = xse.getMessage();
if (mesg == null)
mesg = "";
else mesg = "<B>" + mesg + "</B>";
StringTokenizer tokens = new StringTokenizer(mesg, EOL);
StringBuffer strBuf = new StringBuffer();
while (tokens.hasMoreTokens())
strBuf.append(tokens.nextToken() + EOL + "<BR>");
mesg = strBuf.toString();
if (debug)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(bytes, true);
xse.getException().printStackTrace(writer);
mesg += " <PRE> " + bytes.toString() + " </PRE> ";
}
response.setContentType("text/html");
try
{
response.sendError(xse.getStatusCode(), mesg);
}
catch (IOException ioe)
{
System.err.println("IOException is occurring when sendError is called");
}
}
/**
* Mapping of HTTP request's user-Agent values to stylesheet media= values.
* <p>This mapping is defined by a file pointed to by the operational parameter "mediaURL" which can
* either contain a full URL or a path relative to the System's server.root /servlets directory.</p>
* @see #setMediaProps
* @see #getMedia
* @serial
*/
protected OrderedProps ourMediaProps = null;
/**
* Returns a connection which respects the Accept-Language header of the HTTP request. This
* is useful when XSL files are internationalized for use with Web servers which respect this
* header.
* <p>For example, Apache 1.3.6 may be configured for multiviews. Under this configuration,
* requests for http://myhost/index.html would return http://myhost/index.html.fr to French browsers
* and http://myhost/index.html.en to English browsers.</p>
* @param url Location to connect to
* @param request Could contain an Accept-Language header
* @return An Accept-Language-enabled URL connection
* @see #getStylesheet
*/
protected URLConnection toAcceptLanguageConnection(URL url, HttpServletRequest request)
throws Exception
{
URLConnection tempConnection = url.openConnection();
tempConnection.setRequestProperty("Accept-Language", request.getHeader("Accept-Language"));
return tempConnection;
}
/**
* Returns the XSL stylesheet URL associated with the specified XML document. If multiple XSL
* stylesheets are associated with the XML document, preference will be given to the stylesheet
* which contains an attribute name/value pair that corresponds to the specified attributeName
* and attributeValue.
* @param xmlSource XML XSLTInputSource to be searched for associated XSL stylesheets
* @param attributeName Attribute name to provide preferential matching
* @param attributeValue Attribute value to provide preferential matching
* @return The preferred XSL stylesheet URL, or null if no XSL stylesheet association is found
* @see #getStylesheet
*/
public static String getXSLURLfromDoc(InputSource xmlSource,
String attributeName,
String attributeValue,
Processor processor)
{
String tempURL = null, returnURL = null;
try
{
DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
Node sourceTree = docBuilder.parse(xmlSource);
for(Node child=sourceTree.getFirstChild(); null != child; child=child.getNextSibling())
{
if(Node.PROCESSING_INSTRUCTION_NODE == child.getNodeType())
{
ProcessingInstruction pi = (ProcessingInstruction)child;
if(pi.getNodeName().equals("xml-stylesheet"))
{
PIA pia = new PIA(pi);
if("text/xsl".equals(pia.getAttribute("type")))
{
tempURL = pia.getAttribute("href");
String attribute = pia.getAttribute(attributeName);
if ((attribute != null) && (attribute.indexOf(attributeValue) > -1))
return tempURL;
if (!"yes".equals(pia.getAttribute("alternate")))
returnURL = tempURL;
}
}
}
}
}
catch(Exception saxExc)
{
}
return returnURL;
}
/**
* The attribute name in the <?xml-stylesheet> tag used in stylesheet selection.
*/
protected static final String STYLESHEET_ATTRIBUTE = "media";
/**
* The HTTP Header used for matching the Stylesheet attribute via the
* media properties file selected.
*/
protected static final String HEADER_NAME = "user-Agent";
}
/**
* Stores the keys and values from a file (similar to a properties file) and
* can return the first value which has a key contained in its string.
* File can have comment lines starting with '#" and for each line the entries are
* separated by tabs and '=' char.
*/
class OrderedProps
{
/**
* Stores the Key and Values as an array of Strings
*/
private Vector attVec = new Vector(15);
/**
* Constructor.
* @param inputStream Stream containing the properties file.
* @exception IOException Thrown if unable to read from stream
*/
OrderedProps(InputStream inputStream)
throws IOException
{
BufferedReader input = new BufferedReader(new InputStreamReader(inputStream));
String currentLine, Key = null;
StringTokenizer currentTokens;
while ((currentLine = input.readLine()) != null)
{
currentTokens = new StringTokenizer(currentLine, "=\t\r\n");
if (currentTokens.hasMoreTokens()) Key = currentTokens.nextToken().trim();
if ((Key != null) && !Key.startsWith("#") && currentTokens.hasMoreTokens())
{
String temp[] = new String[2];
temp[0] = Key; temp[1] = currentTokens.nextToken().trim();
attVec.addElement(temp);
}
}
}
/**
* Iterates through the Key list and returns the first value for whose
* key the given string contains. Returns "unknown" if no key is contained
* in the string.
* @param s String being searched for a key.
* @return Value for key found in string, otherwise "unknown"
*/
String getValue(String s)
{
int i, j = attVec.size();
for (i = 0; i < j; i++)
{
String temp[] = (String[]) attVec.elementAt(i);
if (s.indexOf(temp[0]) > -1)
return temp[1];
}
return "unknown";
}
}
/**
* Parses a processing instruction's (PI) attributes for easy retrieval.
*/
class PIA
{
private Hashtable piAttributes = null;
/**
* Constructor.
* @param pi The processing instruction whose attributes are to be parsed
*/
PIA(ProcessingInstruction pi)
{
piAttributes = new Hashtable();
StringTokenizer tokenizer = new StringTokenizer(pi.getNodeValue(), "=\"");
while(tokenizer.hasMoreTokens())
{
piAttributes.put(tokenizer.nextToken().trim(), tokenizer.nextToken().trim());
}
}
/**
* Returns value of specified attribute.
* @param name Attribute name
* @return Attribute value, or null if the attribute name does not exist
*/
String getAttribute(String name)
{
return (String) piAttributes.get(name);
}
}
1.1 xml-xalan/samples/Servlet/ApplyXSLTException.java
Index: ApplyXSLTException.java
===================================================================
/*****************************************************************************************************
* $Id: ApplyXSLTException.java,v 1.1 2000/08/02 17:14:08 dleslie Exp $
*
* Copyright (c) 1998-1999 Lotus Corporation, Inc. All Rights Reserved.
* This software is provided without a warranty of any kind.
*
* $State: Exp $
*****************************************************************************************************/
/*****************************************************************************************************
*
* Wrapper for exceptions occurring during apply XSL processing.
* Allows for exceptions to be returned with an associated HTTP Status Code.
*
* @author Spencer Shepard (sshepard@us.ibm.com)
* @author R. Adam King (rak@us.ibm.com)
* @author Tom Rowe (trowe@us.ibm.com)
*
*****************************************************************************************************/
package samples.servlet;
public class ApplyXSLTException extends Exception {
/**
* Exception Message.
* @serial
*/
private String myMessage = "";
/**
* HTTP Status Code. Default= internal server error.
* @serial
*/
private int myHttpStatusCode = javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
/**
* Wrapped exception
* @serial
*/
private Exception myException = null;
/**
* Constructor for exception with no additional detail.
*/
public ApplyXSLTException()
{
super();
}
/**
* Constructor for exception with message.
* @param s Exception message
*/
public ApplyXSLTException(String s)
{
super();
myMessage = s;
}
/**
* Constructor for exception with HTTP status code.
* @param hsc Valid status code from javax.servlet.http.HttpServletResponse
*/
public ApplyXSLTException(int hsc)
{
super();
myHttpStatusCode = hsc;
}
/**
* Constructor for exception with message and HTTP status code.
* @param s Exception message
* @param hsc Valid status code from javax.servlet.http.HttpServletResponse
*/
public ApplyXSLTException(String s, int hsc)
{
super();
myHttpStatusCode = hsc;
}
/**
* Constructor for exception.
* @param e Exception to be wrapped.
*/
public ApplyXSLTException(Exception e)
{
super();
myMessage = e.getMessage();
myException = e;
}
/**
* Constructor for passed exception with message.
* @param s Exception message
* @param e Exception to be wrapped.
*/
public ApplyXSLTException (String s, Exception e)
{
super();
myMessage = s;
myException = e;
}
/**
* Constructor for passed exception with HTTP status code.
* @param e Exception to be wrapped.
* @param hsc Valid status code from javax.servlet.http.HttpServletResponse
*/
public ApplyXSLTException(Exception e, int hsc)
{
super();
myMessage = e.getMessage();
myException = e;
myHttpStatusCode = hsc;
}
/**
* Constructor for passed exception with HTTP status code and message.
* @param s Exception message
* @param e Exception to be wrapped.
* @param hsc Valid status code from javax.servlet.http.HttpServletResponse
*/
public ApplyXSLTException(String s, Exception e, int hsc)
{
super();
myMessage = s;
myException = e;
myHttpStatusCode = hsc;
}
/**
* Returns exception message.
* @return exception message
*/
public String getMessage()
{
return myMessage;
}
/**
* Appends string to exception message.
* @param s String to be added to message
*/
public void appendMessage(String s)
{
myMessage += s;
}
/**
* Returns the wrapped exception.
* @return Wrapped exception
*/
public Exception getException()
{
return myException;
}
/**
* Returns the HTTP status code associated with the exception.
* @return Valid status code from javax.servlet.http.HttpServletResponse
*/
public int getStatusCode()
{
return myHttpStatusCode;
}
}
1.1 xml-xalan/samples/Servlet/ApplyXSLTListener.java
Index: ApplyXSLTListener.java
===================================================================
/*****************************************************************************************************
* $Id: ApplyXSLTListener.java,v 1.1 2000/08/02 17:14:08 dleslie Exp $
*
* Copyright (c) 1998-1999 Lotus Corporation, Inc. All Rights Reserved.
* This software is provided without a warranty of any kind.
*
* $State: Exp $
*****************************************************************************************************/
package samples.servlet;
import java.io.*;
import org.xml.sax.*;
import org.apache.xalan.xpath.xml.ProblemListenerDefault.*;
/*****************************************************************************************************
* ApplyXSLTListener provides a buffered listener essential for capturing, and then subsequently
* reporting, XML and XSL processor messages which may be of use in debugging XML+XSL processed at
* the server.
*
* @author Spencer Shepard (sshepard@us.ibm.com)
* @author R. Adam King (rak@us.ibm.com)
* @author Tom Rowe (trowe@us.ibm.com)
*
*****************************************************************************************************/
public class ApplyXSLTListener extends org.apache.xalan.xpath.xml.ProblemListenerDefault implements ErrorHandler
{
/**
* Output stream
*/
private ByteArrayOutputStream outStream = new ByteArrayOutputStream();
/**
* Buffered output stream
*/
public PrintWriter out = null;
/**
* Constructor.
*/
public ApplyXSLTListener()
{
out = new PrintWriter(new BufferedOutputStream(outStream), true);
}
/**
* Receive notification of a warning.
*
* @param spe The warning information encapsulated in a SAX parse exception.
*/
public void warning(SAXParseException spe)
{
out.println("Parser Warning: " + spe.getMessage());
}
/**
* Receive notification of a recoverable error.
*
* @param spe The error information encapsulated in a SAX parse exception.
*/
public void error(SAXParseException spe)
{
out.println("Parser Error: " + spe.getMessage());
}
/**
* Receive notification of a non-recoverable error.
*
* @param spe The error information encapsulated in a SAX parse exception.
* @exception SAXException Always thrown
*/
public void fatalError(SAXParseException spe)
throws SAXException
{
out.println("Parser Fatal Error: " + spe.getMessage());
throw spe;
}
/**
* Returns the buffered processing message(s).
* @return Buffered processing message(s)
*/
public String getMessage()
{
return outStream.toString();
}
}
1.1 xml-xalan/samples/Servlet/ApplyXSLTProperties.java
Index: ApplyXSLTProperties.java
===================================================================
/*****************************************************************************************************
* $Id: ApplyXSLTProperties.java,v 1.1 2000/08/02 17:14:08 dleslie Exp $
*
* Copyright (c) 1998-1999 Lotus Corporation, Inc. All Rights Reserved.
* This software is provided without a warranty of any kind.
*
* $State: Exp $
*****************************************************************************************************/
package samples.servlet;
import java.net.MalformedURLException;
import javax.servlet.*;
import javax.servlet.http.*;
/*****************************************************************************************************
*
* ApplyXSLTProperties contains operational parameters for ApplyXSLT based
* on program defaults and configuration.
* <p>This class is also used to return values for request-time parameters.</p>
*
* @author Spencer Shepard (sshepard@us.ibm.com)
* @author R. Adam King (rak@us.ibm.com)
* @author Tom Rowe (trowe@us.ibm.com)
*
*****************************************************************************************************/
public class ApplyXSLTProperties {
/**
* Program default for parameter "URL"
*/
private final String DEFAULT_URL;
/**
* Program default for parameter "xslURL"
*/
private final String DEFAULT_xslURL;
/**
* Program default for parameter "debug"
*/
private final boolean DEFAULT_debug;
/**
* Program default for parameter "noConflictWarnings"
*/
private final boolean DEFAULT_noCW;
/**
* Constructor to use program defaults.
*/
public ApplyXSLTProperties()
{
DEFAULT_URL = null;
DEFAULT_xslURL = null;
DEFAULT_debug = false;
DEFAULT_noCW = false;
}
/**
* Constructor to use to override program defaults.
* @param config Servlet configuration
*/
public ApplyXSLTProperties(ServletConfig config)
{
String xm = config.getInitParameter("URL"),
xu = config.getInitParameter("xslURL"),
db = config.getInitParameter("debug"),
cw = config.getInitParameter("noConflictWarnings");
if (xm != null) DEFAULT_URL = xm;
else DEFAULT_URL = null;
if (xu != null) DEFAULT_xslURL = xu;
else DEFAULT_xslURL = null;
if (db != null) DEFAULT_debug = new Boolean(db).booleanValue();
else DEFAULT_debug = false;
if (cw != null) DEFAULT_noCW = new Boolean(cw).booleanValue();
else DEFAULT_noCW = false;
}
/**
* Given a parameter name, returns the HTTP request's String value;
* if not present in request, returns default String value.
* @param request Request to check for default override
* @param param Name of the parameter
* @return String value of named parameter
*/
public String getRequestParmString(HttpServletRequest request, String param)
{
if (request != null) {
String[] paramVals = request.getParameterValues(param);
if (paramVals != null)
return paramVals[0];
}
return null;
}
/**
* Returns the current setting for "URL".
* @param request Request to check for parameter value
* @return String value for "URL"
* @exception MalformedURLException Will not be thrown
*/
public String getXMLurl(HttpServletRequest request)
throws MalformedURLException
{
String temp = getRequestParmString(request, "URL");
if (temp != null)
return temp;
return DEFAULT_URL;
}
/**
* Returns the current setting for "xslURL".
* @param request Request to check for parameter value
* @return String value for "xslURL"
* @exception MalformedURLException Will not be thrown
*/
public String getXSLurl(HttpServletRequest request)
throws MalformedURLException
{
String temp = getRequestParmString(request, "xslURL");
if (temp != null)
return temp;
return DEFAULT_xslURL;
}
/**
* Returns the current setting for "debug".
* @param request Request to check for parameter value
* @return Boolean value for "debug"
*/
public boolean isDebug(HttpServletRequest request)
{
String temp = getRequestParmString(request, "debug");
if (temp != null)
return new Boolean(temp).booleanValue();
return DEFAULT_debug;
}
/**
* Returns the current setting for "noConflictWarnings".
* @param request Request to check for parameter value
* @return Boolean value for "noConflictWarnings"
*/
boolean isNoCW(HttpServletRequest request)
{
String temp = getRequestParmString(request, "noConflictWarnings");
if (temp != null)
return new Boolean(temp).booleanValue();
return DEFAULT_noCW;
}
}
1.1 xml-xalan/samples/Servlet/DefaultApplyXSLTProperties.java
Index: DefaultApplyXSLTProperties.java
===================================================================
/*****************************************************************************************************
* $Id: DefaultApplyXSLTProperties.java,v 1.1 2000/08/02 17:14:09 dleslie Exp $
*
* Copyright (c) 1998-1999 Lotus Corporation, Inc. All Rights Reserved.
* This software is provided without a warranty of any kind.
*
* $State: Exp $
*****************************************************************************************************/
package samples.servlet;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
/*****************************************************************************************************
*
* DefaultApplyXSLTProperties contains operational parameters for DefaultApplyXSLT based
* on program defaults and configuration.
* <p>This class is also used to return values for request-time parameters.</p>
*
* @author Spencer Shepard (sshepard@us.ibm.com)
* @author R. Adam King (rak@us.ibm.com)
* @author Tom Rowe (trowe@us.ibm.com)
*
*****************************************************************************************************/
public class DefaultApplyXSLTProperties extends ApplyXSLTProperties {
/**
* Program default for parameter "catalog".
* @see #getCatalog
*/
private final String DEFAULT_catalog;
/**
* Host used for local context comparisons.
* @see #getLocalHost
* @see #setLocalHost
*/
protected transient String localHost = null;
/**
* Constructor to use program defaults.
*/
public DefaultApplyXSLTProperties()
{
super();
DEFAULT_catalog = null;
setLocalHost();
setSystemProperties();
}
/**
* Constructor to use to override program defaults.
* @param config Servlet configuration
* @see #setLocalHost
*/
public DefaultApplyXSLTProperties(ServletConfig config)
{
super(config);
String cat = config.getInitParameter("catalog");
if (cat != null) DEFAULT_catalog = cat;
else DEFAULT_catalog = null;
setLocalHost();
setSystemProperties();
}
/**
* Sets the name of the local IP host name; this value will be used to constrain untrusted
* XML document and XSL stylesheet URLs to this trusted host.
* @see #getLocalHost
*/
protected void setLocalHost()
{
try {
localHost = InetAddress.getLocalHost().getHostName();
} catch (Exception uhe) {
localHost = null;
}
}
/**
* Returns the name of trusted IP host.
* @return Name of trusted host
* @see #setLocalHost
*/
public String getLocalHost()
{
return localHost;
}
/**
* Returns a URL which is constrained to a trusted IP host.
* @param xURL URL or file path to be made safe
* @return Safe URL
* @exception MalformedURLException Thrown when xURL is not a valid URL
* @see #setLocalHost
* @see #getLocalHost
*/
public URL toSafeURL(String xURL)
throws MalformedURLException
{
if (xURL == null)
return null;
if (xURL.startsWith("/")) {
try {
return new URL("http", localHost, xURL);
} catch (MalformedURLException mue) {
throw new MalformedURLException("toSafeURL(): " + xURL +
" did not map to local");
}
}
URL tempURL = null;
try {
tempURL = new URL(xURL);
} catch (MalformedURLException mue) {
throw new MalformedURLException("toSafeURL(): " + xURL +
" not a valid URL");
}
try {
return new URL(tempURL.getProtocol(), localHost,
tempURL.getPort(), tempURL.getFile());
} catch (MalformedURLException mue) {
throw new MalformedURLException("toSafeURL(): " + xURL +
" could not be converted to local host");
}
}
/**
* Returns a string representing the constrained URL for the XML document.
* If there is no request parameter for the XML document, return the configured default.
* @param request May contain an XML document URL parameter
* @return String form of XML URL
* @exception MalformedURLException Thrown when request URL is not a valid URL or path
* @see #toSafeURL
*/
public String getXMLurl(HttpServletRequest request)
throws MalformedURLException
{
URL url = toSafeURL(getRequestParmString(request, "URL"));
if (url == null)
return super.getXMLurl(null);
return url.toExternalForm();
}
/**
* Returns a string representing the constrained URL for the XSL stylesheet
* from the request.
* @param request May contain an XSL stylesheet URL parameter
* @return String form of request XSL URL, or null if request contains no xslURL parameter
* @exception MalformedURLException Thrown when request URL is not a valid URL or path
* @see #toSafeURL
*/
public String getXSLRequestURL(HttpServletRequest request)
throws MalformedURLException
{
URL url = toSafeURL(getRequestParmString(request, "xslURL"));
if (url == null)
return null;
return url.toExternalForm();
}
/**
* Returns a string representing the constrained request URL for the XSL stylesheet.
* If there is no request parameter for the XSL stylesheet, return the configured default.
* @param request May contain an XSL stylesheet URL parameter
* @return String form of XSL URL
* @exception MalformedURLException Thrown when request URL is not a valid URL or path
* @see #toSafeURL
*/
public String getXSLurl(HttpServletRequest request)
throws MalformedURLException
{
String reqURL = getXSLRequestURL(request);
if (reqURL != null)
return reqURL;
return super.getXSLurl(null);
}
/**
* Returns URLs for all <a href="http://www.ccil.org/~cowan/XML/XCatalog.html">XCatalogs</a>
* that are to be used to process the request. Catalogs are used to resolve XML public identifiers
* into system identifiers.
* <p>A single XCatalog can be configured as a default,
* but multiple XCatalogs can be specified at request time to augment the configured default.
* @param request May contain one or more XCatalog parameters
* @return Array of strings for all catalog URLs
*/
public String[] getCatalog(HttpServletRequest request)
{
String temp[] = request.getParameterValues("catalog");
if (DEFAULT_catalog == null)
return temp;
if (temp == null) {
String defaultArray[] = new String [1];
defaultArray[0] = DEFAULT_catalog;
return defaultArray;
}
int i, len = temp.length + 1;
String newCatalogs[] = new String[len];
newCatalogs[0] = DEFAULT_catalog;
for (i=1; i < len; i++) {
newCatalogs[i] = temp[i-1];
}
return newCatalogs;
}
/**
* Sets required system properties until we figure out why servlet
* sometimes fails to read properties from properties files.
*/
protected void setSystemProperties()
{
System.setProperty("trax.processor.xslt", "org.apache.xalan.processor.StylesheetProcessor");
System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");
System.setProperty("serialize.methods", "xml,html,Text");
System.setProperty("serialize.xml", "org.apache.xml.serialize.XMLSerializer");
System.setProperty("serialize.html", "org.apache.xml.serialize.HTMLSerializer");
System.setProperty("serialize.text", "org.apache.xml.serialize.TextSerializer");
System.setProperty("serialize.xhtml", "org.apache.xml.serialize.XHTMLSerializer");
System.setProperty("serialize.wml", "org.apache.xml.serialize.WMLSerializer");
System.setProperty("serialize.format.xml", "serialize.format.XMLOutputFormat");
System.setProperty("serialize.format.html", "serialize.format.XMLOutputFormat");
System.setProperty("serialize.format.text", "serialize.format.XMLOutputFormat");
System.setProperty("serialize.format.xhtml", "serialize.format.XHTMLOutputFormat");
System.setProperty("serialize.format.text", "serialize.format.TextOutputFormat");
}
}