1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xalan.xslt;
  58. import java.io.FileOutputStream;
  59. import java.io.FileWriter;
  60. import java.io.PrintWriter;
  61. import java.io.StringReader;
  62. import java.util.Properties;
  63. import java.util.ResourceBundle;
  64. import java.util.Vector;
  65. import javax.xml.parsers.DocumentBuilder;
  66. import javax.xml.parsers.DocumentBuilderFactory;
  67. import javax.xml.parsers.FactoryConfigurationError;
  68. import javax.xml.parsers.ParserConfigurationException;
  69. import javax.xml.parsers.SAXParser;
  70. import javax.xml.parsers.SAXParserFactory;
  71. import javax.xml.transform.OutputKeys;
  72. import javax.xml.transform.Source;
  73. import javax.xml.transform.Templates;
  74. import javax.xml.transform.Transformer;
  75. import javax.xml.transform.TransformerException;
  76. import javax.xml.transform.TransformerFactory;
  77. import javax.xml.transform.TransformerFactoryConfigurationError;
  78. import javax.xml.transform.URIResolver;
  79. import javax.xml.transform.dom.DOMResult;
  80. import javax.xml.transform.dom.DOMSource;
  81. import javax.xml.transform.sax.SAXResult;
  82. import javax.xml.transform.sax.SAXSource;
  83. import javax.xml.transform.sax.SAXTransformerFactory;
  84. import javax.xml.transform.sax.TransformerHandler;
  85. import javax.xml.transform.stream.StreamResult;
  86. import javax.xml.transform.stream.StreamSource;
  87. import org.apache.xalan.processor.TransformerFactoryImpl;
  88. import org.apache.xalan.processor.XSLProcessorVersion;
  89. import org.apache.xalan.res.XSLMessages;
  90. import org.apache.xalan.res.XSLTErrorResources;
  91. import org.apache.xalan.trace.PrintTraceListener;
  92. import org.apache.xalan.trace.TraceManager;
  93. import org.apache.xalan.transformer.TransformerImpl;
  94. import org.apache.xalan.transformer.XalanProperties;
  95. import org.apache.xml.utils.DefaultErrorHandler;
  96. import org.apache.xml.utils.WrappedRuntimeException;
  97. import org.apache.xml.utils.res.XResourceBundle;
  98. import org.w3c.dom.Document;
  99. import org.w3c.dom.DocumentFragment;
  100. import org.w3c.dom.Node;
  101. import org.xml.sax.ContentHandler;
  102. import org.xml.sax.EntityResolver;
  103. import org.xml.sax.ErrorHandler;
  104. import org.xml.sax.InputSource;
  105. import org.xml.sax.SAXException;
  106. import org.xml.sax.SAXNotRecognizedException;
  107. import org.xml.sax.SAXNotSupportedException;
  108. import org.xml.sax.XMLReader;
  109. import org.xml.sax.helpers.XMLReaderFactory;
  110. /**
  111. * <meta name="usage" content="general"/>
  112. * The main() method handles the Xalan command-line interface.
  113. */
  114. public class Process
  115. {
  116. /**
  117. * Prints argument options.
  118. *
  119. * @param resbundle Resource bundle
  120. */
  121. protected static void printArgOptions(ResourceBundle resbundle)
  122. {
  123. System.out.println(resbundle.getString("xslProc_option")); //"xslproc options: ");
  124. System.out.println("\n\t\t\t" + resbundle.getString("xslProc_common_options") + "\n");
  125. System.out.println(resbundle.getString("optionXSLTC")); //" [-XSLTC (use XSLTC for transformation)]
  126. System.out.println(resbundle.getString("optionIN")); //" [-IN inputXMLURL]");
  127. System.out.println(resbundle.getString("optionXSL")); //" [-XSL XSLTransformationURL]");
  128. System.out.println(resbundle.getString("optionOUT")); //" [-OUT outputFileName]");
  129. // System.out.println(resbundle.getString("optionE")); //" [-E (Do not expand entity refs)]");
  130. System.out.println(resbundle.getString("optionV")); //" [-V (Version info)]");
  131. // System.out.println(resbundle.getString("optionVALIDATE")); //" [-VALIDATE (Set whether validation occurs. Validation is off by default.)]");
  132. System.out.println(resbundle.getString("optionEDUMP")); //" [-EDUMP {optional filename} (Do stackdump on error.)]");
  133. System.out.println(resbundle.getString("optionXML")); //" [-XML (Use XML formatter and add XML header.)]");
  134. System.out.println(resbundle.getString("optionTEXT")); //" [-TEXT (Use simple Text formatter.)]");
  135. System.out.println(resbundle.getString("optionHTML")); //" [-HTML (Use HTML formatter.)]");
  136. System.out.println(resbundle.getString("optionPARAM")); //" [-PARAM name expression (Set a stylesheet parameter)]");
  137. System.out.println(resbundle.getString("optionMEDIA"));
  138. System.out.println(resbundle.getString("optionFLAVOR"));
  139. System.out.println(resbundle.getString("optionDIAG"));
  140. System.out.println(resbundle.getString("optionURIRESOLVER")); //" [-URIRESOLVER full class name (URIResolver to be used to resolve URIs)]");
  141. System.out.println(resbundle.getString("optionENTITYRESOLVER")); //" [-ENTITYRESOLVER full class name (EntityResolver to be used to resolve entities)]");
  142. waitForReturnKey(resbundle);
  143. System.out.println(resbundle.getString("optionCONTENTHANDLER")); //" [-CONTENTHANDLER full class name (ContentHandler to be used to serialize output)]");
  144. System.out.println("\n\t\t\t" + resbundle.getString("xslProc_xalan_options") + "\n");
  145. System.out.println(resbundle.getString("optionQC")); //" [-QC (Quiet Pattern Conflicts Warnings)]");
  146. // System.out.println(resbundle.getString("optionQ")); //" [-Q (Quiet Mode)]"); // sc 28-Feb-01 commented out
  147. System.out.println(resbundle.getString("optionTT")); //" [-TT (Trace the templates as they are being called.)]");
  148. System.out.println(resbundle.getString("optionTG")); //" [-TG (Trace each generation event.)]");
  149. System.out.println(resbundle.getString("optionTS")); //" [-TS (Trace each selection event.)]");
  150. System.out.println(resbundle.getString("optionTTC")); //" [-TTC (Trace the template children as they are being processed.)]");
  151. System.out.println(resbundle.getString("optionTCLASS")); //" [-TCLASS (TraceListener class for trace extensions.)]");
  152. System.out.println(resbundle.getString("optionLINENUMBERS")); //" [-L use line numbers]"
  153. System.out.println(resbundle.getString("optionINCREMENTAL"));
  154. System.out.println(resbundle.getString("optionNOOPTIMIMIZE"));
  155. System.out.println(resbundle.getString("optionRL"));
  156. System.out.println("\n\t\t\t" + resbundle.getString("xslProc_xsltc_options") + "\n");
  157. System.out.println(resbundle.getString("optionXO"));
  158. System.out.println(resbundle.getString("optionXD"));
  159. waitForReturnKey(resbundle);
  160. System.out.println(resbundle.getString("optionXJ"));
  161. System.out.println(resbundle.getString("optionXP"));
  162. System.out.println(resbundle.getString("optionXN"));
  163. System.out.println(resbundle.getString("optionXX"));
  164. System.out.println(resbundle.getString("optionXT"));
  165. }
  166. /**
  167. * Command line interface to transform an XML document according to
  168. * the instructions found in an XSL stylesheet.
  169. * <p>The Process class provides basic functionality for
  170. * performing transformations from the command line. To see a
  171. * list of arguments supported, call with zero arguments.</p>
  172. * <p>To set stylesheet parameters from the command line, use
  173. * <code>-PARAM name expression</code>. If you want to set the
  174. * parameter to a string value, simply pass the string value
  175. * as-is, and it will be interpreted as a string. (Note: if
  176. * the value has spaces in it, you may need to quote it depending
  177. * on your shell environment).</p>
  178. *
  179. * @param argv Input parameters from command line
  180. */
  181. public static void main(String argv[])
  182. {
  183. // Runtime.getRuntime().traceMethodCalls(false); // turns Java tracing off
  184. boolean doStackDumpOnError = false;
  185. boolean setQuietMode = false;
  186. boolean doDiag = false;
  187. // Runtime.getRuntime().traceMethodCalls(false);
  188. // Runtime.getRuntime().traceInstructions(false);
  189. /**
  190. * The default diagnostic writer...
  191. */
  192. java.io.PrintWriter diagnosticsWriter = new PrintWriter(System.err, true);
  193. java.io.PrintWriter dumpWriter = diagnosticsWriter;
  194. ResourceBundle resbundle =
  195. (XSLMessages.loadResourceBundle(
  196. org.apache.xml.utils.res.XResourceBundle.ERROR_RESOURCES));
  197. String flavor = "s2s";
  198. if (argv.length < 1)
  199. {
  200. printArgOptions(resbundle);
  201. }
  202. else
  203. {
  204. boolean useXSLTC = false;
  205. for (int i = 0; i < argv.length; i++)
  206. {
  207. if ("-XSLTC".equalsIgnoreCase(argv[i]))
  208. {
  209. useXSLTC = true;
  210. }
  211. }
  212. TransformerFactory tfactory;
  213. if (useXSLTC)
  214. {
  215. String key = "javax.xml.transform.TransformerFactory";
  216. String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
  217. Properties props = System.getProperties();
  218. props.put(key, value);
  219. System.setProperties(props);
  220. }
  221. try
  222. {
  223. tfactory = TransformerFactory.newInstance();
  224. }
  225. catch (TransformerFactoryConfigurationError pfe)
  226. {
  227. pfe.printStackTrace(dumpWriter);
  228. diagnosticsWriter.println(
  229. XSLMessages.createMessage(
  230. XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
  231. tfactory = null; // shut up compiler
  232. doExit(-1);
  233. }
  234. boolean formatOutput = false;
  235. boolean useSourceLocation = false;
  236. String inFileName = null;
  237. String outFileName = null;
  238. String dumpFileName = null;
  239. String xslFileName = null;
  240. String treedumpFileName = null;
  241. PrintTraceListener tracer = null;
  242. String outputType = null;
  243. String media = null;
  244. Vector params = new Vector();
  245. boolean quietConflictWarnings = false;
  246. URIResolver uriResolver = null;
  247. EntityResolver entityResolver = null;
  248. ContentHandler contentHandler = null;
  249. int recursionLimit=-1;
  250. for (int i = 0; i < argv.length; i++)
  251. {
  252. if ("-XSLTC".equalsIgnoreCase(argv[i]))
  253. {
  254. // The -XSLTC option has been processed.
  255. }
  256. else if ("-TT".equalsIgnoreCase(argv[i]))
  257. {
  258. if (!useXSLTC)
  259. {
  260. if (null == tracer)
  261. tracer = new PrintTraceListener(diagnosticsWriter);
  262. tracer.m_traceTemplates = true;
  263. }
  264. else
  265. printInvalidXSLTCOption("-TT");
  266. // tfactory.setTraceTemplates(true);
  267. }
  268. else if ("-TG".equalsIgnoreCase(argv[i]))
  269. {
  270. if (!useXSLTC)
  271. {
  272. if (null == tracer)
  273. tracer = new PrintTraceListener(diagnosticsWriter);
  274. tracer.m_traceGeneration = true;
  275. }
  276. else
  277. printInvalidXSLTCOption("-TG");
  278. // tfactory.setTraceSelect(true);
  279. }
  280. else if ("-TS".equalsIgnoreCase(argv[i]))
  281. {
  282. if (!useXSLTC)
  283. {
  284. if (null == tracer)
  285. tracer = new PrintTraceListener(diagnosticsWriter);
  286. tracer.m_traceSelection = true;
  287. }
  288. else
  289. printInvalidXSLTCOption("-TS");
  290. // tfactory.setTraceTemplates(true);
  291. }
  292. else if ("-TTC".equalsIgnoreCase(argv[i]))
  293. {
  294. if (!useXSLTC)
  295. {
  296. if (null == tracer)
  297. tracer = new PrintTraceListener(diagnosticsWriter);
  298. tracer.m_traceElements = true;
  299. }
  300. else
  301. printInvalidXSLTCOption("-TTC");
  302. // tfactory.setTraceTemplateChildren(true);
  303. }
  304. else if ("-INDENT".equalsIgnoreCase(argv[i]))
  305. {
  306. int indentAmount;
  307. if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-'))
  308. {
  309. indentAmount = Integer.parseInt(argv[++i]);
  310. }
  311. else
  312. {
  313. indentAmount = 0;
  314. }
  315. // TBD:
  316. // xmlProcessorLiaison.setIndent(indentAmount);
  317. }
  318. else if ("-IN".equalsIgnoreCase(argv[i]))
  319. {
  320. if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
  321. inFileName = argv[++i];
  322. else
  323. System.err.println(
  324. XSLMessages.createMessage(
  325. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  326. new Object[]{ "-IN" })); //"Missing argument for);
  327. }
  328. else if ("-MEDIA".equalsIgnoreCase(argv[i]))
  329. {
  330. if (i + 1 < argv.length)
  331. media = argv[++i];
  332. else
  333. System.err.println(
  334. XSLMessages.createMessage(
  335. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  336. new Object[]{ "-MEDIA" })); //"Missing argument for);
  337. }
  338. else if ("-OUT".equalsIgnoreCase(argv[i]))
  339. {
  340. if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
  341. outFileName = argv[++i];
  342. else
  343. System.err.println(
  344. XSLMessages.createMessage(
  345. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  346. new Object[]{ "-OUT" })); //"Missing argument for);
  347. }
  348. else if ("-XSL".equalsIgnoreCase(argv[i]))
  349. {
  350. if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
  351. xslFileName = argv[++i];
  352. else
  353. System.err.println(
  354. XSLMessages.createMessage(
  355. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  356. new Object[]{ "-XSL" })); //"Missing argument for);
  357. }
  358. else if ("-FLAVOR".equalsIgnoreCase(argv[i]))
  359. {
  360. if (i + 1 < argv.length)
  361. {
  362. flavor = argv[++i];
  363. }
  364. else
  365. System.err.println(
  366. XSLMessages.createMessage(
  367. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  368. new Object[]{ "-FLAVOR" })); //"Missing argument for);
  369. }
  370. else if ("-PARAM".equalsIgnoreCase(argv[i]))
  371. {
  372. if (i + 2 < argv.length)
  373. {
  374. String name = argv[++i];
  375. params.addElement(name);
  376. String expression = argv[++i];
  377. params.addElement(expression);
  378. }
  379. else
  380. System.err.println(
  381. XSLMessages.createMessage(
  382. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  383. new Object[]{ "-PARAM" })); //"Missing argument for);
  384. }
  385. else if ("-E".equalsIgnoreCase(argv[i]))
  386. {
  387. // TBD:
  388. // xmlProcessorLiaison.setShouldExpandEntityRefs(false);
  389. }
  390. else if ("-V".equalsIgnoreCase(argv[i]))
  391. {
  392. diagnosticsWriter.println(resbundle.getString("version") //">>>>>>> Xalan Version "
  393. + XSLProcessorVersion.S_VERSION + ", " +
  394. /* xmlProcessorLiaison.getParserDescription()+ */
  395. resbundle.getString("version2")); // "<<<<<<<");
  396. }
  397. else if ("-QC".equalsIgnoreCase(argv[i]))
  398. {
  399. if (!useXSLTC)
  400. quietConflictWarnings = true;
  401. else
  402. printInvalidXSLTCOption("-QC");
  403. }
  404. else if ("-Q".equalsIgnoreCase(argv[i]))
  405. {
  406. setQuietMode = true;
  407. }
  408. else if ("-DIAG".equalsIgnoreCase(argv[i]))
  409. {
  410. doDiag = true;
  411. }
  412. else if ("-XML".equalsIgnoreCase(argv[i]))
  413. {
  414. outputType = "xml";
  415. }
  416. else if ("-TEXT".equalsIgnoreCase(argv[i]))
  417. {
  418. outputType = "text";
  419. }
  420. else if ("-HTML".equalsIgnoreCase(argv[i]))
  421. {
  422. outputType = "html";
  423. }
  424. else if ("-EDUMP".equalsIgnoreCase(argv[i]))
  425. {
  426. doStackDumpOnError = true;
  427. if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-'))
  428. {
  429. dumpFileName = argv[++i];
  430. }
  431. }
  432. else if ("-URIRESOLVER".equalsIgnoreCase(argv[i]))
  433. {
  434. if (i + 1 < argv.length)
  435. {
  436. try
  437. {
  438. uriResolver =
  439. (URIResolver) Class.forName(argv[++i]).newInstance();
  440. tfactory.setURIResolver(uriResolver);
  441. }
  442. catch (Exception cnfe)
  443. {
  444. System.err.println(
  445. XSLMessages.createMessage(
  446. XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
  447. new Object[]{ "-URIResolver" }));
  448. doExit(-1);
  449. }
  450. }
  451. else
  452. {
  453. System.err.println(
  454. XSLMessages.createMessage(
  455. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  456. new Object[]{ "-URIResolver" })); //"Missing argument for);
  457. doExit(-1);
  458. }
  459. }
  460. else if ("-ENTITYRESOLVER".equalsIgnoreCase(argv[i]))
  461. {
  462. if (i + 1 < argv.length)
  463. {
  464. try
  465. {
  466. entityResolver =
  467. (EntityResolver) Class.forName(argv[++i]).newInstance();
  468. }
  469. catch (Exception cnfe)
  470. {
  471. System.err.println(
  472. XSLMessages.createMessage(
  473. XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
  474. new Object[]{ "-EntityResolver" }));
  475. doExit(-1);
  476. }
  477. }
  478. else
  479. {
  480. System.err.println(
  481. XSLMessages.createMessage(
  482. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  483. new Object[]{ "-EntityResolver" })); //"Missing argument for);
  484. doExit(-1);
  485. }
  486. }
  487. else if ("-CONTENTHANDLER".equalsIgnoreCase(argv[i]))
  488. {
  489. if (i + 1 < argv.length)
  490. {
  491. try
  492. {
  493. contentHandler =
  494. (ContentHandler) Class.forName(argv[++i]).newInstance();
  495. }
  496. catch (Exception cnfe)
  497. {
  498. System.err.println(
  499. XSLMessages.createMessage(
  500. XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
  501. new Object[]{ "-ContentHandler" }));
  502. doExit(-1);
  503. }
  504. }
  505. else
  506. {
  507. System.err.println(
  508. XSLMessages.createMessage(
  509. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  510. new Object[]{ "-ContentHandler" })); //"Missing argument for);
  511. doExit(-1);
  512. }
  513. }
  514. else if ("-L".equalsIgnoreCase(argv[i]))
  515. {
  516. if (!useXSLTC)
  517. useSourceLocation = true;
  518. else
  519. printInvalidXSLTCOption("-L");
  520. }
  521. else if ("-INCREMENTAL".equalsIgnoreCase(argv[i]))
  522. {
  523. if (!useXSLTC)
  524. tfactory.setAttribute
  525. ("http://xml.apache.org/xalan/features/incremental",
  526. java.lang.Boolean.TRUE);
  527. else
  528. printInvalidXSLTCOption("-INCREMENTAL");
  529. }
  530. else if ("-NOOPTIMIZE".equalsIgnoreCase(argv[i]))
  531. {
  532. // Default is true.
  533. //
  534. // %REVIEW% We should have a generalized syntax for negative
  535. // switches... and probably should accept the inverse even
  536. // if it is the default.
  537. if (!useXSLTC)
  538. tfactory.setAttribute
  539. ("http://xml.apache.org/xalan/features/optimize",
  540. java.lang.Boolean.FALSE);
  541. else
  542. printInvalidXSLTCOption("-NOOPTIMIZE");
  543. }
  544. else if ("-RL".equalsIgnoreCase(argv[i]))
  545. {
  546. if (!useXSLTC)
  547. {
  548. if (i + 1 < argv.length)
  549. recursionLimit = Integer.parseInt(argv[++i]);
  550. else
  551. System.err.println(
  552. XSLMessages.createMessage(
  553. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  554. new Object[]{ "-rl" })); //"Missing argument for);
  555. }
  556. else
  557. {
  558. if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
  559. i++;
  560. printInvalidXSLTCOption("-RL");
  561. }
  562. }
  563. // Generate the translet class and optionally specify the name
  564. // of the translet class.
  565. else if ("-XO".equalsIgnoreCase(argv[i]))
  566. {
  567. if (useXSLTC)
  568. {
  569. if (i + 1 < argv.length && argv[i+1].charAt(0) != '-')
  570. {
  571. tfactory.setAttribute("generate-translet", "true");
  572. tfactory.setAttribute("translet-name", argv[++i]);
  573. }
  574. else
  575. tfactory.setAttribute("generate-translet", "true");
  576. }
  577. else
  578. {
  579. if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
  580. i++;
  581. printInvalidXalanOption("-XO");
  582. }
  583. }
  584. // Specify the destination directory for the translet classes.
  585. else if ("-XD".equalsIgnoreCase(argv[i]))
  586. {
  587. if (useXSLTC)
  588. {
  589. if (i + 1 < argv.length && argv[i+1].charAt(0) != '-')
  590. tfactory.setAttribute("destination-directory", argv[++i]);
  591. else
  592. System.err.println(
  593. XSLMessages.createMessage(
  594. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  595. new Object[]{ "-XD" })); //"Missing argument for);
  596. }
  597. else
  598. {
  599. if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
  600. i++;
  601. printInvalidXalanOption("-XD");
  602. }
  603. }
  604. // Specify the jar file name which the translet classes are packaged into.
  605. else if ("-XJ".equalsIgnoreCase(argv[i]))
  606. {
  607. if (useXSLTC)
  608. {
  609. if (i + 1 < argv.length && argv[i+1].charAt(0) != '-')
  610. {
  611. tfactory.setAttribute("generate-translet", "true");
  612. tfactory.setAttribute("jar-name", argv[++i]);
  613. }
  614. else
  615. System.err.println(
  616. XSLMessages.createMessage(
  617. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  618. new Object[]{ "-XJ" })); //"Missing argument for);
  619. }
  620. else
  621. {
  622. if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
  623. i++;
  624. printInvalidXalanOption("-XJ");
  625. }
  626. }
  627. // Specify the package name prefix for the generated translet classes.
  628. else if ("-XP".equalsIgnoreCase(argv[i]))
  629. {
  630. if (useXSLTC)
  631. {
  632. if (i + 1 < argv.length && argv[i+1].charAt(0) != '-')
  633. tfactory.setAttribute("package-name", argv[++i]);
  634. else
  635. System.err.println(
  636. XSLMessages.createMessage(
  637. XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
  638. new Object[]{ "-XP" })); //"Missing argument for);
  639. }
  640. else
  641. {
  642. if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-')
  643. i++;
  644. printInvalidXalanOption("-XP");
  645. }
  646. }
  647. // Enable template inlining.
  648. else if ("-XN".equalsIgnoreCase(argv[i]))
  649. {
  650. if (useXSLTC)
  651. {
  652. tfactory.setAttribute("enable-inlining", "true");
  653. }
  654. else
  655. printInvalidXalanOption("-XN");
  656. }
  657. // Turns on additional debugging message output
  658. else if ("-XX".equalsIgnoreCase(argv[i]))
  659. {
  660. if (useXSLTC)
  661. {
  662. tfactory.setAttribute("debug", "true");
  663. }
  664. else
  665. printInvalidXalanOption("-XX");
  666. }
  667. // Create the Transformer from the translet if the translet class is newer
  668. // than the stylesheet.
  669. else if ("-XT".equalsIgnoreCase(argv[i]))
  670. {
  671. if (useXSLTC)
  672. {
  673. tfactory.setAttribute("auto-translet", "true");
  674. }
  675. else
  676. printInvalidXalanOption("-XT");
  677. }
  678. else
  679. System.err.println(
  680. XSLMessages.createMessage(
  681. XSLTErrorResources.ER_INVALID_OPTION, new Object[]{ argv[i] })); //"Invalid argument:);
  682. }
  683. // Print usage instructions if no xml and xsl file is specified in the command line
  684. if (inFileName == null && xslFileName == null)
  685. {
  686. System.err.println(resbundle.getString("xslProc_no_input"));
  687. doExit(-1);
  688. }
  689. // Note that there are usage cases for calling us without a -IN arg
  690. // The main XSL transformation occurs here!
  691. try
  692. {
  693. long start = System.currentTimeMillis();
  694. if (null != dumpFileName)
  695. {
  696. dumpWriter = new PrintWriter(new FileWriter(dumpFileName));
  697. }
  698. Templates stylesheet = null;
  699. if (null != xslFileName)
  700. {
  701. if (flavor.equals("d2d"))
  702. {
  703. // Parse in the xml data into a DOM
  704. DocumentBuilderFactory dfactory =
  705. DocumentBuilderFactory.newInstance();
  706. dfactory.setNamespaceAware(true);
  707. DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
  708. Node xslDOM = docBuilder.parse(new InputSource(xslFileName));
  709. stylesheet = tfactory.newTemplates(new DOMSource(xslDOM,
  710. xslFileName));
  711. }
  712. else
  713. {
  714. // System.out.println("Calling newTemplates: "+xslFileName);
  715. stylesheet = tfactory.newTemplates(new StreamSource(xslFileName));
  716. // System.out.println("Done calling newTemplates: "+xslFileName);
  717. }
  718. }
  719. PrintWriter resultWriter;
  720. StreamResult strResult;
  721. if (null != outFileName)
  722. {
  723. strResult = new StreamResult(new FileOutputStream(outFileName));
  724. // One possible improvement might be to ensure this is
  725. // a valid URI before setting the systemId, but that
  726. // might have subtle changes that pre-existing users
  727. // might notice; we can think about that later -sc r1.46
  728. strResult.setSystemId(outFileName);
  729. }
  730. else
  731. {
  732. strResult = new StreamResult(System.out);
  733. // We used to default to incremental mode in this case.
  734. // We've since decided that since the -INCREMENTAL switch is
  735. // available, that default is probably not necessary nor
  736. // necessarily a good idea.
  737. }
  738. SAXTransformerFactory stf = (SAXTransformerFactory) tfactory;
  739. // This is currently controlled via TransformerFactoryImpl.
  740. if (!useXSLTC && useSourceLocation)
  741. stf.setAttribute(XalanProperties.SOURCE_LOCATION, Boolean.TRUE);
  742. // Did they pass in a stylesheet, or should we get it from the
  743. // document?
  744. if (null == stylesheet)
  745. {
  746. Source source =
  747. stf.getAssociatedStylesheet(new StreamSource(inFileName), media,
  748. null, null);
  749. if (null != source)
  750. stylesheet = tfactory.newTemplates(source);
  751. else
  752. {
  753. if (null != media)
  754. throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEET_IN_MEDIA, new Object[]{inFileName, media})); //"No stylesheet found in: "
  755. // + inFileName + ", media="
  756. // + media);
  757. else
  758. throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEET_PI, new Object[]{inFileName})); //"No xml-stylesheet PI found in: "
  759. //+ inFileName);
  760. }
  761. }
  762. if (null != stylesheet)
  763. {
  764. Transformer transformer = flavor.equals("th") ? null : stylesheet.newTransformer();
  765. // Override the output format?
  766. if (null != outputType)
  767. {
  768. transformer.setOutputProperty(OutputKeys.METHOD, outputType);
  769. }
  770. if (transformer instanceof org.apache.xalan.transformer.TransformerImpl)
  771. {
  772. org.apache.xalan.transformer.TransformerImpl impl = (org.apache.xalan.transformer.TransformerImpl)transformer;
  773. TraceManager tm = impl.getTraceManager();
  774. if (null != tracer)
  775. tm.addTraceListener(tracer);
  776. impl.setQuietConflictWarnings(quietConflictWarnings);
  777. // This is currently controlled via TransformerFactoryImpl.
  778. if (useSourceLocation)
  779. impl.setProperty(XalanProperties.SOURCE_LOCATION, Boolean.TRUE);
  780. if(recursionLimit>0)
  781. impl.setRecursionLimit(recursionLimit);
  782. // sc 28-Feb-01 if we re-implement this, please uncomment helpmsg in printArgOptions
  783. // impl.setDiagnosticsOutput( setQuietMode ? null : diagnosticsWriter );
  784. }
  785. int nParams = params.size();
  786. for (int i = 0; i < nParams; i += 2)
  787. {
  788. transformer.setParameter((String) params.elementAt(i),
  789. (String) params.elementAt(i + 1));
  790. }
  791. if (uriResolver != null)
  792. transformer.setURIResolver(uriResolver);
  793. if (null != inFileName)
  794. {
  795. if (flavor.equals("d2d"))
  796. {
  797. // Parse in the xml data into a DOM
  798. DocumentBuilderFactory dfactory =
  799. DocumentBuilderFactory.newInstance();
  800. dfactory.setCoalescing(true);
  801. dfactory.setNamespaceAware(true);
  802. DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
  803. if (entityResolver != null)
  804. docBuilder.setEntityResolver(entityResolver);
  805. Node xmlDoc = docBuilder.parse(new InputSource(inFileName));
  806. Document doc = docBuilder.newDocument();
  807. org.w3c.dom.DocumentFragment outNode =
  808. doc.createDocumentFragment();
  809. transformer.transform(new DOMSource(xmlDoc, inFileName),
  810. new DOMResult(outNode));
  811. // Now serialize output to disk with identity transformer
  812. Transformer serializer = stf.newTransformer();
  813. Properties serializationProps =
  814. stylesheet.getOutputProperties();
  815. serializer.setOutputProperties(serializationProps);
  816. if (contentHandler != null)
  817. {
  818. SAXResult result = new SAXResult(contentHandler);
  819. serializer.transform(new DOMSource(outNode), result);
  820. }
  821. else
  822. serializer.transform(new DOMSource(outNode), strResult);
  823. }
  824. else if (flavor.equals("th"))
  825. {
  826. for (int i = 0; i < 1; i++) // Loop for diagnosing bugs with inconsistent behavior
  827. {
  828. // System.out.println("Testing the TransformerHandler...");
  829. // ===============
  830. XMLReader reader = null;
  831. // Use JAXP1.1 ( if possible )
  832. try
  833. {
  834. javax.xml.parsers.SAXParserFactory factory =
  835. javax.xml.parsers.SAXParserFactory.newInstance();
  836. factory.setNamespaceAware(true);
  837. javax.xml.parsers.SAXParser jaxpParser =
  838. factory.newSAXParser();
  839. reader = jaxpParser.getXMLReader();
  840. }
  841. catch (javax.xml.parsers.ParserConfigurationException ex)
  842. {
  843. throw new org.xml.sax.SAXException(ex);
  844. }
  845. catch (javax.xml.parsers.FactoryConfigurationError ex1)
  846. {
  847. throw new org.xml.sax.SAXException(ex1.toString());
  848. }
  849. catch (NoSuchMethodError ex2){}
  850. catch (AbstractMethodError ame){}
  851. if (null == reader)
  852. {
  853. reader = XMLReaderFactory.createXMLReader();
  854. }
  855. if (!useXSLTC)
  856. stf.setAttribute(org.apache.xalan.processor.TransformerFactoryImpl.FEATURE_INCREMENTAL,
  857. Boolean.TRUE);
  858. TransformerHandler th = stf.newTransformerHandler(stylesheet);
  859. reader.setContentHandler(th);
  860. reader.setDTDHandler(th);
  861. if(th instanceof org.xml.sax.ErrorHandler)
  862. reader.setErrorHandler((org.xml.sax.ErrorHandler)th);
  863. try
  864. {
  865. reader.setProperty(
  866. "http://xml.org/sax/properties/lexical-handler", th);
  867. }
  868. catch (org.xml.sax.SAXNotRecognizedException e){}
  869. catch (org.xml.sax.SAXNotSupportedException e){}
  870. try
  871. {
  872. reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
  873. true);
  874. } catch (org.xml.sax.SAXException se) {}
  875. try
  876. {
  877. reader.setFeature("http://apache.org/xml/features/validation/dynamic",
  878. true);
  879. } catch (org.xml.sax.SAXException se) {}
  880. th.setResult(strResult);
  881. reader.parse(new InputSource(inFileName));
  882. }
  883. }
  884. else
  885. {
  886. if (entityResolver != null)
  887. {
  888. XMLReader reader = null;
  889. // Use JAXP1.1 ( if possible )
  890. try
  891. {
  892. javax.xml.parsers.SAXParserFactory factory =
  893. javax.xml.parsers.SAXParserFactory.newInstance();
  894. factory.setNamespaceAware(true);
  895. javax.xml.parsers.SAXParser jaxpParser =
  896. factory.newSAXParser();
  897. reader = jaxpParser.getXMLReader();
  898. }
  899. catch (javax.xml.parsers.ParserConfigurationException ex)
  900. {
  901. throw new org.xml.sax.SAXException(ex);
  902. }
  903. catch (javax.xml.parsers.FactoryConfigurationError ex1)
  904. {
  905. throw new org.xml.sax.SAXException(ex1.toString());
  906. }
  907. catch (NoSuchMethodError ex2){}
  908. catch (AbstractMethodError ame){}
  909. if (null == reader)
  910. {
  911. reader = XMLReaderFactory.createXMLReader();
  912. }
  913. reader.setEntityResolver(entityResolver);
  914. if (contentHandler != null)
  915. {
  916. SAXResult result = new SAXResult(contentHandler);
  917. transformer.transform(
  918. new SAXSource(reader, new InputSource(inFileName)),
  919. result);
  920. }
  921. else
  922. {
  923. transformer.transform(
  924. new SAXSource(reader, new InputSource(inFileName)),
  925. strResult);
  926. }
  927. }
  928. else if (contentHandler != null)
  929. {
  930. SAXResult result = new SAXResult(contentHandler);
  931. transformer.transform(new StreamSource(inFileName), result);
  932. }
  933. else
  934. {
  935. // System.out.println("Starting transform");
  936. transformer.transform(new StreamSource(inFileName),
  937. strResult);
  938. // System.out.println("Done with transform");
  939. }
  940. }
  941. }
  942. else
  943. {
  944. StringReader reader =
  945. new StringReader("<?xml version=\"1.0\"?> <doc/>");
  946. transformer.transform(new StreamSource(reader), strResult);
  947. }
  948. }
  949. else
  950. {
  951. diagnosticsWriter.println(
  952. XSLMessages.createMessage(
  953. XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
  954. doExit(-1);
  955. }
  956. // close output streams
  957. if (null != outFileName && strResult!=null)
  958. {
  959. java.io.OutputStream out = strResult.getOutputStream();
  960. java.io.Writer writer = strResult.getWriter();
  961. try
  962. {
  963. if (out != null) out.close();
  964. if (writer != null) writer.close();
  965. }
  966. catch(java.io.IOException ie) {}
  967. }
  968. long stop = System.currentTimeMillis();
  969. long millisecondsDuration = stop - start;
  970. if (doDiag)
  971. {
  972. Object[] msgArgs = new Object[]{ inFileName, xslFileName, new Long(millisecondsDuration) };
  973. String msg = XSLMessages.createMessage("diagTiming", msgArgs);
  974. diagnosticsWriter.println('\n');
  975. diagnosticsWriter.println(msg);
  976. }
  977. }
  978. catch (Throwable throwable)
  979. {
  980. while (throwable
  981. instanceof org.apache.xml.utils.WrappedRuntimeException)
  982. {
  983. throwable =
  984. ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException();
  985. }
  986. if ((throwable instanceof NullPointerException)
  987. || (throwable instanceof ClassCastException))
  988. doStackDumpOnError = true;
  989. diagnosticsWriter.println();
  990. if (doStackDumpOnError)
  991. throwable.printStackTrace(dumpWriter);
  992. else
  993. {
  994. DefaultErrorHandler.printLocation(diagnosticsWriter, throwable);
  995. diagnosticsWriter.println(
  996. XSLMessages.createMessage(XSLTErrorResources.ER_XSLT_ERROR, null)
  997. + " (" + throwable.getClass().getName() + "): "
  998. + throwable.getMessage());
  999. }
  1000. // diagnosticsWriter.println(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
  1001. if (null != dumpFileName)
  1002. {
  1003. dumpWriter.close();
  1004. }
  1005. doExit(-1);
  1006. }
  1007. if (null != dumpFileName)
  1008. {
  1009. dumpWriter.close();
  1010. }
  1011. if (null != diagnosticsWriter)
  1012. {
  1013. // diagnosticsWriter.close();
  1014. }
  1015. // if(!setQuietMode)
  1016. // diagnosticsWriter.println(resbundle.getString("xsldone")); //"Xalan: done");
  1017. // else
  1018. diagnosticsWriter.println(""); //"Xalan: done");
  1019. }
  1020. }
  1021. /** It is _much_ easier to debug under VJ++ if I can set a single breakpoint
  1022. * before this blows itself out of the water...
  1023. * (I keep checking this in, it keeps vanishing. Grr!)
  1024. * */
  1025. static void doExit(int i)
  1026. {
  1027. System.exit(i);
  1028. }
  1029. /**
  1030. * Wait for a return key to continue
  1031. *
  1032. * @param resbundle The resource bundle
  1033. */
  1034. private static void waitForReturnKey(ResourceBundle resbundle)
  1035. {
  1036. System.out.println(resbundle.getString("xslProc_return_to_continue"));
  1037. try
  1038. {
  1039. while (System.in.read() != '\n');
  1040. }
  1041. catch (java.io.IOException e) { }
  1042. }
  1043. /**
  1044. * Print a message if an option cannot be used with -XSLTC.
  1045. *
  1046. * @param option The option String
  1047. */
  1048. private static void printInvalidXSLTCOption(String option)
  1049. {
  1050. System.err.println(XSLMessages.createMessage("xslProc_invalid_xsltc_option", new Object[]{option}));
  1051. }
  1052. /**
  1053. * Print a message if an option can only be used with -XSLTC.
  1054. *
  1055. * @param option The option String
  1056. */
  1057. private static void printInvalidXalanOption(String option)
  1058. {
  1059. System.err.println(XSLMessages.createMessage("xslProc_invalid_xalan_option", new Object[]{option}));
  1060. }
  1061. }