1 package com.icl.saxon; 2 import com.icl.saxon.tree.TreeBuilder; 3 import com.icl.saxon.tinytree.TinyBuilder; 4 import com.icl.saxon.om.Builder; 5 import com.icl.saxon.om.Navigator; 6 import com.icl.saxon.om.DocumentInfo; 7 import com.icl.saxon.om.Namespace; 8 import com.icl.saxon.om.NamePool; 9 import com.icl.saxon.expr.*; 10 import com.icl.saxon.style.*; 11 import com.icl.saxon.output.*; 12 import com.icl.saxon.trace.*; 13 import com.icl.saxon.style.TerminationException; 14 15 import org.xml.sax.SAXException ; 16 import org.xml.sax.helpers.AttributesImpl ; 17 import org.xml.sax.*; 18 19 import org.w3c.dom.Node ; 20 import org.w3c.dom.Document ; 21 22 import java.util.*; 23 import java.io.*; 24 import java.net.URL ; 25 import java.net.MalformedURLException ; 26 27 import javax.xml.transform.*; 28 import javax.xml.transform.sax.*; 29 import javax.xml.transform.stream.*; 30 31 41 42 public class StyleSheet { 43 44 protected TransformerFactoryImpl factory = new TransformerFactoryImpl(); 45 46 protected NamePool namePool = NamePool.getDefaultNamePool(); 47 boolean showTime = false; 48 int repeat = 1; 49 50 58 59 public static void main (String args[]) 60 throws java.lang.Exception 61 { 62 (new StyleSheet()).doMain(args, new StyleSheet(), " java com.icl.saxon.StyleSheet"); 64 } 65 66 73 74 protected void doMain(String args[], StyleSheet app, String name) { 75 76 77 String sourceFileName = null; 78 String styleFileName = null; 79 File sourceFile = null; 80 File styleFile = null; 81 File outputFile = null; 82 boolean useURLs = false; 83 ParameterSet params = new ParameterSet(); 84 Properties outputProperties = new Properties(); 85 String outputFileName = null; 86 boolean useAssociatedStylesheet = false; 87 boolean wholeDirectory = false; 88 89 91 try { 92 int i = 0; 93 while (true) { 94 if (i>=args.length) badUsage(name, "No source file name"); 95 96 if (args[i].charAt(0)=='-') { 97 98 if (args[i].equals("-a")) { 99 useAssociatedStylesheet = true; 100 i++; 101 } 102 103 else if (args[i].equals("-ds")) { 104 factory.setAttribute( 105 FeatureKeys.TREE_MODEL, 106 new Integer (Builder.STANDARD_TREE)); 107 i++; 108 } 109 110 else if (args[i].equals("-dt")) { 111 factory.setAttribute( 112 FeatureKeys.TREE_MODEL, 113 new Integer (Builder.TINY_TREE)); 114 i++; 115 } 116 117 118 else if (args[i].equals("-l")) { 119 factory.setAttribute( 120 FeatureKeys.LINE_NUMBERING, 121 new Boolean (true)); 122 i++; 123 } 124 125 else if (args[i].equals("-u")) { 126 useURLs = true; 127 i++; 128 } 129 130 else if (args[i].equals("-t")) { 131 System.err.println(Version.getProductName()); 132 System.err.println("Java version " + System.getProperty("java.version")); 133 factory.setAttribute( 134 FeatureKeys.TIMING, 135 new Boolean (true)); 136 137 Loader.setTracing(true); 138 showTime = true; 139 i++; 140 } 141 142 else if (args[i].equals("-3")) { i++; 144 repeat = 3; 145 } 146 147 else if (args[i].equals("-9")) { i++; 149 repeat = 9; 150 } 151 152 else if (args[i].equals("-o")) { 153 i++; 154 if (args.length < i+2) badUsage(name, "No output file name"); 155 outputFileName = args[i++]; 156 } 157 158 else if (args[i].equals("-x")) { 159 i++; 160 if (args.length < i+2) badUsage(name, "No source parser class"); 161 String sourceParserName = args[i++]; 162 factory.setAttribute( 163 FeatureKeys.SOURCE_PARSER_CLASS, 164 sourceParserName); 165 } 166 167 else if (args[i].equals("-y")) { 168 i++; 169 if (args.length < i+2) badUsage(name, "No style parser class"); 170 String styleParserName = args[i++]; 171 factory.setAttribute( 172 FeatureKeys.STYLE_PARSER_CLASS, 173 styleParserName); 174 } 175 176 else if (args[i].equals("-r")) { 177 i++; 178 if (args.length < i+2) badUsage(name, "No URIResolver class"); 179 String r = args[i++]; 180 factory.setURIResolver(makeURIResolver(r)); 181 } 182 183 else if (args[i].equals("-T")) { 184 i++; 185 TraceListener traceListener = new com.icl.saxon.trace.SimpleTraceListener(); 186 factory.setAttribute( 187 FeatureKeys.TRACE_LISTENER, 188 traceListener); 189 factory.setAttribute( 190 FeatureKeys.LINE_NUMBERING, 191 Boolean.TRUE); 192 } 193 194 else if (args[i].equals("-TL")) { 195 i++; 196 if (args.length < i+2) badUsage(name, "No TraceListener class"); 197 TraceListener traceListener = makeTraceListener(args[i++]); 198 factory.setAttribute( 199 FeatureKeys.TRACE_LISTENER, 200 traceListener); 201 factory.setAttribute( 202 FeatureKeys.LINE_NUMBERING, 203 Boolean.TRUE); 204 } 205 206 else if (args[i].equals("-w0")) { 207 i++; 208 factory.setAttribute( 209 FeatureKeys.RECOVERY_POLICY, 210 new Integer (Controller.RECOVER_SILENTLY)); 211 } 212 else if (args[i].equals("-w1")) { 213 i++; 214 factory.setAttribute( 215 FeatureKeys.RECOVERY_POLICY, 216 new Integer (Controller.RECOVER_WITH_WARNINGS)); 217 } 218 else if (args[i].equals("-w2")) { 219 i++; 220 factory.setAttribute( 221 FeatureKeys.RECOVERY_POLICY, 222 new Integer (Controller.DO_NOT_RECOVER)); 223 } 224 225 else if (args[i].equals("-m")) { 226 i++; 227 if (args.length < i+2) badUsage(name, "No message Emitter class"); 228 factory.setAttribute( 229 FeatureKeys.MESSAGE_EMITTER_CLASS, 230 args[i++]); 231 } 232 233 else if (args[i].equals("-noext")) { 234 i++; 235 factory.setAttribute( 236 FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS, 237 new Boolean (false)); 238 } 239 240 else badUsage(name, "Unknown option " + args[i]); 241 } 242 243 else break; 244 } 245 246 if (args.length < i+1 ) badUsage(name, "No source file name"); 247 sourceFileName = args[i++]; 248 249 if (!useAssociatedStylesheet) { 250 if (args.length < i+1 ) badUsage(name, "No stylesheet file name"); 251 styleFileName = args[i++]; 252 } 253 254 for (int p=i; p<args.length; p++) { 255 String arg = args[p]; 256 int eq = arg.indexOf("="); 257 if (eq<1 || eq>=arg.length()-1) badUsage(name, "Bad param=value pair on command line"); 258 String argname = arg.substring(0,eq); 259 int argcode = namePool.allocate("", "", argname); 260 params.put(argcode, new StringValue(arg.substring(eq+1))); 261 } 262 263 Source sourceInput = null; 264 265 if (useURLs || sourceFileName.startsWith("http:") || sourceFileName.startsWith("file:")) { 266 sourceInput = factory.getURIResolver().resolve(sourceFileName, null); 267 268 } else { 269 sourceFile = new File(sourceFileName); 270 if (!sourceFile.exists()) { 271 quit("Source file " + sourceFile + " does not exist", 2); 272 } 273 if (sourceFile.isDirectory()) { 274 wholeDirectory = true; 275 if (outputFileName==null) { 276 quit("To process a directory, -o must be specified", 2); 277 } else if (outputFileName.equals(sourceFileName)) { 278 quit("Output directory must be different from input", 2); 279 } else { 280 outputFile = new File(outputFileName); 281 if (!outputFile.isDirectory()) { 282 quit("Input is a directory, but output is not", 2); 283 } 284 } 285 } else { 286 ExtendedInputSource eis = new ExtendedInputSource(sourceFile); 287 sourceInput = new SAXSource(factory.getSourceParser(), eis); 288 eis.setEstimatedLength((int)sourceFile.length()); 289 } 290 } 291 292 if (outputFileName!=null && !wholeDirectory) { 293 outputFile = new File(outputFileName); 294 if (outputFile.isDirectory()) { 295 quit("Output is a directory, but input is not", 2); 296 } 297 } 298 299 if (useAssociatedStylesheet) { 300 if (wholeDirectory) { 301 processDirectoryAssoc(sourceFile, outputFile, params); 302 } else { 303 processFileAssoc(sourceInput, null, outputFile, params); 304 } 305 } else { 306 307 long startTime = (new Date()).getTime(); 308 309 Source styleSource; 310 if (useURLs || styleFileName.startsWith("http:") 311 || styleFileName.startsWith("file:")) { 312 styleSource = factory.getURIResolver().resolve(styleFileName, null); 313 314 } else { 315 File sheetFile = new File(styleFileName); 316 if (!sheetFile.exists()) { 317 quit("Stylesheet file " + sheetFile + " does not exist", 2); 318 } 319 ExtendedInputSource eis = new ExtendedInputSource(sheetFile); 320 styleSource = new SAXSource(factory.getStyleParser(), eis); 321 } 322 323 if (styleSource==null) { 324 quit("URIResolver for stylesheet file must return a Source", 2); 325 } 326 327 Templates sheet = factory.newTemplates(styleSource); 328 329 if (showTime) { 330 long endTime = (new Date()).getTime(); 331 System.err.println("Preparation time: " + (endTime-startTime) + " milliseconds"); 332 startTime = endTime; 333 } 334 335 if (wholeDirectory) { 336 processDirectory(sourceFile, sheet, outputFile, params); 337 } else { 338 processFile(sourceInput, sheet, outputFile, params); 339 } 340 } 341 } catch (TerminationException err) { 342 quit(err.getMessage(), 1); 343 } catch (TransformerException err) { 344 quit("Transformation failed: " + err.getMessage(), 2); 345 } catch (Exception err2) { 346 err2.printStackTrace(); 347 } 348 349 350 } 352 353 356 357 protected static void quit(String message, int code) { 358 System.err.println(message); 359 System.exit(code); 360 } 361 362 365 366 public void processDirectoryAssoc( 367 File sourceDir, File outputDir, ParameterSet params) 368 throws Exception { 369 370 String [] files = sourceDir.list(); 371 int failures = 0; 372 for (int f=0; f<files.length; f++) { 373 File file = new File(sourceDir, files[f]); 374 if (!file.isDirectory()) { 375 String localName = file.getName(); 376 try { 377 ExtendedInputSource eis = new ExtendedInputSource(file); 378 SAXSource source = new SAXSource(factory.getSourceParser(), eis); 379 processFileAssoc(source, localName, outputDir, params); 380 } catch (TransformerException err) { 381 failures++; 382 System.err.println("While processing " + localName + 383 ": " + err.getMessage() + "\n"); 384 } 385 } 386 } 387 if (failures>0) { 388 throw new TransformerException(failures + " transformation" + 389 (failures==1?"":"s") + " failed"); 390 } 391 } 392 393 397 398 private File makeOutputFile(File directory, String localName, 399 Templates sheet) { 400 String mediaType = sheet.getOutputProperties().getProperty( 401 OutputKeys.MEDIA_TYPE); 402 String suffix = ".xml"; 403 if ("text/html".equals(mediaType)) { 404 suffix = ".html"; 405 } else if ("text/plain".equals(mediaType)) { 406 suffix = ".txt"; 407 } 408 String prefix = localName; 409 if (localName.endsWith(".xml") || localName.endsWith(".XML")) { 410 prefix = localName.substring(0, localName.length()-4); 411 } 412 return new File(directory, prefix+suffix); 413 } 414 415 416 419 420 public void processFileAssoc( 421 Source sourceInput, String localName, File outputFile, ParameterSet params) 422 throws TransformerException 423 { 424 if (showTime) { 425 System.err.println("Processing " + sourceInput.getSystemId() + " using associated stylesheet"); 426 } 427 long startTime = (new Date()).getTime(); 428 429 Source style = factory.getAssociatedStylesheet(sourceInput, null, null, null); 430 Templates sheet = factory.newTemplates(style); 431 if (showTime) { 432 System.err.println("Prepared associated stylesheet " + style.getSystemId()); 433 } 434 Transformer instance = sheet.newTransformer(); 435 ((Controller)instance).setParams(params); 436 437 File outFile = outputFile; 438 439 if (outFile!=null && outFile.isDirectory()) { 440 outFile = makeOutputFile(outFile, localName, sheet); 441 } 442 443 StreamResult result = 444 (outFile==null ? new StreamResult(System.out) : new StreamResult(outFile)); 445 446 try { 447 instance.transform(sourceInput, result); 448 } catch (TerminationException err) { 449 throw err; 450 } catch (TransformerException err) { 451 throw new TransformerException("Run-time errors were reported"); 453 } 454 455 if (showTime) { 456 long endTime = (new Date()).getTime(); 457 System.err.println("Execution time: " + (endTime-startTime) + " milliseconds"); 458 startTime = endTime; 459 } 460 } 461 462 465 466 public void processDirectory( 467 File sourceDir, Templates sheet, File outputDir, ParameterSet params) 468 throws TransformerException 469 { 470 471 String [] files = sourceDir.list(); 472 int failures = 0; 473 for (int f=0; f<files.length; f++) { 474 File file = new File(sourceDir, files[f]); 475 String localName = file.getName(); 476 try { 477 if (!file.isDirectory()) { 478 File outputFile = makeOutputFile(outputDir, localName, sheet); 479 ExtendedInputSource eis = new ExtendedInputSource(file); 480 Source source = new SAXSource(factory.getSourceParser(), eis); 481 processFile(source, sheet, outputFile, params); 482 } 483 } catch (TransformerException err) { 484 failures++; 485 System.err.println("While processing " + localName + ": " + err.getMessage() + "\n"); 486 } 487 } 488 if (failures>0) { 489 throw new TransformerException(failures + " transformation" + 490 (failures==1?"":"s") + " failed"); 491 } 492 } 493 494 497 498 public void processFile( 499 Source source, Templates sheet, File outputFile, ParameterSet params) 500 throws TransformerException { 501 502 for (int r=0; r<repeat; r++) { if (showTime) { 504 System.err.println("Processing " + source.getSystemId()); 505 } 506 long startTime = (new Date()).getTime(); 507 Transformer instance = sheet.newTransformer(); 508 ((Controller)instance).setParams(params); 509 510 Result result = 511 (outputFile==null ? 512 new StreamResult(System.out) : 513 new StreamResult(outputFile)); 514 515 try { 516 instance.transform(source, result); 517 } catch (TerminationException err) { 518 throw err; 519 } catch (TransformerException err) { 520 throw new TransformerException("Run-time errors were reported"); 522 } 523 524 if (showTime) { 525 long endTime = (new Date()).getTime(); 526 System.err.println("Execution time: " + (endTime-startTime) + " milliseconds"); 527 startTime = endTime; 528 } 529 } 530 } 531 532 protected void badUsage(String name, String message) { 533 System.err.println(message); 534 System.err.println(Version.getProductName()); 535 System.err.println("Usage: " + name + " [options] source-doc style-doc {param=value}..."); 536 System.err.println("Options: "); 537 System.err.println(" -a Use xml-stylesheet PI, not style-doc argument "); 538 System.err.println(" -ds Use standard tree data structure "); 539 System.err.println(" -dt Use tinytree data structure (default)"); 540 System.err.println(" -o filename Send output to named file or directory "); 541 System.err.println(" -m classname Use specified Emitter class for xsl:message output "); 542 System.err.println(" -r classname Use specified URIResolver class "); 543 System.err.println(" -t Display version and timing information "); 544 System.err.println(" -T Set standard TraceListener"); 545 System.err.println(" -TL classname Set a specific TraceListener"); 546 System.err.println(" -u Names are URLs not filenames "); 547 System.err.println(" -w0 Recover silently from recoverable errors "); 548 System.err.println(" -w1 Report recoverable errors and continue (default)"); 549 System.err.println(" -w2 Treat recoverable errors as fatal"); 550 System.err.println(" -x classname Use specified SAX parser for source file "); 551 System.err.println(" -y classname Use specified SAX parser for stylesheet "); 552 System.err.println(" -? Display this message "); 553 System.exit(2); 554 } 555 556 public static URIResolver makeURIResolver (String className) 557 throws TransformerException 558 { 559 Object obj = Loader.getInstance(className); 560 if (obj instanceof URIResolver) { 561 return (URIResolver)obj; 562 } 563 throw new TransformerException("Class " + className + " is not a URIResolver"); 564 } 565 566 public static TraceListener makeTraceListener (String className) 567 throws TransformerException 568 { 569 Object obj = Loader.getInstance(className); 570 if (obj instanceof TraceListener) { 571 return (TraceListener)obj; 572 } 573 throw new TransformerException("Class " + className + " is not a TraceListener"); 574 } 575 576 } 577 578 | Popular Tags |