KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > Transform


1 package net.sf.saxon;
2
3 import net.sf.saxon.event.Builder;
4 import net.sf.saxon.instruct.TerminationException;
5 import net.sf.saxon.om.Validation;
6 import net.sf.saxon.trace.TraceListener;
7 import net.sf.saxon.trans.DynamicError;
8 import net.sf.saxon.trans.XPathException;
9 import net.sf.saxon.value.UntypedAtomicValue;
10 import org.xml.sax.InputSource JavaDoc;
11 import org.xml.sax.XMLReader JavaDoc;
12
13 import javax.xml.transform.*;
14 import javax.xml.transform.sax.SAXSource JavaDoc;
15 import javax.xml.transform.stream.StreamResult JavaDoc;
16 import javax.xml.transform.stream.StreamSource JavaDoc;
17 import java.io.File JavaDoc;
18 import java.net.URI JavaDoc;
19 import java.net.URISyntaxException JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.List JavaDoc;
23
24 /**
25  * This <B>Transform</B> class is the entry point to the Saxon XSLT Processor. This
26  * class is provided to control the processor from the command line.<p>
27  * <p/>
28  * The XSLT syntax supported conforms to the W3C XSLT 1.0 and XPath 1.0 recommendation.
29  * Only the transformation language is implemented (not the formatting objects).
30  * Saxon extensions are documented in the file extensions.html
31  *
32  * @author Michael H. Kay
33  */

34
35 public class Transform {
36
37     protected TransformerFactoryImpl factory = new TransformerFactoryImpl();
38     protected Configuration config;
39     protected boolean useURLs = false;
40     protected boolean showTime = false;
41     protected int repeat = 1;
42     String JavaDoc sourceParserName = null;
43
44     /**
45      * Main program, can be used directly from the command line.
46      * <p>The format is:</P>
47      * <p>java net.sf.saxon.Transform [options] <I>source-file</I> <I>style-file</I> &gt;<I>output-file</I></P>
48      * <p>followed by any number of parameters in the form {keyword=value}... which can be
49      * referenced from within the stylesheet.</p>
50      * <p>This program applies the XSL style sheet in style-file to the source XML document in source-file.</p>
51      *
52      * @param args List of arguments supplied on operating system command line
53      * @throws java.lang.Exception Indicates that a compile-time or
54      * run-time error occurred
55      */

56
57     public static void main(String JavaDoc args[])
58             throws java.lang.Exception JavaDoc {
59         // the real work is delegated to another routine so that it can be used in a subclass
60
(new Transform()).doMain(args, "java net.sf.saxon.Transform");
61     }
62
63     /**
64      * Set the configuration in the TransformerFactory. This is designed to be
65      * overridden in a subclass
66      */

67
68     protected void setFactoryConfiguration() {
69         Configuration config = new Configuration();
70         factory.setConfiguration(config);
71         // In basic XSLT, all nodes are untyped by definition
72
config.setAllNodesUntyped(true);
73     }
74
75     /**
76      * Support method for main program. This support method can also be invoked from subclasses
77      * that support the same command line interface
78      *
79      * @param args the command-line arguments
80      * @param name name of the class, to be used in error messages
81      */

82
83     protected void doMain(String JavaDoc args[], String JavaDoc name) {
84
85
86         String JavaDoc sourceFileName = null;
87         String JavaDoc styleFileName = null;
88         File JavaDoc outputFile = null;
89         ArrayList JavaDoc parameterList = new ArrayList JavaDoc(20);
90         String JavaDoc outputFileName = null;
91         String JavaDoc initialMode = null;
92         String JavaDoc initialTemplate = null;
93         boolean useAssociatedStylesheet = false;
94         boolean wholeDirectory = false;
95         boolean precompiled = false;
96         boolean dtdValidation = false;
97         String JavaDoc styleParserName = null;
98
99         setFactoryConfiguration();
100         config = factory.getConfiguration();
101         boolean schemaAware = config.isSchemaAware(Configuration.XSLT);
102
103         // Check the command-line arguments.
104

105         try {
106             int i = 0;
107             while (true) {
108                 if (i >= args.length) {
109                     badUsage(name, "No source file name");
110                 }
111
112                 if (args[i].charAt(0) == '-') {
113
114                     if (args[i].equals("-a")) {
115                         useAssociatedStylesheet = true;
116                         i++;
117                     } else if (args[i].equals("-c")) {
118                         precompiled = true;
119                         i++;
120                     } else if (args[i].equals("-cr")) {
121                         i++;
122                         if (args.length < i + 2) {
123                             badUsage(name, "No resolver after -cr");
124                         }
125                         String JavaDoc crclass = args[i++];
126                         Object JavaDoc resolver = config.getInstance(crclass, null);
127                         factory.setAttribute(FeatureKeys.COLLECTION_URI_RESOLVER,
128                                 resolver);
129                     } else if (args[i].equals("-ds")) {
130                         factory.setAttribute(FeatureKeys.TREE_MODEL,
131                                 new Integer JavaDoc(Builder.STANDARD_TREE));
132                         i++;
133                     } else if (args[i].equals("-dt")) {
134                         factory.setAttribute(FeatureKeys.TREE_MODEL,
135                                 new Integer JavaDoc(Builder.TINY_TREE));
136                         i++;
137                     } else if (args[i].equals("-im")) {
138                         i++;
139                         if (args.length < i + 2) {
140                             badUsage(name, "No initial mode after -im");
141                         }
142                         initialMode = args[i++];
143                     } else if (args[i].equals("-it")) {
144                         i++;
145                         if (args.length < i + 2) {
146                             badUsage(name, "No initial template after -it");
147                         }
148                         initialTemplate = args[i++];
149                     } else if (args[i].equals("-l")) {
150                         factory.setAttribute(FeatureKeys.LINE_NUMBERING,
151                                 Boolean.valueOf(true));
152                         i++;
153                     } else if (args[i].equals("-novw")) {
154                         factory.setAttribute(FeatureKeys.VERSION_WARNING,
155                                 Boolean.valueOf(false));
156                         i++;
157                     } else if (args[i].equals("-u")) {
158                         useURLs = true;
159                         i++;
160                     } else if (args[i].equals("-v")) {
161                         factory.setAttribute(FeatureKeys.DTD_VALIDATION,
162                                 Boolean.valueOf(true));
163                         dtdValidation = true;
164                         i++;
165                     } else if (args[i].equals("-vw")) {
166                         if (schemaAware) {
167                             factory.setAttribute(FeatureKeys.VALIDATION_WARNINGS,
168                                     Boolean.valueOf(true));
169                         } else {
170                             quit("The -vw option requires a schema-aware processor", 2);
171                         }
172                         i++;
173                     } else if (args[i].equals("-val")) {
174                         if (schemaAware) {
175                             factory.setAttribute(FeatureKeys.SCHEMA_VALIDATION,
176                                     new Integer JavaDoc(Validation.STRICT));
177                         } else {
178                             quit("The -val option requires a schema-aware processor", 2);
179                         }
180                         i++;
181                     } else if (args[i].equals("-vlax")) {
182                         if (schemaAware) {
183                             factory.setAttribute(FeatureKeys.SCHEMA_VALIDATION,
184                                     new Integer JavaDoc(Validation.LAX));
185                         } else {
186                             quit("The -vlax option requires a schema-aware processor", 2);
187                         }
188                         i++;
189                     } else if (args[i].equals("-t")) {
190                         System.err.println(config.getProductTitle());
191                         System.err.println("Java version " + System.getProperty("java.version"));
192                         factory.setAttribute(FeatureKeys.TIMING,
193                                 Boolean.valueOf(true));
194
195                         //Loader.setTracing(true);
196
showTime = true;
197                         i++;
198                     } else if (args[i].equals("-3")) { // undocumented option: do it thrice
199
i++;
200                         repeat = 3;
201                     } else if (args[i].equals("-9")) { // undocumented option: do it nine times
202
i++;
203                         repeat = 9;
204                     } else if (args[i].equals("-o")) {
205                         i++;
206                         if (args.length < i + 2) {
207                             badUsage(name, "No output file name");
208                         }
209                         outputFileName = args[i++];
210                     } else if (args[i].equals("-p")) {
211                         i++;
212                         setPOption(config);
213                         useURLs = true;
214                     } else if (args[i].equals("-x")) {
215                         i++;
216                         if (args.length < i + 2) {
217                             badUsage(name, "No source parser class");
218                         }
219                         sourceParserName = args[i++];
220                         factory.setAttribute(FeatureKeys.SOURCE_PARSER_CLASS,
221                                 sourceParserName);
222                     } else if (args[i].equals("-y")) {
223                         i++;
224                         if (args.length < i + 2) {
225                             badUsage(name, "No style parser class");
226                         }
227                         styleParserName = args[i++];
228                         factory.setAttribute(FeatureKeys.STYLE_PARSER_CLASS,
229                                 styleParserName);
230                     } else if (args[i].equals("-r")) {
231                         i++;
232                         if (args.length < i + 2) {
233                             badUsage(name, "No URIResolver class");
234                         }
235                         String JavaDoc r = args[i++];
236                         factory.setURIResolver(config.makeURIResolver(r));
237                     } else if (args[i].equals("-T")) {
238                         i++;
239                         TraceListener traceListener = new net.sf.saxon.trace.XSLTTraceListener();
240                         factory.setAttribute(FeatureKeys.TRACE_LISTENER,
241                                 traceListener);
242                         factory.setAttribute(FeatureKeys.LINE_NUMBERING,
243                                 Boolean.TRUE);
244                     } else if (args[i].equals("-TP")) {
245                         i++;
246                         TraceListener traceListener = new net.sf.saxon.trace.TimedTraceListener();
247                         factory.setAttribute(FeatureKeys.TRACE_LISTENER,
248                                 traceListener);
249                         factory.setAttribute(FeatureKeys.LINE_NUMBERING,
250                                 Boolean.TRUE);
251                     } else if (args[i].equals("-TJ")) {
252                         i++;
253                         factory.setAttribute(FeatureKeys.TRACE_EXTERNAL_FUNCTIONS,
254                                 Boolean.TRUE);
255                     } else if (args[i].equals("-TL")) {
256                         i++;
257                         if (args.length < i + 2) {
258                             badUsage(name, "No TraceListener class");
259                         }
260                         TraceListener traceListener = config.makeTraceListener(args[i++]);
261                         factory.setAttribute(FeatureKeys.TRACE_LISTENER,
262                                 traceListener);
263                         factory.setAttribute(FeatureKeys.LINE_NUMBERING,
264                                 Boolean.TRUE);
265                     } else if (args[i].equals("-w0")) {
266                         i++;
267                         factory.setAttribute(FeatureKeys.RECOVERY_POLICY,
268                                 new Integer JavaDoc(Configuration.RECOVER_SILENTLY));
269                     } else if (args[i].equals("-w1")) {
270                         i++;
271                         factory.setAttribute(FeatureKeys.RECOVERY_POLICY,
272                                 new Integer JavaDoc(Configuration.RECOVER_WITH_WARNINGS));
273                     } else if (args[i].equals("-w2")) {
274                         i++;
275                         factory.setAttribute(FeatureKeys.RECOVERY_POLICY,
276                                 new Integer JavaDoc(Configuration.DO_NOT_RECOVER));
277                     } else if (args[i].equals("-m")) {
278                         i++;
279                         if (args.length < i + 2) {
280                             badUsage(name, "No message Emitter class");
281                         }
282                         factory.setAttribute(FeatureKeys.MESSAGE_EMITTER_CLASS,
283                                 args[i++]);
284                     } else if (args[i].equals("-noext")) {
285                         i++;
286                         factory.setAttribute(FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS,
287                                 Boolean.valueOf(false));
288                     } else if (args[i].equals("-?")) {
289                         badUsage(name, "");
290                     } else if (args[i].equals("-")) {
291                         break;
292                         // this means take the source from standard input
293
} else {
294                         badUsage(name, "Unknown option " + args[i]);
295                     }
296                 } else {
297                     break;
298                 }
299             }
300
301             if (initialTemplate != null && useAssociatedStylesheet) {
302                 badUsage(name, "-it and -a options cannot be used together");
303             }
304
305             if (initialTemplate == null) {
306                 if (args.length < i + 1) {
307                     badUsage(name, "No source file name");
308                 }
309                 sourceFileName = args[i++];
310             }
311
312             if (!useAssociatedStylesheet) {
313                 if (args.length < i + 1) {
314                     badUsage(name, "No stylesheet file name");
315                 }
316                 styleFileName = args[i++];
317             }
318
319             for (int p = i; p < args.length; p++) {
320                 String JavaDoc arg = args[p];
321                 int eq = arg.indexOf("=");
322                 if (eq < 1 || eq >= arg.length() - 1) {
323                     badUsage(name, "Bad param=value pair on command line: " + arg);
324                 }
325                 parameterList.add(arg);
326             }
327
328             config.displayLicenseMessage();
329
330             List JavaDoc sources = null;
331             if (initialTemplate == null) {
332                 boolean useSAXSource = sourceParserName != null || dtdValidation;
333                 Object JavaDoc loaded = loadDocuments(sourceFileName, useURLs, config, useSAXSource);
334                 if (loaded instanceof List JavaDoc) {
335                     wholeDirectory = true;
336                     sources = (List JavaDoc)loaded;
337                 } else {
338                     wholeDirectory = false;
339                     sources = new ArrayList JavaDoc(1);
340                     sources.add(loaded);
341                 }
342                 sources = preprocess(sources);
343                 if (wholeDirectory) {
344                     if (outputFileName == null) {
345                         quit("To process a directory, -o must be specified", 2);
346                     } else if (outputFileName.equals(sourceFileName)) {
347                         quit("Output directory must be different from input", 2);
348                     } else {
349                         outputFile = new File JavaDoc(outputFileName);
350                         if (!outputFile.isDirectory()) {
351                             quit("Input is a directory, but output is not", 2);
352                         }
353                     }
354                 }
355             }
356
357             if (outputFileName != null && !wholeDirectory) {
358                 outputFile = new File JavaDoc(outputFileName);
359                 if (outputFile.isDirectory()) {
360                     quit("Output is a directory, but input is not", 2);
361                 }
362             }
363
364             if (useAssociatedStylesheet) {
365                 if (wholeDirectory) {
366                     processDirectoryAssoc(sources, outputFile, parameterList, initialMode);
367                 } else {
368                     processFileAssoc((Source JavaDoc)sources.get(0), null, outputFile, parameterList, initialMode);
369                 }
370             } else {
371
372                 long startTime = (new Date JavaDoc()).getTime();
373
374
375                 PreparedStylesheet sheet = null;
376
377                 if (precompiled) {
378                     try {
379                         sheet = PreparedStylesheet.loadCompiledStylesheet(config, styleFileName);
380                         if (showTime) {
381                             long endTime = (new Date JavaDoc()).getTime();
382                             System.err.println("Stylesheet loading time: " + (endTime - startTime) + " milliseconds");
383                         }
384                     } catch (Exception JavaDoc err) {
385                         err.printStackTrace();
386                     }
387                 } else {
388                     Source JavaDoc styleSource;
389                     XMLReader JavaDoc styleParser = null;
390                     if (useURLs || styleFileName.startsWith("http:")
391                             || styleFileName.startsWith("file:")) {
392                         styleSource = config.getURIResolver().resolve(styleFileName, null);
393                         if (styleSource == null) {
394                             styleSource = config.getSystemURIResolver().resolve(styleFileName, null);
395                         }
396                     } else if (styleFileName.equals("-")) {
397                         // take input from stdin
398
if (styleParserName == null) {
399                             styleSource = new StreamSource JavaDoc(System.in);
400                         } else {
401                             styleParser = config.getStyleParser();
402                             styleSource = new SAXSource JavaDoc(styleParser, new InputSource JavaDoc(System.in));
403                         }
404                     } else {
405                         File JavaDoc sheetFile = new File JavaDoc(styleFileName);
406                         if (!sheetFile.exists()) {
407                             quit("Stylesheet file " + sheetFile + " does not exist", 2);
408                         }
409                         if (styleParserName == null) {
410                             styleSource = new StreamSource JavaDoc(sheetFile.toURI().toString());
411                         } else {
412                             InputSource JavaDoc eis = new InputSource JavaDoc(sheetFile.toURI().toString());
413                             styleParser = config.getStyleParser();
414                             styleSource = new SAXSource JavaDoc(styleParser, eis);
415                         }
416                     }
417
418                     if (styleSource == null) {
419                         quit("URIResolver for stylesheet file must return a Source", 2);
420                     }
421
422                     sheet = (PreparedStylesheet)factory.newTemplates(styleSource);
423                     if (styleParser != null) {
424                         config.reuseStyleParser(styleParser);
425                         // pointless, because the Configuration won't be used again; but we want to set a good example
426
}
427                     if (showTime) {
428                         long endTime = (new Date JavaDoc()).getTime();
429                         System.err.println("Stylesheet compilation time: " + (endTime - startTime) + " milliseconds");
430                     }
431                 }
432
433                 if (initialTemplate != null) {
434                     execute(initialTemplate, sheet, outputFile, parameterList, initialMode);
435                 } else if (wholeDirectory) {
436                     processDirectory(sources, sheet, outputFile, parameterList, initialMode);
437                 } else {
438                     processFile((Source JavaDoc)sources.get(0), sheet, outputFile, parameterList, initialMode);
439                 }
440             }
441         } catch (TerminationException err) {
442             quit(err.getMessage(), 1);
443         } catch (TransformerConfigurationException err) {
444             //err.printStackTrace();
445
quit(err.getMessage(), 2);
446         } catch (TransformerException err) {
447             //err.printStackTrace();
448
quit("Transformation failed: " + err.getMessage(), 2);
449         } catch (TransformerFactoryConfigurationError err) {
450             //err.printStackTrace();
451
quit("Transformation failed: " + err.getMessage(), 2);
452         } catch (Exception JavaDoc err2) {
453             err2.printStackTrace();
454             quit("Fatal error during transformation: " + err2.getMessage(), 2);
455         }
456
457
458         //System.exit(0);
459
}
460
461     /**
462      * Preprocess the list of sources. This method exists so that it can be
463      * overridden in a subclass
464      */

465
466     public List JavaDoc preprocess(List JavaDoc sources) throws XPathException {
467         return sources;
468     }
469
470     /**
471      * Get the configuration.
472      */

473
474     protected Configuration getConfiguration() {
475         return config;
476     }
477
478     /**
479      * Exit with a message
480      *
481      * @param message The message to be output
482      * @param code The result code to be returned to the operating
483      * system shell
484      */

485
486     protected static void quit(String JavaDoc message, int code) {
487         System.err.println(message);
488         System.exit(code);
489     }
490
491     /**
492      * Load a document, or all the documents in a directory, given a filename or URL
493      *
494      * @return if sourceFileName represents a single source document, return a Source object representing
495      * that document. If sourceFileName represents a directory, return a List containing multiple Source
496      * objects, one for each file in the directory.
497      */

498
499     public static Object JavaDoc loadDocuments(String JavaDoc sourceFileName, boolean useURLs, Configuration config, boolean useSAXSource)
500             throws TransformerException {
501
502         Source JavaDoc sourceInput;
503         XMLReader JavaDoc parser = null;
504         if (useURLs || sourceFileName.startsWith("http:") || sourceFileName.startsWith("file:")) {
505             sourceInput = config.getURIResolver().resolve(sourceFileName, null);
506             if (sourceInput == null) {
507                 sourceInput = config.getSystemURIResolver().resolve(sourceFileName, null);
508             }
509             return sourceInput;
510         } else if (sourceFileName.equals("-")) {
511             // take input from stdin
512
if (useSAXSource) {
513                 parser = config.getSourceParser();
514                 sourceInput = new SAXSource JavaDoc(parser, new InputSource JavaDoc(System.in));
515             } else {
516                 sourceInput = new StreamSource JavaDoc(System.in);
517             }
518             return sourceInput;
519         } else {
520             File JavaDoc sourceFile = new File JavaDoc(sourceFileName);
521             if (!sourceFile.exists()) {
522                 quit("Source file " + sourceFile + " does not exist", 2);
523             }
524             if (sourceFile.isDirectory()) {
525                 parser = config.getSourceParser();
526                 List JavaDoc result = new ArrayList JavaDoc(20);
527                 String JavaDoc[] files = sourceFile.list();
528                 for (int f = 0; f < files.length; f++) {
529                     File JavaDoc file = new File JavaDoc(sourceFile, files[f]);
530                     if (!file.isDirectory()) {
531                         if (useSAXSource) {
532                             InputSource JavaDoc eis = new InputSource JavaDoc(file.toURI().toString());
533                             sourceInput = new SAXSource JavaDoc(parser, eis);
534                                 // it's safe to use the same parser for each document, as they
535
// will be processed one at a time.
536
} else {
537                             sourceInput = new StreamSource JavaDoc(file.toURI().toString());
538                         }
539                         result.add(sourceInput);
540                     }
541                 }
542                 return result;
543             } else {
544                 if (useSAXSource) {
545                     InputSource JavaDoc eis = new InputSource JavaDoc(sourceFile.toURI().toString());
546                     sourceInput = new SAXSource JavaDoc(config.getSourceParser(), eis);
547                 } else {
548                     sourceInput = new StreamSource JavaDoc(sourceFile.toURI().toString());
549                 }
550                 return sourceInput;
551             }
552         }
553     }
554
555     /**
556      * Process each file in the source directory using its own associated stylesheet
557      *
558      * @param sources The sources in the directory to be processed
559      * @param outputDir The directory in which output files are to be
560      * created
561      * @param parameterList List of parameters to be supplied to each
562      * transformation
563      * @param initialMode Initial mode for executing each
564      * transformation
565      * @throws Exception when any error occurs during a transformation
566      */

567
568     public void processDirectoryAssoc(List JavaDoc sources, File JavaDoc outputDir, ArrayList JavaDoc parameterList, String JavaDoc initialMode)
569             throws Exception JavaDoc {
570
571         int failures = 0;
572         for (int f = 0; f < sources.size(); f++) {
573             Source JavaDoc source = (Source JavaDoc)sources.get(f);
574             String JavaDoc localName = getLocalFileName(source);
575             try {
576                 processFileAssoc(source, localName, outputDir, parameterList, initialMode);
577             } catch (XPathException err) {
578                 failures++;
579                 System.err.println("While processing " + localName +
580                         ": " + err.getMessage() + '\n');
581             }
582         }
583         if (failures > 0) {
584             throw new DynamicError(failures + " transformation" +
585                     (failures == 1 ? "" : "s") + " failed");
586         }
587     }
588
589     /**
590      * Make an output file in the output directory, with filename extension derived from the
591      * media-type produced by the stylesheet
592      *
593      * @param directory The directory in which the file is to be created
594      * @param localName The local name of the file within the
595      * directory, excluding the file type suffix
596      * @param sheet The Templates object identifying the stylesheet -
597      * used to determine the output method, and hence the suffix to be
598      * used for the filename
599      * @return The newly created file
600      */

601
602     private File JavaDoc makeOutputFile(File JavaDoc directory, String JavaDoc localName,
603                                 Templates sheet) {
604         String JavaDoc mediaType = sheet.getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE);
605         String JavaDoc suffix = ".xml";
606         if ("text/html".equals(mediaType)) {
607             suffix = ".html";
608         } else if ("text/plain".equals(mediaType)) {
609             suffix = ".txt";
610         }
611         String JavaDoc prefix = localName;
612         if (localName.endsWith(".xml") || localName.endsWith(".XML")) {
613             prefix = localName.substring(0, localName.length() - 4);
614         }
615         return new File JavaDoc(directory, prefix + suffix);
616     }
617
618
619     /**
620      * Process a single source file using its associated stylesheet(s)
621      *
622      * @param sourceInput Identifies the source file to be transformed
623      * @param localName The local name of the file within the
624      * directory, excluding the file type suffix
625      * @param outputFile The output file to contain the results of the
626      * transformation
627      * @param parameterList List of parameters to be supplied to the
628      * transformation
629      * @param initialMode Initial mode for executing the transformation
630      * @throws XPathException If the transformation fails
631      */

632
633     public void processFileAssoc(Source JavaDoc sourceInput, String JavaDoc localName, File JavaDoc outputFile, ArrayList JavaDoc parameterList, String JavaDoc initialMode)
634             throws TransformerException {
635         if (showTime) {
636             System.err.println("Processing " + sourceInput.getSystemId() + " using associated stylesheet");
637         }
638         long startTime = (new Date JavaDoc()).getTime();
639
640         Source JavaDoc style = factory.getAssociatedStylesheet(sourceInput, null, null, null);
641         Templates sheet = factory.newTemplates(style);
642         if (showTime) {
643             System.err.println("Prepared associated stylesheet " + style.getSystemId());
644         }
645
646         Transformer instance = sheet.newTransformer();
647         setParams(instance, parameterList);
648         if (initialMode != null) {
649             ((Controller)instance).setInitialMode(initialMode);
650         }
651
652         File JavaDoc outFile = outputFile;
653
654         if (outFile != null && outFile.isDirectory()) {
655             outFile = makeOutputFile(outFile, localName, sheet);
656         }
657
658         StreamResult JavaDoc result =
659                 (outFile == null ? new StreamResult JavaDoc(System.out) : new StreamResult JavaDoc(outFile.toURI().toString()));
660
661         try {
662             instance.transform(sourceInput, result);
663         } catch (TerminationException err) {
664             throw err;
665         } catch (XPathException err) {
666             // The error message will already have been displayed; don't do it twice
667
throw new DynamicError("Run-time errors were reported");
668         }
669
670         if (showTime) {
671             long endTime = (new Date JavaDoc()).getTime();
672             System.err.println("Execution time: " + (endTime - startTime) + " milliseconds");
673         }
674     }
675
676     /**
677      * Process each file in the source directory using the same supplied stylesheet
678      *
679      * @param sources The sources in the directory to be processed
680      * @param sheet The Templates object identifying the stylesheet
681      * @param outputDir The directory in which output files are to be
682      * created
683      * @param parameterList List of parameters to be supplied to each
684      * transformation
685      * @param initialMode Initial mode for executing each
686      * transformation
687      * @throws XPathException when any error occurs during a
688      * transformation
689      */

690
691     public void processDirectory(List JavaDoc sources, Templates sheet, File JavaDoc outputDir, ArrayList JavaDoc parameterList, String JavaDoc initialMode)
692             throws TransformerException {
693         int failures = 0;
694         for (int f = 0; f < sources.size(); f++) {
695             Source JavaDoc source = (Source JavaDoc)sources.get(f);
696             String JavaDoc localName = getLocalFileName(source);
697             try {
698                 File JavaDoc outputFile = makeOutputFile(outputDir, localName, sheet);
699                 processFile(source, sheet, outputFile, parameterList, initialMode);
700             } catch (XPathException err) {
701                 failures++;
702                 System.err.println("While processing " + localName + ": " + err.getMessage() + '\n');
703             }
704         }
705         if (failures > 0) {
706             throw new DynamicError(failures + " transformation" +
707                     (failures == 1 ? "" : "s") + " failed");
708         }
709     }
710
711     private static String JavaDoc getLocalFileName(Source JavaDoc source) {
712         try {
713             String JavaDoc path = new URI JavaDoc(source.getSystemId()).getPath();
714             while (true) {
715                 int sep = path.indexOf('/');
716                 if (sep < 0) {
717                     return path;
718                 } else {
719                     path = path.substring(sep + 1);
720                 }
721             }
722         } catch (URISyntaxException JavaDoc err) {
723             throw new IllegalArgumentException JavaDoc(err.getMessage());
724         }
725     }
726
727     /**
728      * Process a single file using a supplied stylesheet
729      *
730      * @param source The source XML document to be transformed
731      * @param sheet The Templates object identifying the stylesheet
732      * @param outputFile The output file to contain the results of the
733      * transformation
734      * @param parameterList List of parameters to be supplied to the
735      * transformation
736      * @param initialMode Initial mode for executing the transformation
737      * @throws net.sf.saxon.trans.XPathException
738      * If the transformation fails
739      */

740
741     public void processFile(Source JavaDoc source, Templates sheet, File JavaDoc outputFile, ArrayList JavaDoc parameterList, String JavaDoc initialMode)
742             throws TransformerException {
743
744         for (int r = 0; r < repeat; r++) { // repeat is for internal testing/timing
745
if (showTime) {
746                 System.err.println("Processing " + source.getSystemId());
747             }
748             long startTime = (new Date JavaDoc()).getTime();
749             Transformer instance = sheet.newTransformer();
750             setParams(instance, parameterList);
751             if (initialMode != null) {
752                 ((Controller)instance).setInitialMode(initialMode);
753             }
754 // if (outputFile==null) {
755
// ((Controller)instance).setBaseOutputURI(new File(System.getProperty("user.dir")).toURI().toString());
756
// }
757
Result JavaDoc result =
758                     (outputFile == null ?
759                     new StreamResult JavaDoc(System.out) :
760                     new StreamResult JavaDoc(outputFile.toURI().toString()));
761
762             try {
763                 instance.transform(source, result);
764             } catch (TerminationException err) {
765                 throw err;
766             } catch (XPathException err) {
767                 // The message will already have been displayed; don't do it twice
768
throw new DynamicError("Run-time errors were reported");
769             }
770
771             if (showTime) {
772                 long endTime = (new Date JavaDoc()).getTime();
773                 System.err.println("Execution time: " + (endTime - startTime) + " milliseconds");
774                 System.err.println("Memory used: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
775                 config.getNamePool().statistics();
776                 if (repeat > 1) {
777                     System.err.println("-------------------------------");
778                     Runtime.getRuntime().gc();
779                 }
780             }
781         }
782     }
783
784     /**
785      * Invoke a supplied stylesheet with no source document
786      *
787      * @param initialTemplate The entry point to the stylesheet
788      * @param sheet The Templates object identifying the stylesheet
789      * @param outputFile The output file to contain the results of the
790      * transformation
791      * @param parameterList List of parameters to be supplied to the
792      * transformation
793      * @param initialMode Initial mode for executing the transformation
794      * @throws net.sf.saxon.trans.XPathException
795      * If the transformation fails
796      */

797
798     public void execute(String JavaDoc initialTemplate, Templates sheet, File JavaDoc outputFile, ArrayList JavaDoc parameterList, String JavaDoc initialMode)
799             throws TransformerException {
800
801         for (int r = 0; r < repeat; r++) { // repeat is for internal testing/timing
802
if (showTime) {
803                 System.err.println("Calling template " + initialTemplate);
804             }
805             long startTime = (new Date JavaDoc()).getTime();
806             Transformer instance = sheet.newTransformer();
807             setParams(instance, parameterList);
808             if (initialMode != null) {
809                 ((Controller)instance).setInitialMode(initialMode);
810             }
811             ((Controller)instance).setInitialTemplate(initialTemplate);
812             Result JavaDoc result =
813                     (outputFile == null ?
814                     new StreamResult JavaDoc(System.out) :
815                     new StreamResult JavaDoc(outputFile.toURI().toString()));
816
817             try {
818                 instance.transform(null, result);
819             } catch (TerminationException err) {
820                 throw err;
821             } catch (XPathException err) {
822                 // The message will already have been displayed; don't do it twice
823
throw new DynamicError("Run-time errors were reported");
824             }
825
826             if (showTime) {
827                 long endTime = (new Date JavaDoc()).getTime();
828                 System.err.println("Execution time: " + (endTime - startTime) + " milliseconds");
829             }
830         }
831     }
832
833     /**
834      * Supply the requested parameters to the transformer
835      *
836      * @param t The transformer to be used for the transformation
837      * @param parameterList List of parameters to be supplied to the
838      * transformation
839      */

840     private void setParams(Transformer t, ArrayList JavaDoc parameterList)
841             throws TransformerException {
842         for (int i = 0; i < parameterList.size(); i++) {
843             String JavaDoc arg = (String JavaDoc)parameterList.get(i);
844             int eq = arg.indexOf("=");
845             String JavaDoc argname = arg.substring(0, eq);
846             if (argname.startsWith("!")) {
847                 // parameters starting with "!" are taken as output properties
848
t.setOutputProperty(argname.substring(1), arg.substring(eq + 1));
849             } else if (argname.startsWith("+")) {
850 // parameters starting with "+" are taken as input documents
851
Object JavaDoc sources = loadDocuments(arg.substring(eq + 1), useURLs, config, true);
852                 t.setParameter(argname.substring(1), sources);
853             } else {
854                 t.setParameter(argname, new UntypedAtomicValue(arg.substring(eq + 1)));
855             }
856         }
857     }
858
859     public void setPOption(Configuration config) {
860         factory.setAttribute(FeatureKeys.RECOGNIZE_URI_QUERY_PARAMETERS,
861                 Boolean.valueOf(true));
862     }
863
864     /**
865      * Report incorrect usage of the command line, with a list of the options and arguments that are available
866      *
867      * @param name The name of the command being executed (allows subclassing)
868      * @param message The error message
869      */

870     protected void badUsage(String JavaDoc name, String JavaDoc message) {
871         if (!"".equals(message)) {
872             System.err.println(message);
873         }
874         if (!showTime) {
875             System.err.println(config.getProductTitle());
876         }
877         System.err.println("Usage: " + name + " [options] source-doc style-doc {param=value}...");
878         System.err.println("Options: ");
879         System.err.println(" -a Use xml-stylesheet PI, not style-doc argument");
880         System.err.println(" -c Indicates that style-doc is a compiled stylesheet");
881         System.err.println(" -cr classname Use specified collection URI resolver class");
882         System.err.println(" -ds Use standard tree data structure");
883         System.err.println(" -dt Use tinytree data structure (default)");
884         System.err.println(" -im modename Start transformation in specified mode");
885         System.err.println(" -it template Start transformation by calling named template");
886         System.err.println(" -l Retain line numbers in source document tree");
887         System.err.println(" -o filename Send output to named file or directory");
888         System.err.println(" -m classname Use specified Emitter class for xsl:message output");
889         System.err.println(" -novw Suppress warning when running with an XSLT 1.0 stylesheet");
890         System.err.println(" -r classname Use specified URIResolver class");
891         System.err.println(" -p Recognize Saxon file extensions and query parameters");
892         System.err.println(" -t Display version and timing information");
893         System.err.println(" -T Set standard TraceListener");
894         System.err.println(" -TJ Trace calls to external Java functions");
895         System.err.println(" -TL classname Set a specific TraceListener");
896         System.err.println(" -u Names are URLs not filenames");
897         System.err.println(" -v Validate source documents using DTD");
898         if (config.isSchemaAware(Configuration.XSLT)) {
899             System.err.println(" -val Validate source documents using schema");
900             System.err.println(" -vlax Lax validation of source documents using schema");
901             System.err.println(" -vw Treat validation errors on result document as warnings");
902         }
903         System.err.println(" -w0 Recover silently from recoverable errors");
904         System.err.println(" -w1 Report recoverable errors and continue (default)");
905         System.err.println(" -w2 Treat recoverable errors as fatal");
906         System.err.println(" -x classname Use specified SAX parser for source file");
907         System.err.println(" -y classname Use specified SAX parser for stylesheet");
908         System.err.println(" -? Display this message ");
909         System.err.println(" param=value Set stylesheet string parameter");
910         System.err.println(" +param=file Set stylesheet document parameter");
911         System.err.println(" !option=value Set serialization option");
912         if ("".equals(message)) {
913             System.exit(0);
914         } else {
915             System.exit(2);
916         }
917     }
918
919 }
920
921 //
922
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
923
// you may not use this file except in compliance with the License. You may obtain a copy of the
924
// License at http://www.mozilla.org/MPL/
925
//
926
// Software distributed under the License is distributed on an "AS IS" basis,
927
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
928
// See the License for the specific language governing rights and limitations under the License.
929
//
930
// The Original Code is: all this file.
931
//
932
// The Initial Developer of the Original Code is Michael H. Kay.
933
//
934
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
935
//
936
// Contributor(s): changes to allow source and/or stylesheet from stdin contributed by
937
// Gunther Schadow [gunther@aurora.regenstrief.org]
938
//
939
Popular Tags