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