alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (SyntaxTreeNode.java)

This example Java source code file (SyntaxTreeNode.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

errormsg, hashtable, methodgenerator, param, parser, push, qname, sax, string, string_sig, stylesheet, syntaxtreenode, template, util, variable, vector

The SyntaxTreeNode.java Java example source code

/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: SyntaxTreeNode.java,v 1.6 2006/06/06 22:34:33 spericas Exp $
 */

package com.sun.org.apache.xalan.internal.xsltc.compiler;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import com.sun.org.apache.bcel.internal.generic.ANEWARRAY;
import com.sun.org.apache.bcel.internal.generic.BasicType;
import com.sun.org.apache.bcel.internal.generic.CHECKCAST;
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
import com.sun.org.apache.bcel.internal.generic.DUP_X1;
import com.sun.org.apache.bcel.internal.generic.GETFIELD;
import com.sun.org.apache.bcel.internal.generic.ICONST;
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
import com.sun.org.apache.bcel.internal.generic.InstructionList;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.sun.org.apache.bcel.internal.generic.NEWARRAY;
import com.sun.org.apache.bcel.internal.generic.PUSH;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;

import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;


/**
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author G. Todd Miller
 * @author Morten Jorensen
 * @author Erwin Bolwidt <ejb@klomp.org>
 * @author John Howard <JohnH@schemasoft.com>
 */
public abstract class SyntaxTreeNode implements Constants {

    // Reference to the AST parser
    private Parser _parser;

    // AST navigation pointers
    protected SyntaxTreeNode _parent;          // Parent node
    private Stylesheet       _stylesheet;      // Stylesheet ancestor node
    private Template         _template;        // Template ancestor node
    private final Vector _contents = new Vector(2); // Child nodes

    // Element description data
    protected QName _qname;                    // The element QName
    private int _line;                         // Source file line number
    protected AttributesImpl _attributes = null;   // Attributes of this element
    private   Hashtable _prefixMapping = null; // Namespace declarations

    // Sentinel - used to denote unrecognised syntaxt tree nodes.
    protected static final SyntaxTreeNode Dummy = new AbsolutePathPattern(null);

    // These two are used for indenting nodes in the AST (debug output)
    protected static final int IndentIncrement = 4;
    private static final char[] _spaces =
        "                                                       ".toCharArray();

    /**
     * Creates a new SyntaxTreeNode with a 'null' QName and no source file
     * line number reference.
     */
    public SyntaxTreeNode() {
        _line = 0;
        _qname = null;
    }

    /**
     * Creates a new SyntaxTreeNode with a 'null' QName.
     * @param line Source file line number reference
     */
    public SyntaxTreeNode(int line) {
        _line = line;
        _qname = null;
    }

    /**
     * Creates a new SyntaxTreeNode with no source file line number reference.
     * @param uri The element's namespace URI
     * @param prefix The element's namespace prefix
     * @param local The element's local name
     */
    public SyntaxTreeNode(String uri, String prefix, String local) {
        _line = 0;
        setQName(uri, prefix, local);
    }

    /**
     * Set the source file line number for this element
     * @param line The source file line number.
     */
    protected final void setLineNumber(int line) {
        _line = line;
    }

    /**
     * Get the source file line number for this element. If unavailable, lookup
     * in ancestors.
     *
     * @return The source file line number.
     */
    public final int getLineNumber() {
        if (_line > 0) return _line;
        SyntaxTreeNode parent = getParent();
        return (parent != null) ? parent.getLineNumber() : 0;
    }

    /**
     * Set the QName for the syntax tree node.
     * @param qname The QName for the syntax tree node
     */
    protected void setQName(QName qname) {
        _qname = qname;
    }

    /**
     * Set the QName for the SyntaxTreeNode
     * @param uri The element's namespace URI
     * @param prefix The element's namespace prefix
     * @param local The element's local name
     */
    protected void setQName(String uri, String prefix, String localname) {
        _qname = new QName(uri, prefix, localname);
    }

    /**
     * Set the QName for the SyntaxTreeNode
     * @param qname The QName for the syntax tree node
     */
    protected QName getQName() {
        return(_qname);
    }

    /**
     * Set the attributes for this SyntaxTreeNode.
     * @param attributes Attributes for the element. Must be passed in as an
     *                   implementation of org.xml.sax.Attributes.
     */
    protected void setAttributes(AttributesImpl attributes) {
        _attributes = attributes;
    }

    /**
     * Returns a value for an attribute from the source element.
     * @param qname The QName of the attribute to return.
     * @return The value of the attribute of name 'qname'.
     */
    protected String getAttribute(String qname) {
        if (_attributes == null) {
            return EMPTYSTRING;
        }
        final String value = _attributes.getValue(qname);
        return (value == null || value.equals(EMPTYSTRING)) ?
            EMPTYSTRING : value;
    }

    protected String getAttribute(String prefix, String localName) {
        return getAttribute(prefix + ':' + localName);
    }

    protected boolean hasAttribute(String qname) {
        return (_attributes != null && _attributes.getValue(qname) != null);
    }

    protected void addAttribute(String qname, String value) {
        int index = _attributes.getIndex(qname);
        if (index != -1) {
            _attributes.setAttribute(index, "", Util.getLocalName(qname),
                    qname, "CDATA", value);
        }
        else {
            _attributes.addAttribute("", Util.getLocalName(qname), qname,
                    "CDATA", value);
        }
    }

    /**
     * Returns a list of all attributes declared for the element represented by
     * this syntax tree node.
     * @return Attributes for this syntax tree node
     */
    protected Attributes getAttributes() {
        return(_attributes);
    }

    /**
     * Sets the prefix mapping for the namespaces that were declared in this
     * element. This does not include all prefix mappings in scope, so one
     * may have to check ancestor elements to get all mappings that are in
     * in scope. The prefixes must be passed in as a Hashtable that maps
     * namespace prefixes (String objects) to namespace URIs (also String).
     * @param mapping The Hashtable containing the mappings.
     */
    protected void setPrefixMapping(Hashtable mapping) {
        _prefixMapping = mapping;
    }

    /**
     * Returns a Hashtable containing the prefix mappings that were declared
     * for this element. This does not include all prefix mappings in scope,
     * so one may have to check ancestor elements to get all mappings that are
     * in in scope.
     * @return Prefix mappings (for this element only).
     */
    protected Hashtable getPrefixMapping() {
        return _prefixMapping;
    }

    /**
     * Adds a single prefix mapping to this syntax tree node.
     * @param prefix Namespace prefix.
     * @param uri Namespace URI.
     */
    protected void addPrefixMapping(String prefix, String uri) {
        if (_prefixMapping == null)
            _prefixMapping = new Hashtable();
        _prefixMapping.put(prefix, uri);
    }

    /**
     * Returns any namespace URI that is in scope for a given prefix. This
     * method checks namespace mappings for this element, and if necessary
     * for ancestor elements as well (ie. if the prefix maps to an URI in this
     * scope then you'll definately get the URI from this method).
     * @param prefix Namespace prefix.
     * @return Namespace URI.
     */
    protected String lookupNamespace(String prefix) {
        // Initialise the output (default is 'null' for undefined)
        String uri = null;

        // First look up the prefix/uri mapping in our own hashtable...
        if (_prefixMapping != null)
            uri = (String)_prefixMapping.get(prefix);
        // ... but if we can't find it there we ask our parent for the mapping
        if ((uri == null) && (_parent != null)) {
            uri = _parent.lookupNamespace(prefix);
            if ((prefix == Constants.EMPTYSTRING) && (uri == null))
                uri = Constants.EMPTYSTRING;
        }
        // ... and then we return whatever URI we've got.
        return(uri);
    }

    /**
     * Returns any namespace prefix that is mapped to a prefix in the current
     * scope. This method checks namespace mappings for this element, and if
     * necessary for ancestor elements as well (ie. if the URI is declared
     * within the current scope then you'll definately get the prefix from
     * this method). Note that this is a very slow method and consequentially
     * it should only be used strictly when needed.
     * @param uri Namespace URI.
     * @return Namespace prefix.
     */
    protected String lookupPrefix(String uri) {
        // Initialise the output (default is 'null' for undefined)
        String prefix = null;

        // First look up the prefix/uri mapping in our own hashtable...
        if ((_prefixMapping != null) &&
            (_prefixMapping.contains(uri))) {
            Enumeration prefixes = _prefixMapping.keys();
            while (prefixes.hasMoreElements()) {
                prefix = (String)prefixes.nextElement();
                String mapsTo = (String)_prefixMapping.get(prefix);
                if (mapsTo.equals(uri)) return(prefix);
            }
        }
        // ... but if we can't find it there we ask our parent for the mapping
        else if (_parent != null) {
            prefix = _parent.lookupPrefix(uri);
            if ((uri == Constants.EMPTYSTRING) && (prefix == null))
                prefix = Constants.EMPTYSTRING;
        }
        return(prefix);
    }

    /**
     * Set this node's parser. The parser (the XSLT parser) gives this
     * syntax tree node access to the symbol table and XPath parser.
     * @param parser The XSLT parser.
     */
    protected void setParser(Parser parser) {
        _parser = parser;
    }

    /**
     * Returns this node's XSLT parser.
     * @return The XSLT parser.
     */
    public final Parser getParser() {
        return _parser;
    }

    /**
     * Set this syntax tree node's parent node, if unset. For
     * re-parenting just use <code>node._parent = newparent.
     *
     * @param parent The parent node.
     */
    protected void setParent(SyntaxTreeNode parent) {
        if (_parent == null) _parent = parent;
    }

    /**
     * Returns this syntax tree node's parent node.
     * @return The parent syntax tree node.
     */
    protected final SyntaxTreeNode getParent() {
        return _parent;
    }

    /**
     * Returns 'true' if this syntax tree node is the Sentinal node.
     * @return 'true' if this syntax tree node is the Sentinal node.
     */
    protected final boolean isDummy() {
        return this == Dummy;
    }

    /**
     * Get the import precedence of this element. The import precedence equals
     * the import precedence of the stylesheet in which this element occured.
     * @return The import precedence of this syntax tree node.
     */
    protected int getImportPrecedence() {
        Stylesheet stylesheet = getStylesheet();
        if (stylesheet == null) return Integer.MIN_VALUE;
        return stylesheet.getImportPrecedence();
    }

    /**
     * Get the Stylesheet node that represents the <xsl:stylesheet/> element
     * that this node occured under.
     * @return The Stylesheet ancestor node of this node.
     */
    public Stylesheet getStylesheet() {
        if (_stylesheet == null) {
            SyntaxTreeNode parent = this;
            while (parent != null) {
                if (parent instanceof Stylesheet)
                    return((Stylesheet)parent);
                parent = parent.getParent();
            }
            _stylesheet = (Stylesheet)parent;
        }
        return(_stylesheet);
    }

    /**
     * Get the Template node that represents the <xsl:template/> element
     * that this node occured under. Note that this method will return 'null'
     * for nodes that represent top-level elements.
     * @return The Template ancestor node of this node or 'null'.
     */
    protected Template getTemplate() {
        if (_template == null) {
            SyntaxTreeNode parent = this;
            while ((parent != null) && (!(parent instanceof Template)))
                parent = parent.getParent();
            _template = (Template)parent;
        }
        return(_template);
    }

    /**
     * Returns a reference to the XSLTC (XSLT compiler) in use.
     * @return XSLTC - XSLT compiler.
     */
    protected final XSLTC getXSLTC() {
        return _parser.getXSLTC();
    }

    /**
     * Returns the XSLT parser's symbol table.
     * @return Symbol table.
     */
    protected final SymbolTable getSymbolTable() {
        return (_parser == null) ? null : _parser.getSymbolTable();
    }

    /**
     * Parse the contents of this syntax tree nodes (child nodes, XPath
     * expressions, patterns and functions). The default behaviour is to parser
     * the syntax tree node's children (since there are no common expressions,
     * patterns, etc. that can be handled in this base class.
     * @param parser reference to the XSLT parser
     */
    public void parseContents(Parser parser) {
        parseChildren(parser);
    }

    /**
     * Parse all children of this syntax tree node. This method is normally
     * called by the parseContents() method.
     * @param parser reference to the XSLT parser
     */
    protected final void parseChildren(Parser parser) {

        Vector locals = null;   // only create when needed

        final int count = _contents.size();
        for (int i=0; i<count; i++) {
            SyntaxTreeNode child = (SyntaxTreeNode)_contents.elementAt(i);
            parser.getSymbolTable().setCurrentNode(child);
            child.parseContents(parser);
            // if variable or parameter, add it to scope
            final QName varOrParamName = updateScope(parser, child);
            if (varOrParamName != null) {
                if (locals == null) {
                    locals = new Vector(2);
                }
                locals.addElement(varOrParamName);
            }
        }

        parser.getSymbolTable().setCurrentNode(this);

        // after the last element, remove any locals from scope
        if (locals != null) {
            final int nLocals = locals.size();
            for (int i = 0; i < nLocals; i++) {
                parser.removeVariable((QName)locals.elementAt(i));
            }
        }
    }

    /**
     * Add a node to the current scope and return name of a variable or
     * parameter if the node represents a variable or a parameter.
     */
    protected QName updateScope(Parser parser, SyntaxTreeNode node) {
        if (node instanceof Variable) {
            final Variable var = (Variable)node;
            parser.addVariable(var);
            return var.getName();
        }
        else if (node instanceof Param) {
            final Param param = (Param)node;
            parser.addParameter(param);
            return param.getName();
        }
        else {
            return null;
        }
    }

    /**
     * Type check the children of this node. The type check phase may add
     * coercions (CastExpr) to the AST.
     * @param stable The compiler/parser's symbol table
     */
    public abstract Type typeCheck(SymbolTable stable) throws TypeCheckError;

    /**
     * Call typeCheck() on all child syntax tree nodes.
     * @param stable The compiler/parser's symbol table
     */
    protected Type typeCheckContents(SymbolTable stable) throws TypeCheckError {
        final int n = elementCount();
        for (int i = 0; i < n; i++) {
            SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i);
            item.typeCheck(stable);
        }
        return Type.Void;
    }

    /**
     * Translate this abstract syntax tree node into JVM bytecodes.
     * @param classGen BCEL Java class generator
     * @param methodGen BCEL Java method generator
     */
    public abstract void translate(ClassGenerator classGen,
                                   MethodGenerator methodGen);

    /**
     * Call translate() on all child syntax tree nodes.
     * @param classGen BCEL Java class generator
     * @param methodGen BCEL Java method generator
     */
    protected void translateContents(ClassGenerator classGen,
                                     MethodGenerator methodGen) {
        // Call translate() on all child nodes
        final int n = elementCount();

        for (int i = 0; i < n; i++) {
            methodGen.markChunkStart();
            final SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i);
            item.translate(classGen, methodGen);
            methodGen.markChunkEnd();
        }

        // After translation, unmap any registers for any variables/parameters
        // that were declared in this scope. Performing this unmapping in the
        // same AST scope as the declaration deals with the problems of
        // references falling out-of-scope inside the for-each element.
        // (the cause of which being 'lazy' register allocation for references)
        for (int i = 0; i < n; i++) {
            if( _contents.elementAt(i) instanceof VariableBase) {
                final VariableBase var = (VariableBase)_contents.elementAt(i);
                var.unmapRegister(methodGen);
            }
        }
    }

    /**
     * Return true if the node represents a simple RTF.
     *
     * A node is a simple RTF if all children only produce Text value.
     *
     * @param node A node
     * @return true if the node content can be considered as a simple RTF.
     */
    private boolean isSimpleRTF(SyntaxTreeNode node) {

        Vector contents = node.getContents();
        for (int i = 0; i < contents.size(); i++) {
            SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i);
            if (!isTextElement(item, false))
                return false;
        }

        return true;
    }

     /**
     * Return true if the node represents an adaptive RTF.
     *
     * A node is an adaptive RTF if each children is a Text element
     * or it is <xsl:call-template> or .
     *
     * @param node A node
     * @return true if the node content can be considered as an adaptive RTF.
     */
    private boolean isAdaptiveRTF(SyntaxTreeNode node) {

        Vector contents = node.getContents();
        for (int i = 0; i < contents.size(); i++) {
            SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i);
            if (!isTextElement(item, true))
                return false;
        }

        return true;
    }

    /**
     * Return true if the node only produces Text content.
     *
     * A node is a Text element if it is Text, xsl:value-of, xsl:number,
     * or a combination of these nested in a control instruction (xsl:if or
     * xsl:choose).
     *
     * If the doExtendedCheck flag is true, xsl:call-template and xsl:apply-templates
     * are also considered as Text elements.
     *
     * @param node A node
     * @param doExtendedCheck If this flag is true, <xsl:call-template> and
     * <xsl:apply-templates> are also considered as Text elements.
     *
     * @return true if the node of Text type
     */
    private boolean isTextElement(SyntaxTreeNode node, boolean doExtendedCheck) {
        if (node instanceof ValueOf || node instanceof Number
            || node instanceof Text)
        {
            return true;
        }
        else if (node instanceof If) {
            return doExtendedCheck ? isAdaptiveRTF(node) : isSimpleRTF(node);
        }
        else if (node instanceof Choose) {
            Vector contents = node.getContents();
            for (int i = 0; i < contents.size(); i++) {
                SyntaxTreeNode item = (SyntaxTreeNode)contents.elementAt(i);
                if (item instanceof Text ||
                     ((item instanceof When || item instanceof Otherwise)
                     && ((doExtendedCheck && isAdaptiveRTF(item))
                         || (!doExtendedCheck && isSimpleRTF(item)))))
                    continue;
                else
                    return false;
            }
            return true;
        }
        else if (doExtendedCheck &&
                  (node instanceof CallTemplate
                   || node instanceof ApplyTemplates))
            return true;
        else
            return false;
    }

    /**
     * Utility method used by parameters and variables to store result trees
     * @param classGen BCEL Java class generator
     * @param methodGen BCEL Java method generator
     */
    protected void compileResultTree(ClassGenerator classGen,
                                     MethodGenerator methodGen)
    {
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
        final Stylesheet stylesheet = classGen.getStylesheet();

        boolean isSimple = isSimpleRTF(this);
        boolean isAdaptive = false;
        if (!isSimple) {
            isAdaptive = isAdaptiveRTF(this);
        }

        int rtfType = isSimple ? DOM.SIMPLE_RTF
                               : (isAdaptive ? DOM.ADAPTIVE_RTF : DOM.TREE_RTF);

        // Save the current handler base on the stack
        il.append(methodGen.loadHandler());

        final String DOM_CLASS = classGen.getDOMClass();

        // Create new instance of DOM class (with RTF_INITIAL_SIZE nodes)
        //int index = cpg.addMethodref(DOM_IMPL, "<init>", "(I)V");
        //il.append(new NEW(cpg.addClass(DOM_IMPL)));

        il.append(methodGen.loadDOM());
        int index = cpg.addInterfaceMethodref(DOM_INTF,
                                 "getResultTreeFrag",
                                 "(IIZ)" + DOM_INTF_SIG);
        il.append(new PUSH(cpg, RTF_INITIAL_SIZE));
        il.append(new PUSH(cpg, rtfType));
        il.append(new PUSH(cpg, stylesheet.callsNodeset()));
        il.append(new INVOKEINTERFACE(index,4));

        il.append(DUP);

        // Overwrite old handler with DOM handler
        index = cpg.addInterfaceMethodref(DOM_INTF,
                                 "getOutputDomBuilder",
                                 "()" + TRANSLET_OUTPUT_SIG);

        il.append(new INVOKEINTERFACE(index,1));
        il.append(DUP);
        il.append(methodGen.storeHandler());

        // Call startDocument on the new handler
        il.append(methodGen.startDocument());

        // Instantiate result tree fragment
        translateContents(classGen, methodGen);

        // Call endDocument on the new handler
        il.append(methodGen.loadHandler());
        il.append(methodGen.endDocument());

        // Check if we need to wrap the DOMImpl object in a DOMAdapter object.
        // DOMAdapter is not needed if the RTF is a simple RTF and the nodeset()
        // function is not used.
        if (stylesheet.callsNodeset()
            && !DOM_CLASS.equals(DOM_IMPL_CLASS)) {
            // new com.sun.org.apache.xalan.internal.xsltc.dom.DOMAdapter(DOMImpl,String[]);
            index = cpg.addMethodref(DOM_ADAPTER_CLASS,
                                     "<init>",
                                     "("+DOM_INTF_SIG+
                                     "["+STRING_SIG+
                                     "["+STRING_SIG+
                                     "[I"+
                                     "["+STRING_SIG+")V");
            il.append(new NEW(cpg.addClass(DOM_ADAPTER_CLASS)));
            il.append(new DUP_X1());
            il.append(SWAP);

            /*
             * Give the DOM adapter an empty type mapping if the nodeset
             * extension function is never called.
             */
            if (!stylesheet.callsNodeset()) {
                il.append(new ICONST(0));
                il.append(new ANEWARRAY(cpg.addClass(STRING)));
                il.append(DUP);
                il.append(DUP);
                il.append(new ICONST(0));
                il.append(new NEWARRAY(BasicType.INT));
                il.append(SWAP);
                il.append(new INVOKESPECIAL(index));
            }
            else {
                // Push name arrays on the stack
                il.append(ALOAD_0);
                il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
                                           NAMES_INDEX,
                                           NAMES_INDEX_SIG)));
                il.append(ALOAD_0);
                il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
                                           URIS_INDEX,
                                           URIS_INDEX_SIG)));
                il.append(ALOAD_0);
                il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
                                           TYPES_INDEX,
                                           TYPES_INDEX_SIG)));
                il.append(ALOAD_0);
                il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
                                           NAMESPACE_INDEX,
                                           NAMESPACE_INDEX_SIG)));

                // Initialized DOM adapter
                il.append(new INVOKESPECIAL(index));

                // Add DOM adapter to MultiDOM class by calling addDOMAdapter()
                il.append(DUP);
                il.append(methodGen.loadDOM());
                il.append(new CHECKCAST(cpg.addClass(classGen.getDOMClass())));
                il.append(SWAP);
                index = cpg.addMethodref(MULTI_DOM_CLASS,
                                         "addDOMAdapter",
                                         "(" + DOM_ADAPTER_SIG + ")I");
                il.append(new INVOKEVIRTUAL(index));
                il.append(POP);         // ignore mask returned by addDOMAdapter
            }
        }

        // Restore old handler base from stack
        il.append(SWAP);
        il.append(methodGen.storeHandler());
    }

    /**
     * Returns true if this expression/instruction depends on the context. By
     * default, every expression/instruction depends on the context unless it
     * overrides this method. Currently used to determine if result trees are
     * compiled using procedures or little DOMs (result tree fragments).
     * @return 'true' if this node depends on the context.
     */
    protected boolean contextDependent() {
        return true;
    }

    /**
     * Return true if any of the expressions/instructions in the contents of
     * this node is context dependent.
     * @return 'true' if the contents of this node is context dependent.
     */
    protected boolean dependentContents() {
        final int n = elementCount();
        for (int i = 0; i < n; i++) {
            final SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i);
            if (item.contextDependent()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Adds a child node to this syntax tree node.
     * @param element is the new child node.
     */
    protected final void addElement(SyntaxTreeNode element) {
        _contents.addElement(element);
        element.setParent(this);
    }

    /**
     * Inserts the first child node of this syntax tree node. The existing
     * children are shifted back one position.
     * @param element is the new child node.
     */
    protected final void setFirstElement(SyntaxTreeNode element) {
        _contents.insertElementAt(element,0);
        element.setParent(this);
    }

    /**
     * Removed a child node of this syntax tree node.
     * @param element is the child node to remove.
     */
    protected final void removeElement(SyntaxTreeNode element) {
        _contents.remove(element);
        element.setParent(null);
    }

    /**
     * Returns a Vector containing all the child nodes of this node.
     * @return A Vector containing all the child nodes of this node.
     */
    protected final Vector getContents() {
        return _contents;
    }

    /**
     * Tells you if this node has any child nodes.
     * @return 'true' if this node has any children.
     */
    protected final boolean hasContents() {
        return elementCount() > 0;
    }

    /**
     * Returns the number of children this node has.
     * @return Number of child nodes.
     */
    protected final int elementCount() {
        return _contents.size();
    }

    /**
     * Returns an Enumeration of all child nodes of this node.
     * @return An Enumeration of all child nodes of this node.
     */
    protected final Enumeration elements() {
        return _contents.elements();
    }

    /**
     * Returns a child node at a given position.
     * @param pos The child node's position.
     * @return The child node.
     */
    protected final Object elementAt(int pos) {
        return _contents.elementAt(pos);
    }

    /**
     * Returns this element's last child
     * @return The child node.
     */
    protected final SyntaxTreeNode lastChild() {
        if (_contents.size() == 0) return null;
        return (SyntaxTreeNode)_contents.lastElement();
    }

    /**
     * Displays the contents of this syntax tree node (to stdout).
     * This method is intended for debugging _only_, and should be overridden
     * by all syntax tree node implementations.
     * @param indent Indentation level for syntax tree levels.
     */
    public void display(int indent) {
        displayContents(indent);
    }

    /**
     * Displays the contents of this syntax tree node (to stdout).
     * This method is intended for debugging _only_ !!!
     * @param indent Indentation level for syntax tree levels.
     */
    protected void displayContents(int indent) {
        final int n = elementCount();
        for (int i = 0; i < n; i++) {
            SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i);
            item.display(indent);
        }
    }

    /**
     * Set the indentation level for debug output.
     * @param indent Indentation level for syntax tree levels.
     */
    protected final void indent(int indent) {
        System.out.print(new String(_spaces, 0, indent));
    }

    /**
     * Report an error to the parser.
     * @param element The element in which the error occured (normally 'this'
     * but it could also be an expression/pattern/etc.)
     * @param parser The XSLT parser to report the error to.
     * @param error The error code (from util/ErrorMsg).
     * @param message Any additional error message.
     */
    protected void reportError(SyntaxTreeNode element, Parser parser,
                               String errorCode, String message) {
        final ErrorMsg error = new ErrorMsg(errorCode, message, element);
        parser.reportError(Constants.ERROR, error);
    }

    /**
     * Report a recoverable error to the parser.
     * @param element The element in which the error occured (normally 'this'
     * but it could also be an expression/pattern/etc.)
     * @param parser The XSLT parser to report the error to.
     * @param error The error code (from util/ErrorMsg).
     * @param message Any additional error message.
     */
    protected  void reportWarning(SyntaxTreeNode element, Parser parser,
                                  String errorCode, String message) {
        final ErrorMsg error = new ErrorMsg(errorCode, message, element);
        parser.reportError(Constants.WARNING, error);
    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java SyntaxTreeNode.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.