| 1 package net.sf.saxon; 2 import net.sf.saxon.event.*; 3 import net.sf.saxon.expr.XPathContext; 4 import net.sf.saxon.expr.XPathContextMajor; 5 import net.sf.saxon.functions.Component; 6 import net.sf.saxon.instruct.*; 7 import net.sf.saxon.om.*; 8 import net.sf.saxon.tinytree.TinyBuilder; 9 import net.sf.saxon.trace.*; 10 import net.sf.saxon.trans.*; 11 import net.sf.saxon.tree.TreeBuilder; 12 import net.sf.saxon.value.DateTimeValue; 13 import org.xml.sax.SAXParseException ; 14 15 import javax.xml.transform.*; 16 import javax.xml.transform.dom.DOMSource ; 17 import javax.xml.transform.stream.StreamResult ; 18 import java.io.OutputStream ; 19 import java.io.PrintStream ; 20 import java.util.*; 21 22 53 54 public class Controller extends Transformer implements InstructionInfoProvider { 55 56 private Configuration config; 57 private DocumentInfo principalSourceDocument; 58 private Bindery bindery; private NamePool namePool; 60 private Emitter messageEmitter; 61 private RuleManager ruleManager; 62 private Properties outputProperties; 63 private GlobalParameterSet parameters; 64 private PreparedStylesheet preparedStylesheet; 65 private TraceListener traceListener; 66 private boolean tracingPaused; 67 private URIResolver standardURIResolver; 68 private URIResolver userURIResolver; 69 private Result principalResult; 70 private String principalResultURI; 71 private OutputURIResolver outputURIResolver; 72 private ErrorListener errorListener; 73 private Executable executable; 74 private int treeModel = Builder.TINY_TREE; 75 private Template initialTemplate = null; 76 private HashSet allOutputDestinations; 77 private DocumentPool sourceDocumentPool; 78 private HashMap userDataTable; 79 private DateTimeValue currentDateTime; 80 private boolean dateTimePreset = false; 81 private int initialMode = -1; 82 private NodeInfo lastRememberedNode = null; 83 private int lastRememberedNumber = -1; 84 private ClassLoader classLoader; 85 87 94 95 public Controller(Configuration config) { 96 this.config = config; 97 executable = new Executable(); 99 executable.setConfiguration(config); 100 executable.setHostLanguage(config.getHostLanguage()); 101 sourceDocumentPool = new DocumentPool(); 102 reset(); 103 } 104 105 113 114 public Controller(Configuration config, Executable executable) { 115 this.config = config; 116 this.executable = executable; 117 sourceDocumentPool = new DocumentPool(); 118 reset(); 119 } 120 121 144 145 public void reset() { 146 bindery = new Bindery(); 147 namePool = NamePool.getDefaultNamePool(); 148 standardURIResolver = config.getSystemURIResolver(); 149 userURIResolver = config.getURIResolver(); 150 151 outputURIResolver = config.getOutputURIResolver(); 152 errorListener = config.getErrorListener(); 153 if (errorListener instanceof StandardErrorListener) { 154 PrintStream ps = ((StandardErrorListener)errorListener).getErrorOutput(); 158 errorListener = ((StandardErrorListener)errorListener).makeAnother(executable.getHostLanguage()); 159 ((StandardErrorListener)errorListener).setErrorOutput(ps); 160 ((StandardErrorListener)errorListener).setRecoveryPolicy( 161 config.getRecoveryPolicy()); 162 } 163 164 userDataTable = new HashMap(20); 165 166 traceListener = null; 167 tracingPaused = false; 168 TraceListener tracer = config.getTraceListener(); 169 if (tracer!=null) { 170 addTraceListener(tracer); 171 } 172 173 setTreeModel(config.getTreeModel()); 174 principalSourceDocument = null; 175 messageEmitter = null; 176 outputProperties = null; 177 parameters = null; 178 179 principalResult = null; 180 principalResultURI = null; 181 initialTemplate = null; 182 allOutputDestinations = null; 183 currentDateTime = null; 184 dateTimePreset = false; 185 initialMode = -1; 186 lastRememberedNode = null; 187 lastRememberedNumber = -1; 188 classLoader = null; 189 190 } 191 192 198 public Configuration getConfiguration() { 199 return config; 200 } 201 202 216 217 public void setInitialMode(String expandedModeName) { 218 if (expandedModeName==null) return; 219 if (expandedModeName.equals("")) return; 220 initialMode = namePool.allocateClarkName(expandedModeName); 221 } 222 223 227 246 247 public void setOutputProperties(Properties properties) { 248 if (properties == null) { 249 outputProperties = null; 250 } else { 251 Enumeration keys = properties.propertyNames(); 252 while(keys.hasMoreElements()) { 253 String key = (String )keys.nextElement(); 254 setOutputProperty(key, properties.getProperty(key)); 255 } 256 } 257 } 258 259 275 276 public Properties getOutputProperties() { 277 if (outputProperties == null) { 278 if (executable==null) { 279 return new Properties(); 280 } else { 281 outputProperties = executable.getDefaultOutputProperties(); 282 } 283 } 284 285 287 Properties newProps = new Properties(); 288 Enumeration keys = outputProperties.propertyNames(); 289 while(keys.hasMoreElements()) { 290 String key = (String )keys.nextElement(); 291 newProps.put(key, outputProperties.getProperty(key)); 292 } 293 return newProps; 294 } 295 296 311 312 public void setOutputProperty(String name, String value) { 313 if (outputProperties == null) { 314 outputProperties = getOutputProperties(); 315 } 316 try { 317 SaxonOutputKeys.checkOutputProperty(name, value); 318 } catch (DynamicError err) { 319 throw new IllegalArgumentException (err.getMessage()); 320 } 321 outputProperties.put(name, value); 322 } 323 324 339 340 public String getOutputProperty(String name) { 341 try { 342 SaxonOutputKeys.checkOutputProperty(name, null); 343 } catch (DynamicError err) { 344 throw new IllegalArgumentException (err.getMessage()); 345 } 346 if (outputProperties == null) { 347 if (executable==null) { 348 return null; 349 } else { 350 outputProperties = executable.getDefaultOutputProperties(); 351 } 352 } 353 return outputProperties.getProperty(name); 354 } 355 356 370 371 public void setBaseOutputURI(String uri) { 372 principalResultURI = uri; 373 } 374 375 389 390 public String getBaseOutputURI() { 391 return principalResultURI; 392 } 393 394 399 400 public Result getPrincipalResult() { 401 return principalResult; 402 } 403 404 409 410 public boolean checkUniqueOutputDestination(String uri) { 411 if (allOutputDestinations == null) { 412 allOutputDestinations = new HashSet(20); 413 } 414 if (allOutputDestinations.contains(uri)) { 415 return false; 416 } 417 allOutputDestinations.add(uri); 418 return true; 419 } 420 421 423 441 442 public void setInitialTemplate(String expandedName) throws XPathException { 443 int fingerprint = namePool.allocateClarkName(expandedName); 444 Template t = getExecutable().getNamedTemplate(fingerprint); 445 if (t == null) { 446 DynamicError err = new DynamicError("There is no named template with expanded name " 447 + expandedName); 448 err.setErrorCode("XTDE0040"); 449 throw err; 450 } else { 451 initialTemplate = t; 452 } 453 } 454 455 457 464 465 public PipelineConfiguration makePipelineConfiguration() { 466 PipelineConfiguration pipe = new PipelineConfiguration(); 467 pipe.setConfiguration(getConfiguration()); 468 pipe.setErrorListener(getErrorListener()); 469 pipe.setURIResolver(userURIResolver==null ? standardURIResolver : userURIResolver); 470 pipe.setController(this); 471 if (getExecutable() != null) { 472 pipe.setLocationProvider(getExecutable().getLocationMap()); 474 } 475 return pipe; 476 } 477 478 488 489 public Emitter makeMessageEmitter() throws XPathException { 490 String emitterClass = config.getMessageEmitterClass(); 491 492 Object emitter = config.getInstance(emitterClass, getClassLoader()); 493 if (!(emitter instanceof Emitter)) { 494 throw new DynamicError(emitterClass + " is not an Emitter"); 495 } 496 setMessageEmitter((Emitter)emitter); 497 return messageEmitter; 498 } 499 500 521 522 public void setMessageEmitter(Emitter emitter) { 523 messageEmitter = emitter; 524 messageEmitter.setPipelineConfiguration(makePipelineConfiguration()); 525 } 526 527 534 535 public Emitter getMessageEmitter() { 536 return messageEmitter; 537 } 538 539 553 554 public CharacterMapExpander makeCharacterMapExpander(String useMaps) throws XPathException { 555 CharacterMapExpander characterMapExpander = null; 556 HashMap characterMapIndex = getExecutable().getCharacterMapIndex(); 557 if (useMaps != null && characterMapIndex != null) { 558 List characterMaps = new ArrayList(5); 559 StringTokenizer st = new StringTokenizer(useMaps); 560 while (st.hasMoreTokens()) { 561 String expandedName = st.nextToken(); 562 int f = namePool.getFingerprintForExpandedName(expandedName); 563 HashMap map = (HashMap)characterMapIndex.get(new Integer (f)); 564 if (map==null) { 565 throw new DynamicError("Character map '" + expandedName + "' has not been defined"); 566 } 567 characterMaps.add(map); 568 } 569 if (characterMaps.size() > 0) { 570 characterMapExpander = new CharacterMapExpander(); 571 characterMapExpander.setCharacterMaps(characterMaps); 572 } 573 } 574 return characterMapExpander; 575 } 576 577 585 586 public int getRecoveryPolicy() { 587 if (errorListener instanceof StandardErrorListener) { 588 return ((StandardErrorListener)errorListener).getRecoveryPolicy(); 589 } else { 590 return Configuration.RECOVER_WITH_WARNINGS; 591 } 592 } 593 594 599 600 public void setErrorListener(ErrorListener listener) { 601 errorListener = listener; 602 } 603 604 609 610 public ErrorListener getErrorListener() { 611 return errorListener; 612 } 613 614 625 626 public void recoverableError(XPathException err) throws DynamicError { 627 try { 628 if (executable.getHostLanguage() == Configuration.XQUERY) { 629 errorListener.fatalError(err); 630 throw err; 631 } else { 632 errorListener.error(err); 633 } 634 } catch (TransformerException e) { 635 throw DynamicError.makeDynamicError(e); 636 } 637 } 638 639 643 644 651 652 public Executable getExecutable() { 653 return executable; 654 } 655 656 663 664 public DocumentPool getDocumentPool() { 665 return sourceDocumentPool; 666 } 667 668 674 675 public void clearDocumentPool() { 676 sourceDocumentPool = new DocumentPool(); 677 } 678 679 689 690 public void setPrincipalSourceDocument(DocumentInfo doc) { 691 principalSourceDocument = doc; 692 } 693 694 701 702 public Bindery getBindery() { 703 return bindery; 704 } 705 706 713 714 public DocumentInfo getPrincipalSourceDocument() { 715 return principalSourceDocument; 716 } 717 718 725 726 public void setURIResolver(URIResolver resolver) { 727 userURIResolver = resolver; 728 } 729 730 739 740 public URIResolver getURIResolver() { 741 return userURIResolver; 742 } 743 744 752 753 public URIResolver getStandardURIResolver() { 754 return standardURIResolver; 755 } 756 757 772 773 public void setOutputURIResolver(OutputURIResolver resolver) { 774 if (resolver==null) { 775 outputURIResolver = StandardOutputResolver.getInstance(); 776 } else { 777 outputURIResolver = resolver; 778 } 779 } 780 781 789 790 public OutputURIResolver getOutputURIResolver() { 791 return outputURIResolver; 792 } 793 794 801 802 public KeyManager getKeyManager() { 803 return executable.getKeyManager(); 804 } 805 806 815 816 public NamePool getNamePool() { 817 return namePool; 818 } 819 820 830 831 public void setTreeModel(int model) { 832 treeModel = model; 833 } 834 835 841 842 public Builder makeBuilder() { 843 Builder b; 844 if (treeModel==Builder.TINY_TREE) { 845 b = new TinyBuilder(); 846 } else { 847 b = new TreeBuilder(); 848 } 849 b.setTiming(config.isTiming()); 850 b.setLineNumbering(config.isLineNumbering()); 851 b.setPipelineConfiguration(makePipelineConfiguration()); 852 return b; 853 } 854 855 873 874 public Stripper makeStripper(Receiver b) { 875 if (config.isStripsAllWhiteSpace()) { 876 if (b==null) { 877 return AllElementStripper.getInstance(); 878 } else { 879 Stripper s = new AllElementStripper(); 880 s.setUnderlyingReceiver(b); 881 return s; 882 } 883 } 884 Stripper stripper; 885 if (executable==null) { 886 stripper = new Stripper(new Mode(Mode.STRIPPER_MODE)); 887 } else { 888 stripper = executable.newStripper(); 889 } 890 stripper.setPipelineConfiguration(makePipelineConfiguration()); 891 if (b != null) { 893 stripper.setUnderlyingReceiver(b); 894 } 895 896 return stripper; 897 } 898 899 907 public void registerDocument(DocumentInfo doc, String systemId) { 908 sourceDocumentPool.add(doc, systemId); 909 } 911 912 916 923 public void setRuleManager(RuleManager r) { 924 ruleManager = r; 925 } 926 927 935 public RuleManager getRuleManager() { 936 return ruleManager; 937 } 938 939 943 953 public TraceListener getTraceListener() { return traceListener; 955 } 956 957 966 967 public final boolean isTracing() { return traceListener != null && !tracingPaused; 969 } 970 971 978 public final void pauseTracing(boolean pause) { 979 tracingPaused = pause; 980 } 981 982 996 997 public void addTraceListener(TraceListener trace) { traceListener = TraceEventMulticaster.add(traceListener, trace); 999 } 1000 1001 |