001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 /*
019 * $Id: OneStepIteratorForward.java 469314 2006-10-30 23:31:59Z minchau $
020 */
021 package org.apache.xpath.axes;
022
023 import org.apache.xml.dtm.DTM;
024 import org.apache.xml.dtm.DTMFilter;
025 import org.apache.xpath.Expression;
026 import org.apache.xpath.compiler.Compiler;
027 import org.apache.xpath.compiler.OpMap;
028
029 /**
030 * This class implements a general iterator for
031 * those LocationSteps with only one step, and perhaps a predicate,
032 * that only go forward (i.e. it can not be used with ancestors,
033 * preceding, etc.)
034 * @see org.apache.xpath.axes#ChildTestIterator
035 * @xsl.usage advanced
036 */
037 public class OneStepIteratorForward extends ChildTestIterator
038 {
039 static final long serialVersionUID = -1576936606178190566L;
040 /** The traversal axis from where the nodes will be filtered. */
041 protected int m_axis = -1;
042
043 /**
044 * Create a OneStepIterator object.
045 *
046 * @param compiler A reference to the Compiler that contains the op map.
047 * @param opPos The position within the op map, which contains the
048 * location path expression for this itterator.
049 *
050 * @throws javax.xml.transform.TransformerException
051 */
052 OneStepIteratorForward(Compiler compiler, int opPos, int analysis)
053 throws javax.xml.transform.TransformerException
054 {
055 super(compiler, opPos, analysis);
056 int firstStepPos = OpMap.getFirstChildPos(opPos);
057
058 m_axis = WalkerFactory.getAxisFromStep(compiler, firstStepPos);
059
060 }
061
062 /**
063 * Create a OneStepIterator object that will just traverse the self axes.
064 *
065 * @param axis One of the org.apache.xml.dtm.Axis integers.
066 *
067 * @throws javax.xml.transform.TransformerException
068 */
069 public OneStepIteratorForward(int axis)
070 {
071 super(null);
072
073 m_axis = axis;
074 int whatToShow = DTMFilter.SHOW_ALL;
075 initNodeTest(whatToShow);
076 }
077
078
079
080
081 /**
082 * Initialize the context values for this expression
083 * after it is cloned.
084 *
085 * @param context The XPath runtime context for this
086 * transformation.
087 */
088 public void setRoot(int context, Object environment)
089 {
090 super.setRoot(context, environment);
091 m_traverser = m_cdtm.getAxisTraverser(m_axis);
092
093 }
094
095 // /**
096 // * Return the first node out of the nodeset, if this expression is
097 // * a nodeset expression. This is the default implementation for
098 // * nodesets.
099 // * <p>WARNING: Do not mutate this class from this function!</p>
100 // * @param xctxt The XPath runtime context.
101 // * @return the first node out of the nodeset, or DTM.NULL.
102 // */
103 // public int asNode(XPathContext xctxt)
104 // throws javax.xml.transform.TransformerException
105 // {
106 // if(getPredicateCount() > 0)
107 // return super.asNode(xctxt);
108 //
109 // int current = xctxt.getCurrentNode();
110 //
111 // DTM dtm = xctxt.getDTM(current);
112 // DTMAxisTraverser traverser = dtm.getAxisTraverser(m_axis);
113 //
114 // String localName = getLocalName();
115 // String namespace = getNamespace();
116 // int what = m_whatToShow;
117 //
118 // // System.out.println("what: ");
119 // // NodeTest.debugWhatToShow(what);
120 // if(DTMFilter.SHOW_ALL == what
121 // || ((DTMFilter.SHOW_ELEMENT & what) == 0)
122 // || localName == NodeTest.WILD
123 // || namespace == NodeTest.WILD)
124 // {
125 // return traverser.first(current);
126 // }
127 // else
128 // {
129 // int type = getNodeTypeTest(what);
130 // int extendedType = dtm.getExpandedTypeID(namespace, localName, type);
131 // return traverser.first(current, extendedType);
132 // }
133 // }
134
135 /**
136 * Get the next node via getFirstAttribute && getNextAttribute.
137 */
138 protected int getNextNode()
139 {
140 m_lastFetched = (DTM.NULL == m_lastFetched)
141 ? m_traverser.first(m_context)
142 : m_traverser.next(m_context, m_lastFetched);
143 return m_lastFetched;
144 }
145
146 /**
147 * Returns the axis being iterated, if it is known.
148 *
149 * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple
150 * types.
151 */
152 public int getAxis()
153 {
154 return m_axis;
155 }
156
157 /**
158 * @see Expression#deepEquals(Expression)
159 */
160 public boolean deepEquals(Expression expr)
161 {
162 if(!super.deepEquals(expr))
163 return false;
164
165 if(m_axis != ((OneStepIteratorForward)expr).m_axis)
166 return false;
167
168 return true;
169 }
170
171
172 }