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