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