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