1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.io.StringReader ; 25 import java.util.Dictionary ; 26 import java.util.Enumeration ; 27 import java.util.Hashtable ; 28 import java.util.Properties ; 29 import java.util.Stack ; 30 import java.util.StringTokenizer ; 31 import java.util.Vector ; 32 33 import com.sun.java_cup.internal.runtime.Symbol; 34 import javax.xml.XMLConstants ; 35 import javax.xml.parsers.ParserConfigurationException ; 36 import javax.xml.parsers.SAXParser ; 37 import javax.xml.parsers.SAXParserFactory ; 38 39 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType; 41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 43 import com.sun.org.apache.xalan.internal.xsltc.runtime.AttributeList; 44 import org.xml.sax.Attributes ; 45 import org.xml.sax.ContentHandler ; 46 import org.xml.sax.InputSource ; 47 import org.xml.sax.Locator ; 48 import org.xml.sax.SAXException ; 49 import org.xml.sax.SAXParseException ; 50 import org.xml.sax.XMLReader ; 51 52 59 public class Parser implements Constants, ContentHandler { 60 61 private static final String XSL = "xsl"; private static final String TRANSLET = "translet"; 64 private Locator _locator = null; 65 66 private XSLTC _xsltc; private XPathParser _xpathParser; private Vector _errors; private Vector _warnings; 71 private Hashtable _instructionClasses; private Hashtable _instructionAttrs;; private Hashtable _qNames; 74 private Hashtable _namespaces; 75 private QName _useAttributeSets; 76 private QName _excludeResultPrefixes; 77 private QName _extensionElementPrefixes; 78 private Hashtable _variableScope; 79 private Stylesheet _currentStylesheet; 80 private SymbolTable _symbolTable; private Output _output; 82 private Template _template; 84 private boolean _rootNamespaceDef; 86 private SyntaxTreeNode _root; 87 88 private String _target; 89 90 private int _currentImportPrecedence; 91 92 public Parser(XSLTC xsltc) { 93 _xsltc = xsltc; 94 } 95 96 public void init() { 97 _qNames = new Hashtable (512); 98 _namespaces = new Hashtable (); 99 _instructionClasses = new Hashtable (); 100 _instructionAttrs = new Hashtable (); 101 _variableScope = new Hashtable (); 102 _template = null; 103 _errors = new Vector (); 104 _warnings = new Vector (); 105 _symbolTable = new SymbolTable(); 106 _xpathParser = new XPathParser(this); 107 _currentStylesheet = null; 108 _output = null; 109 _root = null; 110 _rootNamespaceDef = false; 111 _currentImportPrecedence = 1; 112 113 initStdClasses(); 114 initInstructionAttrs(); 115 initExtClasses(); 116 initSymbolTable(); 117 118 _useAttributeSets = 119 getQName(XSLT_URI, XSL, "use-attribute-sets"); 120 _excludeResultPrefixes = 121 getQName(XSLT_URI, XSL, "exclude-result-prefixes"); 122 _extensionElementPrefixes = 123 getQName(XSLT_URI, XSL, "extension-element-prefixes"); 124 } 125 126 public void setOutput(Output output) { 127 if (_output != null) { 128 if (_output.getImportPrecedence() <= output.getImportPrecedence()) { 129 String cdata = _output.getCdata(); 130 output.mergeOutput(_output); 131 _output.disable(); 132 _output = output; 133 } 134 else { 135 output.disable(); 136 } 137 } 138 else { 139 _output = output; 140 } 141 } 142 143 public Output getOutput() { 144 return _output; 145 } 146 147 public Properties getOutputProperties() { 148 return getTopLevelStylesheet().getOutputProperties(); 149 } 150 151 public void addVariable(Variable var) { 152 addVariableOrParam(var); 153 } 154 155 public void addParameter(Param param) { 156 addVariableOrParam(param); 157 } 158 159 private void addVariableOrParam(VariableBase var) { 160 Object existing = _variableScope.get(var.getName()); 161 if (existing != null) { 162 if (existing instanceof Stack ) { 163 Stack stack = (Stack )existing; 164 stack.push(var); 165 } 166 else if (existing instanceof VariableBase) { 167 Stack stack = new Stack (); 168 stack.push(existing); 169 stack.push(var); 170 _variableScope.put(var.getName(), stack); 171 } 172 } 173 else { 174 _variableScope.put(var.getName(), var); 175 } 176 } 177 178 public void removeVariable(QName name) { 179 Object existing = _variableScope.get(name); 180 if (existing instanceof Stack ) { 181 Stack stack = (Stack )existing; 182 if (!stack.isEmpty()) stack.pop(); 183 if (!stack.isEmpty()) return; 184 } 185 _variableScope.remove(name); 186 } 187 188 public VariableBase lookupVariable(QName name) { 189 Object existing = _variableScope.get(name); 190 if (existing instanceof VariableBase) { 191 return((VariableBase)existing); 192 } 193 else if (existing instanceof Stack ) { 194 Stack stack = (Stack )existing; 195 return((VariableBase)stack.peek()); 196 } 197 return(null); 198 } 199 200 public void setXSLTC(XSLTC xsltc) { 201 _xsltc = xsltc; 202 } 203 204 public XSLTC getXSLTC() { 205 return _xsltc; 206 } 207 208 public int getCurrentImportPrecedence() { 209 return _currentImportPrecedence; 210 } 211 212 public int getNextImportPrecedence() { 213 return ++_currentImportPrecedence; 214 } 215 216 public void setCurrentStylesheet(Stylesheet stylesheet) { 217 _currentStylesheet = stylesheet; 218 } 219 220 public Stylesheet getCurrentStylesheet() { 221 return _currentStylesheet; 222 } 223 224 public Stylesheet getTopLevelStylesheet() { 225 return _xsltc.getStylesheet(); 226 } 227 228 public QName getQNameSafe(final String stringRep) { 229 final int colon = stringRep.lastIndexOf(':'); 231 if (colon != -1) { 232 final String prefix = stringRep.substring(0, colon); 233 final String localname = stringRep.substring(colon + 1); 234 String namespace = null; 235 236 if (prefix.equals(XMLNS_PREFIX) == false) { 238 namespace = _symbolTable.lookupNamespace(prefix); 239 if (namespace == null) namespace = EMPTYSTRING; 240 } 241 return getQName(namespace, prefix, localname); 242 } 243 else { 244 final String uri = stringRep.equals(XMLNS_PREFIX) ? null 245 : _symbolTable.lookupNamespace(EMPTYSTRING); 246 return getQName(uri, null, stringRep); 247 } 248 } 249 250 public QName getQName(final String stringRep) { 251 return getQName(stringRep, true, false); 252 } 253 254 public QName getQNameIgnoreDefaultNs(final String stringRep) { 255 return getQName(stringRep, true, true); 256 } 257 258 public QName getQName(final String stringRep, boolean reportError) { 259 return getQName(stringRep, reportError, false); 260 } 261 262 private QName getQName(final String stringRep, boolean reportError, 263 boolean ignoreDefaultNs) 264 { 265 final int colon = stringRep.lastIndexOf(':'); 267 if (colon != -1) { 268 final String prefix = stringRep.substring(0, colon); 269 final String localname = stringRep.substring(colon + 1); 270 String namespace = null; 271 272 if (prefix.equals(XMLNS_PREFIX) == false) { 274 namespace = _symbolTable.lookupNamespace(prefix); 275 if (namespace == null && reportError) { 276 final int line = _locator.getLineNumber(); 277 ErrorMsg err = new ErrorMsg(ErrorMsg.NAMESPACE_UNDEF_ERR, 278 line, prefix); 279 reportError(ERROR, err); 280 } 281 } 282 return getQName(namespace, prefix, localname); 283 } 284 else { 285 if (stringRep.equals(XMLNS_PREFIX)) { 286 ignoreDefaultNs = true; 287 } 288 final String defURI = ignoreDefaultNs ? null 289 : _symbolTable.lookupNamespace(EMPTYSTRING); 290 return getQName(defURI, null, stringRep); 291 } 292 } 293 294 public QName getQName(String namespace, String prefix, String localname) { 295 if (namespace == null || namespace.equals(EMPTYSTRING)) { 296 QName name = (QName)_qNames.get(localname); 297 if (name == null) { 298 name = new QName(null, prefix, localname); 299 _qNames.put(localname, name); 300 } 301 return name; 302 } 303 else { 304 Dictionary space = (Dictionary )_namespaces.get(namespace); 305 if (space == null) { 306 final QName name = new QName(namespace, prefix, localname); 307 _namespaces.put(namespace, space = new Hashtable ()); 308 space.put(localname, name); 309 return name; 310 } 311 else { 312 QName name = (QName)space.get(localname); 313 if (name == null) { 314 name = new QName(namespace, prefix, localname); 315 space.put(localname, name); 316 } 317 return name; 318 } 319 } 320 } 321 322 public QName getQName(String scope, String name) { 323 return getQName(scope + name); 324 } 325 326 public QName getQName(QName scope, QName name) { 327 return getQName(scope.toString() + name.toString()); 328 } 329 330 public QName getUseAttributeSets() { 331 return _useAttributeSets; 332 } 333 334 public QName getExtensionElementPrefixes() { 335 return _extensionElementPrefixes; 336 } 337 338 public QName getExcludeResultPrefixes() { 339 return _excludeResultPrefixes; 340 } 341 342 347 public Stylesheet makeStylesheet(SyntaxTreeNode element) 348 throws CompilerException { 349 try { 350 Stylesheet stylesheet; 351 352 if (element instanceof Stylesheet) { 353 stylesheet = (Stylesheet)element; 354 } 355 else { 356 stylesheet = new Stylesheet(); 357 stylesheet.setSimplified(); 358 stylesheet.addElement(element); 359 stylesheet.setAttributes((AttributeList) element.getAttributes()); 360 361 if (element.lookupNamespace(EMPTYSTRING) == null) { 363 element.addPrefixMapping(EMPTYSTRING, EMPTYSTRING); 364 } 365 } 366 stylesheet.setParser(this); 367 return stylesheet; 368 } 369 catch (ClassCastException e) { 370 ErrorMsg err = new ErrorMsg(ErrorMsg.NOT_STYLESHEET_ERR, element); 371 throw new CompilerException(err.toString()); 372 } 373 } 374 375 378 public void createAST(Stylesheet stylesheet) { 379 try { 380 if (stylesheet != null) { 381 stylesheet.parseContents(this); 382 final int precedence = stylesheet.getImportPrecedence(); 383 final Enumeration elements = stylesheet.elements(); 384 while (elements.hasMoreElements()) { 385 Object child = elements.nextElement(); 386 if (child instanceof Text) { 387 final int l = _locator.getLineNumber(); 388 ErrorMsg err = 389 new ErrorMsg(ErrorMsg.ILLEGAL_TEXT_NODE_ERR,l,null); 390 reportError(ERROR, err); 391 } 392 } 393 if (!errorsFound()) { 394 stylesheet.typeCheck(_symbolTable); 395 } 396 } 397 } 398 catch (TypeCheckError e) { 399 reportError(ERROR, new ErrorMsg(e)); 400 } 401 } 402 403 409 public SyntaxTreeNode parse(XMLReader reader, InputSource input) { 410 try { 411 reader.setContentHandler(this); 413 reader.parse(input); 414 return (SyntaxTreeNode)getStylesheet(_root); 416 } 417 catch (IOException e) { 418 if (_xsltc.debug()) e.printStackTrace(); 419 reportError(ERROR,new ErrorMsg(e)); 420 } 421 catch (SAXException e) { 422 Throwable ex = e.getException(); 423 if (_xsltc.debug()) { 424 e.printStackTrace(); 425 if (ex != null) ex.printStackTrace(); 426 } 427 reportError(ERROR, new ErrorMsg(e)); 428 } 429 catch (CompilerException e) { 430 if (_xsltc.debug()) e.printStackTrace(); 431 reportError(ERROR, new ErrorMsg(e)); 432 } 433 catch (Exception e) { 434 if (_xsltc.debug()) e.printStackTrace(); 435 reportError(ERROR, new ErrorMsg(e)); 436 } 437 return null; 438 } 439 440 445 public SyntaxTreeNode parse(InputSource input) { 446 try { 447 final SAXParserFactory factory = SAXParserFactory.newInstance(); 449 450 if (_xsltc.isSecureProcessing()) { 451 try { 452 factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); 453 } 454 catch (SAXException e) {} 455 } 456 457 try { 458 factory.setFeature(Constants.NAMESPACE_FEATURE,true); 459 } 460 catch (Exception e) { 461 factory.setNamespaceAware(true); 462 } 463 final SAXParser parser = factory.newSAXParser(); 464 final XMLReader reader = parser.getXMLReader(); 465 return(parse(reader, input)); 466 } 467 catch (ParserConfigurationException e) { 468 ErrorMsg err = new ErrorMsg(ErrorMsg.SAX_PARSER_CONFIG_ERR); 469 reportError(ERROR, err); 470 } 471 catch (SAXParseException e){ 472 reportError(ERROR, new ErrorMsg(e.getMessage(),e.getLineNumber())); 473 } 474 catch (SAXException e) { 475 reportError(ERROR, new ErrorMsg(e.getMessage())); 476 } 477 return null; 478 } 479 480 public SyntaxTreeNode getDocumentRoot() { 481 return _root; 482 } 483 484 private String _PImedia = null; 485 private String _PItitle = null; 486 private String _PIcharset = null; 487 488 497 protected void setPIParameters(String media, String title, String charset) { 498 _PImedia = media; 499 _PItitle = title; 500 _PIcharset = charset; 501 } 502 503 512 private SyntaxTreeNode getStylesheet(SyntaxTreeNode root) 513 throws CompilerException { 514 515 if (_target == null) { 518 if (!_rootNamespaceDef) { 519 ErrorMsg msg = new ErrorMsg(ErrorMsg.MISSING_XSLT_URI_ERR); 520 throw new CompilerException(msg.toString()); 521 } 522 return(root); 523 } 524 525 if (_target.charAt(0) == '#') { 527 SyntaxTreeNode element = findStylesheet(root, _target.substring(1)); 528 if (element == null) { 529 ErrorMsg msg = new ErrorMsg(ErrorMsg.MISSING_XSLT_TARGET_ERR, 530 _target, root); 531 throw new CompilerException(msg.toString()); 532 } 533 return(element); 534 } 535 else { 536 return(loadExternalStylesheet(_target)); 537 } 538 } 539 540 545 private SyntaxTreeNode findStylesheet(SyntaxTreeNode root, String href) { 546 547 if (root == null) return null; 548 549 if (root instanceof Stylesheet) { 550 String id = root.getAttribute("id"); 551 if (id.equals(href)) return root; 552 } 553 Vector children = root.getContents(); 554 if (children != null) { 555 final int count = children.size(); 556 for (int i = 0; i < count; i++) { 557 SyntaxTreeNode child = (SyntaxTreeNode)children.elementAt(i); 558 SyntaxTreeNode node = findStylesheet(child, href); 559 if (node != null) return node; 560 } 561 } 562 return null; 563 } 564 565 568 private SyntaxTreeNode loadExternalStylesheet(String location) 569 throws CompilerException { 570 571 InputSource source; 572 573 if ((new File (location)).exists()) 575 source = new InputSource ("file:"+location); 576 else 577 source = new InputSource (location); 578 579 SyntaxTreeNode external = (SyntaxTreeNode)parse(source); 580 return(external); 581 } 582 583 private void initAttrTable(String elementName, String [] attrs) { 584 _instructionAttrs.put(getQName(XSLT_URI, XSL, elementName), 585 attrs); 586 } 587 588 private void initInstructionAttrs() { 589 initAttrTable("template", 590 new String [] {"match", "name", "priority", "mode"}); 591 initAttrTable("stylesheet", 592 new String [] {"id", "version", "extension-element-prefixes", 593 "exclude-result-prefixes"}); 594 initAttrTable("transform", 595 new String [] {"id", "version", "extension-element-prefixes", 596 "exclude-result-prefixes"}); 597 initAttrTable("text", new String [] {"disable-output-escaping"}); 598 initAttrTable("if", new String [] {"test"}); 599 initAttrTable("choose", new String [] {}); 600 initAttrTable("when", new String [] {"test"}); 601 initAttrTable("otherwise", new String [] {}); 602 initAttrTable("for-each", new String [] {"select"}); 603 initAttrTable("message", new String [] {"terminate"}); 604 initAttrTable("number", 605 new String [] {"level", "count", "from", "value", "format", "lang", 606 "letter-value", "grouping-separator", "grouping-size"}); 607 initAttrTable("comment", new String [] {}); 608 initAttrTable("copy", new String [] {"use-attribute-sets"}); 609 initAttrTable("copy-of", new String [] {"select"}); 610 initAttrTable("param", new String [] {"name", "select"}); 611 initAttrTable("with-param", new String [] {"name", "select"}); 612 initAttrTable("variable", new String [] {"name", "select"}); 613 initAttrTable("output", 614 new String [] {"method", "version", "encoding", 615 "omit-xml-declaration", "standalone", "doctype-public", 616 "doctype-system", "cdata-section-elements", "indent", 617 "media-type"}); 618 initAttrTable("sort", 619 new String [] {"select", "order", "case-order", "lang", "data-type"}); 620 initAttrTable("key", new String [] {"name", "match", "use"}); 621 initAttrTable("fallback", new String [] {}); 622 initAttrTable("attribute", new String [] {"name", "namespace"}); 623 initAttrTable("attribute-set", 624 new String [] {"name", "use-attribute-sets"}); 625 initAttrTable("value-of", 626 new String [] {"select", "disable-output-escaping"}); 627 initAttrTable("element", 628 new String [] {"name", "namespace", "use-attribute-sets"}); 629 initAttrTable("call-template", new String [] {"name"}); 630 initAttrTable("apply-templates", new String [] {"select", "mode"}); 631 initAttrTable("apply-imports", new String [] {}); 632 initAttrTable("decimal-format", 633 new String [] {"name", "decimal-separator", "grouping-separator", 634 "infinity", "minus-sign", "NaN", "percent", "per-mille", 635 "zero-digit", "digit", "pattern-separator"}); 636 initAttrTable("import", new String [] {"href"}); 637 initAttrTable("include", new String [] {"href"}); 638 initAttrTable("strip-space", new String [] {"elements"}); 639 initAttrTable("preserve-space", new String [] {"elements"}); 640 initAttrTable("processing-instruction", new String [] {"name"}); 641 initAttrTable("namespace-alias", 642 new String [] {"stylesheet-prefix", "result-prefix"}); 643 } 644 645 646 647 651 private void initStdClasses() { 652 initStdClass("template", "Template"); 653 initStdClass("stylesheet", "Stylesheet"); 654 initStdClass("transform", "Stylesheet"); 655 initStdClass("text", "Text"); 656 initStdClass("if", "If"); 657 initStdClass("choose", "Choose"); 658 initStdClass("when", "When"); 659 initStdClass("otherwise", "Otherwise"); 660 initStdClass("for-each", "ForEach"); 661 initStdClass("message", "Message"); 662 initStdClass("number", "Number"); 663 initStdClass("comment", "Comment"); 664 initStdClass("copy", "Copy"); 665 initStdClass("copy-of", "CopyOf"); 666 initStdClass("param", "Param"); 667 initStdClass("with-param", "WithParam"); 668 initStdClass("variable", "Variable"); 669 initStdClass("output", "Output"); 670 initStdClass("sort", "Sort"); 671 initStdClass("key", "Key"); 672 initStdClass("fallback", "Fallback"); 673 initStdClass("attribute", "XslAttribute"); 674 initStdClass("attribute-set", "AttributeSet"); 675 initStdClass("value-of", "ValueOf"); 676 initStdClass("element", "XslElement"); 677 initStdClass("call-template", "CallTemplate"); 678 initStdClass("apply-templates", "ApplyTemplates"); 679 initStdClass("apply-imports", "ApplyImports"); 680 initStdClass("decimal-format", "DecimalFormatting"); 681 initStdClass("import", "Import"); 682 initStdClass("include", "Include"); 683 initStdClass("strip-space", "Whitespace"); 684 initStdClass("preserve-space", "Whitespace"); 685 initStdClass("processing-instruction", "ProcessingInstruction"); 686 initStdClass("namespace-alias", "NamespaceAlias"); 687 } 688 689 private void initStdClass(String elementName, String className) { 690 _instructionClasses.put(getQName(XSLT_URI, XSL, elementName), 691 COMPILER_PACKAGE + '.' + className); 692 } 693 694 public boolean elementSupported(String namespace, String localName) { 695 return(_instructionClasses.get(getQName(namespace, XSL, localName)) != null); 696 } 697 698 public boolean functionSupported(String fname) { 699 return(_symbolTable.lookupPrimop(fname) != null); 700 } 701 702 private void initExtClasses() { 703 initExtClass("output", "TransletOutput"); 704 initExtClass(REDIRECT_URI, "write", "TransletOutput"); 705 } 706 707 private void initExtClass(String elementName, String className) { 708 _instructionClasses.put(getQName(TRANSLET_URI, TRANSLET, elementName), 709 COMPILER_PACKAGE + '.' + className); 710 } 711 712 private void initExtClass(String namespace, String elementName, String className) { 713 _instructionClasses.put(getQName(namespace, TRANSLET, elementName), 714 COMPILER_PACKAGE + '.' + className); 715 } 716 717 720 private void initSymbolTable() { 721 MethodType I_V = new MethodType(Type.Int, Type.Void); 722 MethodType I_R = new MethodType(Type.Int, Type.Real); 723 MethodType I_S = new MethodType(Type.Int, Type.String); 724 MethodType I_D = new MethodType(Type.Int, Type.NodeSet); 725 MethodType R_I = new MethodType(Type.Real, Type.Int); 726 MethodType R_V = new MethodType(Type.Real, Type.Void); 727 MethodType R_R = new MethodType(Type.Real, Type.Real); 728 MethodType R_D = new MethodType(Type.Real, Type.NodeSet); 729 MethodType R_O = new MethodType(Type.Real, Type.Reference); 730 MethodType I_I = new MethodType(Type.Int, Type.Int); 731 MethodType D_O = new MethodType(Type.NodeSet, Type.Reference); 732 MethodType D_V = new MethodType(Type.NodeSet, Type.Void); 733 MethodType D_S = new MethodType(Type.NodeSet, Type.String); 734 MethodType D_D = new MethodType(Type.NodeSet, Type.NodeSet); 735 MethodType A_V = new MethodType(Type.Node, Type.Void); 736 MethodType S_V = new MethodType(Type.String, Type.Void); 737 MethodType S_S = new MethodType(Type.String, Type.String); 738 MethodType S_A = new MethodType(Type.String, Type.Node); 739 MethodType S_D = new MethodType(Type.String, Type.NodeSet); 740 MethodType S_O = new MethodType(Type.String, Type.Reference); 741 MethodType B_O = new MethodType(Type.Boolean, Type.Reference); 742 MethodType B_V = new MethodType(Type.Boolean, Type.Void); 743 MethodType B_B = new MethodType(Type.Boolean, Type.Boolean); 744 MethodType B_S = new MethodType(Type.Boolean, Type.String); 745 MethodType D_X = new MethodType(Type.NodeSet, Type.Object); 746 MethodType R_RR = new MethodType(Type.Real, Type.Real, Type.Real); 747 MethodType I_II = new MethodType(Type.Int, Type.Int, Type.Int); 748 MethodType B_RR = new MethodType(Type.Boolean, Type.Real, Type.Real); 749 MethodType B_II = new MethodType(Type.Boolean, Type.Int, Type.Int); 750 MethodType S_SS = new MethodType(Type.String, Type.String, Type.String); 751 MethodType S_DS = new MethodType(Type.String, Type.Real, Type.String); 752 MethodType S_SR = new MethodType(Type.String, Type.String, Type.Real); 753 MethodType O_SO = new MethodType(Type.Reference, Type.String, Type.Reference); 754 755 MethodType D_SS = 756 new MethodType(Type.NodeSet, Type.String, Type.String); 757 MethodType D_SD = 758 new MethodType(Type.NodeSet, Type.String, Type.NodeSet); 759 MethodType B_BB = 760 new MethodType(Type.Boolean, Type.Boolean, Type.Boolean); 761 MethodType B_SS = 762 new MethodType(Type.Boolean, Type.String, Type.String); 763 MethodType S_SD = 764 new MethodType(Type.String, Type.String, Type.NodeSet); 765 MethodType S_DSS = 766 new MethodType(Type.String, Type.Real, Type.String, Type.String); 767 MethodType S_SRR = 768 new MethodType(Type.String, Type.String, Type.Real, Type.Real); 769 MethodType S_SSS = 770 new MethodType(Type.String, Type.String, Type.String, Type.String); 771 772 777 778 780 _symbolTable.addPrimop("current", A_V); 781 _symbolTable.addPrimop("last", I_V); 782 _symbolTable.addPrimop("position", I_V); 783 _symbolTable.addPrimop("true", B_V); 784 _symbolTable.addPrimop("false", B_V); 785 _symbolTable.addPrimop("not", B_B); 786 _symbolTable.addPrimop("name", S_V); 787 _symbolTable.addPrimop("name", S_A); 788 _symbolTable.addPrimop("generate-id", S_V); 789 _symbolTable.addPrimop("generate-id", S_A); 790 _symbolTable.addPrimop("ceiling", R_R); 791 _symbolTable.addPrimop("floor", R_R); 792 _symbolTable.addPrimop("round", R_R); 793 _symbolTable.addPrimop("contains", B_SS); 794 _symbolTable.addPrimop("number", R_O); 795 _symbolTable.addPrimop("number", R_V); 796 _symbolTable.addPrimop("boolean", B_O); 797 _symbolTable.addPrimop("string", S_O); 798 _symbolTable.addPrimop("string", S_V); 799 _symbolTable.addPrimop("translate", S_SSS); 800 _symbolTable.addPrimop("string-length", I_V); 801 _symbolTable.addPrimop("string-length", I_S); 802 _symbolTable.addPrimop("starts-with", B_SS); 803 _symbolTable.addPrimop("format-number", S_DS); 804 _symbolTable.addPrimop("format-number", S_DSS); 805 _symbolTable.addPrimop("unparsed-entity-uri", S_S); 806 _symbolTable.addPrimop("key", D_SS); 807 _symbolTable.addPrimop("key", D_SD); 808 _symbolTable.addPrimop("id", D_S); 809 _symbolTable.addPrimop("id", D_D); 810 _symbolTable.addPrimop("namespace-uri", S_V); 811 _symbolTable.addPrimop("function-available", B_S); 812 _symbolTable.addPrimop("element-available", B_S); 813 _symbolTable.addPrimop("document", D_S); 814 _symbolTable.addPrimop("document", D_V); 815 816 _symbolTable.addPrimop("count", I_D); 818 _symbolTable.addPrimop("sum", R_D); 819 _symbolTable.addPrimop("local-name", S_V); 820 _symbolTable.addPrimop("local-name", S_D); 821 _symbolTable.addPrimop("namespace-uri", S_V); 822 _symbolTable.addPrimop("namespace-uri", S_D); 823 _symbolTable.addPrimop("substring", S_SR); 824 _symbolTable.addPrimop("substring", S_SRR); 825 _symbolTable.addPrimop("substring-after", S_SS); 826 _symbolTable.addPrimop("substring-before", S_SS); 827 _symbolTable.addPrimop("normalize-space", S_V); 828 _symbolTable.addPrimop("normalize-space", S_S); 829 _symbolTable.addPrimop("system-property", S_S); 830 831 _symbolTable.addPrimop("nodeset", D_O); 833 _symbolTable.addPrimop("objectType", S_O); 834 _symbolTable.addPrimop("cast", O_SO); 835 836 _symbolTable.addPrimop("+", R_RR); 838 _symbolTable.addPrimop("-", R_RR); 839 _symbolTable.addPrimop("*", R_RR); 840 _symbolTable.addPrimop("/", R_RR); 841 _symbolTable.addPrimop("%", R_RR); 842 843 _symbolTable.addPrimop("+", I_II); 846 _symbolTable.addPrimop("-", I_II); 847 _symbolTable.addPrimop("*", I_II); 848 849 _symbolTable.addPrimop("<", B_RR); 851 _symbolTable.addPrimop("<=", B_RR); 852 _symbolTable.addPrimop(">", B_RR); 853 _symbolTable.addPrimop(">=", B_RR); 854 855 _symbolTable.addPrimop("<", B_II); 857 _symbolTable.addPrimop("<=", B_II); 858 _symbolTable.addPrimop(">", B_II); 859 _symbolTable.addPrimop(">=", B_II); 860 861 _symbolTable.addPrimop("<", B_BB); 863 _symbolTable.addPrimop("<=", B_BB); 864 _symbolTable.addPrimop(">", B_BB); 865 _symbolTable.addPrimop(">=", B_BB); 866 867 _symbolTable.addPrimop("or", B_BB); 869 _symbolTable.addPrimop("and", B_BB); 870 871 _symbolTable.addPrimop("u-", R_R); 873 _symbolTable.addPrimop("u-", I_I); 874 } 875 876 public SymbolTable getSymbolTable() { 877 return _symbolTable; 878 } 879 880 public Template getTemplate() { 881 return _template; 882 } 883 884 public void setTemplate(Template template) { 885 _template = template; 886 } 887 888 private int _templateIndex = 0; 889 890 public int getTemplateIndex() { 891 return(_templateIndex++); 892 } 893 894 905 906 private boolean versionIsOne = true; 907 908 public SyntaxTreeNode makeInstance(String uri, String prefix, 909 String local, Attributes attributes) 910 { 911 SyntaxTreeNode node = null; 912 QName qname = getQName(uri, prefix, local); 913 String className = (String )_instructionClasses.get(qname); 914 915 if (className != null) { 916 try { 917 final Class clazz = ObjectFactory.findProviderClass( 918 className, ObjectFactory.findClassLoader(), true); 919 node = (SyntaxTreeNode)clazz.newInstance(); 920 node.setQName(qname); 921 node.setParser(this); 922 if (_locator != null) { 923 node.setLineNumber(_locator.getLineNumber()); 924 } 925 if (node instanceof Stylesheet) { 926 _xsltc.setStylesheet((Stylesheet)node); 927 } 928 checkForSuperfluousAttributes(node, attributes); 929 } 930 catch (ClassNotFoundException e) { 931 ErrorMsg err = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, node); 932 reportError(ERROR, err); 933 } 934 catch (Exception e) { 935 ErrorMsg err = new ErrorMsg(ErrorMsg.INTERNAL_ERR, 936 e.getMessage(), node); 937 reportError(FATAL, err); 938 } 939 } 940 else { 941 if (uri != null) { 942 if (uri.equals(XSLT_URI)) { 944 node = new UnsupportedElement(uri, prefix, local, false); 945 UnsupportedElement element = (UnsupportedElement)node; 946 ErrorMsg msg = new ErrorMsg(ErrorMsg.UNSUPPORTED_XSL_ERR, 947 _locator.getLineNumber(),local); 948 element.setErrorMessage(msg); 949 if (versionIsOne) { 950 reportError(UNSUPPORTED,msg); 951 } 952 } 953 else if (uri.equals(TRANSLET_URI)) { 955 node = new UnsupportedElement(uri, prefix, local, true); 956 UnsupportedElement element = (UnsupportedElement)node; 957 ErrorMsg msg = new ErrorMsg(ErrorMsg.UNSUPPORTED_EXT_ERR, 958 _locator.getLineNumber(),local); 959 element.setErrorMessage(msg); 960 } 961 else { 963 Stylesheet sheet = _xsltc.getStylesheet(); 964 if ((sheet != null) && (sheet.isExtension(uri))) { 965 if (sheet != (SyntaxTreeNode)_parentStack.peek()) { 966 node = new UnsupportedElement(uri, prefix, local, true); 967 UnsupportedElement elem = (UnsupportedElement)node; 968 ErrorMsg msg = 969 new ErrorMsg(ErrorMsg.UNSUPPORTED_EXT_ERR, 970 _locator.getLineNumber(), 971 prefix+":"+local); 972 elem.setErrorMessage(msg); 973 } 974 } 975 } 976 } 977 if (node == null) { 978 node = new LiteralElement(); 979 node.setLineNumber(_locator.getLineNumber()); 980 } 981 } 982 if ((node != null) && (node instanceof LiteralElement)) { 983 ((LiteralElement)node).setQName(qname); 984 } 985 return(node); 986 } 987 988 992 private void checkForSuperfluousAttributes(SyntaxTreeNode node, 993 Attributes attrs) 994 { 995 QName qname = node.getQName(); 996 boolean isStylesheet = (node instanceof Stylesheet); 997 String [] legal = (String []) _instructionAttrs.get(qname); 998 if (versionIsOne && legal != null) { 999 int j; 1000 final int n = attrs.getLength(); 1001 1002 for (int i = 0; i < n; i++) { 1003 final String attrQName = attrs.getQName(i); 1004 1005 if (isStylesheet && attrQName.equals("version")) { 1006 versionIsOne = attrs.getValue(i).equals("1.0"); 1007 } 1008 1009 if (attrQName.startsWith("xml") || 1011 attrQName.indexOf(':') > 0) continue; 1012 1013 for (j = 0; j < legal.length; j++) { 1014 if (attrQName.equalsIgnoreCase(legal[j])) { 1015 break; 1016 } 1017 } 1018 if (j == legal.length) { 1019 final ErrorMsg err = 1020 new ErrorMsg(ErrorMsg.ILLEGAL_ATTRIBUTE_ERR, 1021 attrQName, node); 1022 reportError(WARNING, err); 1023 } 1024 } 1025 } 1026 } 1027 1028 1029 1034 public Expression parseExpression(SyntaxTreeNode parent, String exp) { 1035 return (Expression)parseTopLevel(parent, "<EXPRESSION>"+exp, null); 1036 } 1037 1038 1044 public Expression parseExpression(SyntaxTreeNode parent, 1045 String attr, String def) { 1046 String exp = parent.getAttribute(attr); 1048 if ((exp.length() == 0) && (def != null)) exp = def; 1050 return (Expression)parseTopLevel(parent, "<EXPRESSION>"+exp, exp); 1052 } 1053 1054 1059 public Pattern parsePattern(SyntaxTreeNode parent, String pattern) { 1060 return (Pattern)parseTopLevel(parent, "<PATTERN>"+pattern, pattern); 1061 } 1062 1063 1069 public Pattern parsePattern(SyntaxTreeNode parent, 1070 String attr, String def) { 1071 String pattern = parent.getAttribute(attr); 1073 if ((pattern.length() == 0) && (def != null)) pattern = def; 1075 return (Pattern)parseTopLevel(parent, "<PATTERN>"+pattern, pattern); 1077 } 1078 1079 1083 private SyntaxTreeNode parseTopLevel(SyntaxTreeNode parent, String text, 1084 String expression) { 1085 int line = 0; 1086 if (_locator != null) line = _locator.getLineNumber(); 1087 1088 try { 1089 _xpathParser.setScanner(new XPathLexer(new StringReader (text))); 1090 Symbol result = _xpathParser.parse(expression, line); 1091 if (result != null) { 1092 final SyntaxTreeNode node = (SyntaxTreeNode)result.value; 1093 if (node != null) { 1094 node.setParser(this); 1095 node.setParent(parent); 1096 node.setLineNumber(line); 1097 return node; 1099 } 1100 } 1101 reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR, 1102 expression, parent)); 1103 } 1104 catch (Exception e) { 1105 if (_xsltc.debug()) e.printStackTrace(); 1106 reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR, 1107 expression, parent)); 1108 } 1109 1110 SyntaxTreeNode.Dummy.setParser(this); 1112 return SyntaxTreeNode.Dummy; 1113 } 1114 1115 1116 1117 1120 public boolean errorsFound() { 1121 return _errors.size() > 0; 1122 } 1123 1124 1127 public void printErrors() { 1128 final int size = _errors.size(); 1129 if (size > 0) { 1130 System.err.println(new ErrorMsg(ErrorMsg.COMPILER_ERROR_KEY)); 1131 for (int i = 0; i < size; i++) { 1132 System.err.println(" " + _errors.elementAt(i)); 1133 } 1134 } 1135 } 1136 1137 1140 public void printWarnings() { 1141 final int size = _warnings.size(); 1142 if (size > 0) { 1143 System.err.println(new ErrorMsg(ErrorMsg.COMPILER_WARNING_KEY)); 1144 for (int i = 0; i < size; i++) { 1145 System.err.println(" " + _warnings.elementAt(i)); 1146 } 1147 } 1148 } 1149 1150 1153 public void reportError(final int category, final ErrorMsg error) { 1154 switch (category) { 1155 case Constants.INTERNAL: 1156 _errors.addElement(error); 1159 break; 1160 case Constants.UNSUPPORTED: 1161 _errors.addElement(error); 1164 break; 1165 case Constants.FATAL: 1166 _errors.addElement(error); 1169 break; 1170 case Constants.ERROR: 1171 _errors.addElement(error); 1174 break; 1175 case Constants.WARNING: 1176 _warnings.addElement(error); 1179 break; 1180 } 1181 } 1182 1183 public Vector getErrors() { 1184 return _errors; 1185 } 1186 1187 public Vector getWarnings() { 1188 return _warnings; 1189 } 1190 1191 1192 1193 private Stack _parentStack = null; 1194 private Hashtable _prefixMapping = null; 1195 1196 1199 public void startDocument() { 1200 _root = null; 1201 _target = null; 1202 _prefixMapping = null; 1203 _parentStack = new Stack (); 1204 } 1205 1206 1209 public void endDocument() { } 1210 1211 1212 1216 public void startPrefixMapping(String prefix, String uri) { 1217 if (_prefixMapping == null) { 1218 _prefixMapping = new Hashtable (); 1219 } 1220 _prefixMapping.put(prefix, uri); 1221 } 1222 1223 1227 public void endPrefixMapping(String prefix) { } 1228 1229 1234 public void startElement(String uri, String localname, 1235 String qname, Attributes attributes) 1236 throws SAXException { 1237 final int col = qname.lastIndexOf(':'); 1238 final String prefix = (col == -1) ? null : qname.substring(0, col); 1239 1240 SyntaxTreeNode element = makeInstance(uri, prefix, 1241 localname, attributes); 1242 if (element == null) { 1243 ErrorMsg err = new ErrorMsg(ErrorMsg.ELEMENT_PARSE_ERR, 1244 prefix+':'+localname); 1245 throw new SAXException (err.toString()); 1246 } 1247 1248 if (_root == null) { 1251 if ((_prefixMapping == null) || 1252 (_prefixMapping.containsValue(Constants.XSLT_URI) == false)) 1253 _rootNamespaceDef = false; 1254 else 1255 _rootNamespaceDef = true; 1256 _root = element; 1257 } 1258 else { 1259 SyntaxTreeNode parent = (SyntaxTreeNode)_parentStack.peek(); 1260 parent.addElement(element); 1261 element.setParent(parent); 1262 } 1263 element.setAttributes(new AttributeList(attributes)); 1264 element.setPrefixMapping(_prefixMapping); 1265 1266 if (element instanceof Stylesheet) { 1267 getSymbolTable().setCurrentNode(element); 1271 ((Stylesheet)element).excludeExtensionPrefixes(this); 1272 } 1273 1274 _prefixMapping = null; 1275 _parentStack.push(element); 1276 } 1277 1278 1281 public void endElement(String uri, String localname, String qname) { 1282 _parentStack.pop(); 1283 } 1284 1285 1288 public void characters(char[] ch, int start, int length) { 1289 String string = new String (ch, start, length); 1290 SyntaxTreeNode parent = (SyntaxTreeNode)_parentStack.peek(); 1291 1292 if (string.length() == 0) return; 1293 1294 if (parent instanceof Text) { 1297 ((Text)parent).setText(string); 1298 return; 1299 } 1300 1301 if (parent instanceof Stylesheet) return; 1303 1304 SyntaxTreeNode bro = parent.lastChild(); 1305 if ((bro != null) && (bro instanceof Text)) { 1306 Text text = (Text)bro; 1307 if (!text.isTextElement()) { 1308 if ((length > 1) || ( ((int)ch[0]) < 0x100)) { 1309 text.setText(string); 1310 return; 1311 } 1312 } 1313 } 1314 1315 parent.addElement(new Text(string)); 1317 } 1318 1319 private String getTokenValue(String token) { 1320 final int start = token.indexOf('"'); 1321 final int stop = token.lastIndexOf('"'); 1322 return token.substring(start+1, stop); 1323 } 1324 1325 1329 public void processingInstruction(String name, String value) { 1330 if ((_target == null) && (name.equals("xml-stylesheet"))) { 1332 1333 String href = null; String media = null; String title = null; String charset = null; 1338 StringTokenizer tokens = new StringTokenizer (value); 1340 while (tokens.hasMoreElements()) { 1341 String token = (String )tokens.nextElement(); 1342 if (token.startsWith("href")) 1343 href = getTokenValue(token); 1344 else if (token.startsWith("media")) 1345 media = getTokenValue(token); 1346 else if (token.startsWith("title")) 1347 title = getTokenValue(token); 1348 else if (token.startsWith("charset")) 1349 charset = getTokenValue(token); 1350 } 1351 1352 if ( ((_PImedia == null) || (_PImedia.equals(media))) && 1355 ((_PItitle == null) || (_PImedia.equals(title))) && 1356 ((_PIcharset == null) || (_PImedia.equals(charset))) ) { 1357 _target = href; 1358 } 1359 } 1360 } 1361 1362 1365 public void ignorableWhitespace(char[] ch, int start, int length) { } 1366 1367 1370 public void skippedEntity(String name) { } 1371 1372 1376 public void setDocumentLocator(Locator locator) { 1377 _locator = locator; 1378 } 1379 1380} 1381 | Popular Tags |