blob: 6b6612101744c3fccbd7bc34f0b0ac32cd55873d [file] [log] [blame]
/*
* @(#)$Id$
*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Sun
* Microsystems., http://www.sun.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* @author Jacek Ambroziak
* @author Santiago Pericas-Geertsen
* @author G. Todd Miller
* @author Morten Jorgensen
*
*/
package org.apache.xalan.xsltc.runtime;
import java.io.*;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.util.Vector;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.apache.xalan.xsltc.*;
import org.apache.xalan.xsltc.dom.DOMImpl;
import org.apache.xalan.xsltc.dom.Axis;
import org.apache.xalan.xsltc.dom.DTDMonitor;
import org.apache.xalan.xsltc.runtime.Constants;
final public class DefaultRun {
private TransletOutputHandler _handler;
private String _fileName;
private String _className;
private String _jarFileSrc;
private boolean _isJarFileSpecified = false;
private Vector _params = null;
private boolean _uri, _debug;
AbstractTranslet _translet;
public DefaultRun(String className, String fileName,
boolean uri, boolean debug) {
_fileName = fileName;
_className = className;
_uri = uri;
_debug = debug;
}
public void setParameters(Vector params) {
_params = params;
}
private void setJarFileInputSrc(boolean flag, String jarFile) {
// TODO: at this time we do not do anything with this
// information, attempts to add the jarfile to the CLASSPATH
// were successful via System.setProperty, but the effects
// were not visible to the running JVM. For now we add jarfile
// to CLASSPATH in the wrapper script that calls this program.
_isJarFileSpecified = flag;
// TODO verify jarFile exists...
_jarFileSrc = jarFile;
}
private void doTransform() {
try {
final Class clazz = Class.forName(_className);
final Translet translet = (Translet)clazz.newInstance();
// Create a SAX parser and get the XMLReader object it uses
final SAXParserFactory factory = SAXParserFactory.newInstance();
try {
factory.setFeature(Constants.NAMESPACE_FEATURE, true);
}
catch (Exception e) {
factory.setNamespaceAware(true);
}
final SAXParser parser = factory.newSAXParser();
final XMLReader reader = parser.getXMLReader();
// Set the DOM's DOM builder as the XMLReader's SAX2 content handler
final DOMImpl dom = new DOMImpl();
reader.setContentHandler(dom.getBuilder());
// Create a DTD monitor and pass it to the XMLReader object
final DTDMonitor dtdMonitor = new DTDMonitor();
dtdMonitor.handleDTD(reader);
_translet = (AbstractTranslet)translet;
dom.setDocumentURI(_fileName);
if (_uri)
reader.parse(_fileName);
else {
reader.parse(new File(_fileName).toURL().toExternalForm());
}
// Set size of key/id indices
_translet.setIndexSize(dom.getSize());
// If there are any elements with ID attributes, build an index
dtdMonitor.buildIdIndex(dom, 0, _translet);
_translet.setDTDMonitor(dtdMonitor);
// Pass global parameters
int n = _params.size();
for (int i = 0; i < n; i++) {
Parameter param = (Parameter) _params.elementAt(i);
translet.addParameter(param._name, param._value);
}
// Transform the document
String encoding = _translet._encoding;
DefaultSAXOutputHandler saxHandler =
new DefaultSAXOutputHandler(System.out, encoding);
TextOutput textOutput =
new TextOutput((ContentHandler)saxHandler,
(LexicalHandler)saxHandler, encoding);
translet.transform(dom, textOutput);
if (_debug) {
TransletOutputBase handler = new TransletOutputBase();
long start = System.currentTimeMillis();
final int nTimes = 100;
for (int i = 0; i < nTimes; i++)
translet.transform(dom, dom.getIterator(), handler);
long end = System.currentTimeMillis();
System.out.println("total " + (end - start) + " msec for "
+ nTimes + " transformations");
System.out.println(((double)end - start)/nTimes + " msec avg");
}
}
catch (TransletException e) {
System.err.println("\nTranslet Error: " + e.getMessage());
if (_debug) {
System.err.println(e.toString());
e.printStackTrace();
}
doSystemExit(1);
}
catch (RuntimeException e) {
System.err.println("\nRuntime Error: " + e.getMessage());
if (_debug) {
System.err.println(e.toString());
e.printStackTrace();
}
doSystemExit(1);
}
catch (FileNotFoundException e) {
System.err.println("Error: File or URI '"+_fileName+"' not found.");
doSystemExit(1);
}
catch (MalformedURLException e) {
System.err.println("Error: Invalid URI '"+_fileName+"'.");
doSystemExit(1);
}
catch (ClassNotFoundException e) {
System.err.println("Error: Cannot find class '"+_className+"'.");
doSystemExit(1);
}
catch (UnknownHostException e) {
System.err.println("Error: Can't resolve URI specification '"+
_fileName+"'.");
doSystemExit(1);
}
catch (Exception e) {
e.printStackTrace();
System.err.println("Error: internal error.");
doSystemExit(1);
}
}
/** If we should call System.exit or not */
protected static boolean allowSystemExit = true;
/** Worker method to call System.exit or not */
protected static void doSystemExit(int retVal) {
if (allowSystemExit)
System.exit(retVal);
}
private final static String USAGE_STRING =
"Usage: \n" +
" xslt [-j <jarfile>] {-u <document_url> | <document>} <class>\n"+
" [<name1>=<value1> ...]\n\n" +
" <document> is the xml document to be transformed, or\n" +
" <document_url> is a url for the xml document,\n" +
" <class> is the translet class which is either in\n" +
" user's CLASSPATH or in the <jarfile> specified \n" +
" with the -j option.\n" +
" also: [-x] (debug), [-s] (don't allow System.exit)";
public static void printUsage() {
System.err.println(USAGE_STRING);
System.exit(1);
}
public static void main(String[] args) {
try {
if (args.length > 0) {
int i;
boolean uri = false, debug = false;
boolean isJarFileSpecified = false;
String jarFile = null;
// Parse options starting with '-'
for (i = 0; i < args.length && args[i].charAt(0) == '-'; i++) {
if (args[i].equals("-u")) {
uri = true;
}
else if (args[i].equals("-s")){
allowSystemExit = false;
}
else if (args[i].equals("-x")) {
debug = true;
}
else if (args[i].equals("-j")) {
isJarFileSpecified = true;
jarFile = args[++i];
}
else {
printUsage();
}
}
// Enough arguments left ?
if (args.length - i < 2) {
printUsage();
}
// Get document file and class name
DefaultRun handler = new DefaultRun(args[i+1], args[i],
uri, debug);
handler.setJarFileInputSrc(isJarFileSpecified, jarFile);
// Parse stylesheet parameters
Vector params = new Vector();
for (i += 2; i < args.length; i++) {
int equal = args[i].indexOf('=');
if (equal > 0) {
final Parameter param =
new Parameter(args[i].substring(0, equal),
args[i].substring(equal + 1,
args[i].length()));
params.addElement(param);
}
else {
printUsage();
}
}
if (i == args.length) {
handler.setParameters(params);
handler.doTransform();
doSystemExit(0);
}
}else{
printUsage();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}