1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /*
6  * Copyright 2001-2004 The Apache Software Foundation.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 /*
21  * $Id: NodeIteratorBase.java,v 1.2.4.1 2005/09/06 09:37:02 pvedula Exp $
22  */
23 
24 package com.sun.org.apache.xalan.internal.xsltc.dom;
25 
26 import com.sun.org.apache.xalan.internal.xsltc.NodeIterator;
27 import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
28 
29 /**
30  * @author Jacek Ambroziak
31  * @author Santiago Pericas-Geertsen
32  * @author Morten Jorgensen
33  */
34 public abstract class NodeIteratorBase implements NodeIterator {
35 
36     /**
37      * Cached computed value of last().
38      */
39     protected int _last = -1;
40 
41     /**
42      * Value of position() in this iterator. Incremented in
43      * returnNode().
44      */
45     protected int _position = 0;
46 
47     /**
48      * Store node in call to setMark().
49      */
50     protected int _markedNode;
51 
52     /**
53      * Store node in call to setStartNode().
54      */
55     protected int _startNode = NodeIterator.END;
56 
57     /**
58      * Flag indicating if "self" should be returned.
59      */
60     protected boolean _includeSelf = false;
61 
62     /**
63      * Flag indicating if iterator can be restarted.
64      */
65     protected boolean _isRestartable = true;
66 
67     /**
68      * Setter for _isRestartable flag.
69      */
setRestartable(boolean isRestartable)70     public void setRestartable(boolean isRestartable) {
71         _isRestartable = isRestartable;
72     }
73 
74     /**
75      * Initialize iterator using a node. If iterator is not
76      * restartable, then do nothing. If node is equal to END then
77      * subsequent calls to next() must return END.
78      */
setStartNode(int node)79     abstract public NodeIterator setStartNode(int node);
80 
81     /**
82      * Reset this iterator using state from last call to
83      * setStartNode().
84      */
reset()85     public NodeIterator reset() {
86         final boolean temp = _isRestartable;
87         _isRestartable = true;
88         // Must adjust _startNode if self is included
89         setStartNode(_includeSelf ? _startNode + 1 : _startNode);
90         _isRestartable = temp;
91         return this;
92     }
93 
94     /**
95      * Setter for _includeSelf flag.
96      */
includeSelf()97     public NodeIterator includeSelf() {
98         _includeSelf = true;
99         return this;
100     }
101 
102     /**
103      * Default implementation of getLast(). Stores current position
104      * and current node, resets the iterator, counts all nodes and
105      * restores iterator to original state.
106      */
getLast()107     public int getLast() {
108         if (_last == -1) {
109             final int temp = _position;
110             setMark();
111             reset();
112             do {
113                 _last++;
114             } while (next() != END);
115             gotoMark();
116             _position = temp;
117         }
118         return _last;
119     }
120 
121     /**
122      * Returns the position() in this iterator.
123      */
getPosition()124     public int getPosition() {
125         return _position == 0 ? 1 : _position;
126     }
127 
128     /**
129      * Indicates if position in this iterator is computed in reverse
130      * document order. Note that nodes are always returned in document
131      * order.
132      */
isReverse()133     public boolean isReverse() {
134         return false;
135     }
136 
137     /**
138      * Clones and resets this iterator. Note that the cloned iterator is
139      * not restartable. This is because cloning is needed for variable
140      * references, and the context node of the original variable
141      * declaration must be preserved.
142      */
cloneIterator()143     public NodeIterator cloneIterator() {
144         try {
145             final NodeIteratorBase clone = (NodeIteratorBase)super.clone();
146             clone._isRestartable = false;
147             return clone.reset();
148         }
149         catch (CloneNotSupportedException e) {
150             BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
151                                       e.toString());
152             return null;
153         }
154     }
155 
156     /**
157      * Utility method that increments position and returns its
158      * argument.
159      */
returnNode(final int node)160     protected final int returnNode(final int node) {
161         _position++;
162         return node;
163     }
164 
165     /**
166      * Reset the position in this iterator.
167      */
resetPosition()168     protected final NodeIterator resetPosition() {
169         _position = 0;
170         return this;
171     }
172 }
173