001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: /*
017: * $Id: FilterExprIterator.java,v 1.7 2005/01/23 01:02:10 mcnamara Exp $
018: */
019: package org.apache.xpath.axes;
020:
021: import org.apache.xml.dtm.DTM;
022: import org.apache.xpath.Expression;
023: import org.apache.xpath.ExpressionOwner;
024: import org.apache.xpath.XPathVisitor;
025: import org.apache.xpath.objects.XNodeSet;
026:
027: public class FilterExprIterator extends BasicTestIterator {
028: static final long serialVersionUID = 2552176105165737614L;
029: /** The contained expression. Should be non-null.
030: * @serial */
031: private Expression m_expr;
032:
033: /** The result of executing m_expr. Needs to be deep cloned on clone op. */
034: transient private XNodeSet m_exprObj;
035:
036: private boolean m_mustHardReset = false;
037: private boolean m_canDetachNodeset = true;
038:
039: /**
040: * Create a FilterExprIterator object.
041: *
042: */
043: public FilterExprIterator() {
044: super (null);
045: }
046:
047: /**
048: * Create a FilterExprIterator object.
049: *
050: */
051: public FilterExprIterator(Expression expr) {
052: super (null);
053: m_expr = expr;
054: }
055:
056: /**
057: * Initialize the context values for this expression
058: * after it is cloned.
059: *
060: * @param context The XPath runtime context for this
061: * transformation.
062: */
063: public void setRoot(int context, Object environment) {
064: super .setRoot(context, environment);
065:
066: m_exprObj = FilterExprIteratorSimple.executeFilterExpr(context,
067: m_execContext, getPrefixResolver(), getIsTopLevel(),
068: m_stackFrame, m_expr);
069: }
070:
071: /**
072: * Get the next node via getNextXXX. Bottlenecked for derived class override.
073: * @return The next node on the axis, or DTM.NULL.
074: */
075: protected int getNextNode() {
076: if (null != m_exprObj) {
077: m_lastFetched = m_exprObj.nextNode();
078: } else
079: m_lastFetched = DTM.NULL;
080:
081: return m_lastFetched;
082: }
083:
084: /**
085: * Detaches the walker from the set which it iterated over, releasing
086: * any computational resources and placing the iterator in the INVALID
087: * state.
088: */
089: public void detach() {
090: super .detach();
091: m_exprObj.detach();
092: m_exprObj = null;
093: }
094:
095: /**
096: * This function is used to fixup variables from QNames to stack frame
097: * indexes at stylesheet build time.
098: * @param vars List of QNames that correspond to variables. This list
099: * should be searched backwards for the first qualified name that
100: * corresponds to the variable reference qname. The position of the
101: * QName in the vector from the start of the vector will be its position
102: * in the stack frame (but variables above the globalsTop value will need
103: * to be offset to the current stack frame).
104: */
105: public void fixupVariables(java.util.Vector vars, int globalsSize) {
106: super .fixupVariables(vars, globalsSize);
107: m_expr.fixupVariables(vars, globalsSize);
108: }
109:
110: /**
111: * Get the inner contained expression of this filter.
112: */
113: public Expression getInnerExpression() {
114: return m_expr;
115: }
116:
117: /**
118: * Set the inner contained expression of this filter.
119: */
120: public void setInnerExpression(Expression expr) {
121: expr.exprSetParent(this );
122: m_expr = expr;
123: }
124:
125: /**
126: * Get the analysis bits for this walker, as defined in the WalkerFactory.
127: * @return One of WalkerFactory#BIT_DESCENDANT, etc.
128: */
129: public int getAnalysisBits() {
130: if (null != m_expr && m_expr instanceof PathComponent) {
131: return ((PathComponent) m_expr).getAnalysisBits();
132: }
133: return WalkerFactory.BIT_FILTER;
134: }
135:
136: /**
137: * Returns true if all the nodes in the iteration well be returned in document
138: * order.
139: * Warning: This can only be called after setRoot has been called!
140: *
141: * @return true as a default.
142: */
143: public boolean isDocOrdered() {
144: return m_exprObj.isDocOrdered();
145: }
146:
147: class filterExprOwner implements ExpressionOwner {
148: /**
149: * @see ExpressionOwner#getExpression()
150: */
151: public Expression getExpression() {
152: return m_expr;
153: }
154:
155: /**
156: * @see ExpressionOwner#setExpression(Expression)
157: */
158: public void setExpression(Expression exp) {
159: exp.exprSetParent(FilterExprIterator.this );
160: m_expr = exp;
161: }
162:
163: }
164:
165: /**
166: * This will traverse the heararchy, calling the visitor for
167: * each member. If the called visitor method returns
168: * false, the subtree should not be called.
169: *
170: * @param visitor The visitor whose appropriate method will be called.
171: */
172: public void callPredicateVisitors(XPathVisitor visitor) {
173: m_expr.callVisitors(new filterExprOwner(), visitor);
174:
175: super .callPredicateVisitors(visitor);
176: }
177:
178: /**
179: * @see Expression#deepEquals(Expression)
180: */
181: public boolean deepEquals(Expression expr) {
182: if (!super .deepEquals(expr))
183: return false;
184:
185: FilterExprIterator fet = (FilterExprIterator) expr;
186: if (!m_expr.deepEquals(fet.m_expr))
187: return false;
188:
189: return true;
190: }
191:
192: }
|