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 
  24 // This file is a copied and modified version of
  25 // com/sun/org/apache/xalan/internal/xslt/Process.java
  26 // which has been modified to only use public exported APIs.
  27 // The only adherence is with
  28 // com.sun.org.apache.xml.internal.utils.DefaultErrorHandler
  29 // which we try to instantiate using reflection, as that class
  30 // can do a better job at reporting error location.
  31 // We however don't have a hard dependency on it. We will use
  32 // our own ErrorHandler if the default one is not accessible.
  33 //
  34 import java.io.FileOutputStream;
  35 import java.io.FileWriter;
  36 import java.io.PrintWriter;
  37 import java.io.StringReader;
  38 import java.util.Properties;
  39 
  40 import javax.xml.XMLConstants;
  41 import javax.xml.parsers.DocumentBuilder;
  42 import javax.xml.parsers.DocumentBuilderFactory;
  43 import javax.xml.parsers.ParserConfigurationException;
  44 import javax.xml.transform.OutputKeys;
  45 import javax.xml.transform.Source;
  46 import javax.xml.transform.Templates;
  47 import javax.xml.transform.Transformer;
  48 import javax.xml.transform.TransformerConfigurationException;
  49 import javax.xml.transform.TransformerException;
  50 import javax.xml.transform.TransformerFactory;
  51 import javax.xml.transform.TransformerFactoryConfigurationError;
  52 import javax.xml.transform.URIResolver;
  53 import javax.xml.transform.dom.DOMResult;
  54 import javax.xml.transform.dom.DOMSource;
  55 import javax.xml.transform.sax.SAXResult;
  56 import javax.xml.transform.sax.SAXSource;
  57 import javax.xml.transform.sax.SAXTransformerFactory;
  58 import javax.xml.transform.sax.TransformerHandler;
  59 import javax.xml.transform.stream.StreamResult;
  60 import javax.xml.transform.stream.StreamSource;
  61 import java.lang.reflect.Constructor;
  62 import java.lang.reflect.Method;
  63 import java.util.ArrayList;
  64 import java.util.List;
  65 import javax.xml.transform.ErrorListener;
  66 import javax.xml.transform.SourceLocator;
  67 
  68 import org.w3c.dom.Document;
  69 import org.w3c.dom.Node;
  70 
  71 import org.xml.sax.ContentHandler;
  72 import org.xml.sax.EntityResolver;
  73 import org.xml.sax.ErrorHandler;
  74 import org.xml.sax.InputSource;
  75 import org.xml.sax.SAXException;
  76 import org.xml.sax.SAXParseException;
  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  */
  83 public class ProcessXSLT
  84 {
  85 
  86     /**
  87      * Prints argument options.
  88      *
  89      */
  90     protected static void printArgOptions() {
  91         System.out.println("xslproc options: ");
  92         System.out.println("\n\t\t\t" + "-Common Options-" + "\n");
  93         System.out.println("   [-XSLTC (use XSLTC for transformation)]");  //"    [-XSLTC (use XSLTC for transformation)]
  94         System.out.println("   [-IN inputXMLURL]");  //"    [-IN inputXMLURL]");
  95         System.out.println("   [-XSL XSLTransformationURL]");  //"   [-XSL XSLTransformationURL]");
  96         System.out.println("   [-OUT outputFileName]");  //"   [-OUT outputFileName]");
  97 
  98         System.out.println("   [-E (Do not expand entity refs)]");  //"   [-V (Version info)]");
  99 
 100         System.out.println("   [-EDUMP {optional filename} (Do stackdump on error.)]");  //"   [-EDUMP {optional filename} (Do stackdump on error.)]");
 101         System.out.println("   [-XML (Use XML formatter and add XML header.)]");  //"   [-XML (Use XML formatter and add XML header.)]");
 102         System.out.println("   [-TEXT (Use simple Text formatter.)]");  //"   [-TEXT (Use simple Text formatter.)]");
 103         System.out.println("   [-HTML (Use HTML formatter.)]");  //"   [-HTML (Use HTML formatter.)]");
 104         System.out.println( "   [-PARAM name expression (Set a stylesheet parameter)]");  //"   [-PARAM name expression (Set a stylesheet parameter)]");
 105 
 106         System.out.println("   [-MEDIA mediaType (use media attribute to find stylesheet associated with a document.)]");
 107         System.out.println("   [-FLAVOR flavorName (Explicitly use s2s=SAX or d2d=DOM to do transform.)] ");
 108         System.out.println("   [-DIAG (Print overall milliseconds transform took.)]");
 109         System.out.println("   [-URIRESOLVER full class name (URIResolver to be used to resolve URIs)]");  //"   [-URIRESOLVER full class name (URIResolver to be used to resolve URIs)]");
 110         System.out.println("   [-ENTITYRESOLVER full class name (EntityResolver to be used to resolve entities)]");  //"   [-ENTITYRESOLVER full class name (EntityResolver to be used to resolve entities)]");
 111         waitForReturnKey();
 112         System.out.println("   [-CONTENTHANDLER full class name (ContentHandler to be used to serialize output)]");  //"   [-CONTENTHANDLER full class name (ContentHandler to be used to serialize output)]");
 113         System.out.println("   [-SECURE (set the secure processing feature to true.)]"); //"   [-SECURE (set the secure processing feature to true)]");
 114 
 115 
 116         System.out.println("\n\t\t\t"+  "-Options for XSLTC-" + "\n");
 117         System.out.println("   [-XO [transletName] (assign the name to the generated translet)]");
 118         waitForReturnKey();
 119         System.out.println("   [-XD destinationDirectory (specify a destination directory for translet)]");
 120         System.out.println("   [-XJ jarfile (packages translet classes into a jar file of name <jarfile>)]");
 121         System.out.println("   [-XP package (specifies a package name prefix for all generated translet classes)]");
 122         System.out.println("   [-XN (enables template inlining)]");
 123         System.out.println("   [-XX (turns on additional debugging message output)]");
 124         System.out.println("   [-XT (use translet to transform if possible)]");
 125     }
 126 
 127   /**
 128    * Command line interface to transform an XML document according to
 129    * the instructions found in an XSL stylesheet.
 130    * <p>The Process class provides basic functionality for
 131    * performing transformations from the command line.  To see a
 132    * list of arguments supported, call with zero arguments.</p>
 133    * <p>To set stylesheet parameters from the command line, use
 134    * <code>-PARAM name expression</code>. If you want to set the
 135    * parameter to a string value, simply pass the string value
 136    * as-is, and it will be interpreted as a string.  (Note: if
 137    * the value has spaces in it, you may need to quote it depending
 138    * on your shell environment).</p>
 139    *
 140    * @param argv Input parameters from command line
 141    */
 142     public static void main(String argv[]) {
 143 
 144         // Runtime.getRuntime().traceMethodCalls(false); // turns Java tracing off
 145         boolean doStackDumpOnError = false;
 146         boolean doDiag = false;
 147         boolean setQuietMode = false;
 148         String msg = null;
 149         boolean isSecureProcessing = false;
 150 
 151         // Runtime.getRuntime().traceMethodCalls(false);
 152         // Runtime.getRuntime().traceInstructions(false);
 153         /**
 154          * The default diagnostic writer...
 155          */
 156         java.io.PrintWriter diagnosticsWriter = new PrintWriter(System.err, true);
 157         java.io.PrintWriter dumpWriter = diagnosticsWriter;
 158         String flavor = "s2s";
 159 
 160         if (argv.length < 1) {
 161             printArgOptions();
 162         } else {
 163              // J2SE does not support Xalan interpretive
 164             // false -> true
 165             boolean useXSLTC = true;
 166             for (int i = 0; i < argv.length; i++) {
 167                 if ("-XSLTC".equalsIgnoreCase(argv[i])) {
 168                     useXSLTC = true;
 169                 }
 170             }
 171 
 172             TransformerFactory tfactory;
 173             if (useXSLTC) {
 174                 String key = "javax.xml.transform.TransformerFactory";
 175                 String value = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
 176                 Properties props = System.getProperties();
 177                 props.put(key, value);
 178                 System.setProperties(props);
 179             }
 180 
 181             try {
 182                 tfactory = TransformerFactory.newInstance();
 183                 tfactory.setErrorListener(createDefaultErrorListener());
 184             } catch (TransformerFactoryConfigurationError pfe) {
 185                 pfe.printStackTrace(dumpWriter);
 186                 //      "XSL Process was not successful.");
 187                 msg = "XSL Process was not successful.";
 188                 diagnosticsWriter.println(msg);
 189 
 190                 tfactory = null;  // shut up compiler
 191 
 192                 doExit(msg);
 193             }
 194 
 195             boolean formatOutput = false;
 196             boolean useSourceLocation = false;
 197             String inFileName = null;
 198             String outFileName = null;
 199             String dumpFileName = null;
 200             String xslFileName = null;
 201             String treedumpFileName = null;
 202             String outputType = null;
 203             String media = null;
 204             List<String> params = new ArrayList<>();
 205             boolean quietConflictWarnings = false;
 206             URIResolver uriResolver = null;
 207             EntityResolver entityResolver = null;
 208             ContentHandler contentHandler = null;
 209             int recursionLimit = -1;
 210 
 211             for (int i = 0; i < argv.length; i++) {
 212                 if ("-XSLTC".equalsIgnoreCase(argv[i])) {
 213                     // The -XSLTC option has been processed.
 214                 } // J2SE does not support Xalan interpretive
 215                 else if ("-INDENT".equalsIgnoreCase(argv[i])) {
 216                     int indentAmount;
 217 
 218                     if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-')) {
 219                         indentAmount = Integer.parseInt(argv[++i]);
 220                     } else {
 221                         indentAmount = 0;
 222                     }
 223 
 224                 } else if ("-IN".equalsIgnoreCase(argv[i])) {
 225                     if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 226                         inFileName = argv[++i];
 227                     } else {
 228                         System.err.println("Missing argument for -IN");
 229                     }
 230                 } else if ("-MEDIA".equalsIgnoreCase(argv[i])) {
 231                     if (i + 1 < argv.length) {
 232                         media = argv[++i];
 233                     } else {
 234                         System.err.println("Missing argument for -MEDIA");  //"Missing argument for);
 235                     }
 236                 } else if ("-OUT".equalsIgnoreCase(argv[i])) {
 237                     if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 238                         outFileName = argv[++i];
 239                     } else {
 240                         System.err.println("Missing argument for -OUT");  //"Missing argument for);
 241                     }
 242                 } else if ("-XSL".equalsIgnoreCase(argv[i])) {
 243                     if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 244                         xslFileName = argv[++i];
 245                     } else {
 246                         System.err.println("Missing argument for -XSL");  //"Missing argument for);
 247                     }
 248                 } else if ("-FLAVOR".equalsIgnoreCase(argv[i])) {
 249                     if (i + 1 < argv.length) {
 250                         flavor = argv[++i];
 251                     } else {
 252                         System.err.println("Missing argument for -FLAVOR");  //"Missing argument for);
 253                     }
 254                 } else if ("-PARAM".equalsIgnoreCase(argv[i])) {
 255                     if (i + 2 < argv.length) {
 256                         String name = argv[++i];
 257 
 258                         params.add(name);
 259 
 260                         String expression = argv[++i];
 261 
 262                         params.add(expression);
 263                     } else {
 264                         System.err.println("Missing argument for -PARAM");  //"Missing argument for);
 265                     }
 266                 } else if ("-E".equalsIgnoreCase(argv[i])) {
 267 
 268                 } else if ("-V".equalsIgnoreCase(argv[i])) {
 269                     diagnosticsWriter.println(">>>>>>> Java Version "
 270                             + System.getProperty("java.version") + ", "
 271                             + /* xmlProcessorLiaison.getParserDescription()+ */ "<<<<<<<");
 272                 } // J2SE does not support Xalan interpretive
 273                 /*
 274                  else if ("-QC".equalsIgnoreCase(argv[i]))
 275                  {
 276                  if (!useXSLTC)
 277                  quietConflictWarnings = true;
 278                  else
 279                  printInvalidXSLTCOption("-QC");
 280                  }
 281                  */ else if ("-Q".equalsIgnoreCase(argv[i])) {
 282                     setQuietMode = true;
 283                 } else if ("-DIAG".equalsIgnoreCase(argv[i])) {
 284                     doDiag = true;
 285                 } else if ("-XML".equalsIgnoreCase(argv[i])) {
 286                     outputType = "xml";
 287                 } else if ("-TEXT".equalsIgnoreCase(argv[i])) {
 288                     outputType = "text";
 289                 } else if ("-HTML".equalsIgnoreCase(argv[i])) {
 290                     outputType = "html";
 291                 } else if ("-EDUMP".equalsIgnoreCase(argv[i])) {
 292                     doStackDumpOnError = true;
 293 
 294                     if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-')) {
 295                         dumpFileName = argv[++i];
 296                     }
 297                 } else if ("-URIRESOLVER".equalsIgnoreCase(argv[i])) {
 298                     if (i + 1 < argv.length) {
 299                         try {
 300                             Class<?> uriResolverClass = Class.forName(argv[++i]);
 301                             Constructor<?> ctor = uriResolverClass.getConstructor();
 302                             ctor.setAccessible(true);
 303                             uriResolver = (URIResolver) ctor.newInstance();
 304 
 305                             tfactory.setURIResolver(uriResolver);
 306                         } catch (Throwable cnfe) {
 307                             msg = "Class not found for option -URIResolver";
 308                             System.err.println(msg);
 309                             doExit(msg);
 310                         }
 311                     } else {
 312                         msg = "Missing argument for -URIResolver";
 313                         System.err.println(msg);  //"Missing argument for);
 314                         doExit(msg);
 315                     }
 316                 } else if ("-ENTITYRESOLVER".equalsIgnoreCase(argv[i])) {
 317                     if (i + 1 < argv.length) {
 318                         try {
 319                             Class<?> entityResolverClass = Class.forName(argv[++i]);
 320                             Constructor<?> ctor = entityResolverClass.getConstructor();
 321                             ctor.setAccessible(true);
 322                             entityResolver = (EntityResolver) ctor.newInstance();
 323                         } catch (Throwable cnfe) {
 324                             msg = "Class not found for option -EntityResolver";
 325                             System.err.println(msg);
 326                             doExit(msg);
 327                         }
 328                     } else {
 329                         //            "Missing argument for);
 330                         msg = "Missing argument for -EntityResolver";
 331                         System.err.println(msg);
 332                         doExit(msg);
 333                     }
 334                 } else if ("-CONTENTHANDLER".equalsIgnoreCase(argv[i])) {
 335                     if (i + 1 < argv.length) {
 336                         try {
 337                             Class<?> contentHandlerClass = Class.forName(argv[++i]);
 338                             Constructor<?> ctor = contentHandlerClass.getConstructor();
 339                             ctor.setAccessible(true);
 340                             contentHandler = (ContentHandler) ctor.newInstance();
 341                         } catch (Throwable cnfe) {
 342                             msg = "Class not found for option -ContentHandler";
 343                             System.err.println(msg);
 344                             doExit(msg);
 345                         }
 346                     } else {
 347                         //            "Missing argument for);
 348                         msg = "Missing argument for -ContentHandler";
 349                         System.err.println(msg);
 350                         doExit(msg);
 351                     }
 352                 } else if ("-XO".equalsIgnoreCase(argv[i])) {
 353                     if (useXSLTC) {
 354                         if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 355                             tfactory.setAttribute("generate-translet", "true");
 356                             tfactory.setAttribute("translet-name", argv[++i]);
 357                         } else {
 358                             tfactory.setAttribute("generate-translet", "true");
 359                         }
 360                     } else {
 361                         if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 362                             i++;
 363                         }
 364                         printInvalidXalanOption("-XO");
 365                     }
 366                 } // Specify the destination directory for the translet classes.
 367                 else if ("-XD".equalsIgnoreCase(argv[i])) {
 368                     if (useXSLTC) {
 369                         if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 370                             tfactory.setAttribute("destination-directory", argv[++i]);
 371                         } else {
 372                             System.err.println("Missing argument for -XD");  //"Missing argument for);
 373                         }
 374                     } else {
 375                         if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 376                             i++;
 377                         }
 378 
 379                         printInvalidXalanOption("-XD");
 380                     }
 381                 } // Specify the jar file name which the translet classes are packaged into.
 382                 else if ("-XJ".equalsIgnoreCase(argv[i])) {
 383                     if (useXSLTC) {
 384                         if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 385                             tfactory.setAttribute("generate-translet", "true");
 386                             tfactory.setAttribute("jar-name", argv[++i]);
 387                         } else {
 388                             System.err.println("Missing argument for -XJ");  //"Missing argument for);
 389                         }
 390                     } else {
 391                         if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 392                             i++;
 393                         }
 394 
 395                         printInvalidXalanOption("-XJ");
 396                     }
 397 
 398                 } // Specify the package name prefix for the generated translet classes.
 399                 else if ("-XP".equalsIgnoreCase(argv[i])) {
 400                     if (useXSLTC) {
 401                         if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 402                             tfactory.setAttribute("package-name", argv[++i]);
 403                         } else {
 404                             System.err.println("Missing argument for -XP");  //"Missing argument for);
 405                         }
 406                     } else {
 407                         if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-') {
 408                             i++;
 409                         }
 410 
 411                         printInvalidXalanOption("-XP");
 412                     }
 413 
 414                 } // Enable template inlining.
 415                 else if ("-XN".equalsIgnoreCase(argv[i])) {
 416                     if (useXSLTC) {
 417                         tfactory.setAttribute("enable-inlining", "true");
 418                     } else {
 419                         printInvalidXalanOption("-XN");
 420                     }
 421                 } // Turns on additional debugging message output
 422                 else if ("-XX".equalsIgnoreCase(argv[i])) {
 423                     if (useXSLTC) {
 424                         tfactory.setAttribute("debug", "true");
 425                     } else {
 426                         printInvalidXalanOption("-XX");
 427                     }
 428                 } // Create the Transformer from the translet if the translet class is newer
 429                 // than the stylesheet.
 430                 else if ("-XT".equalsIgnoreCase(argv[i])) {
 431                     if (useXSLTC) {
 432                         tfactory.setAttribute("auto-translet", "true");
 433                     } else {
 434                         printInvalidXalanOption("-XT");
 435                     }
 436                 } else if ("-SECURE".equalsIgnoreCase(argv[i])) {
 437                     isSecureProcessing = true;
 438                     try {
 439                         tfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
 440                     } catch (TransformerConfigurationException e) {
 441                     }
 442                 } else {
 443                     System.err.println("Invalid argument: " + argv[i]);  //"Invalid argument:);
 444                 }
 445             }
 446 
 447             // Print usage instructions if no xml and xsl file is specified in the command line
 448             if (inFileName == null && xslFileName == null) {
 449                 msg = "Error: No stylesheet or input xml is specified. Run this command without any option for usage instructions.";
 450                 System.err.println(msg);
 451                 doExit(msg);
 452             }
 453 
 454       // Note that there are usage cases for calling us without a -IN arg
 455             // The main XSL transformation occurs here!
 456             try {
 457                 long start = System.currentTimeMillis();
 458 
 459                 if (null != dumpFileName) {
 460                     dumpWriter = new PrintWriter(new FileWriter(dumpFileName));
 461                 }
 462 
 463                 Templates stylesheet = null;
 464 
 465                 if (null != xslFileName) {
 466                     if (flavor.equals("d2d")) {
 467 
 468                         // Parse in the xml data into a DOM
 469                         DocumentBuilderFactory dfactory
 470                                 = DocumentBuilderFactory.newInstance();
 471 
 472                         dfactory.setNamespaceAware(true);
 473 
 474                         if (isSecureProcessing) {
 475                             try {
 476                                 dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
 477                             } catch (ParserConfigurationException pce) {
 478                             }
 479                         }
 480 
 481                         DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
 482                         Node xslDOM = docBuilder.parse(new InputSource(xslFileName));
 483 
 484                         stylesheet = tfactory.newTemplates(new DOMSource(xslDOM,
 485                                 xslFileName));
 486                     } else {
 487                         // System.out.println("Calling newTemplates: "+xslFileName);
 488                         stylesheet = tfactory.newTemplates(new StreamSource(xslFileName));
 489                         // System.out.println("Done calling newTemplates: "+xslFileName);
 490                     }
 491                 }
 492 
 493                 PrintWriter resultWriter;
 494                 StreamResult strResult;
 495 
 496                 if (null != outFileName) {
 497                     strResult = new StreamResult(new FileOutputStream(outFileName));
 498                     // One possible improvement might be to ensure this is
 499                     //  a valid URI before setting the systemId, but that
 500                     //  might have subtle changes that pre-existing users
 501                     //  might notice; we can think about that later -sc r1.46
 502                     strResult.setSystemId(outFileName);
 503                 } else {
 504                     strResult = new StreamResult(System.out);
 505                     // We used to default to incremental mode in this case.
 506                     // We've since decided that since the -INCREMENTAL switch is
 507                     // available, that default is probably not necessary nor
 508                     // necessarily a good idea.
 509                 }
 510 
 511                 SAXTransformerFactory stf = (SAXTransformerFactory) tfactory;
 512 
 513                 // Did they pass in a stylesheet, or should we get it from the
 514                 // document?
 515                 if (null == stylesheet) {
 516                     Source source
 517                             = stf.getAssociatedStylesheet(new StreamSource(inFileName), media,
 518                                     null, null);
 519 
 520                     if (null != source) {
 521                         stylesheet = tfactory.newTemplates(source);
 522                     } else {
 523                         if (null != media) {
 524                             throw new TransformerException("No stylesheet found in:  "
 525                                     + inFileName + ", media=" + media); //"No stylesheet found in: "
 526                         } // + inFileName + ", media="
 527                         // + media);
 528                         else {
 529                             throw new TransformerException("No xml-stylesheet PI found in: " + inFileName); //"No xml-stylesheet PI found in: "
 530                         }                                             //+ inFileName);
 531                     }
 532                 }
 533 
 534                 if (null != stylesheet) {
 535                     Transformer transformer = flavor.equals("th") ? null : stylesheet.newTransformer();
 536                     transformer.setErrorListener(createDefaultErrorListener());
 537 
 538                     // Override the output format?
 539                     if (null != outputType) {
 540                         transformer.setOutputProperty(OutputKeys.METHOD, outputType);
 541                     }
 542 
 543                     int nParams = params.size();
 544 
 545                     for (int i = 0; i < nParams; i += 2) {
 546                         transformer.setParameter((String) params.get(i),
 547                                 (String) params.get(i + 1));
 548                     }
 549 
 550                     if (uriResolver != null) {
 551                         transformer.setURIResolver(uriResolver);
 552                     }
 553 
 554                     if (null != inFileName) {
 555                         if (flavor.equals("d2d")) {
 556 
 557                             // Parse in the xml data into a DOM
 558                             DocumentBuilderFactory dfactory
 559                                     = DocumentBuilderFactory.newInstance();
 560 
 561                             dfactory.setCoalescing(true);
 562                             dfactory.setNamespaceAware(true);
 563 
 564                             if (isSecureProcessing) {
 565                                 try {
 566                                     dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
 567                                 } catch (ParserConfigurationException pce) {
 568                                 }
 569                             }
 570 
 571                             DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
 572 
 573                             if (entityResolver != null) {
 574                                 docBuilder.setEntityResolver(entityResolver);
 575                             }
 576 
 577                             Node xmlDoc = docBuilder.parse(new InputSource(inFileName));
 578                             Document doc = docBuilder.newDocument();
 579                             org.w3c.dom.DocumentFragment outNode
 580                                     = doc.createDocumentFragment();
 581 
 582                             transformer.transform(new DOMSource(xmlDoc, inFileName),
 583                                     new DOMResult(outNode));
 584 
 585                             // Now serialize output to disk with identity transformer
 586                             Transformer serializer = stf.newTransformer();
 587                             serializer.setErrorListener(createDefaultErrorListener());
 588 
 589                             Properties serializationProps
 590                                     = stylesheet.getOutputProperties();
 591 
 592                             serializer.setOutputProperties(serializationProps);
 593 
 594                             if (contentHandler != null) {
 595                                 SAXResult result = new SAXResult(contentHandler);
 596 
 597                                 serializer.transform(new DOMSource(outNode), result);
 598                             } else {
 599                                 serializer.transform(new DOMSource(outNode), strResult);
 600                             }
 601                         } else if (flavor.equals("th")) {
 602                             for (int i = 0; i < 1; i++) // Loop for diagnosing bugs with inconsistent behavior
 603                             {
 604                                 // System.out.println("Testing the TransformerHandler...");
 605 
 606                                 XMLReader reader = null;
 607 
 608                                 // Use JAXP1.1 ( if possible )
 609                                 try {
 610                                     javax.xml.parsers.SAXParserFactory factory
 611                                             = javax.xml.parsers.SAXParserFactory.newInstance();
 612 
 613                                     factory.setNamespaceAware(true);
 614 
 615                                     if (isSecureProcessing) {
 616                                         try {
 617                                             factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
 618                                         } catch (org.xml.sax.SAXException se) {
 619                                         }
 620                                     }
 621 
 622                                     javax.xml.parsers.SAXParser jaxpParser
 623                                             = factory.newSAXParser();
 624 
 625                                     reader = jaxpParser.getXMLReader();
 626                                 } catch (javax.xml.parsers.ParserConfigurationException ex) {
 627                                     throw new org.xml.sax.SAXException(ex);
 628                                 } catch (javax.xml.parsers.FactoryConfigurationError ex1) {
 629                                     throw new org.xml.sax.SAXException(ex1.toString());
 630                                 } catch (NoSuchMethodError ex2) {
 631                                 } catch (AbstractMethodError ame) {
 632                                 }
 633 
 634                                 if (null == reader) {
 635                                     reader = XMLReaderFactory.createXMLReader();
 636                                 }
 637 
 638                                 TransformerHandler th = stf.newTransformerHandler(stylesheet);
 639 
 640                                 reader.setContentHandler(th);
 641                                 reader.setDTDHandler(th);
 642 
 643                                 if (th instanceof org.xml.sax.ErrorHandler) {
 644                                     reader.setErrorHandler((org.xml.sax.ErrorHandler) th);
 645                                 }
 646 
 647                                 try {
 648                                     reader.setProperty(
 649                                             "http://xml.org/sax/properties/lexical-handler", th);
 650                                 } catch (org.xml.sax.SAXNotRecognizedException e) {
 651                                 } catch (org.xml.sax.SAXNotSupportedException e) {
 652                                 }
 653                                 try {
 654                                     reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
 655                                             true);
 656                                 } catch (org.xml.sax.SAXException se) {
 657                                 }
 658 
 659                                 th.setResult(strResult);
 660 
 661                                 reader.parse(new InputSource(inFileName));
 662                             }
 663                         } else {
 664                             if (entityResolver != null) {
 665                                 XMLReader reader = null;
 666 
 667                                 // Use JAXP1.1 ( if possible )
 668                                 try {
 669                                     javax.xml.parsers.SAXParserFactory factory
 670                                             = javax.xml.parsers.SAXParserFactory.newInstance();
 671 
 672                                     factory.setNamespaceAware(true);
 673 
 674                                     if (isSecureProcessing) {
 675                                         try {
 676                                             factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
 677                                         } catch (org.xml.sax.SAXException se) {
 678                                         }
 679                                     }
 680 
 681                                     javax.xml.parsers.SAXParser jaxpParser
 682                                             = factory.newSAXParser();
 683 
 684                                     reader = jaxpParser.getXMLReader();
 685                                 } catch (javax.xml.parsers.ParserConfigurationException ex) {
 686                                     throw new org.xml.sax.SAXException(ex);
 687                                 } catch (javax.xml.parsers.FactoryConfigurationError ex1) {
 688                                     throw new org.xml.sax.SAXException(ex1.toString());
 689                                 } catch (NoSuchMethodError ex2) {
 690                                 } catch (AbstractMethodError ame) {
 691                                 }
 692 
 693                                 if (null == reader) {
 694                                     reader = XMLReaderFactory.createXMLReader();
 695                                 }
 696 
 697                                 reader.setEntityResolver(entityResolver);
 698 
 699                                 if (contentHandler != null) {
 700                                     SAXResult result = new SAXResult(contentHandler);
 701 
 702                                     transformer.transform(
 703                                             new SAXSource(reader, new InputSource(inFileName)),
 704                                             result);
 705                                 } else {
 706                                     transformer.transform(
 707                                             new SAXSource(reader, new InputSource(inFileName)),
 708                                             strResult);
 709                                 }
 710                             } else if (contentHandler != null) {
 711                                 SAXResult result = new SAXResult(contentHandler);
 712 
 713                                 transformer.transform(new StreamSource(inFileName), result);
 714                             } else {
 715                                 // System.out.println("Starting transform");
 716                                 transformer.transform(new StreamSource(inFileName),
 717                                         strResult);
 718                                 // System.out.println("Done with transform");
 719                             }
 720                         }
 721                     } else {
 722                         StringReader reader
 723                                 = new StringReader("<?xml version=\"1.0\"?> <doc/>");
 724 
 725                         transformer.transform(new StreamSource(reader), strResult);
 726                     }
 727                 } else {
 728                     //          "XSL Process was not successful.");
 729                     msg = "XSL Process was not successful.";
 730                     diagnosticsWriter.println(msg);
 731                     doExit(msg);
 732                 }
 733 
 734                 // close output streams
 735                 if (null != outFileName && strResult != null) {
 736                     java.io.OutputStream out = strResult.getOutputStream();
 737                     java.io.Writer writer = strResult.getWriter();
 738                     try {
 739                         if (out != null) {
 740                             out.close();
 741                         }
 742                         if (writer != null) {
 743                             writer.close();
 744                         }
 745                     } catch (java.io.IOException ie) {
 746                     }
 747                 }
 748 
 749                 long stop = System.currentTimeMillis();
 750                 long millisecondsDuration = stop - start;
 751 
 752                 if (doDiag) {
 753                     msg = " --------- Transform of " + inFileName + " via "
 754                             + xslFileName + " took " + millisecondsDuration + " ms";
 755                     diagnosticsWriter.println('\n');
 756                     diagnosticsWriter.println(msg);
 757                 }
 758 
 759             } catch (Throwable throwable) {
 760                 doStackDumpOnError = true;
 761 
 762                 diagnosticsWriter.println();
 763 
 764                 if (doStackDumpOnError) {
 765                     throwable.printStackTrace(dumpWriter);
 766                 } else {
 767                     printLocation(diagnosticsWriter, throwable);
 768                     diagnosticsWriter.println("Unexpected exception: " + throwable);
 769                 }
 770 
 771                 // diagnosticsWriter.println(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
 772                 if (null != dumpFileName) {
 773                     dumpWriter.close();
 774                 }
 775 
 776                 doExit(throwable.getMessage());
 777             }
 778 
 779             if (null != dumpFileName) {
 780                 dumpWriter.close();
 781             }
 782 
 783             if (null != diagnosticsWriter) {
 784 
 785                 // diagnosticsWriter.close();
 786             }
 787 
 788             // if(!setQuietMode)
 789             //  diagnosticsWriter.println(resbundle.getString("xsldone")); //"Xalan: done");
 790             // else
 791             // diagnosticsWriter.println("");  //"Xalan: done");
 792         }
 793     }
 794 
 795     /**
 796      * It is _much_ easier to debug under VJ++ if I can set a single breakpoint
 797      * before this blows itself out of the water... (I keep checking this in, it
 798      * keeps vanishing. Grr!)
 799      *
 800      */
 801     static void doExit(String msg) {
 802         throw new RuntimeException(msg);
 803     }
 804 
 805     /**
 806      * Wait for a return key to continue
 807      *
 808      * @param resbundle The resource bundle
 809      */
 810     private static void waitForReturnKey() {
 811         System.out.println("(press <return> to continue)");
 812         try {
 813             while (System.in.read() != '\n');
 814         } catch (java.io.IOException e) {
 815         }
 816     }
 817 
 818     /**
 819      * Print a message if an option cannot be used with -XSLTC.
 820      *
 821      * @param option The option String
 822      */
 823     private static void printInvalidXSLTCOption(String option) {
 824         System.err.println("The option " + option + " is not supported in XSLTC mode.");
 825     }
 826 
 827     /**
 828      * Print a message if an option can only be used with -XSLTC.
 829      *
 830      * @param option The option String
 831      */
 832     private static void printInvalidXalanOption(String option) {
 833         System.err.println("The option " + option + " can only be used with -XSLTC.");
 834     }
 835 
 836     static class DummyErrorListenerHandler implements ErrorHandler, ErrorListener {
 837         @Override
 838         public void warning(SAXParseException exception) throws SAXException {
 839             System.err.println("WARNING: " + exception);
 840         }
 841         @Override
 842         public void error(SAXParseException exception) throws SAXException {
 843             throw exception;
 844         }
 845         @Override
 846         public void fatalError(SAXParseException exception) throws SAXException {
 847             throw exception;
 848         }
 849         @Override
 850         public void warning(TransformerException exception) throws TransformerException {
 851             System.err.println("WARNING: " + exception);
 852         }
 853         @Override
 854         public void error(TransformerException exception) throws TransformerException {
 855             throw exception;
 856         }
 857         @Override
 858         public void fatalError(TransformerException exception) throws TransformerException {
 859             throw exception;
 860         }
 861     }
 862 
 863     static ErrorListener createDefaultErrorListener() {
 864         try {
 865             Class<?> errorHandler =
 866                     Class.forName("com.sun.org.apache.xml.internal.utils.DefaultErrorHandler");
 867             Constructor<?> ctor = errorHandler.getConstructor();
 868             return (ErrorListener) ctor.newInstance();
 869         } catch (Throwable r) {
 870             return new DummyErrorListenerHandler();
 871         }
 872     }
 873 
 874     private static void printLocation(PrintWriter diagnosticsWriter, Throwable throwable) {
 875         try {
 876             Class<?> errorHandler =
 877                     Class.forName("com.sun.org.apache.xml.internal.utils.DefaultErrorHandler");
 878             Method m = errorHandler.getMethod("printLocation", PrintWriter.class, Throwable.class);
 879             m.invoke(null, diagnosticsWriter, throwable);
 880         } catch (Throwable t) {
 881             SourceLocator locator = null;
 882             Throwable cause = throwable;
 883 
 884             // Try to find the locator closest to the cause.
 885             do {
 886                 if (cause instanceof TransformerException) {
 887                     SourceLocator causeLocator = ((TransformerException) cause).getLocator();
 888                     if (null != causeLocator) {
 889                         locator = causeLocator;
 890                     }
 891                     cause = ((TransformerException) cause).getCause();
 892                 } else if (cause instanceof SAXException) {
 893                     cause = ((SAXException) cause).getException();
 894                 } else {
 895                     cause = cause.getCause();
 896                 }
 897             } while (null != cause);
 898 
 899             if (null != locator) {
 900                 // m_pw.println("Parser fatal error: "+exception.getMessage());
 901                 String id = (null != locator.getPublicId())
 902                         ? locator.getPublicId()
 903                         : (null != locator.getSystemId())
 904                                 ? locator.getSystemId() : "SystemId Unknown"; //"SystemId Unknown";
 905 
 906                 diagnosticsWriter.print(id + "; " + "line: " + locator.getLineNumber()
 907                         + "; column: " + locator.getColumnNumber() + "; ");
 908             }
 909             diagnosticsWriter.print("(" + throwable + ": unknown location)");
 910         }
 911     }
 912 
 913 }