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