001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: Process.java 475586 2006-11-16 05:19:36Z minchau $ 020 */ 021 package org.apache.xalan.xslt; 022 023 import java.io.FileOutputStream; 024 import java.io.FileWriter; 025 import java.io.PrintWriter; 026 import java.io.StringReader; 027 import java.util.Properties; 028 import java.util.ResourceBundle; 029 import java.util.Vector; 030 031 import javax.xml.XMLConstants; 032 import javax.xml.parsers.DocumentBuilder; 033 import javax.xml.parsers.DocumentBuilderFactory; 034 import javax.xml.parsers.ParserConfigurationException; 035 import javax.xml.transform.OutputKeys; 036 import javax.xml.transform.Source; 037 import javax.xml.transform.Templates; 038 import javax.xml.transform.Transformer; 039 import javax.xml.transform.TransformerConfigurationException; 040 import javax.xml.transform.TransformerException; 041 import javax.xml.transform.TransformerFactory; 042 import javax.xml.transform.TransformerFactoryConfigurationError; 043 import javax.xml.transform.URIResolver; 044 import javax.xml.transform.dom.DOMResult; 045 import javax.xml.transform.dom.DOMSource; 046 import javax.xml.transform.sax.SAXResult; 047 import javax.xml.transform.sax.SAXSource; 048 import javax.xml.transform.sax.SAXTransformerFactory; 049 import javax.xml.transform.sax.TransformerHandler; 050 import javax.xml.transform.stream.StreamResult; 051 import javax.xml.transform.stream.StreamSource; 052 053 import org.apache.xalan.Version; 054 import org.apache.xalan.res.XSLMessages; 055 import org.apache.xalan.res.XSLTErrorResources; 056 import org.apache.xalan.trace.PrintTraceListener; 057 import org.apache.xalan.trace.TraceManager; 058 import org.apache.xalan.transformer.XalanProperties; 059 import org.apache.xml.utils.DefaultErrorHandler; 060 061 import org.w3c.dom.Document; 062 import org.w3c.dom.Node; 063 064 import org.xml.sax.ContentHandler; 065 import org.xml.sax.EntityResolver; 066 import org.xml.sax.InputSource; 067 import org.xml.sax.XMLReader; 068 import org.xml.sax.helpers.XMLReaderFactory; 069 070 /** 071 * The main() method handles the Xalan command-line interface. 072 * @xsl.usage general 073 */ 074 public class Process 075 { 076 /** 077 * Prints argument options. 078 * 079 * @param resbundle Resource bundle 080 */ 081 protected static void printArgOptions(ResourceBundle resbundle) 082 { 083 System.out.println(resbundle.getString("xslProc_option")); //"xslproc options: "); 084 System.out.println("\n\t\t\t" + resbundle.getString("xslProc_common_options") + "\n"); 085 System.out.println(resbundle.getString("optionXSLTC")); //" [-XSLTC (use XSLTC for transformation)] 086 System.out.println(resbundle.getString("optionIN")); //" [-IN inputXMLURL]"); 087 System.out.println(resbundle.getString("optionXSL")); //" [-XSL XSLTransformationURL]"); 088 System.out.println(resbundle.getString("optionOUT")); //" [-OUT outputFileName]"); 089 090 // System.out.println(resbundle.getString("optionE")); //" [-E (Do not expand entity refs)]"); 091 System.out.println(resbundle.getString("optionV")); //" [-V (Version info)]"); 092 093 // System.out.println(resbundle.getString("optionVALIDATE")); //" [-VALIDATE (Set whether validation occurs. Validation is off by default.)]"); 094 System.out.println(resbundle.getString("optionEDUMP")); //" [-EDUMP {optional filename} (Do stackdump on error.)]"); 095 System.out.println(resbundle.getString("optionXML")); //" [-XML (Use XML formatter and add XML header.)]"); 096 System.out.println(resbundle.getString("optionTEXT")); //" [-TEXT (Use simple Text formatter.)]"); 097 System.out.println(resbundle.getString("optionHTML")); //" [-HTML (Use HTML formatter.)]"); 098 System.out.println(resbundle.getString("optionPARAM")); //" [-PARAM name expression (Set a stylesheet parameter)]"); 099 100 System.out.println(resbundle.getString("optionMEDIA")); 101 System.out.println(resbundle.getString("optionFLAVOR")); 102 System.out.println(resbundle.getString("optionDIAG")); 103 System.out.println(resbundle.getString("optionURIRESOLVER")); //" [-URIRESOLVER full class name (URIResolver to be used to resolve URIs)]"); 104 System.out.println(resbundle.getString("optionENTITYRESOLVER")); //" [-ENTITYRESOLVER full class name (EntityResolver to be used to resolve entities)]"); 105 waitForReturnKey(resbundle); 106 System.out.println(resbundle.getString("optionCONTENTHANDLER")); //" [-CONTENTHANDLER full class name (ContentHandler to be used to serialize output)]"); 107 System.out.println(resbundle.getString("optionSECUREPROCESSING")); //" [-SECURE (set the secure processing feature to true)]"); 108 109 System.out.println("\n\t\t\t" + resbundle.getString("xslProc_xalan_options") + "\n"); 110 111 System.out.println(resbundle.getString("optionQC")); //" [-QC (Quiet Pattern Conflicts Warnings)]"); 112 113 // System.out.println(resbundle.getString("optionQ")); //" [-Q (Quiet Mode)]"); // sc 28-Feb-01 commented out 114 System.out.println(resbundle.getString("optionTT")); //" [-TT (Trace the templates as they are being called.)]"); 115 System.out.println(resbundle.getString("optionTG")); //" [-TG (Trace each generation event.)]"); 116 System.out.println(resbundle.getString("optionTS")); //" [-TS (Trace each selection event.)]"); 117 System.out.println(resbundle.getString("optionTTC")); //" [-TTC (Trace the template children as they are being processed.)]"); 118 System.out.println(resbundle.getString("optionTCLASS")); //" [-TCLASS (TraceListener class for trace extensions.)]"); 119 System.out.println(resbundle.getString("optionLINENUMBERS")); //" [-L use line numbers]" 120 System.out.println(resbundle.getString("optionINCREMENTAL")); 121 System.out.println(resbundle.getString("optionNOOPTIMIMIZE")); 122 System.out.println(resbundle.getString("optionRL")); 123 124 System.out.println("\n\t\t\t" + resbundle.getString("xslProc_xsltc_options") + "\n"); 125 System.out.println(resbundle.getString("optionXO")); 126 waitForReturnKey(resbundle); 127 System.out.println(resbundle.getString("optionXD")); 128 System.out.println(resbundle.getString("optionXJ")); 129 System.out.println(resbundle.getString("optionXP")); 130 System.out.println(resbundle.getString("optionXN")); 131 System.out.println(resbundle.getString("optionXX")); 132 System.out.println(resbundle.getString("optionXT")); 133 } 134 135 /** 136 * Command line interface to transform an XML document according to 137 * the instructions found in an XSL stylesheet. 138 * <p>The Process class provides basic functionality for 139 * performing transformations from the command line. To see a 140 * list of arguments supported, call with zero arguments.</p> 141 * <p>To set stylesheet parameters from the command line, use 142 * <code>-PARAM name expression</code>. If you want to set the 143 * parameter to a string value, simply pass the string value 144 * as-is, and it will be interpreted as a string. (Note: if 145 * the value has spaces in it, you may need to quote it depending 146 * on your shell environment).</p> 147 * 148 * @param argv Input parameters from command line 149 */ 150 public static void main(String argv[]) 151 { 152 153 // Runtime.getRuntime().traceMethodCalls(false); // turns Java tracing off 154 boolean doStackDumpOnError = false; 155 boolean setQuietMode = false; 156 boolean doDiag = false; 157 String msg = null; 158 boolean isSecureProcessing = false; 159 160 // Runtime.getRuntime().traceMethodCalls(false); 161 // Runtime.getRuntime().traceInstructions(false); 162 163 /** 164 * The default diagnostic writer... 165 */ 166 java.io.PrintWriter diagnosticsWriter = new PrintWriter(System.err, true); 167 java.io.PrintWriter dumpWriter = diagnosticsWriter; 168 ResourceBundle resbundle = 169 (XSLMessages.loadResourceBundle( 170 org.apache.xml.utils.res.XResourceBundle.ERROR_RESOURCES)); 171 String flavor = "s2s"; 172 173 if (argv.length < 1) 174 { 175 printArgOptions(resbundle); 176 } 177 else 178 { 179 boolean useXSLTC = false; 180 for (int i = 0; i < argv.length; i++) 181 { 182 if ("-XSLTC".equalsIgnoreCase(argv[i])) 183 { 184 useXSLTC = true; 185 } 186 } 187 188 TransformerFactory tfactory; 189 if (useXSLTC) 190 { 191 String key = "javax.xml.transform.TransformerFactory"; 192 String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl"; 193 Properties props = System.getProperties(); 194 props.put(key, value); 195 System.setProperties(props); 196 } 197 198 try 199 { 200 tfactory = TransformerFactory.newInstance(); 201 tfactory.setErrorListener(new DefaultErrorHandler(false)); 202 } 203 catch (TransformerFactoryConfigurationError pfe) 204 { 205 pfe.printStackTrace(dumpWriter); 206 // "XSL Process was not successful."); 207 msg = XSLMessages.createMessage( 208 XSLTErrorResources.ER_NOT_SUCCESSFUL, null); 209 diagnosticsWriter.println(msg); 210 211 tfactory = null; // shut up compiler 212 213 doExit(msg); 214 } 215 216 boolean formatOutput = false; 217 boolean useSourceLocation = false; 218 String inFileName = null; 219 String outFileName = null; 220 String dumpFileName = null; 221 String xslFileName = null; 222 String treedumpFileName = null; 223 PrintTraceListener tracer = null; 224 String outputType = null; 225 String media = null; 226 Vector params = new Vector(); 227 boolean quietConflictWarnings = false; 228 URIResolver uriResolver = null; 229 EntityResolver entityResolver = null; 230 ContentHandler contentHandler = null; 231 int recursionLimit=-1; 232 233 for (int i = 0; i < argv.length; i++) 234 { 235 if ("-XSLTC".equalsIgnoreCase(argv[i])) 236 { 237 // The -XSLTC option has been processed. 238 } 239 else if ("-TT".equalsIgnoreCase(argv[i])) 240 { 241 if (!useXSLTC) 242 { 243 if (null == tracer) 244 tracer = new PrintTraceListener(diagnosticsWriter); 245 246 tracer.m_traceTemplates = true; 247 } 248 else 249 printInvalidXSLTCOption("-TT"); 250 251 // tfactory.setTraceTemplates(true); 252 } 253 else if ("-TG".equalsIgnoreCase(argv[i])) 254 { 255 if (!useXSLTC) 256 { 257 if (null == tracer) 258 tracer = new PrintTraceListener(diagnosticsWriter); 259 260 tracer.m_traceGeneration = true; 261 } 262 else 263 printInvalidXSLTCOption("-TG"); 264 265 // tfactory.setTraceSelect(true); 266 } 267 else if ("-TS".equalsIgnoreCase(argv[i])) 268 { 269 if (!useXSLTC) 270 { 271 if (null == tracer) 272 tracer = new PrintTraceListener(diagnosticsWriter); 273 274 tracer.m_traceSelection = true; 275 } 276 else 277 printInvalidXSLTCOption("-TS"); 278 279 // tfactory.setTraceTemplates(true); 280 } 281 else if ("-TTC".equalsIgnoreCase(argv[i])) 282 { 283 if (!useXSLTC) 284 { 285 if (null == tracer) 286 tracer = new PrintTraceListener(diagnosticsWriter); 287 288 tracer.m_traceElements = true; 289 } 290 else 291 printInvalidXSLTCOption("-TTC"); 292 293 // tfactory.setTraceTemplateChildren(true); 294 } 295 else if ("-INDENT".equalsIgnoreCase(argv[i])) 296 { 297 int indentAmount; 298 299 if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-')) 300 { 301 indentAmount = Integer.parseInt(argv[++i]); 302 } 303 else 304 { 305 indentAmount = 0; 306 } 307 308 // TBD: 309 // xmlProcessorLiaison.setIndent(indentAmount); 310 } 311 else if ("-IN".equalsIgnoreCase(argv[i])) 312 { 313 if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') 314 inFileName = argv[++i]; 315 else 316 System.err.println( 317 XSLMessages.createMessage( 318 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 319 new Object[]{ "-IN" })); //"Missing argument for); 320 } 321 else if ("-MEDIA".equalsIgnoreCase(argv[i])) 322 { 323 if (i + 1 < argv.length) 324 media = argv[++i]; 325 else 326 System.err.println( 327 XSLMessages.createMessage( 328 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 329 new Object[]{ "-MEDIA" })); //"Missing argument for); 330 } 331 else if ("-OUT".equalsIgnoreCase(argv[i])) 332 { 333 if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') 334 outFileName = argv[++i]; 335 else 336 System.err.println( 337 XSLMessages.createMessage( 338 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 339 new Object[]{ "-OUT" })); //"Missing argument for); 340 } 341 else if ("-XSL".equalsIgnoreCase(argv[i])) 342 { 343 if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') 344 xslFileName = argv[++i]; 345 else 346 System.err.println( 347 XSLMessages.createMessage( 348 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 349 new Object[]{ "-XSL" })); //"Missing argument for); 350 } 351 else if ("-FLAVOR".equalsIgnoreCase(argv[i])) 352 { 353 if (i + 1 < argv.length) 354 { 355 flavor = argv[++i]; 356 } 357 else 358 System.err.println( 359 XSLMessages.createMessage( 360 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 361 new Object[]{ "-FLAVOR" })); //"Missing argument for); 362 } 363 else if ("-PARAM".equalsIgnoreCase(argv[i])) 364 { 365 if (i + 2 < argv.length) 366 { 367 String name = argv[++i]; 368 369 params.addElement(name); 370 371 String expression = argv[++i]; 372 373 params.addElement(expression); 374 } 375 else 376 System.err.println( 377 XSLMessages.createMessage( 378 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 379 new Object[]{ "-PARAM" })); //"Missing argument for); 380 } 381 else if ("-E".equalsIgnoreCase(argv[i])) 382 { 383 384 // TBD: 385 // xmlProcessorLiaison.setShouldExpandEntityRefs(false); 386 } 387 else if ("-V".equalsIgnoreCase(argv[i])) 388 { 389 diagnosticsWriter.println(resbundle.getString("version") //">>>>>>> Xalan Version " 390 + Version.getVersion() + ", " + 391 392 /* xmlProcessorLiaison.getParserDescription()+ */ 393 resbundle.getString("version2")); // "<<<<<<<"); 394 } 395 else if ("-QC".equalsIgnoreCase(argv[i])) 396 { 397 if (!useXSLTC) 398 quietConflictWarnings = true; 399 else 400 printInvalidXSLTCOption("-QC"); 401 } 402 else if ("-Q".equalsIgnoreCase(argv[i])) 403 { 404 setQuietMode = true; 405 } 406 else if ("-DIAG".equalsIgnoreCase(argv[i])) 407 { 408 doDiag = true; 409 } 410 else if ("-XML".equalsIgnoreCase(argv[i])) 411 { 412 outputType = "xml"; 413 } 414 else if ("-TEXT".equalsIgnoreCase(argv[i])) 415 { 416 outputType = "text"; 417 } 418 else if ("-HTML".equalsIgnoreCase(argv[i])) 419 { 420 outputType = "html"; 421 } 422 else if ("-EDUMP".equalsIgnoreCase(argv[i])) 423 { 424 doStackDumpOnError = true; 425 426 if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-')) 427 { 428 dumpFileName = argv[++i]; 429 } 430 } 431 else if ("-URIRESOLVER".equalsIgnoreCase(argv[i])) 432 { 433 if (i + 1 < argv.length) 434 { 435 try 436 { 437 uriResolver = (URIResolver) ObjectFactory.newInstance( 438 argv[++i], ObjectFactory.findClassLoader(), true); 439 440 tfactory.setURIResolver(uriResolver); 441 } 442 catch (ObjectFactory.ConfigurationError cnfe) 443 { 444 msg = XSLMessages.createMessage( 445 XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION, 446 new Object[]{ "-URIResolver" }); 447 System.err.println(msg); 448 doExit(msg); 449 } 450 } 451 else 452 { 453 msg = XSLMessages.createMessage( 454 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 455 new Object[]{ "-URIResolver" }); //"Missing argument for); 456 System.err.println(msg); 457 doExit(msg); 458 } 459 } 460 else if ("-ENTITYRESOLVER".equalsIgnoreCase(argv[i])) 461 { 462 if (i + 1 < argv.length) 463 { 464 try 465 { 466 entityResolver = (EntityResolver) ObjectFactory.newInstance( 467 argv[++i], ObjectFactory.findClassLoader(), true); 468 } 469 catch (ObjectFactory.ConfigurationError cnfe) 470 { 471 msg = XSLMessages.createMessage( 472 XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION, 473 new Object[]{ "-EntityResolver" }); 474 System.err.println(msg); 475 doExit(msg); 476 } 477 } 478 else 479 { 480 // "Missing argument for); 481 msg = XSLMessages.createMessage( 482 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 483 new Object[]{ "-EntityResolver" }); 484 System.err.println(msg); 485 doExit(msg); 486 } 487 } 488 else if ("-CONTENTHANDLER".equalsIgnoreCase(argv[i])) 489 { 490 if (i + 1 < argv.length) 491 { 492 try 493 { 494 contentHandler = (ContentHandler) ObjectFactory.newInstance( 495 argv[++i], ObjectFactory.findClassLoader(), true); 496 } 497 catch (ObjectFactory.ConfigurationError cnfe) 498 { 499 msg = XSLMessages.createMessage( 500 XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION, 501 new Object[]{ "-ContentHandler" }); 502 System.err.println(msg); 503 doExit(msg); 504 } 505 } 506 else 507 { 508 // "Missing argument for); 509 msg = XSLMessages.createMessage( 510 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 511 new Object[]{ "-ContentHandler" }); 512 System.err.println(msg); 513 doExit(msg); 514 } 515 } 516 else if ("-L".equalsIgnoreCase(argv[i])) 517 { 518 if (!useXSLTC) 519 tfactory.setAttribute(XalanProperties.SOURCE_LOCATION, Boolean.TRUE); 520 else 521 printInvalidXSLTCOption("-L"); 522 } 523 else if ("-INCREMENTAL".equalsIgnoreCase(argv[i])) 524 { 525 if (!useXSLTC) 526 tfactory.setAttribute 527 ("http://xml.apache.org/xalan/features/incremental", 528 java.lang.Boolean.TRUE); 529 else 530 printInvalidXSLTCOption("-INCREMENTAL"); 531 } 532 else if ("-NOOPTIMIZE".equalsIgnoreCase(argv[i])) 533 { 534 // Default is true. 535 // 536 // %REVIEW% We should have a generalized syntax for negative 537 // switches... and probably should accept the inverse even 538 // if it is the default. 539 if (!useXSLTC) 540 tfactory.setAttribute 541 ("http://xml.apache.org/xalan/features/optimize", 542 java.lang.Boolean.FALSE); 543 else 544 printInvalidXSLTCOption("-NOOPTIMIZE"); 545 } 546 else if ("-RL".equalsIgnoreCase(argv[i])) 547 { 548 if (!useXSLTC) 549 { 550 if (i + 1 < argv.length) 551 recursionLimit = Integer.parseInt(argv[++i]); 552 else 553 System.err.println( 554 XSLMessages.createMessage( 555 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 556 new Object[]{ "-rl" })); //"Missing argument for); 557 } 558 else 559 { 560 if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') 561 i++; 562 563 printInvalidXSLTCOption("-RL"); 564 } 565 } 566 // Generate the translet class and optionally specify the name 567 // of the translet class. 568 else if ("-XO".equalsIgnoreCase(argv[i])) 569 { 570 if (useXSLTC) 571 { 572 if (i + 1 < argv.length && argv[i+1].charAt(0) != '-') 573 { 574 tfactory.setAttribute("generate-translet", "true"); 575 tfactory.setAttribute("translet-name", argv[++i]); 576 } 577 else 578 tfactory.setAttribute("generate-translet", "true"); 579 } 580 else 581 { 582 if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') 583 i++; 584 printInvalidXalanOption("-XO"); 585 } 586 } 587 // Specify the destination directory for the translet classes. 588 else if ("-XD".equalsIgnoreCase(argv[i])) 589 { 590 if (useXSLTC) 591 { 592 if (i + 1 < argv.length && argv[i+1].charAt(0) != '-') 593 tfactory.setAttribute("destination-directory", argv[++i]); 594 else 595 System.err.println( 596 XSLMessages.createMessage( 597 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 598 new Object[]{ "-XD" })); //"Missing argument for); 599 600 } 601 else 602 { 603 if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') 604 i++; 605 606 printInvalidXalanOption("-XD"); 607 } 608 } 609 // Specify the jar file name which the translet classes are packaged into. 610 else if ("-XJ".equalsIgnoreCase(argv[i])) 611 { 612 if (useXSLTC) 613 { 614 if (i + 1 < argv.length && argv[i+1].charAt(0) != '-') 615 { 616 tfactory.setAttribute("generate-translet", "true"); 617 tfactory.setAttribute("jar-name", argv[++i]); 618 } 619 else 620 System.err.println( 621 XSLMessages.createMessage( 622 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 623 new Object[]{ "-XJ" })); //"Missing argument for); 624 } 625 else 626 { 627 if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') 628 i++; 629 630 printInvalidXalanOption("-XJ"); 631 } 632 633 } 634 // Specify the package name prefix for the generated translet classes. 635 else if ("-XP".equalsIgnoreCase(argv[i])) 636 { 637 if (useXSLTC) 638 { 639 if (i + 1 < argv.length && argv[i+1].charAt(0) != '-') 640 tfactory.setAttribute("package-name", argv[++i]); 641 else 642 System.err.println( 643 XSLMessages.createMessage( 644 XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION, 645 new Object[]{ "-XP" })); //"Missing argument for); 646 } 647 else 648 { 649 if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') 650 i++; 651 652 printInvalidXalanOption("-XP"); 653 } 654 655 } 656 // Enable template inlining. 657 else if ("-XN".equalsIgnoreCase(argv[i])) 658 { 659 if (useXSLTC) 660 { 661 tfactory.setAttribute("enable-inlining", "true"); 662 } 663 else 664 printInvalidXalanOption("-XN"); 665 } 666 // Turns on additional debugging message output 667 else if ("-XX".equalsIgnoreCase(argv[i])) 668 { 669 if (useXSLTC) 670 { 671 tfactory.setAttribute("debug", "true"); 672 } 673 else 674 printInvalidXalanOption("-XX"); 675 } 676 // Create the Transformer from the translet if the translet class is newer 677 // than the stylesheet. 678 else if ("-XT".equalsIgnoreCase(argv[i])) 679 { 680 if (useXSLTC) 681 { 682 tfactory.setAttribute("auto-translet", "true"); 683 } 684 else 685 printInvalidXalanOption("-XT"); 686 } 687 else if ("-SECURE".equalsIgnoreCase(argv[i])) 688 { 689 isSecureProcessing = true; 690 try 691 { 692 tfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 693 } 694 catch (TransformerConfigurationException e) {} 695 } 696 else 697 System.err.println( 698 XSLMessages.createMessage( 699 XSLTErrorResources.ER_INVALID_OPTION, new Object[]{ argv[i] })); //"Invalid argument:); 700 } 701 702 // Print usage instructions if no xml and xsl file is specified in the command line 703 if (inFileName == null && xslFileName == null) 704 { 705 msg = resbundle.getString("xslProc_no_input"); 706 System.err.println(msg); 707 doExit(msg); 708 } 709 710 // Note that there are usage cases for calling us without a -IN arg 711 // The main XSL transformation occurs here! 712 try 713 { 714 long start = System.currentTimeMillis(); 715 716 if (null != dumpFileName) 717 { 718 dumpWriter = new PrintWriter(new FileWriter(dumpFileName)); 719 } 720 721 Templates stylesheet = null; 722 723 if (null != xslFileName) 724 { 725 if (flavor.equals("d2d")) 726 { 727 728 // Parse in the xml data into a DOM 729 DocumentBuilderFactory dfactory = 730 DocumentBuilderFactory.newInstance(); 731 732 dfactory.setNamespaceAware(true); 733 734 if (isSecureProcessing) 735 { 736 try 737 { 738 dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 739 } 740 catch (ParserConfigurationException pce) {} 741 } 742 743 DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); 744 Node xslDOM = docBuilder.parse(new InputSource(xslFileName)); 745 746 stylesheet = tfactory.newTemplates(new DOMSource(xslDOM, 747 xslFileName)); 748 } 749 else 750 { 751 // System.out.println("Calling newTemplates: "+xslFileName); 752 stylesheet = tfactory.newTemplates(new StreamSource(xslFileName)); 753 // System.out.println("Done calling newTemplates: "+xslFileName); 754 } 755 } 756 757 PrintWriter resultWriter; 758 StreamResult strResult; 759 760 if (null != outFileName) 761 { 762 strResult = new StreamResult(new FileOutputStream(outFileName)); 763 // One possible improvement might be to ensure this is 764 // a valid URI before setting the systemId, but that 765 // might have subtle changes that pre-existing users 766 // might notice; we can think about that later -sc r1.46 767 strResult.setSystemId(outFileName); 768 } 769 else 770 { 771 strResult = new StreamResult(System.out); 772 // We used to default to incremental mode in this case. 773 // We've since decided that since the -INCREMENTAL switch is 774 // available, that default is probably not necessary nor 775 // necessarily a good idea. 776 } 777 778 SAXTransformerFactory stf = (SAXTransformerFactory) tfactory; 779 780 // This is currently controlled via TransformerFactoryImpl. 781 if (!useXSLTC && useSourceLocation) 782 stf.setAttribute(XalanProperties.SOURCE_LOCATION, Boolean.TRUE); 783 784 // Did they pass in a stylesheet, or should we get it from the 785 // document? 786 if (null == stylesheet) 787 { 788 Source source = 789 stf.getAssociatedStylesheet(new StreamSource(inFileName), media, 790 null, null); 791 792 if (null != source) 793 stylesheet = tfactory.newTemplates(source); 794 else 795 { 796 if (null != media) 797 throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEET_IN_MEDIA, new Object[]{inFileName, media})); //"No stylesheet found in: " 798 // + inFileName + ", media=" 799 // + media); 800 else 801 throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEET_PI, new Object[]{inFileName})); //"No xml-stylesheet PI found in: " 802 //+ inFileName); 803 } 804 } 805 806 if (null != stylesheet) 807 { 808 Transformer transformer = flavor.equals("th") ? null : stylesheet.newTransformer(); 809 transformer.setErrorListener(new DefaultErrorHandler(false)); 810 811 // Override the output format? 812 if (null != outputType) 813 { 814 transformer.setOutputProperty(OutputKeys.METHOD, outputType); 815 } 816 817 if (transformer instanceof org.apache.xalan.transformer.TransformerImpl) 818 { 819 org.apache.xalan.transformer.TransformerImpl impl = (org.apache.xalan.transformer.TransformerImpl)transformer; 820 TraceManager tm = impl.getTraceManager(); 821 822 if (null != tracer) 823 tm.addTraceListener(tracer); 824 825 impl.setQuietConflictWarnings(quietConflictWarnings); 826 827 // This is currently controlled via TransformerFactoryImpl. 828 if (useSourceLocation) 829 impl.setProperty(XalanProperties.SOURCE_LOCATION, Boolean.TRUE); 830 831 if(recursionLimit>0) 832 impl.setRecursionLimit(recursionLimit); 833 834 // sc 28-Feb-01 if we re-implement this, please uncomment helpmsg in printArgOptions 835 // impl.setDiagnosticsOutput( setQuietMode ? null : diagnosticsWriter ); 836 } 837 838 int nParams = params.size(); 839 840 for (int i = 0; i < nParams; i += 2) 841 { 842 transformer.setParameter((String) params.elementAt(i), 843 (String) params.elementAt(i + 1)); 844 } 845 846 if (uriResolver != null) 847 transformer.setURIResolver(uriResolver); 848 849 if (null != inFileName) 850 { 851 if (flavor.equals("d2d")) 852 { 853 854 // Parse in the xml data into a DOM 855 DocumentBuilderFactory dfactory = 856 DocumentBuilderFactory.newInstance(); 857 858 dfactory.setCoalescing(true); 859 dfactory.setNamespaceAware(true); 860 861 if (isSecureProcessing) 862 { 863 try 864 { 865 dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 866 } 867 catch (ParserConfigurationException pce) {} 868 } 869 870 DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); 871 872 if (entityResolver != null) 873 docBuilder.setEntityResolver(entityResolver); 874 875 Node xmlDoc = docBuilder.parse(new InputSource(inFileName)); 876 Document doc = docBuilder.newDocument(); 877 org.w3c.dom.DocumentFragment outNode = 878 doc.createDocumentFragment(); 879 880 transformer.transform(new DOMSource(xmlDoc, inFileName), 881 new DOMResult(outNode)); 882 883 // Now serialize output to disk with identity transformer 884 Transformer serializer = stf.newTransformer(); 885 serializer.setErrorListener(new DefaultErrorHandler(false)); 886 887 Properties serializationProps = 888 stylesheet.getOutputProperties(); 889 890 serializer.setOutputProperties(serializationProps); 891 892 if (contentHandler != null) 893 { 894 SAXResult result = new SAXResult(contentHandler); 895 896 serializer.transform(new DOMSource(outNode), result); 897 } 898 else 899 serializer.transform(new DOMSource(outNode), strResult); 900 } 901 else if (flavor.equals("th")) 902 { 903 for (int i = 0; i < 1; i++) // Loop for diagnosing bugs with inconsistent behavior 904 { 905 // System.out.println("Testing the TransformerHandler..."); 906 907 // =============== 908 XMLReader reader = null; 909 910 // Use JAXP1.1 ( if possible ) 911 try 912 { 913 javax.xml.parsers.SAXParserFactory factory = 914 javax.xml.parsers.SAXParserFactory.newInstance(); 915 916 factory.setNamespaceAware(true); 917 918 if (isSecureProcessing) 919 { 920 try 921 { 922 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 923 } 924 catch (org.xml.sax.SAXException se) {} 925 } 926 927 javax.xml.parsers.SAXParser jaxpParser = 928 factory.newSAXParser(); 929 930 reader = jaxpParser.getXMLReader(); 931 } 932 catch (javax.xml.parsers.ParserConfigurationException ex) 933 { 934 throw new org.xml.sax.SAXException(ex); 935 } 936 catch (javax.xml.parsers.FactoryConfigurationError ex1) 937 { 938 throw new org.xml.sax.SAXException(ex1.toString()); 939 } 940 catch (NoSuchMethodError ex2){} 941 catch (AbstractMethodError ame){} 942 943 if (null == reader) 944 { 945 reader = XMLReaderFactory.createXMLReader(); 946 } 947 948 if (!useXSLTC) 949 stf.setAttribute(org.apache.xalan.processor.TransformerFactoryImpl.FEATURE_INCREMENTAL, 950 Boolean.TRUE); 951 952 TransformerHandler th = stf.newTransformerHandler(stylesheet); 953 954 reader.setContentHandler(th); 955 reader.setDTDHandler(th); 956 957 if(th instanceof org.xml.sax.ErrorHandler) 958 reader.setErrorHandler((org.xml.sax.ErrorHandler)th); 959 960 try 961 { 962 reader.setProperty( 963 "http://xml.org/sax/properties/lexical-handler", th); 964 } 965 catch (org.xml.sax.SAXNotRecognizedException e){} 966 catch (org.xml.sax.SAXNotSupportedException e){} 967 try 968 { 969 reader.setFeature("http://xml.org/sax/features/namespace-prefixes", 970 true); 971 } catch (org.xml.sax.SAXException se) {} 972 973 th.setResult(strResult); 974 975 reader.parse(new InputSource(inFileName)); 976 } 977 } 978 else 979 { 980 if (entityResolver != null) 981 { 982 XMLReader reader = null; 983 984 // Use JAXP1.1 ( if possible ) 985 try 986 { 987 javax.xml.parsers.SAXParserFactory factory = 988 javax.xml.parsers.SAXParserFactory.newInstance(); 989 990 factory.setNamespaceAware(true); 991 992 if (isSecureProcessing) 993 { 994 try 995 { 996 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 997 } 998 catch (org.xml.sax.SAXException se) {} 999 } 1000 1001 javax.xml.parsers.SAXParser jaxpParser = 1002 factory.newSAXParser(); 1003 1004 reader = jaxpParser.getXMLReader(); 1005 } 1006 catch (javax.xml.parsers.ParserConfigurationException ex) 1007 { 1008 throw new org.xml.sax.SAXException(ex); 1009 } 1010 catch (javax.xml.parsers.FactoryConfigurationError ex1) 1011 { 1012 throw new org.xml.sax.SAXException(ex1.toString()); 1013 } 1014 catch (NoSuchMethodError ex2){} 1015 catch (AbstractMethodError ame){} 1016 1017 if (null == reader) 1018 { 1019 reader = XMLReaderFactory.createXMLReader(); 1020 } 1021 1022 reader.setEntityResolver(entityResolver); 1023 1024 if (contentHandler != null) 1025 { 1026 SAXResult result = new SAXResult(contentHandler); 1027 1028 transformer.transform( 1029 new SAXSource(reader, new InputSource(inFileName)), 1030 result); 1031 } 1032 else 1033 { 1034 transformer.transform( 1035 new SAXSource(reader, new InputSource(inFileName)), 1036 strResult); 1037 } 1038 } 1039 else if (contentHandler != null) 1040 { 1041 SAXResult result = new SAXResult(contentHandler); 1042 1043 transformer.transform(new StreamSource(inFileName), result); 1044 } 1045 else 1046 { 1047 // System.out.println("Starting transform"); 1048 transformer.transform(new StreamSource(inFileName), 1049 strResult); 1050 // System.out.println("Done with transform"); 1051 } 1052 } 1053 } 1054 else 1055 { 1056 StringReader reader = 1057 new StringReader("<?xml version=\"1.0\"?> <doc/>"); 1058 1059 transformer.transform(new StreamSource(reader), strResult); 1060 } 1061 } 1062 else 1063 { 1064 // "XSL Process was not successful."); 1065 msg = XSLMessages.createMessage( 1066 XSLTErrorResources.ER_NOT_SUCCESSFUL, null); 1067 diagnosticsWriter.println(msg); 1068 doExit(msg); 1069 } 1070 1071 // close output streams 1072 if (null != outFileName && strResult!=null) 1073 { 1074 java.io.OutputStream out = strResult.getOutputStream(); 1075 java.io.Writer writer = strResult.getWriter(); 1076 try 1077 { 1078 if (out != null) out.close(); 1079 if (writer != null) writer.close(); 1080 } 1081 catch(java.io.IOException ie) {} 1082 } 1083 1084 long stop = System.currentTimeMillis(); 1085 long millisecondsDuration = stop - start; 1086 1087 if (doDiag) 1088 { 1089 Object[] msgArgs = new Object[]{ inFileName, xslFileName, new Long(millisecondsDuration) }; 1090 msg = XSLMessages.createMessage("diagTiming", msgArgs); 1091 diagnosticsWriter.println('\n'); 1092 diagnosticsWriter.println(msg); 1093 } 1094 1095 } 1096 catch (Throwable throwable) 1097 { 1098 while (throwable 1099 instanceof org.apache.xml.utils.WrappedRuntimeException) 1100 { 1101 throwable = 1102 ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException(); 1103 } 1104 1105 if ((throwable instanceof NullPointerException) 1106 || (throwable instanceof ClassCastException)) 1107 doStackDumpOnError = true; 1108 1109 diagnosticsWriter.println(); 1110 1111 if (doStackDumpOnError) 1112 throwable.printStackTrace(dumpWriter); 1113 else 1114 { 1115 DefaultErrorHandler.printLocation(diagnosticsWriter, throwable); 1116 diagnosticsWriter.println( 1117 XSLMessages.createMessage(XSLTErrorResources.ER_XSLT_ERROR, null) 1118 + " (" + throwable.getClass().getName() + "): " 1119 + throwable.getMessage()); 1120 } 1121 1122 // diagnosticsWriter.println(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful."); 1123 if (null != dumpFileName) 1124 { 1125 dumpWriter.close(); 1126 } 1127 1128 doExit(throwable.getMessage()); 1129 } 1130 1131 if (null != dumpFileName) 1132 { 1133 dumpWriter.close(); 1134 } 1135 1136 if (null != diagnosticsWriter) 1137 { 1138 1139 // diagnosticsWriter.close(); 1140 } 1141 1142 // if(!setQuietMode) 1143 // diagnosticsWriter.println(resbundle.getString("xsldone")); //"Xalan: done"); 1144 // else 1145 // diagnosticsWriter.println(""); //"Xalan: done"); 1146 } 1147 } 1148 1149 /** It is _much_ easier to debug under VJ++ if I can set a single breakpoint 1150 * before this blows itself out of the water... 1151 * (I keep checking this in, it keeps vanishing. Grr!) 1152 * */ 1153 static void doExit(String msg) 1154 { 1155 throw new RuntimeException(msg); 1156 } 1157 1158 /** 1159 * Wait for a return key to continue 1160 * 1161 * @param resbundle The resource bundle 1162 */ 1163 private static void waitForReturnKey(ResourceBundle resbundle) 1164 { 1165 System.out.println(resbundle.getString("xslProc_return_to_continue")); 1166 try 1167 { 1168 while (System.in.read() != '\n'); 1169 } 1170 catch (java.io.IOException e) { } 1171 } 1172 1173 /** 1174 * Print a message if an option cannot be used with -XSLTC. 1175 * 1176 * @param option The option String 1177 */ 1178 private static void printInvalidXSLTCOption(String option) 1179 { 1180 System.err.println(XSLMessages.createMessage("xslProc_invalid_xsltc_option", new Object[]{option})); 1181 } 1182 1183 /** 1184 * Print a message if an option can only be used with -XSLTC. 1185 * 1186 * @param option The option String 1187 */ 1188 private static void printInvalidXalanOption(String option) 1189 { 1190 System.err.println(XSLMessages.createMessage("xslProc_invalid_xalan_option", new Object[]{option})); 1191 } 1192 }