KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > dom > CurrentNodeListIterator


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: CurrentNodeListIterator.java,v 1.13 2004/02/16 22:54:59 minchau Exp $
18  */

19
20 package org.apache.xalan.xsltc.dom;
21
22 import org.apache.xalan.xsltc.runtime.AbstractTranslet;
23 import org.apache.xalan.xsltc.runtime.BasisLibrary;
24 import org.apache.xalan.xsltc.util.IntegerArray;
25 import org.apache.xml.dtm.DTMAxisIterator;
26 import org.apache.xml.dtm.ref.DTMAxisIteratorBase;
27
28 /**
29  * Iterators of this kind use a CurrentNodeListFilter to filter a subset of
30  * nodes from a source iterator. For each node from the source, the boolean
31  * method CurrentNodeListFilter.test() is called.
32  *
33  * All nodes from the source are read into an array upon calling setStartNode()
34  * (this is needed to determine the value of last, a parameter to
35  * CurrentNodeListFilter.test()). The method getLast() returns the last element
36  * after applying the filter.
37  * @author Jacek Ambroziak
38  * @author Santiago Pericas-Geertsen
39  * @author Morten Jorgensen
40  */

41
42 public final class CurrentNodeListIterator extends DTMAxisIteratorBase {
43     /**
44      * A flag indicating if nodes are returned in document order.
45      */

46     private boolean _docOrder;
47
48     /**
49      * The source for this iterator.
50      */

51     private DTMAxisIterator _source;
52
53     /**
54      * A reference to a filter object.
55      */

56     private final CurrentNodeListFilter _filter;
57
58     /**
59      * An integer array to store nodes from source iterator.
60      */

61     private IntegerArray _nodes = new IntegerArray();
62     
63     /**
64      * Index in _nodes of the next node to filter.
65      */

66     private int _currentIndex;
67     
68     /**
69      * The current node in the stylesheet at the time of evaluation.
70      */

71     private final int _currentNode;
72
73     /**
74      * A reference to the translet.
75      */

76     private AbstractTranslet _translet;
77
78     public CurrentNodeListIterator(DTMAxisIterator source,
79                    CurrentNodeListFilter filter,
80                    int currentNode,
81                    AbstractTranslet translet)
82     {
83     this(source, !source.isReverse(), filter, currentNode, translet);
84     }
85
86     public CurrentNodeListIterator(DTMAxisIterator source, boolean docOrder,
87                    CurrentNodeListFilter filter,
88                    int currentNode,
89                    AbstractTranslet translet)
90     {
91     _source = source;
92     _filter = filter;
93     _translet = translet;
94     _docOrder = docOrder;
95     _currentNode = currentNode;
96     }
97
98     public DTMAxisIterator forceNaturalOrder() {
99     _docOrder = true;
100     return this;
101     }
102
103     public void setRestartable(boolean isRestartable) {
104     _isRestartable = isRestartable;
105     _source.setRestartable(isRestartable);
106     }
107
108     public boolean isReverse() {
109     return !_docOrder;
110     }
111
112     public DTMAxisIterator cloneIterator() {
113     try {
114         final CurrentNodeListIterator clone =
115         (CurrentNodeListIterator) super.clone();
116         clone._nodes = (IntegerArray) _nodes.clone();
117         clone._source = _source.cloneIterator();
118         clone._isRestartable = false;
119         return clone.reset();
120     }
121     catch (CloneNotSupportedException JavaDoc e) {
122         BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
123                       e.toString());
124         return null;
125     }
126     }
127     
128     public DTMAxisIterator reset() {
129     _currentIndex = 0;
130     return resetPosition();
131     }
132
133     public int next() {
134     final int last = _nodes.cardinality();
135     final int currentNode = _currentNode;
136     final AbstractTranslet translet = _translet;
137
138     for (int index = _currentIndex; index < last; ) {
139         final int position = _docOrder ? index + 1 : last - index;
140         final int node = _nodes.at(index++); // note increment
141

142         if (_filter.test(node, position, last, currentNode, translet,
143                              this)) {
144         _currentIndex = index;
145         return returnNode(node);
146         }
147     }
148     return END;
149     }
150
151     public DTMAxisIterator setStartNode(int node) {
152     if (_isRestartable) {
153         _source.setStartNode(_startNode = node);
154
155         _nodes.clear();
156         while ((node = _source.next()) != END) {
157         _nodes.add(node);
158         }
159         _currentIndex = 0;
160         resetPosition();
161     }
162     return this;
163     }
164     
165     public int getLast() {
166     if (_last == -1) {
167         _last = computePositionOfLast();
168     }
169     return _last;
170     }
171
172     public void setMark() {
173     _markedNode = _currentIndex;
174     }
175
176     public void gotoMark() {
177     _currentIndex = _markedNode;
178     }
179
180     private int computePositionOfLast() {
181         final int last = _nodes.cardinality();
182         final int currNode = _currentNode;
183     final AbstractTranslet translet = _translet;
184
185     int lastPosition = _position;
186     for (int index = _currentIndex; index < last; ) {
187         final int position = _docOrder ? index + 1 : last - index;
188             int nodeIndex = _nodes.at(index++); // note increment
189

190             if (_filter.test(nodeIndex, position, last, currNode, translet,
191                              this)) {
192                 lastPosition++;
193             }
194         }
195     return lastPosition;
196     }
197 }
198
Popular Tags