1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import java.util.Enumeration ; 23 import java.util.Hashtable ; 24 import java.util.Vector ; 25 26 import com.sun.org.apache.bcel.internal.generic.ANEWARRAY; 27 import com.sun.org.apache.bcel.internal.generic.BasicType; 28 import com.sun.org.apache.bcel.internal.generic.CHECKCAST; 29 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 30 import com.sun.org.apache.bcel.internal.generic.DUP_X1; 31 import com.sun.org.apache.bcel.internal.generic.GETFIELD; 32 import com.sun.org.apache.bcel.internal.generic.ICONST; 33 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 34 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 35 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; 36 import com.sun.org.apache.bcel.internal.generic.InstructionList; 37 import com.sun.org.apache.bcel.internal.generic.NEW; 38 import com.sun.org.apache.bcel.internal.generic.NEWARRAY; 39 import com.sun.org.apache.bcel.internal.generic.PUSH; 40 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 41 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 42 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 43 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 44 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 45 import com.sun.org.apache.xalan.internal.xsltc.DOM; 46 import com.sun.org.apache.xalan.internal.xsltc.runtime.AttributeList; 47 48 import org.xml.sax.Attributes ; 49 50 51 52 60 public abstract class SyntaxTreeNode implements Constants { 61 62 private Parser _parser; 64 65 protected SyntaxTreeNode _parent; private Stylesheet _stylesheet; private Template _template; private final Vector _contents = new Vector (2); 71 protected QName _qname; private int _line; protected AttributeList _attributes = null; private Hashtable _prefixMapping = null; 77 protected static final SyntaxTreeNode Dummy = new AbsolutePathPattern(null); 79 80 protected static final int IndentIncrement = 4; 82 private static final char[] _spaces = 83 " ".toCharArray(); 84 85 89 public SyntaxTreeNode() { 90 _line = 0; 91 _qname = null; 92 } 93 94 98 public SyntaxTreeNode(int line) { 99 _line = line; 100 _qname = null; 101 } 102 103 109 public SyntaxTreeNode(String uri, String prefix, String local) { 110 _line = 0; 111 setQName(uri, prefix, local); 112 } 113 114 118 protected final void setLineNumber(int line) { 119 _line = line; 120 } 121 122 128 public final int getLineNumber() { 129 if (_line > 0) return _line; 130 SyntaxTreeNode parent = getParent(); 131 return (parent != null) ? parent.getLineNumber() : 0; 132 } 133 134 138 protected void setQName(QName qname) { 139 _qname = qname; 140 } 141 142 148 protected void setQName(String uri, String prefix, String localname) { 149 _qname = new QName(uri, prefix, localname); 150 } 151 152 156 protected QName getQName() { 157 return(_qname); 158 } 159 160 165 protected void setAttributes(AttributeList attributes) { 166 _attributes = attributes; 167 } 168 169 174 protected String getAttribute(String qname) { 175 if (_attributes == null) { 176 return EMPTYSTRING; 177 } 178 final String value = _attributes.getValue(qname); 179 return (value == null || value.equals(EMPTYSTRING)) ? 180 EMPTYSTRING : value; 181 } 182 183 protected String getAttribute(String prefix, String localName) { 184 return getAttribute(prefix + ':' + localName); 185 } 186 187 protected boolean hasAttribute(String qname) { 188 return (_attributes != null && _attributes.getValue(qname) != null); 189 } 190 191 protected void addAttribute(String qname, String value) { 192 _attributes.add(qname, value); 193 } 194 195 200 protected Attributes getAttributes() { 201 return(_attributes); 202 } 203 204 212 protected void setPrefixMapping(Hashtable mapping) { 213 _prefixMapping = mapping; 214 } 215 216 223 protected Hashtable getPrefixMapping() { 224 return _prefixMapping; 225 } 226 227 232 protected void addPrefixMapping(String prefix, String uri) { 233 if (_prefixMapping == null) 234 _prefixMapping = new Hashtable (); 235 _prefixMapping.put(prefix, uri); 236 } 237 238 246 protected String lookupNamespace(String prefix) { 247 String uri = null; 249 250 if (_prefixMapping != null) 252 uri = (String )_prefixMapping.get(prefix); 253 if ((uri == null) && (_parent != null)) { 255 uri = _parent.lookupNamespace(prefix); 256 if ((prefix == Constants.EMPTYSTRING) && (uri == null)) 257 uri = Constants.EMPTYSTRING; 258 } 259 return(uri); 261 } 262 263 273 protected String lookupPrefix(String uri) { 274 String prefix = null; 276 277 if ((_prefixMapping != null) && 279 (_prefixMapping.contains(uri))) { 280 Enumeration prefixes = _prefixMapping.keys(); 281 while (prefixes.hasMoreElements()) { 282 prefix = (String )prefixes.nextElement(); 283 String mapsTo = (String )_prefixMapping.get(prefix); 284 if (mapsTo.equals(uri)) return(prefix); 285 } 286 } 287 else if (_parent != null) { 289 prefix = _parent.lookupPrefix(uri); 290 if ((uri == Constants.EMPTYSTRING) && (prefix == null)) 291 prefix = Constants.EMPTYSTRING; 292 } 293 return(prefix); 294 } 295 296 301 protected void setParser(Parser parser) { 302 _parser = parser; 303 } 304 305 309 public final Parser getParser() { 310 return _parser; 311 } 312 313 317 protected void setParent(SyntaxTreeNode parent) { 318 if (_parent == null) 319 _parent = parent; 320 } 321 322 326 protected final SyntaxTreeNode getParent() { 327 return _parent; 328 } 329 330 334 protected final boolean isDummy() { 335 return this == Dummy; 336 } 337 338 343 protected int getImportPrecedence() { 344 Stylesheet stylesheet = getStylesheet(); 345 if (stylesheet == null) return Integer.MIN_VALUE; 346 return stylesheet.getImportPrecedence(); 347 } 348 349 354 public Stylesheet getStylesheet() { 355 if (_stylesheet == null) { 356 SyntaxTreeNode parent = this; 357 while (parent != null) { 358 if (parent instanceof Stylesheet) 359 return((Stylesheet)parent); 360 parent = parent.getParent(); 361 } 362 _stylesheet = (Stylesheet)parent; 363 } 364 return(_stylesheet); 365 } 366 367 373 protected Template getTemplate() { 374 if (_template == null) { 375 SyntaxTreeNode parent = this; 376 while ((parent != null) && (!(parent instanceof Template))) 377 parent = parent.getParent(); 378 _template = (Template)parent; 379 } 380 return(_template); 381 } 382 383 387 protected final XSLTC getXSLTC() { 388 return _parser.getXSLTC(); 389 } 390 391 395 protected final SymbolTable getSymbolTable() { 396 return (_parser == null) ? null : _parser.getSymbolTable(); 397 } 398 399 406 public void parseContents(Parser parser) { 407 parseChildren(parser); 408 } 409 410 415 protected final void parseChildren(Parser parser) { 416 417 Vector locals = null; 419 final int count = _contents.size(); 420 for (int i=0; i<count; i++) { 421 SyntaxTreeNode child = (SyntaxTreeNode)_contents.elementAt(i); 422 parser.getSymbolTable().setCurrentNode(child); 423 child.parseContents(parser); 424 final QName varOrParamName = updateScope(parser, child); 426 if (varOrParamName != null) { 427 if (locals == null) { 428 locals = new Vector (2); 429 } 430 locals.addElement(varOrParamName); 431 } 432 } 433 434 parser.getSymbolTable().setCurrentNode(this); 435 436 if (locals != null) { 438 final int nLocals = locals.size(); 439 for (int i = 0; i < nLocals; i++) { 440 parser.removeVariable((QName)locals.elementAt(i)); 441 } 442 } 443 } 444 445 449 protected QName updateScope(Parser parser, SyntaxTreeNode node) { 450 if (node instanceof Variable) { 451 final Variable var = (Variable)node; 452 parser.addVariable(var); 453 return var.getName(); 454 } 455 else if (node instanceof Param) { 456 final Param param = (Param)node; 457 parser.addParameter(param); 458 return param.getName(); 459 } 460 else { 461 return null; 462 } 463 } 464 465 470 public abstract Type typeCheck(SymbolTable stable) throws TypeCheckError; 471 472 476 protected Type typeCheckContents(SymbolTable stable) throws TypeCheckError { 477 final int n = elementCount(); 478 for (int i = 0; i < n; i++) { 479 SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); 480 item.typeCheck(stable); 481 } 482 return Type.Void; 483 } 484 485 490 public abstract void translate(ClassGenerator classGen, 491 MethodGenerator methodGen); 492 493 498 protected void translateContents(ClassGenerator classGen, 499 MethodGenerator methodGen) { 500 final int n = elementCount(); 502 for (int i = 0; i < n; i++) { 503 final SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); 504 item.translate(classGen, methodGen); 505 } 506 507 for (int i = 0; i < n; i++) { 513 if( _contents.elementAt(i) instanceof VariableBase) { 514 final VariableBase var = (VariableBase)_contents.elementAt(i); 515 var.unmapRegister(methodGen); 516 } 517 } 518 } 519 520 528 private boolean isSimpleRTF(SyntaxTreeNode node) { 529 530 Vector contents = node.getContents(); 531 for (int i = 0; i < contents.size(); i++) { 532 SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i); 533 if (!isTextElement(item, false)) 534 return false; 535 } 536 537 return true; 538 } 539 540 549 private boolean isAdaptiveRTF(SyntaxTreeNode node) { 550 551 Vector contents = node.getContents(); 552 for (int i = 0; i < contents.size(); i++) { 553 SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i); 554 if (!isTextElement(item, true)) 555 return false; 556 } 557 558 return true; 559 } 560 561 577 private boolean isTextElement(SyntaxTreeNode node, boolean doExtendedCheck) { 578 if (node instanceof ValueOf || node instanceof Number 579 || node instanceof Text) 580 { 581 return true; 582 } 583 else if (node instanceof If) { 584 return doExtendedCheck ? isAdaptiveRTF(node) : isSimpleRTF(node); 585 } 586 else if (node instanceof Choose) { 587 Vector contents = node.getContents(); 588 for (int i = 0; i < contents.size(); i++) { 589 SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i); 590 if (item instanceof Text || 591 ((item instanceof When || item instanceof Otherwise) 592 && ((doExtendedCheck && isAdaptiveRTF(item)) 593 || (!doExtendedCheck && isSimpleRTF(item))))) 594 continue; 595 else 596 return false; 597 } 598 return true; 599 } 600 else if (doExtendedCheck && 601 (node instanceof CallTemplate 602 || node instanceof ApplyTemplates)) 603 return true; 604 else 605 return false; 606 } 607 608 613 protected void compileResultTree(ClassGenerator classGen, 614 MethodGenerator methodGen) 615 { 616 final ConstantPoolGen cpg = classGen.getConstantPool(); 617 final InstructionList il = methodGen.getInstructionList(); 618 final Stylesheet stylesheet = classGen.getStylesheet(); 619 620 boolean isSimple = isSimpleRTF(this); 621 boolean isAdaptive = false; 622 if (!isSimple) { 623 isAdaptive = isAdaptiveRTF(this); 624 } 625 626 int rtfType = isSimple ? DOM.SIMPLE_RTF 627 : (isAdaptive ? DOM.ADAPTIVE_RTF : DOM.TREE_RTF); 628 629 il.append(methodGen.loadHandler()); 631 632 final String DOM_CLASS = classGen.getDOMClass(); 633 634 638 il.append(methodGen.loadDOM()); 639 int index = cpg.addInterfaceMethodref(DOM_INTF, 640 "getResultTreeFrag", 641 "(IIZ)" + DOM_INTF_SIG); 642 il.append(new PUSH(cpg, RTF_INITIAL_SIZE)); 643 il.append(new PUSH(cpg, rtfType)); 644 il.append(new PUSH(cpg, stylesheet.callsNodeset())); 645 il.append(new INVOKEINTERFACE(index,4)); 646 647 il.append(DUP); 648 649 index = cpg.addInterfaceMethodref(DOM_INTF, 651 "getOutputDomBuilder", 652 "()" + TRANSLET_OUTPUT_SIG); 653 654 il.append(new INVOKEINTERFACE(index,1)); 655 il.append(DUP); 656 il.append(methodGen.storeHandler()); 657 658 il.append(methodGen.startDocument()); 660 661 translateContents(classGen, methodGen); 663 664 il.append(methodGen.loadHandler()); 666 il.append(methodGen.endDocument()); 667 668 if (stylesheet.callsNodeset() 672 && !DOM_CLASS.equals(DOM_IMPL_CLASS)) { 673 index = cpg.addMethodref(DOM_ADAPTER_CLASS, 675 "<init>", 676 "("+DOM_INTF_SIG+ 677 "["+STRING_SIG+ 678 "["+STRING_SIG+ 679 "[I"+ 680 "["+STRING_SIG+")V"); 681 il.append(new NEW(cpg.addClass(DOM_ADAPTER_CLASS))); 682 il.append(new DUP_X1()); 683 il.append(SWAP); 684 685 689 if (!stylesheet.callsNodeset()) { 690 il.append(new ICONST(0)); 691 il.append(new ANEWARRAY(cpg.addClass(STRING))); 692 il.append(DUP); 693 il.append(DUP); 694 il.append(new ICONST(0)); 695 il.append(new NEWARRAY(BasicType.INT)); 696 il.append(SWAP); 697 il.append(new INVOKESPECIAL(index)); 698 } 699 else { 700 il.append(ALOAD_0); 702 il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, 703 NAMES_INDEX, 704 NAMES_INDEX_SIG))); 705 il.append(ALOAD_0); 706 il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, 707 URIS_INDEX, 708 URIS_INDEX_SIG))); 709 il.append(ALOAD_0); 710 il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, 711 TYPES_INDEX, 712 TYPES_INDEX_SIG))); 713 il.append(ALOAD_0); 714 il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, 715 NAMESPACE_INDEX, 716 NAMESPACE_INDEX_SIG))); 717 718 il.append(new INVOKESPECIAL(index)); 720 721 il.append(DUP); 723 il.append(methodGen.loadDOM()); 724 il.append(new CHECKCAST(cpg.addClass(classGen.getDOMClass()))); 725 il.append(SWAP); 726 index = cpg.addMethodref(MULTI_DOM_CLASS, 727 "addDOMAdapter", 728 "(" + DOM_ADAPTER_SIG + ")I"); 729 il.append(new INVOKEVIRTUAL(index)); 730 il.append(POP); } 732 } 733 734 il.append(SWAP); 736 il.append(methodGen.storeHandler()); 737 } 738 739 746 protected boolean contextDependent() { 747 return true; 748 } 749 750 755 protected boolean dependentContents() { 756 final int n = elementCount(); 757 for (int i = 0; i < n; i++) { 758 final SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); 759 if (item.contextDependent()) { 760 return true; 761 } 762 } 763 return false; 764 } 765 766 770 protected final void addElement(SyntaxTreeNode element) { 771 _contents.addElement(element); 772 element.setParent(this); 773 } 774 775 780 protected final void setFirstElement(SyntaxTreeNode element) { 781 _contents.insertElementAt(element,0); 782 element.setParent(this); 783 } 784 785 789 protected final void removeElement(SyntaxTreeNode element) { 790 _contents.remove(element); 791 element.setParent(null); 792 } 793 794 798 protected final Vector getContents() { 799 return _contents; 800 } 801 802 806 protected final boolean hasContents() { 807 return elementCount() > 0; 808 } 809 810 814 protected final int elementCount() { 815 return _contents.size(); 816 } 817 818 822 protected final Enumeration elements() { 823 return _contents.elements(); 824 } 825 826 831 protected final Object elementAt(int pos) { 832 return _contents.elementAt(pos); 833 } 834 835 839 protected final SyntaxTreeNode lastChild() { 840 if (_contents.size() == 0) return null; 841 return (SyntaxTreeNode)_contents.lastElement(); 842 } 843 844 850 public void display(int indent) { 851 displayContents(indent); 852 } 853 854 859 protected void displayContents(int indent) { 860 final int n = elementCount(); 861 for (int i = 0; i < n; i++) { 862 SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); 863 item.display(indent); 864 } 865 } 866 867 871 protected final void indent(int indent) { 872 System.out.print(new String (_spaces, 0, indent)); 873 } 874 875 883 protected void reportError(SyntaxTreeNode element, Parser parser, 884 String errorCode, String message) { 885 final ErrorMsg error = new ErrorMsg(errorCode, message, element); 886 parser.reportError(Constants.ERROR, error); 887 } 888 889 897 protected void reportWarning(SyntaxTreeNode element, Parser parser, 898 String errorCode, String message) { 899 final ErrorMsg error = new ErrorMsg(errorCode, message, element); 900 parser.reportError(Constants.WARNING, error); 901 } 902 903 } 904 | Popular Tags |