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