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