0001: /*
0002: * Copyright 1999-2004 The Apache Software Foundation.
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016: /*
0017: * $Id: Process.java,v 1.64 2005/06/07 15:35:52 mkwan Exp $
0018: */
0019: package org.apache.xalan.xslt;
0020:
0021: import java.io.FileOutputStream;
0022: import java.io.FileWriter;
0023: import java.io.PrintWriter;
0024: import java.io.StringReader;
0025: import java.util.Properties;
0026: import java.util.ResourceBundle;
0027: import java.util.Vector;
0028:
0029: import javax.xml.XMLConstants;
0030: import javax.xml.parsers.DocumentBuilder;
0031: import javax.xml.parsers.DocumentBuilderFactory;
0032: import javax.xml.parsers.ParserConfigurationException;
0033: import javax.xml.transform.OutputKeys;
0034: import javax.xml.transform.Source;
0035: import javax.xml.transform.Templates;
0036: import javax.xml.transform.Transformer;
0037: import javax.xml.transform.TransformerConfigurationException;
0038: import javax.xml.transform.TransformerException;
0039: import javax.xml.transform.TransformerFactory;
0040: import javax.xml.transform.TransformerFactoryConfigurationError;
0041: import javax.xml.transform.URIResolver;
0042: import javax.xml.transform.dom.DOMResult;
0043: import javax.xml.transform.dom.DOMSource;
0044: import javax.xml.transform.sax.SAXResult;
0045: import javax.xml.transform.sax.SAXSource;
0046: import javax.xml.transform.sax.SAXTransformerFactory;
0047: import javax.xml.transform.sax.TransformerHandler;
0048: import javax.xml.transform.stream.StreamResult;
0049: import javax.xml.transform.stream.StreamSource;
0050:
0051: import org.apache.xalan.Version;
0052: import org.apache.xalan.res.XSLMessages;
0053: import org.apache.xalan.res.XSLTErrorResources;
0054: import org.apache.xalan.trace.PrintTraceListener;
0055: import org.apache.xalan.trace.TraceManager;
0056: import org.apache.xalan.transformer.XalanProperties;
0057: import org.apache.xml.utils.DefaultErrorHandler;
0058:
0059: import org.w3c.dom.Document;
0060: import org.w3c.dom.Node;
0061:
0062: import org.xml.sax.ContentHandler;
0063: import org.xml.sax.EntityResolver;
0064: import org.xml.sax.InputSource;
0065: import org.xml.sax.XMLReader;
0066: import org.xml.sax.helpers.XMLReaderFactory;
0067:
0068: /**
0069: * The main() method handles the Xalan command-line interface.
0070: * @xsl.usage general
0071: */
0072: public class Process {
0073: /**
0074: * Prints argument options.
0075: *
0076: * @param resbundle Resource bundle
0077: */
0078: protected static void printArgOptions(ResourceBundle resbundle) {
0079: System.out.println(resbundle.getString("xslProc_option")); //"xslproc options: ");
0080: System.out.println("\n\t\t\t"
0081: + resbundle.getString("xslProc_common_options") + "\n");
0082: System.out.println(resbundle.getString("optionXSLTC")); //" [-XSLTC (use XSLTC for transformation)]
0083: System.out.println(resbundle.getString("optionIN")); //" [-IN inputXMLURL]");
0084: System.out.println(resbundle.getString("optionXSL")); //" [-XSL XSLTransformationURL]");
0085: System.out.println(resbundle.getString("optionOUT")); //" [-OUT outputFileName]");
0086:
0087: // System.out.println(resbundle.getString("optionE")); //" [-E (Do not expand entity refs)]");
0088: System.out.println(resbundle.getString("optionV")); //" [-V (Version info)]");
0089:
0090: // System.out.println(resbundle.getString("optionVALIDATE")); //" [-VALIDATE (Set whether validation occurs. Validation is off by default.)]");
0091: System.out.println(resbundle.getString("optionEDUMP")); //" [-EDUMP {optional filename} (Do stackdump on error.)]");
0092: System.out.println(resbundle.getString("optionXML")); //" [-XML (Use XML formatter and add XML header.)]");
0093: System.out.println(resbundle.getString("optionTEXT")); //" [-TEXT (Use simple Text formatter.)]");
0094: System.out.println(resbundle.getString("optionHTML")); //" [-HTML (Use HTML formatter.)]");
0095: System.out.println(resbundle.getString("optionPARAM")); //" [-PARAM name expression (Set a stylesheet parameter)]");
0096:
0097: System.out.println(resbundle.getString("optionMEDIA"));
0098: System.out.println(resbundle.getString("optionFLAVOR"));
0099: System.out.println(resbundle.getString("optionDIAG"));
0100: System.out.println(resbundle.getString("optionURIRESOLVER")); //" [-URIRESOLVER full class name (URIResolver to be used to resolve URIs)]");
0101: System.out.println(resbundle.getString("optionENTITYRESOLVER")); //" [-ENTITYRESOLVER full class name (EntityResolver to be used to resolve entities)]");
0102: waitForReturnKey(resbundle);
0103: System.out.println(resbundle.getString("optionCONTENTHANDLER")); //" [-CONTENTHANDLER full class name (ContentHandler to be used to serialize output)]");
0104: System.out.println(resbundle
0105: .getString("optionSECUREPROCESSING")); //" [-SECURE (set the secure processing feature to true)]");
0106:
0107: System.out.println("\n\t\t\t"
0108: + resbundle.getString("xslProc_xalan_options") + "\n");
0109:
0110: System.out.println(resbundle.getString("optionQC")); //" [-QC (Quiet Pattern Conflicts Warnings)]");
0111:
0112: // System.out.println(resbundle.getString("optionQ")); //" [-Q (Quiet Mode)]"); // sc 28-Feb-01 commented out
0113: System.out.println(resbundle.getString("optionTT")); //" [-TT (Trace the templates as they are being called.)]");
0114: System.out.println(resbundle.getString("optionTG")); //" [-TG (Trace each generation event.)]");
0115: System.out.println(resbundle.getString("optionTS")); //" [-TS (Trace each selection event.)]");
0116: System.out.println(resbundle.getString("optionTTC")); //" [-TTC (Trace the template children as they are being processed.)]");
0117: System.out.println(resbundle.getString("optionTCLASS")); //" [-TCLASS (TraceListener class for trace extensions.)]");
0118: System.out.println(resbundle.getString("optionLINENUMBERS")); //" [-L use line numbers]"
0119: System.out.println(resbundle.getString("optionINCREMENTAL"));
0120: System.out.println(resbundle.getString("optionNOOPTIMIMIZE"));
0121: System.out.println(resbundle.getString("optionRL"));
0122:
0123: System.out.println("\n\t\t\t"
0124: + resbundle.getString("xslProc_xsltc_options") + "\n");
0125: System.out.println(resbundle.getString("optionXO"));
0126: waitForReturnKey(resbundle);
0127: System.out.println(resbundle.getString("optionXD"));
0128: System.out.println(resbundle.getString("optionXJ"));
0129: System.out.println(resbundle.getString("optionXP"));
0130: System.out.println(resbundle.getString("optionXN"));
0131: System.out.println(resbundle.getString("optionXX"));
0132: System.out.println(resbundle.getString("optionXT"));
0133: }
0134:
0135: /**
0136: * Command line interface to transform an XML document according to
0137: * the instructions found in an XSL stylesheet.
0138: * <p>The Process class provides basic functionality for
0139: * performing transformations from the command line. To see a
0140: * list of arguments supported, call with zero arguments.</p>
0141: * <p>To set stylesheet parameters from the command line, use
0142: * <code>-PARAM name expression</code>. If you want to set the
0143: * parameter to a string value, simply pass the string value
0144: * as-is, and it will be interpreted as a string. (Note: if
0145: * the value has spaces in it, you may need to quote it depending
0146: * on your shell environment).</p>
0147: *
0148: * @param argv Input parameters from command line
0149: */
0150: public static void main(String argv[]) {
0151:
0152: // Runtime.getRuntime().traceMethodCalls(false); // turns Java tracing off
0153: boolean doStackDumpOnError = false;
0154: boolean setQuietMode = false;
0155: boolean doDiag = false;
0156: String msg = null;
0157: boolean isSecureProcessing = false;
0158:
0159: // Runtime.getRuntime().traceMethodCalls(false);
0160: // Runtime.getRuntime().traceInstructions(false);
0161:
0162: /**
0163: * The default diagnostic writer...
0164: */
0165: java.io.PrintWriter diagnosticsWriter = new PrintWriter(
0166: System.err, true);
0167: java.io.PrintWriter dumpWriter = diagnosticsWriter;
0168: ResourceBundle resbundle = (XSLMessages
0169: .loadResourceBundle(org.apache.xml.utils.res.XResourceBundle.ERROR_RESOURCES));
0170: String flavor = "s2s";
0171:
0172: if (argv.length < 1) {
0173: printArgOptions(resbundle);
0174: } else {
0175: boolean useXSLTC = false;
0176: for (int i = 0; i < argv.length; i++) {
0177: if ("-XSLTC".equalsIgnoreCase(argv[i])) {
0178: useXSLTC = true;
0179: }
0180: }
0181:
0182: TransformerFactory tfactory;
0183: if (useXSLTC) {
0184: String key = "javax.xml.transform.TransformerFactory";
0185: String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
0186: Properties props = System.getProperties();
0187: props.put(key, value);
0188: System.setProperties(props);
0189: }
0190:
0191: try {
0192: tfactory = TransformerFactory.newInstance();
0193: tfactory.setErrorListener(new DefaultErrorHandler());
0194: } catch (TransformerFactoryConfigurationError pfe) {
0195: pfe.printStackTrace(dumpWriter);
0196: // "XSL Process was not successful.");
0197: msg = XSLMessages.createMessage(
0198: XSLTErrorResources.ER_NOT_SUCCESSFUL, null);
0199: diagnosticsWriter.println(msg);
0200:
0201: tfactory = null; // shut up compiler
0202:
0203: doExit(msg);
0204: }
0205:
0206: boolean formatOutput = false;
0207: boolean useSourceLocation = false;
0208: String inFileName = null;
0209: String outFileName = null;
0210: String dumpFileName = null;
0211: String xslFileName = null;
0212: String treedumpFileName = null;
0213: PrintTraceListener tracer = null;
0214: String outputType = null;
0215: String media = null;
0216: Vector params = new Vector();
0217: boolean quietConflictWarnings = false;
0218: URIResolver uriResolver = null;
0219: EntityResolver entityResolver = null;
0220: ContentHandler contentHandler = null;
0221: int recursionLimit = -1;
0222:
0223: for (int i = 0; i < argv.length; i++) {
0224: if ("-XSLTC".equalsIgnoreCase(argv[i])) {
0225: // The -XSLTC option has been processed.
0226: } else if ("-TT".equalsIgnoreCase(argv[i])) {
0227: if (!useXSLTC) {
0228: if (null == tracer)
0229: tracer = new PrintTraceListener(
0230: diagnosticsWriter);
0231:
0232: tracer.m_traceTemplates = true;
0233: } else
0234: printInvalidXSLTCOption("-TT");
0235:
0236: // tfactory.setTraceTemplates(true);
0237: } else if ("-TG".equalsIgnoreCase(argv[i])) {
0238: if (!useXSLTC) {
0239: if (null == tracer)
0240: tracer = new PrintTraceListener(
0241: diagnosticsWriter);
0242:
0243: tracer.m_traceGeneration = true;
0244: } else
0245: printInvalidXSLTCOption("-TG");
0246:
0247: // tfactory.setTraceSelect(true);
0248: } else if ("-TS".equalsIgnoreCase(argv[i])) {
0249: if (!useXSLTC) {
0250: if (null == tracer)
0251: tracer = new PrintTraceListener(
0252: diagnosticsWriter);
0253:
0254: tracer.m_traceSelection = true;
0255: } else
0256: printInvalidXSLTCOption("-TS");
0257:
0258: // tfactory.setTraceTemplates(true);
0259: } else if ("-TTC".equalsIgnoreCase(argv[i])) {
0260: if (!useXSLTC) {
0261: if (null == tracer)
0262: tracer = new PrintTraceListener(
0263: diagnosticsWriter);
0264:
0265: tracer.m_traceElements = true;
0266: } else
0267: printInvalidXSLTCOption("-TTC");
0268:
0269: // tfactory.setTraceTemplateChildren(true);
0270: } else if ("-INDENT".equalsIgnoreCase(argv[i])) {
0271: int indentAmount;
0272:
0273: if (((i + 1) < argv.length)
0274: && (argv[i + 1].charAt(0) != '-')) {
0275: indentAmount = Integer.parseInt(argv[++i]);
0276: } else {
0277: indentAmount = 0;
0278: }
0279:
0280: // TBD:
0281: // xmlProcessorLiaison.setIndent(indentAmount);
0282: } else if ("-IN".equalsIgnoreCase(argv[i])) {
0283: if (i + 1 < argv.length
0284: && argv[i + 1].charAt(0) != '-')
0285: inFileName = argv[++i];
0286: else
0287: System.err
0288: .println(XSLMessages
0289: .createMessage(
0290: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0291: new Object[] { "-IN" })); //"Missing argument for);
0292: } else if ("-MEDIA".equalsIgnoreCase(argv[i])) {
0293: if (i + 1 < argv.length)
0294: media = argv[++i];
0295: else
0296: System.err
0297: .println(XSLMessages
0298: .createMessage(
0299: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0300: new Object[] { "-MEDIA" })); //"Missing argument for);
0301: } else if ("-OUT".equalsIgnoreCase(argv[i])) {
0302: if (i + 1 < argv.length
0303: && argv[i + 1].charAt(0) != '-')
0304: outFileName = argv[++i];
0305: else
0306: System.err
0307: .println(XSLMessages
0308: .createMessage(
0309: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0310: new Object[] { "-OUT" })); //"Missing argument for);
0311: } else if ("-XSL".equalsIgnoreCase(argv[i])) {
0312: if (i + 1 < argv.length
0313: && argv[i + 1].charAt(0) != '-')
0314: xslFileName = argv[++i];
0315: else
0316: System.err
0317: .println(XSLMessages
0318: .createMessage(
0319: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0320: new Object[] { "-XSL" })); //"Missing argument for);
0321: } else if ("-FLAVOR".equalsIgnoreCase(argv[i])) {
0322: if (i + 1 < argv.length) {
0323: flavor = argv[++i];
0324: } else
0325: System.err
0326: .println(XSLMessages
0327: .createMessage(
0328: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0329: new Object[] { "-FLAVOR" })); //"Missing argument for);
0330: } else if ("-PARAM".equalsIgnoreCase(argv[i])) {
0331: if (i + 2 < argv.length) {
0332: String name = argv[++i];
0333:
0334: params.addElement(name);
0335:
0336: String expression = argv[++i];
0337:
0338: params.addElement(expression);
0339: } else
0340: System.err
0341: .println(XSLMessages
0342: .createMessage(
0343: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0344: new Object[] { "-PARAM" })); //"Missing argument for);
0345: } else if ("-E".equalsIgnoreCase(argv[i])) {
0346:
0347: // TBD:
0348: // xmlProcessorLiaison.setShouldExpandEntityRefs(false);
0349: } else if ("-V".equalsIgnoreCase(argv[i])) {
0350: diagnosticsWriter.println(resbundle
0351: .getString("version") //">>>>>>> Xalan Version "
0352: + Version.getVersion() + ", " +
0353:
0354: /* xmlProcessorLiaison.getParserDescription()+ */
0355: resbundle.getString("version2")); // "<<<<<<<");
0356: } else if ("-QC".equalsIgnoreCase(argv[i])) {
0357: if (!useXSLTC)
0358: quietConflictWarnings = true;
0359: else
0360: printInvalidXSLTCOption("-QC");
0361: } else if ("-Q".equalsIgnoreCase(argv[i])) {
0362: setQuietMode = true;
0363: } else if ("-DIAG".equalsIgnoreCase(argv[i])) {
0364: doDiag = true;
0365: } else if ("-XML".equalsIgnoreCase(argv[i])) {
0366: outputType = "xml";
0367: } else if ("-TEXT".equalsIgnoreCase(argv[i])) {
0368: outputType = "text";
0369: } else if ("-HTML".equalsIgnoreCase(argv[i])) {
0370: outputType = "html";
0371: } else if ("-EDUMP".equalsIgnoreCase(argv[i])) {
0372: doStackDumpOnError = true;
0373:
0374: if (((i + 1) < argv.length)
0375: && (argv[i + 1].charAt(0) != '-')) {
0376: dumpFileName = argv[++i];
0377: }
0378: } else if ("-URIRESOLVER".equalsIgnoreCase(argv[i])) {
0379: if (i + 1 < argv.length) {
0380: try {
0381: uriResolver = (URIResolver) ObjectFactory
0382: .newInstance(argv[++i],
0383: ObjectFactory
0384: .findClassLoader(),
0385: true);
0386:
0387: tfactory.setURIResolver(uriResolver);
0388: } catch (ObjectFactory.ConfigurationError cnfe) {
0389: msg = XSLMessages
0390: .createMessage(
0391: XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
0392: new Object[] { "-URIResolver" });
0393: System.err.println(msg);
0394: doExit(msg);
0395: }
0396: } else {
0397: msg = XSLMessages
0398: .createMessage(
0399: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0400: new Object[] { "-URIResolver" }); //"Missing argument for);
0401: System.err.println(msg);
0402: doExit(msg);
0403: }
0404: } else if ("-ENTITYRESOLVER".equalsIgnoreCase(argv[i])) {
0405: if (i + 1 < argv.length) {
0406: try {
0407: entityResolver = (EntityResolver) ObjectFactory
0408: .newInstance(argv[++i],
0409: ObjectFactory
0410: .findClassLoader(),
0411: true);
0412: } catch (ObjectFactory.ConfigurationError cnfe) {
0413: msg = XSLMessages
0414: .createMessage(
0415: XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
0416: new Object[] { "-EntityResolver" });
0417: System.err.println(msg);
0418: doExit(msg);
0419: }
0420: } else {
0421: // "Missing argument for);
0422: msg = XSLMessages
0423: .createMessage(
0424: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0425: new Object[] { "-EntityResolver" });
0426: System.err.println(msg);
0427: doExit(msg);
0428: }
0429: } else if ("-CONTENTHANDLER".equalsIgnoreCase(argv[i])) {
0430: if (i + 1 < argv.length) {
0431: try {
0432: contentHandler = (ContentHandler) ObjectFactory
0433: .newInstance(argv[++i],
0434: ObjectFactory
0435: .findClassLoader(),
0436: true);
0437: } catch (ObjectFactory.ConfigurationError cnfe) {
0438: msg = XSLMessages
0439: .createMessage(
0440: XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
0441: new Object[] { "-ContentHandler" });
0442: System.err.println(msg);
0443: doExit(msg);
0444: }
0445: } else {
0446: // "Missing argument for);
0447: msg = XSLMessages
0448: .createMessage(
0449: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0450: new Object[] { "-ContentHandler" });
0451: System.err.println(msg);
0452: doExit(msg);
0453: }
0454: } else if ("-L".equalsIgnoreCase(argv[i])) {
0455: if (!useXSLTC)
0456: tfactory.setAttribute(
0457: XalanProperties.SOURCE_LOCATION,
0458: Boolean.TRUE);
0459: else
0460: printInvalidXSLTCOption("-L");
0461: } else if ("-INCREMENTAL".equalsIgnoreCase(argv[i])) {
0462: if (!useXSLTC)
0463: tfactory
0464: .setAttribute(
0465: "http://xml.apache.org/xalan/features/incremental",
0466: java.lang.Boolean.TRUE);
0467: else
0468: printInvalidXSLTCOption("-INCREMENTAL");
0469: } else if ("-NOOPTIMIZE".equalsIgnoreCase(argv[i])) {
0470: // Default is true.
0471: //
0472: // %REVIEW% We should have a generalized syntax for negative
0473: // switches... and probably should accept the inverse even
0474: // if it is the default.
0475: if (!useXSLTC)
0476: tfactory
0477: .setAttribute(
0478: "http://xml.apache.org/xalan/features/optimize",
0479: java.lang.Boolean.FALSE);
0480: else
0481: printInvalidXSLTCOption("-NOOPTIMIZE");
0482: } else if ("-RL".equalsIgnoreCase(argv[i])) {
0483: if (!useXSLTC) {
0484: if (i + 1 < argv.length)
0485: recursionLimit = Integer
0486: .parseInt(argv[++i]);
0487: else
0488: System.err
0489: .println(XSLMessages
0490: .createMessage(
0491: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0492: new Object[] { "-rl" })); //"Missing argument for);
0493: } else {
0494: if (i + 1 < argv.length
0495: && argv[i + 1].charAt(0) != '-')
0496: i++;
0497:
0498: printInvalidXSLTCOption("-RL");
0499: }
0500: }
0501: // Generate the translet class and optionally specify the name
0502: // of the translet class.
0503: else if ("-XO".equalsIgnoreCase(argv[i])) {
0504: if (useXSLTC) {
0505: if (i + 1 < argv.length
0506: && argv[i + 1].charAt(0) != '-') {
0507: tfactory.setAttribute("generate-translet",
0508: "true");
0509: tfactory.setAttribute("translet-name",
0510: argv[++i]);
0511: } else
0512: tfactory.setAttribute("generate-translet",
0513: "true");
0514: } else {
0515: if (i + 1 < argv.length
0516: && argv[i + 1].charAt(0) != '-')
0517: i++;
0518: printInvalidXalanOption("-XO");
0519: }
0520: }
0521: // Specify the destination directory for the translet classes.
0522: else if ("-XD".equalsIgnoreCase(argv[i])) {
0523: if (useXSLTC) {
0524: if (i + 1 < argv.length
0525: && argv[i + 1].charAt(0) != '-')
0526: tfactory.setAttribute(
0527: "destination-directory", argv[++i]);
0528: else
0529: System.err
0530: .println(XSLMessages
0531: .createMessage(
0532: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0533: new Object[] { "-XD" })); //"Missing argument for);
0534:
0535: } else {
0536: if (i + 1 < argv.length
0537: && argv[i + 1].charAt(0) != '-')
0538: i++;
0539:
0540: printInvalidXalanOption("-XD");
0541: }
0542: }
0543: // Specify the jar file name which the translet classes are packaged into.
0544: else if ("-XJ".equalsIgnoreCase(argv[i])) {
0545: if (useXSLTC) {
0546: if (i + 1 < argv.length
0547: && argv[i + 1].charAt(0) != '-') {
0548: tfactory.setAttribute("generate-translet",
0549: "true");
0550: tfactory
0551: .setAttribute("jar-name", argv[++i]);
0552: } else
0553: System.err
0554: .println(XSLMessages
0555: .createMessage(
0556: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0557: new Object[] { "-XJ" })); //"Missing argument for);
0558: } else {
0559: if (i + 1 < argv.length
0560: && argv[i + 1].charAt(0) != '-')
0561: i++;
0562:
0563: printInvalidXalanOption("-XJ");
0564: }
0565:
0566: }
0567: // Specify the package name prefix for the generated translet classes.
0568: else if ("-XP".equalsIgnoreCase(argv[i])) {
0569: if (useXSLTC) {
0570: if (i + 1 < argv.length
0571: && argv[i + 1].charAt(0) != '-')
0572: tfactory.setAttribute("package-name",
0573: argv[++i]);
0574: else
0575: System.err
0576: .println(XSLMessages
0577: .createMessage(
0578: XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
0579: new Object[] { "-XP" })); //"Missing argument for);
0580: } else {
0581: if (i + 1 < argv.length
0582: && argv[i + 1].charAt(0) != '-')
0583: i++;
0584:
0585: printInvalidXalanOption("-XP");
0586: }
0587:
0588: }
0589: // Enable template inlining.
0590: else if ("-XN".equalsIgnoreCase(argv[i])) {
0591: if (useXSLTC) {
0592: tfactory
0593: .setAttribute("enable-inlining", "true");
0594: } else
0595: printInvalidXalanOption("-XN");
0596: }
0597: // Turns on additional debugging message output
0598: else if ("-XX".equalsIgnoreCase(argv[i])) {
0599: if (useXSLTC) {
0600: tfactory.setAttribute("debug", "true");
0601: } else
0602: printInvalidXalanOption("-XX");
0603: }
0604: // Create the Transformer from the translet if the translet class is newer
0605: // than the stylesheet.
0606: else if ("-XT".equalsIgnoreCase(argv[i])) {
0607: if (useXSLTC) {
0608: tfactory.setAttribute("auto-translet", "true");
0609: } else
0610: printInvalidXalanOption("-XT");
0611: } else if ("-SECURE".equalsIgnoreCase(argv[i])) {
0612: isSecureProcessing = true;
0613: try {
0614: tfactory.setFeature(
0615: XMLConstants.FEATURE_SECURE_PROCESSING,
0616: true);
0617: } catch (TransformerConfigurationException e) {
0618: }
0619: } else
0620: System.err.println(XSLMessages.createMessage(
0621: XSLTErrorResources.ER_INVALID_OPTION,
0622: new Object[] { argv[i] })); //"Invalid argument:);
0623: }
0624:
0625: // Print usage instructions if no xml and xsl file is specified in the command line
0626: if (inFileName == null && xslFileName == null) {
0627: msg = resbundle.getString("xslProc_no_input");
0628: System.err.println(msg);
0629: doExit(msg);
0630: }
0631:
0632: // Note that there are usage cases for calling us without a -IN arg
0633: // The main XSL transformation occurs here!
0634: try {
0635: long start = System.currentTimeMillis();
0636:
0637: if (null != dumpFileName) {
0638: dumpWriter = new PrintWriter(new FileWriter(
0639: dumpFileName));
0640: }
0641:
0642: Templates stylesheet = null;
0643:
0644: if (null != xslFileName) {
0645: if (flavor.equals("d2d")) {
0646:
0647: // Parse in the xml data into a DOM
0648: DocumentBuilderFactory dfactory = DocumentBuilderFactory
0649: .newInstance();
0650:
0651: dfactory.setNamespaceAware(true);
0652:
0653: if (isSecureProcessing) {
0654: try {
0655: dfactory
0656: .setFeature(
0657: XMLConstants.FEATURE_SECURE_PROCESSING,
0658: true);
0659: } catch (ParserConfigurationException pce) {
0660: }
0661: }
0662:
0663: DocumentBuilder docBuilder = dfactory
0664: .newDocumentBuilder();
0665: Node xslDOM = docBuilder.parse(new InputSource(
0666: xslFileName));
0667:
0668: stylesheet = tfactory
0669: .newTemplates(new DOMSource(xslDOM,
0670: xslFileName));
0671: } else {
0672: // System.out.println("Calling newTemplates: "+xslFileName);
0673: stylesheet = tfactory
0674: .newTemplates(new StreamSource(
0675: xslFileName));
0676: // System.out.println("Done calling newTemplates: "+xslFileName);
0677: }
0678: }
0679:
0680: PrintWriter resultWriter;
0681: StreamResult strResult;
0682:
0683: if (null != outFileName) {
0684: strResult = new StreamResult(new FileOutputStream(
0685: outFileName));
0686: // One possible improvement might be to ensure this is
0687: // a valid URI before setting the systemId, but that
0688: // might have subtle changes that pre-existing users
0689: // might notice; we can think about that later -sc r1.46
0690: strResult.setSystemId(outFileName);
0691: } else {
0692: strResult = new StreamResult(System.out);
0693: // We used to default to incremental mode in this case.
0694: // We've since decided that since the -INCREMENTAL switch is
0695: // available, that default is probably not necessary nor
0696: // necessarily a good idea.
0697: }
0698:
0699: SAXTransformerFactory stf = (SAXTransformerFactory) tfactory;
0700:
0701: // This is currently controlled via TransformerFactoryImpl.
0702: if (!useXSLTC && useSourceLocation)
0703: stf.setAttribute(XalanProperties.SOURCE_LOCATION,
0704: Boolean.TRUE);
0705:
0706: // Did they pass in a stylesheet, or should we get it from the
0707: // document?
0708: if (null == stylesheet) {
0709: Source source = stf.getAssociatedStylesheet(
0710: new StreamSource(inFileName), media, null,
0711: null);
0712:
0713: if (null != source)
0714: stylesheet = tfactory.newTemplates(source);
0715: else {
0716: if (null != media)
0717: throw new TransformerException(
0718: XSLMessages
0719: .createMessage(
0720: XSLTErrorResources.ER_NO_STYLESHEET_IN_MEDIA,
0721: new Object[] {
0722: inFileName,
0723: media })); //"No stylesheet found in: "
0724: // + inFileName + ", media="
0725: // + media);
0726: else
0727: throw new TransformerException(
0728: XSLMessages
0729: .createMessage(
0730: XSLTErrorResources.ER_NO_STYLESHEET_PI,
0731: new Object[] { inFileName })); //"No xml-stylesheet PI found in: "
0732: //+ inFileName);
0733: }
0734: }
0735:
0736: if (null != stylesheet) {
0737: Transformer transformer = flavor.equals("th") ? null
0738: : stylesheet.newTransformer();
0739: transformer
0740: .setErrorListener(new DefaultErrorHandler());
0741:
0742: // Override the output format?
0743: if (null != outputType) {
0744: transformer.setOutputProperty(
0745: OutputKeys.METHOD, outputType);
0746: }
0747:
0748: if (transformer instanceof org.apache.xalan.transformer.TransformerImpl) {
0749: org.apache.xalan.transformer.TransformerImpl impl = (org.apache.xalan.transformer.TransformerImpl) transformer;
0750: TraceManager tm = impl.getTraceManager();
0751:
0752: if (null != tracer)
0753: tm.addTraceListener(tracer);
0754:
0755: impl
0756: .setQuietConflictWarnings(quietConflictWarnings);
0757:
0758: // This is currently controlled via TransformerFactoryImpl.
0759: if (useSourceLocation)
0760: impl.setProperty(
0761: XalanProperties.SOURCE_LOCATION,
0762: Boolean.TRUE);
0763:
0764: if (recursionLimit > 0)
0765: impl.setRecursionLimit(recursionLimit);
0766:
0767: // sc 28-Feb-01 if we re-implement this, please uncomment helpmsg in printArgOptions
0768: // impl.setDiagnosticsOutput( setQuietMode ? null : diagnosticsWriter );
0769: }
0770:
0771: int nParams = params.size();
0772:
0773: for (int i = 0; i < nParams; i += 2) {
0774: transformer.setParameter((String) params
0775: .elementAt(i), (String) params
0776: .elementAt(i + 1));
0777: }
0778:
0779: if (uriResolver != null)
0780: transformer.setURIResolver(uriResolver);
0781:
0782: if (null != inFileName) {
0783: if (flavor.equals("d2d")) {
0784:
0785: // Parse in the xml data into a DOM
0786: DocumentBuilderFactory dfactory = DocumentBuilderFactory
0787: .newInstance();
0788:
0789: dfactory.setCoalescing(true);
0790: dfactory.setNamespaceAware(true);
0791:
0792: if (isSecureProcessing) {
0793: try {
0794: dfactory
0795: .setFeature(
0796: XMLConstants.FEATURE_SECURE_PROCESSING,
0797: true);
0798: } catch (ParserConfigurationException pce) {
0799: }
0800: }
0801:
0802: DocumentBuilder docBuilder = dfactory
0803: .newDocumentBuilder();
0804:
0805: if (entityResolver != null)
0806: docBuilder
0807: .setEntityResolver(entityResolver);
0808:
0809: Node xmlDoc = docBuilder
0810: .parse(new InputSource(inFileName));
0811: Document doc = docBuilder.newDocument();
0812: org.w3c.dom.DocumentFragment outNode = doc
0813: .createDocumentFragment();
0814:
0815: transformer
0816: .transform(new DOMSource(xmlDoc,
0817: inFileName), new DOMResult(
0818: outNode));
0819:
0820: // Now serialize output to disk with identity transformer
0821: Transformer serializer = stf
0822: .newTransformer();
0823: serializer
0824: .setErrorListener(new DefaultErrorHandler());
0825:
0826: Properties serializationProps = stylesheet
0827: .getOutputProperties();
0828:
0829: serializer
0830: .setOutputProperties(serializationProps);
0831:
0832: if (contentHandler != null) {
0833: SAXResult result = new SAXResult(
0834: contentHandler);
0835:
0836: serializer.transform(new DOMSource(
0837: outNode), result);
0838: } else
0839: serializer.transform(new DOMSource(
0840: outNode), strResult);
0841: } else if (flavor.equals("th")) {
0842: for (int i = 0; i < 1; i++) // Loop for diagnosing bugs with inconsistent behavior
0843: {
0844: // System.out.println("Testing the TransformerHandler...");
0845:
0846: // ===============
0847: XMLReader reader = null;
0848:
0849: // Use JAXP1.1 ( if possible )
0850: try {
0851: javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory
0852: .newInstance();
0853:
0854: factory.setNamespaceAware(true);
0855:
0856: if (isSecureProcessing) {
0857: try {
0858: factory
0859: .setFeature(
0860: XMLConstants.FEATURE_SECURE_PROCESSING,
0861: true);
0862: } catch (org.xml.sax.SAXException se) {
0863: }
0864: }
0865:
0866: javax.xml.parsers.SAXParser jaxpParser = factory
0867: .newSAXParser();
0868:
0869: reader = jaxpParser.getXMLReader();
0870: } catch (javax.xml.parsers.ParserConfigurationException ex) {
0871: throw new org.xml.sax.SAXException(
0872: ex);
0873: } catch (javax.xml.parsers.FactoryConfigurationError ex1) {
0874: throw new org.xml.sax.SAXException(
0875: ex1.toString());
0876: } catch (NoSuchMethodError ex2) {
0877: } catch (AbstractMethodError ame) {
0878: }
0879:
0880: if (null == reader) {
0881: reader = XMLReaderFactory
0882: .createXMLReader();
0883: }
0884:
0885: if (!useXSLTC)
0886: stf
0887: .setAttribute(
0888: org.apache.xalan.processor.TransformerFactoryImpl.FEATURE_INCREMENTAL,
0889: Boolean.TRUE);
0890:
0891: TransformerHandler th = stf
0892: .newTransformerHandler(stylesheet);
0893:
0894: reader.setContentHandler(th);
0895: reader.setDTDHandler(th);
0896:
0897: if (th instanceof org.xml.sax.ErrorHandler)
0898: reader
0899: .setErrorHandler((org.xml.sax.ErrorHandler) th);
0900:
0901: try {
0902: reader
0903: .setProperty(
0904: "http://xml.org/sax/properties/lexical-handler",
0905: th);
0906: } catch (org.xml.sax.SAXNotRecognizedException e) {
0907: } catch (org.xml.sax.SAXNotSupportedException e) {
0908: }
0909: try {
0910: reader
0911: .setFeature(
0912: "http://xml.org/sax/features/namespace-prefixes",
0913: true);
0914: } catch (org.xml.sax.SAXException se) {
0915: }
0916:
0917: th.setResult(strResult);
0918:
0919: reader
0920: .parse(new InputSource(
0921: inFileName));
0922: }
0923: } else {
0924: if (entityResolver != null) {
0925: XMLReader reader = null;
0926:
0927: // Use JAXP1.1 ( if possible )
0928: try {
0929: javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory
0930: .newInstance();
0931:
0932: factory.setNamespaceAware(true);
0933:
0934: if (isSecureProcessing) {
0935: try {
0936: factory
0937: .setFeature(
0938: XMLConstants.FEATURE_SECURE_PROCESSING,
0939: true);
0940: } catch (org.xml.sax.SAXException se) {
0941: }
0942: }
0943:
0944: javax.xml.parsers.SAXParser jaxpParser = factory
0945: .newSAXParser();
0946:
0947: reader = jaxpParser.getXMLReader();
0948: } catch (javax.xml.parsers.ParserConfigurationException ex) {
0949: throw new org.xml.sax.SAXException(
0950: ex);
0951: } catch (javax.xml.parsers.FactoryConfigurationError ex1) {
0952: throw new org.xml.sax.SAXException(
0953: ex1.toString());
0954: } catch (NoSuchMethodError ex2) {
0955: } catch (AbstractMethodError ame) {
0956: }
0957:
0958: if (null == reader) {
0959: reader = XMLReaderFactory
0960: .createXMLReader();
0961: }
0962:
0963: reader
0964: .setEntityResolver(entityResolver);
0965:
0966: if (contentHandler != null) {
0967: SAXResult result = new SAXResult(
0968: contentHandler);
0969:
0970: transformer
0971: .transform(
0972: new SAXSource(
0973: reader,
0974: new InputSource(
0975: inFileName)),
0976: result);
0977: } else {
0978: transformer
0979: .transform(
0980: new SAXSource(
0981: reader,
0982: new InputSource(
0983: inFileName)),
0984: strResult);
0985: }
0986: } else if (contentHandler != null) {
0987: SAXResult result = new SAXResult(
0988: contentHandler);
0989:
0990: transformer.transform(new StreamSource(
0991: inFileName), result);
0992: } else {
0993: // System.out.println("Starting transform");
0994: transformer.transform(new StreamSource(
0995: inFileName), strResult);
0996: // System.out.println("Done with transform");
0997: }
0998: }
0999: } else {
1000: StringReader reader = new StringReader(
1001: "<?xml version=\"1.0\"?> <doc/>");
1002:
1003: transformer.transform(new StreamSource(reader),
1004: strResult);
1005: }
1006: } else {
1007: // "XSL Process was not successful.");
1008: msg = XSLMessages.createMessage(
1009: XSLTErrorResources.ER_NOT_SUCCESSFUL, null);
1010: diagnosticsWriter.println(msg);
1011: doExit(msg);
1012: }
1013:
1014: // close output streams
1015: if (null != outFileName && strResult != null) {
1016: java.io.OutputStream out = strResult
1017: .getOutputStream();
1018: java.io.Writer writer = strResult.getWriter();
1019: try {
1020: if (out != null)
1021: out.close();
1022: if (writer != null)
1023: writer.close();
1024: } catch (java.io.IOException ie) {
1025: }
1026: }
1027:
1028: long stop = System.currentTimeMillis();
1029: long millisecondsDuration = stop - start;
1030:
1031: if (doDiag) {
1032: Object[] msgArgs = new Object[] { inFileName,
1033: xslFileName, new Long(millisecondsDuration) };
1034: msg = XSLMessages.createMessage("diagTiming",
1035: msgArgs);
1036: diagnosticsWriter.println('\n');
1037: diagnosticsWriter.println(msg);
1038: }
1039:
1040: } catch (Throwable throwable) {
1041: while (throwable instanceof org.apache.xml.utils.WrappedRuntimeException) {
1042: throwable = ((org.apache.xml.utils.WrappedRuntimeException) throwable)
1043: .getException();
1044: }
1045:
1046: if ((throwable instanceof NullPointerException)
1047: || (throwable instanceof ClassCastException))
1048: doStackDumpOnError = true;
1049:
1050: diagnosticsWriter.println();
1051:
1052: if (doStackDumpOnError)
1053: throwable.printStackTrace(dumpWriter);
1054: else {
1055: DefaultErrorHandler.printLocation(
1056: diagnosticsWriter, throwable);
1057: diagnosticsWriter.println(XSLMessages
1058: .createMessage(
1059: XSLTErrorResources.ER_XSLT_ERROR,
1060: null)
1061: + " ("
1062: + throwable.getClass().getName()
1063: + "): " + throwable.getMessage());
1064: }
1065:
1066: // diagnosticsWriter.println(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
1067: if (null != dumpFileName) {
1068: dumpWriter.close();
1069: }
1070:
1071: doExit(throwable.getMessage());
1072: }
1073:
1074: if (null != dumpFileName) {
1075: dumpWriter.close();
1076: }
1077:
1078: if (null != diagnosticsWriter) {
1079:
1080: // diagnosticsWriter.close();
1081: }
1082:
1083: // if(!setQuietMode)
1084: // diagnosticsWriter.println(resbundle.getString("xsldone")); //"Xalan: done");
1085: // else
1086: // diagnosticsWriter.println(""); //"Xalan: done");
1087: }
1088: }
1089:
1090: /** It is _much_ easier to debug under VJ++ if I can set a single breakpoint
1091: * before this blows itself out of the water...
1092: * (I keep checking this in, it keeps vanishing. Grr!)
1093: * */
1094: static void doExit(String msg) {
1095: throw new RuntimeException(msg);
1096: }
1097:
1098: /**
1099: * Wait for a return key to continue
1100: *
1101: * @param resbundle The resource bundle
1102: */
1103: private static void waitForReturnKey(ResourceBundle resbundle) {
1104: System.out.println(resbundle
1105: .getString("xslProc_return_to_continue"));
1106: try {
1107: while (System.in.read() != '\n')
1108: ;
1109: } catch (java.io.IOException e) {
1110: }
1111: }
1112:
1113: /**
1114: * Print a message if an option cannot be used with -XSLTC.
1115: *
1116: * @param option The option String
1117: */
1118: private static void printInvalidXSLTCOption(String option) {
1119: System.err.println(XSLMessages
1120: .createMessage("xslProc_invalid_xsltc_option",
1121: new Object[] { option }));
1122: }
1123:
1124: /**
1125: * Print a message if an option can only be used with -XSLTC.
1126: *
1127: * @param option The option String
1128: */
1129: private static void printInvalidXalanOption(String option) {
1130: System.err.println(XSLMessages
1131: .createMessage("xslProc_invalid_xalan_option",
1132: new Object[] { option }));
1133: }
1134: }
|