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