286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * Copyright 1999-2004 The Apache Software Foundation.
286N/A *
286N/A * Licensed under the Apache License, Version 2.0 (the "License");
286N/A * you may not use this file except in compliance with the License.
286N/A * You may obtain a copy of the License at
286N/A *
286N/A * http://www.apache.org/licenses/LICENSE-2.0
286N/A *
286N/A * Unless required by applicable law or agreed to in writing, software
286N/A * distributed under the License is distributed on an "AS IS" BASIS,
286N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286N/A * See the License for the specific language governing permissions and
286N/A * limitations under the License.
286N/A */
286N/A/*
286N/A * $Id: UnionChildIterator.java,v 1.2.4.1 2005/09/14 19:45:20 jeffsuttor Exp $
286N/A */
286N/Apackage com.sun.org.apache.xpath.internal.axes;
286N/A
286N/Aimport com.sun.org.apache.xml.internal.dtm.DTMIterator;
286N/Aimport com.sun.org.apache.xpath.internal.XPathContext;
286N/Aimport com.sun.org.apache.xpath.internal.objects.XObject;
286N/Aimport com.sun.org.apache.xpath.internal.patterns.NodeTest;
286N/A
286N/A/**
286N/A * This class defines a simplified type of union iterator that only
286N/A * tests along the child axes. If the conditions are right, it is
286N/A * much faster than using a UnionPathIterator.
286N/A */
286N/Apublic class UnionChildIterator extends ChildTestIterator
286N/A{
286N/A static final long serialVersionUID = 3500298482193003495L;
286N/A /**
286N/A * Even though these may hold full LocPathIterators, this array does
286N/A * not have to be cloned, since only the node test and predicate
286N/A * portion are used, and these only need static information. However,
286N/A * also note that index predicates can not be used!
286N/A */
286N/A private PredicatedNodeTest[] m_nodeTests = null;
286N/A
286N/A /**
286N/A * Constructor for UnionChildIterator
286N/A */
286N/A public UnionChildIterator()
286N/A {
286N/A super(null);
286N/A }
286N/A
286N/A /**
286N/A * Add a node test to the union list.
286N/A *
286N/A * @param test reference to a NodeTest, which will be added
286N/A * directly to the list of node tests (in other words, it will
286N/A * not be cloned). The parent of this test will be set to
286N/A * this object.
286N/A */
286N/A public void addNodeTest(PredicatedNodeTest test)
286N/A {
286N/A
286N/A // Increase array size by only 1 at a time. Fix this
286N/A // if it looks to be a problem.
286N/A if (null == m_nodeTests)
286N/A {
286N/A m_nodeTests = new PredicatedNodeTest[1];
286N/A m_nodeTests[0] = test;
286N/A }
286N/A else
286N/A {
286N/A PredicatedNodeTest[] tests = m_nodeTests;
286N/A int len = m_nodeTests.length;
286N/A
286N/A m_nodeTests = new PredicatedNodeTest[len + 1];
286N/A
286N/A System.arraycopy(tests, 0, m_nodeTests, 0, len);
286N/A
286N/A m_nodeTests[len] = test;
286N/A }
286N/A test.exprSetParent(this);
286N/A }
286N/A
286N/A /**
286N/A * This function is used to fixup variables from QNames to stack frame
286N/A * indexes at stylesheet build time.
286N/A * @param vars List of QNames that correspond to variables. This list
286N/A * should be searched backwards for the first qualified name that
286N/A * corresponds to the variable reference qname. The position of the
286N/A * QName in the vector from the start of the vector will be its position
286N/A * in the stack frame (but variables above the globalsTop value will need
286N/A * to be offset to the current stack frame).
286N/A */
286N/A public void fixupVariables(java.util.Vector vars, int globalsSize)
286N/A {
286N/A super.fixupVariables(vars, globalsSize);
286N/A if (m_nodeTests != null) {
286N/A for (int i = 0; i < m_nodeTests.length; i++) {
286N/A m_nodeTests[i].fixupVariables(vars, globalsSize);
286N/A }
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Test whether a specified node is visible in the logical view of a
286N/A * TreeWalker or NodeIterator. This function will be called by the
286N/A * implementation of TreeWalker and NodeIterator; it is not intended to
286N/A * be called directly from user code.
286N/A * @param n The node to check to see if it passes the filter or not.
286N/A * @return a constant to determine whether the node is accepted,
286N/A * rejected, or skipped, as defined above .
286N/A */
286N/A public short acceptNode(int n)
286N/A {
286N/A XPathContext xctxt = getXPathContext();
286N/A try
286N/A {
286N/A xctxt.pushCurrentNode(n);
286N/A for (int i = 0; i < m_nodeTests.length; i++)
286N/A {
286N/A PredicatedNodeTest pnt = m_nodeTests[i];
286N/A XObject score = pnt.execute(xctxt, n);
286N/A if (score != NodeTest.SCORE_NONE)
286N/A {
286N/A // Note that we are assuming there are no positional predicates!
286N/A if (pnt.getPredicateCount() > 0)
286N/A {
286N/A if (pnt.executePredicates(n, xctxt))
286N/A return DTMIterator.FILTER_ACCEPT;
286N/A }
286N/A else
286N/A return DTMIterator.FILTER_ACCEPT;
286N/A
286N/A }
286N/A }
286N/A }
286N/A catch (javax.xml.transform.TransformerException se)
286N/A {
286N/A
286N/A // TODO: Fix this.
286N/A throw new RuntimeException(se.getMessage());
286N/A }
286N/A finally
286N/A {
286N/A xctxt.popCurrentNode();
286N/A }
286N/A return DTMIterator.FILTER_SKIP;
286N/A }
286N/A
286N/A}