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: WalkingIteratorSorted.java 468655 2006-10-28 07:12:06Z minchau $
020 */
021 package org.apache.xpath.axes;
022
023 import org.apache.xml.dtm.Axis;
024 import org.apache.xml.utils.PrefixResolver;
025 import org.apache.xpath.compiler.Compiler;
026
027 /**
028 * This class iterates over set of nodes that needs to be sorted.
029 * @xsl.usage internal
030 */
031 public class WalkingIteratorSorted extends WalkingIterator
032 {
033 static final long serialVersionUID = -4512512007542368213L;
034
035 // /** True if the nodes will be found in document order */
036 // protected boolean m_inNaturalOrder = false;
037
038 /** True if the nodes will be found in document order, and this can
039 * be determined statically. */
040 protected boolean m_inNaturalOrderStatic = false;
041
042 /**
043 * Create a WalkingIteratorSorted object.
044 *
045 * @param nscontext The namespace context for this iterator,
046 * should be OK if null.
047 */
048 public WalkingIteratorSorted(PrefixResolver nscontext)
049 {
050 super(nscontext);
051 }
052
053 /**
054 * Create a WalkingIterator iterator, including creation
055 * of step walkers from the opcode list, and call back
056 * into the Compiler to create predicate expressions.
057 *
058 * @param compiler The Compiler which is creating
059 * this expression.
060 * @param opPos The position of this iterator in the
061 * opcode list from the compiler.
062 * @param shouldLoadWalkers True if walkers should be
063 * loaded, or false if this is a derived iterator and
064 * it doesn't wish to load child walkers.
065 *
066 * @throws javax.xml.transform.TransformerException
067 */
068 WalkingIteratorSorted(
069 Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
070 throws javax.xml.transform.TransformerException
071 {
072 super(compiler, opPos, analysis, shouldLoadWalkers);
073 }
074
075 /**
076 * Returns true if all the nodes in the iteration well be returned in document
077 * order.
078 *
079 * @return true as a default.
080 */
081 public boolean isDocOrdered()
082 {
083 return m_inNaturalOrderStatic;
084 }
085
086
087 /**
088 * Tell if the nodeset can be walked in doc order, via static analysis.
089 *
090 *
091 * @return true if the nodeset can be walked in doc order, without sorting.
092 */
093 boolean canBeWalkedInNaturalDocOrderStatic()
094 {
095
096 if (null != m_firstWalker)
097 {
098 AxesWalker walker = m_firstWalker;
099 int prevAxis = -1;
100 boolean prevIsSimpleDownAxis = true;
101
102 for(int i = 0; null != walker; i++)
103 {
104 int axis = walker.getAxis();
105
106 if(walker.isDocOrdered())
107 {
108 boolean isSimpleDownAxis = ((axis == Axis.CHILD)
109 || (axis == Axis.SELF)
110 || (axis == Axis.ROOT));
111 // Catching the filtered list here is only OK because
112 // FilterExprWalker#isDocOrdered() did the right thing.
113 if(isSimpleDownAxis || (axis == -1))
114 walker = walker.getNextWalker();
115 else
116 {
117 boolean isLastWalker = (null == walker.getNextWalker());
118 if(isLastWalker)
119 {
120 if(walker.isDocOrdered() && (axis == Axis.DESCENDANT ||
121 axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
122 || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
123 return true;
124 }
125 return false;
126 }
127 }
128 else
129 return false;
130 }
131 return true;
132 }
133 return false;
134 }
135
136
137 // /**
138 // * NEEDSDOC Method canBeWalkedInNaturalDocOrder
139 // *
140 // *
141 // * NEEDSDOC (canBeWalkedInNaturalDocOrder) @return
142 // */
143 // boolean canBeWalkedInNaturalDocOrder()
144 // {
145 //
146 // if (null != m_firstWalker)
147 // {
148 // AxesWalker walker = m_firstWalker;
149 // int prevAxis = -1;
150 // boolean prevIsSimpleDownAxis = true;
151 //
152 // for(int i = 0; null != walker; i++)
153 // {
154 // int axis = walker.getAxis();
155 //
156 // if(walker.isDocOrdered())
157 // {
158 // boolean isSimpleDownAxis = ((axis == Axis.CHILD)
159 // || (axis == Axis.SELF)
160 // || (axis == Axis.ROOT));
161 // // Catching the filtered list here is only OK because
162 // // FilterExprWalker#isDocOrdered() did the right thing.
163 // if(isSimpleDownAxis || (axis == -1))
164 // walker = walker.getNextWalker();
165 // else
166 // {
167 // boolean isLastWalker = (null == walker.getNextWalker());
168 // if(isLastWalker)
169 // {
170 // if(walker.isDocOrdered() && (axis == Axis.DESCENDANT ||
171 // axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
172 // || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
173 // return true;
174 // }
175 // return false;
176 // }
177 // }
178 // else
179 // return false;
180 // }
181 // return true;
182 // }
183 // return false;
184 // }
185
186 /**
187 * This function is used to perform some extra analysis of the iterator.
188 *
189 * @param vars List of QNames that correspond to variables. This list
190 * should be searched backwards for the first qualified name that
191 * corresponds to the variable reference qname. The position of the
192 * QName in the vector from the start of the vector will be its position
193 * in the stack frame (but variables above the globalsTop value will need
194 * to be offset to the current stack frame).
195 */
196 public void fixupVariables(java.util.Vector vars, int globalsSize)
197 {
198 super.fixupVariables(vars, globalsSize);
199
200 int analysis = getAnalysisBits();
201 if(WalkerFactory.isNaturalDocOrder(analysis))
202 {
203 m_inNaturalOrderStatic = true;
204 }
205 else
206 {
207 m_inNaturalOrderStatic = false;
208 // System.out.println("Setting natural doc order to false: "+
209 // WalkerFactory.getAnalysisString(analysis));
210 }
211
212 }
213
214 }