1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import java.util.Enumeration ; 23 import java.util.Hashtable ; 24 import java.util.Vector ; 25 26 import org.apache.bcel.generic.ANEWARRAY; 27 import org.apache.bcel.generic.BasicType; 28 import org.apache.bcel.generic.CHECKCAST; 29 import org.apache.bcel.generic.ConstantPoolGen; 30 import org.apache.bcel.generic.DUP_X1; 31 import org.apache.bcel.generic.GETFIELD; 32 import org.apache.bcel.generic.ICONST; 33 import org.apache.bcel.generic.INVOKEINTERFACE; 34 import org.apache.bcel.generic.INVOKESPECIAL; 35 import org.apache.bcel.generic.INVOKEVIRTUAL; 36 import org.apache.bcel.generic.InstructionList; 37 import org.apache.bcel.generic.NEW; 38 import org.apache.bcel.generic.NEWARRAY; 39 import org.apache.bcel.generic.PUSH; 40 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 41 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 42 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 43 import org.apache.xalan.xsltc.compiler.util.Type; 44 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 45 import org.apache.xalan.xsltc.DOM; 46 47 import org.xml.sax.Attributes ; 48 49 50 58 public abstract class SyntaxTreeNode implements Constants { 59 60 private Parser _parser; 62 63 protected SyntaxTreeNode _parent; private Stylesheet _stylesheet; private Template _template; private final Vector _contents = new Vector (2); 69 protected QName _qname; private int _line; protected Attributes _attributes = null; private Hashtable _prefixMapping = null; 75 protected static final SyntaxTreeNode Dummy = new AbsolutePathPattern(null); 77 78 protected static final int IndentIncrement = 4; 80 private static final char[] _spaces = 81 " ".toCharArray(); 82 83 87 public SyntaxTreeNode() { 88 _line = 0; 89 _qname = null; 90 } 91 92 96 public SyntaxTreeNode(int line) { 97 _line = line; 98 _qname = null; 99 } 100 101 107 public SyntaxTreeNode(String uri, String prefix, String local) { 108 _line = 0; 109 setQName(uri, prefix, local); 110 } 111 112 116 protected final void setLineNumber(int line) { 117 _line = line; 118 } 119 120 124 public final int getLineNumber() { 125 return _line; 126 } 127 128 132 protected void setQName(QName qname) { 133 _qname = qname; 134 } 135 136 142 protected void setQName(String uri, String prefix, String localname) { 143 _qname = new QName(uri, prefix, localname); 144 } 145 146 150 protected QName getQName() { 151 return(_qname); 152 } 153 154 159 protected void setAttributes(Attributes attributes) { 160 _attributes = attributes; 161 } 162 163 168 protected String getAttribute(String qname) { 169 if (_attributes == null) { 170 return EMPTYSTRING; 171 } 172 final String value = _attributes.getValue(qname); 173 return (value == null || value.equals(EMPTYSTRING)) ? 174 EMPTYSTRING : value; 175 } 176 177 protected boolean hasAttribute(String qname) { 178 return (_attributes != null && _attributes.getValue(qname) != null); 179 } 180 181 186 protected Attributes getAttributes() { 187 return(_attributes); 188 } 189 190 198 protected void setPrefixMapping(Hashtable mapping) { 199 _prefixMapping = mapping; 200 } 201 202 209 protected Hashtable getPrefixMapping() { 210 return _prefixMapping; 211 } 212 213 218 protected void addPrefixMapping(String prefix, String uri) { 219 if (_prefixMapping == null) 220 _prefixMapping = new Hashtable (); 221 _prefixMapping.put(prefix, uri); 222 } 223 224 232 protected String lookupNamespace(String prefix) { 233 String uri = null; 235 236 if (_prefixMapping != null) 238 uri = (String )_prefixMapping.get(prefix); 239 if ((uri == null) && (_parent != null)) { 241 uri = _parent.lookupNamespace(prefix); 242 if ((prefix == Constants.EMPTYSTRING) && (uri == null)) 243 uri = Constants.EMPTYSTRING; 244 } 245 return(uri); 247 } 248 249 259 protected String lookupPrefix(String uri) { 260 String prefix = null; 262 263 if ((_prefixMapping != null) && 265 (_prefixMapping.contains(uri))) { 266 Enumeration prefixes = _prefixMapping.keys(); 267 while (prefixes.hasMoreElements()) { 268 prefix = (String )prefixes.nextElement(); 269 String mapsTo = (String )_prefixMapping.get(prefix); 270 if (mapsTo.equals(uri)) return(prefix); 271 } 272 } 273 else if (_parent != null) { 275 prefix = _parent.lookupPrefix(uri); 276 if ((uri == Constants.EMPTYSTRING) && (prefix == null)) 277 prefix = Constants.EMPTYSTRING; 278 } 279 return(prefix); 280 } 281 282 287 protected void setParser(Parser parser) { 288 _parser = parser; 289 } 290 291 295 public final Parser getParser() { 296 return _parser; 297 } 298 299 303 protected void setParent(SyntaxTreeNode parent) { 304 if (_parent == null) 305 _parent = parent; 306 } 307 308 312 protected final SyntaxTreeNode getParent() { 313 return _parent; 314 } 315 316 320 protected final boolean isDummy() { 321 return this == Dummy; 322 } 323 324 329 protected int getImportPrecedence() { 330 Stylesheet stylesheet = getStylesheet(); 331 if (stylesheet == null) return Integer.MIN_VALUE; 332 return stylesheet.getImportPrecedence(); 333 } 334 335 340 public Stylesheet getStylesheet() { 341 if (_stylesheet == null) { 342 SyntaxTreeNode parent = this; 343 while (parent != null) { 344 if (parent instanceof Stylesheet) 345 return((Stylesheet)parent); 346 parent = parent.getParent(); 347 } 348 _stylesheet = (Stylesheet)parent; 349 } 350 return(_stylesheet); 351 } 352 353 359 protected Template getTemplate() { 360 if (_template == null) { 361 SyntaxTreeNode parent = this; 362 while ((parent != null) && (!(parent instanceof Template))) 363 parent = parent.getParent(); 364 _template = (Template)parent; 365 } 366 return(_template); 367 } 368 369 373 protected final XSLTC getXSLTC() { 374 return _parser.getXSLTC(); 375 } 376 377 381 protected final SymbolTable getSymbolTable() { 382 return (_parser == null) ? null : _parser.getSymbolTable(); 383 } 384 385 392 public void parseContents(Parser parser) { 393 parseChildren(parser); 394 } 395 396 401 protected final void parseChildren(Parser parser) { 402 403 Vector locals = null; 405 final int count = _contents.size(); 406 for (int i=0; i<count; i++) { 407 SyntaxTreeNode child = (SyntaxTreeNode)_contents.elementAt(i); 408 parser.getSymbolTable().setCurrentNode(child); 409 child.parseContents(parser); 410 final QName varOrParamName = updateScope(parser, child); 412 if (varOrParamName != null) { 413 if (locals == null) { 414 locals = new Vector (2); 415 } 416 locals.addElement(varOrParamName); 417 } 418 } 419 420 parser.getSymbolTable().setCurrentNode(this); 421 422 if (locals != null) { 424 final int nLocals = locals.size(); 425 for (int i = 0; i < nLocals; i++) { 426 parser.removeVariable((QName)locals.elementAt(i)); 427 } 428 } 429 } 430 431 435 protected QName updateScope(Parser parser, SyntaxTreeNode node) { 436 if (node instanceof Variable) { 437 final Variable var = (Variable)node; 438 parser.addVariable(var); 439 return var.getName(); 440 } 441 else if (node instanceof Param) { 442 final Param param = (Param)node; 443 parser.addParameter(param); 444 return param.getName(); 445 } 446 else { 447 return null; 448 } 449 } 450 451 456 public abstract Type typeCheck(SymbolTable stable) throws TypeCheckError; 457 458 462 protected Type typeCheckContents(SymbolTable stable) throws TypeCheckError { 463 final int n = elementCount(); 464 for (int i = 0; i < n; i++) { 465 SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); 466 item.typeCheck(stable); 467 } 468 return Type.Void; 469 } 470 471 476 public abstract void translate(ClassGenerator classGen, 477 MethodGenerator methodGen); 478 479 484 protected void translateContents(ClassGenerator classGen, 485 MethodGenerator methodGen) { 486 final int n = elementCount(); 488 for (int i = 0; i < n; i++) { 489 final SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); 490 item.translate(classGen, methodGen); 491 } 492 493 for (int i = 0; i < n; i++) { 499 if( _contents.elementAt(i) instanceof VariableBase) { 500 final VariableBase var = (VariableBase)_contents.elementAt(i); 501 var.unmapRegister(methodGen); 502 } 503 } 504 } 505 506 514 private boolean isSimpleRTF(SyntaxTreeNode node) { 515 516 Vector contents = node.getContents(); 517 for (int i = 0; i < contents.size(); i++) { 518 SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i); 519 if (!isTextElement(item, false)) 520 return false; 521 } 522 523 return true; 524 } 525 526 535 private boolean isAdaptiveRTF(SyntaxTreeNode node) { 536 537 Vector contents = node.getContents(); 538 for (int i = 0; i < contents.size(); i++) { 539 SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i); 540 if (!isTextElement(item, true)) 541 return false; 542 } 543 544 return true; 545 } 546 547 563 private boolean isTextElement(SyntaxTreeNode node, boolean doExtendedCheck) { 564 if (node instanceof ValueOf || node instanceof Number 565 || node instanceof Text) 566 { 567 return true; 568 } 569 else if (node instanceof If) { 570 return doExtendedCheck ? isAdaptiveRTF(node) : isSimpleRTF(node); 571 } 572 else if (node instanceof Choose) { 573 Vector contents = node.getContents(); 574 for (int i = 0; i < contents.size(); i++) { 575 SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i); 576 if (item instanceof Text || 577 ((item instanceof When || item instanceof Otherwise) 578 && ((doExtendedCheck && isAdaptiveRTF(item)) 579 || (!doExtendedCheck && isSimpleRTF(item))))) 580 continue; 581 else 582 return false; 583 } 584 return true; 585 } 586 else if (doExtendedCheck && 587 (node instanceof CallTemplate 588 || node instanceof ApplyTemplates)) 589 return true; 590 else 591 return false; 592 } 593 594 599 protected void compileResultTree(ClassGenerator classGen, 600 MethodGenerator methodGen) 601 { 602 final ConstantPoolGen cpg = classGen.getConstantPool(); 603 final InstructionList il = methodGen.getInstructionList(); 604 final Stylesheet stylesheet = classGen.getStylesheet(); 605 606 boolean isSimple = isSimpleRTF(this); 607 boolean isAdaptive = false; 608 if (!isSimple) { 609 isAdaptive = isAdaptiveRTF(this); 610 } 611 612 int rtfType = isSimple ? DOM.SIMPLE_RTF 613 : (isAdaptive ? DOM.ADAPTIVE_RTF : DOM.TREE_RTF); 614 615 il.append(methodGen.loadHandler()); 617 618 final String DOM_CLASS = classGen.getDOMClass(); 619 620 624 il.append(methodGen.loadDOM()); 625 int index = cpg.addInterfaceMethodref(DOM_INTF, 626 "getResultTreeFrag", 627 "(IIZ)" + DOM_INTF_SIG); 628 il.append(new PUSH(cpg, RTF_INITIAL_SIZE)); 629 il.append(new PUSH(cpg, rtfType)); 630 il.append(new PUSH(cpg, stylesheet.callsNodeset())); 631 il.append(new INVOKEINTERFACE(index,4)); 632 633 il.append(DUP); 634 635 index = cpg.addInterfaceMethodref(DOM_INTF, 637 "getOutputDomBuilder", 638 "()" + TRANSLET_OUTPUT_SIG); 639 640 il.append(new INVOKEINTERFACE(index,1)); 641 il.append(DUP); 642 il.append(methodGen.storeHandler()); 643 644 il.append(methodGen.startDocument()); 646 647 translateContents(classGen, methodGen); 649 650 il.append(methodGen.loadHandler()); 652 il.append(methodGen.endDocument()); 653 654 if (stylesheet.callsNodeset() 658 && !DOM_CLASS.equals(DOM_IMPL_CLASS)) { 659 index = cpg.addMethodref(DOM_ADAPTER_CLASS, 661 "<init>", 662 "("+DOM_INTF_SIG+ 663 "["+STRING_SIG+ 664 "["+STRING_SIG+ 665 "[I"+ 666 "["+STRING_SIG+")V"); 667 il.append(new NEW(cpg.addClass(DOM_ADAPTER_CLASS))); 668 il.append(new DUP_X1()); 669 il.append(SWAP); 670 671 675 if (!stylesheet.callsNodeset()) { 676 il.append(new ICONST(0)); 677 il.append(new ANEWARRAY(cpg.addClass(STRING))); 678 il.append(DUP); 679 il.append(DUP); 680 il.append(new ICONST(0)); 681 il.append(new NEWARRAY(BasicType.INT)); 682 il.append(SWAP); 683 il.append(new INVOKESPECIAL(index)); 684 } 685 else { 686 il.append(ALOAD_0); 688 il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, 689 NAMES_INDEX, 690 NAMES_INDEX_SIG))); 691 il.append(ALOAD_0); 692 il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, 693 URIS_INDEX, 694 URIS_INDEX_SIG))); 695 il.append(ALOAD_0); 696 il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, 697 TYPES_INDEX, 698 TYPES_INDEX_SIG))); 699 il.append(ALOAD_0); 700 il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, 701 NAMESPACE_INDEX, 702 NAMESPACE_INDEX_SIG))); 703 704 il.append(new INVOKESPECIAL(index)); 706 707 il.append(DUP); 709 il.append(methodGen.loadDOM()); 710 il.append(new CHECKCAST(cpg.addClass(classGen.getDOMClass()))); 711 il.append(SWAP); 712 index = cpg.addMethodref(MULTI_DOM_CLASS, 713 "addDOMAdapter", 714 "(" + DOM_ADAPTER_SIG + ")I"); 715 il.append(new INVOKEVIRTUAL(index)); 716 il.append(POP); } 718 } 719 720 il.append(SWAP); 722 il.append(methodGen.storeHandler()); 723 } 724 725 732 protected boolean contextDependent() { 733 return true; 734 } 735 736 741 protected boolean dependentContents() { 742 final int n = elementCount(); 743 for (int i = 0; i < n; i++) { 744 final SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); 745 if (item.contextDependent()) { 746 return true; 747 } 748 } 749 return false; 750 } 751 752 756 protected final void addElement(SyntaxTreeNode element) { 757 _contents.addElement(element); 758 element.setParent(this); 759 } 760 761 766 protected final void setFirstElement(SyntaxTreeNode element) { 767 _contents.insertElementAt(element,0); 768 element.setParent(this); 769 } 770 771 775 protected final void removeElement(SyntaxTreeNode element) { 776 _contents.remove(element); 777 element.setParent(null); 778 } 779 780 784 protected final Vector getContents() { 785 return _contents; 786 } 787 788 792 protected final boolean hasContents() { 793 return elementCount() > 0; 794 } 795 796 800 protected final int elementCount() { 801 return _contents.size(); 802 } 803 804 808 protected final Enumeration elements() { 809 return _contents.elements(); 810 } 811 812 817 protected final Object elementAt(int pos) { 818 return _contents.elementAt(pos); 819 } 820 821 825 protected final SyntaxTreeNode lastChild() { 826 if (_contents.size() == 0) return null; 827 return (SyntaxTreeNode)_contents.lastElement(); 828 } 829 830 836 public void display(int indent) { 837 displayContents(indent); 838 } 839 840 845 protected void displayContents(int indent) { 846 final int n = elementCount(); 847 for (int i = 0; i < n; i++) { 848 SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); 849 item.display(indent); 850 } 851 } 852 853 857 protected final void indent(int indent) { 858 System.out.print(new String (_spaces, 0, indent)); 859 } 860 861 869 protected void reportError(SyntaxTreeNode element, Parser parser, 870 String errorCode, String message) { 871 final ErrorMsg error = new ErrorMsg(errorCode, message, element); 872 parser.reportError(Constants.ERROR, error); 873 } 874 875 883 protected void reportWarning(SyntaxTreeNode element, Parser parser, 884 String errorCode, String message) { 885 final ErrorMsg error = new ErrorMsg(errorCode, message, element); 886 parser.reportError(Constants.WARNING, error); 887 } 888 889 } 890 | Popular Tags |