KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > dom > traversal > DOMNodeIterator


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

18 package org.apache.batik.dom.traversal;
19
20 import org.apache.batik.dom.AbstractDocument;
21 import org.w3c.dom.DOMException JavaDoc;
22 import org.w3c.dom.Node JavaDoc;
23 import org.w3c.dom.traversal.NodeFilter;
24 import org.w3c.dom.traversal.NodeIterator;
25
26 /**
27  * This class implements the {@link org.w3c.dom.traversal.NodeIterator}
28  * interface.
29  *
30  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
31  * @version $Id: DOMNodeIterator.java,v 1.5 2004/08/18 07:13:37 vhardy Exp $
32  */

33 public class DOMNodeIterator implements NodeIterator {
34
35     /**
36      * The initial state.
37      */

38     protected final static short INITIAL = 0;
39
40     /**
41      * The invalid state.
42      */

43     protected final static short INVALID = 1;
44
45     /**
46      * The forward state.
47      */

48     protected final static short FORWARD = 2;
49
50     /**
51      * The backward state.
52      */

53     protected final static short BACKWARD = 3;
54
55     /**
56      * The document which created the iterator.
57      */

58     protected AbstractDocument document;
59
60     /**
61      * The root node.
62      */

63     protected Node JavaDoc root;
64
65     /**
66      * Which node types are presented via the iterator.
67      */

68     protected int whatToShow;
69
70     /**
71      * The NodeFilter used to screen nodes.
72      */

73     protected NodeFilter filter;
74
75     /**
76      * Whether the children of entity reference nodes are visible
77      * to the iterator.
78      */

79     protected boolean expandEntityReferences;
80
81     /**
82      * The iterator state.
83      */

84     protected short state;
85
86     /**
87      * The reference node.
88      */

89     protected Node JavaDoc referenceNode;
90
91     /**
92      * Creates a new NodeIterator object.
93      * @param doc The document which created the tree walker.
94      * @param n The root node.
95      * @param what Which node types are presented via the iterator.
96      * @param nf The NodeFilter used to screen nodes.
97      * @param exp Whether the children of entity reference nodes are visible
98      * to the iterator.
99      */

100     public DOMNodeIterator(AbstractDocument doc, Node JavaDoc n, int what,
101                            NodeFilter nf, boolean exp) {
102         document = doc;
103         root = n;
104         whatToShow = what;
105         filter = nf;
106         expandEntityReferences = exp;
107
108         referenceNode = root;
109     }
110
111     /**
112      * <b>DOM</b>: Implements {@link NodeIterator#getRoot()}.
113      */

114     public Node JavaDoc getRoot() {
115         return root;
116     }
117
118     /**
119      * <b>DOM</b>: Implements {@link NodeIterator#getWhatToShow()}.
120      */

121     public int getWhatToShow() {
122         return whatToShow;
123     }
124
125     /**
126      * <b>DOM</b>: Implements {@link NodeIterator#getFilter()}.
127      */

128     public NodeFilter getFilter() {
129         return filter;
130     }
131
132     /**
133      * <b>DOM</b>: Implements {@link NodeIterator#getExpandEntityReferences()}.
134      */

135     public boolean getExpandEntityReferences() {
136         return expandEntityReferences;
137     }
138
139     /**
140      * <b>DOM</b>: Implements {@link NodeIterator#nextNode()}.
141      */

142     public Node JavaDoc nextNode() {
143         switch (state) {
144         case INVALID:
145             throw document.createDOMException
146                 (DOMException.INVALID_STATE_ERR,
147                  "detached.iterator", null);
148         case BACKWARD:
149         case INITIAL:
150             state = FORWARD;
151             return referenceNode;
152         case FORWARD:
153         }
154
155         for (;;) {
156             unfilteredNextNode();
157             if (referenceNode == null) {
158                 return null;
159             }
160             if ((whatToShow & (1 << referenceNode.getNodeType() - 1)) != 0) {
161                 if (filter == null ||
162                     filter.acceptNode(referenceNode) == NodeFilter.FILTER_ACCEPT) {
163                     return referenceNode;
164                 }
165             }
166         }
167     }
168     
169     /**
170      * <b>DOM</b>: Implements {@link NodeIterator#previousNode()}.
171      */

172     public Node JavaDoc previousNode() {
173         switch (state) {
174         case INVALID:
175             throw document.createDOMException
176                 (DOMException.INVALID_STATE_ERR,
177                  "detached.iterator", null);
178         case FORWARD:
179         case INITIAL:
180             state = BACKWARD;
181             return referenceNode;
182         case BACKWARD:
183         }
184
185         for (;;) {
186             unfilteredPreviousNode();
187             if (referenceNode == null) {
188                 return referenceNode;
189             }
190             if ((whatToShow & (1 << referenceNode.getNodeType() - 1)) != 0) {
191                 if (filter == null ||
192                     filter.acceptNode(referenceNode) == NodeFilter.FILTER_ACCEPT) {
193                     return referenceNode;
194                 }
195             }
196         }
197     }
198
199     /**
200      * <b>DOM</b>: Implements {@link NodeIterator#detach()}.
201      */

202     public void detach() {
203         state = INVALID;
204         document.detachNodeIterator(this);
205     }
206
207     /**
208      * Called by the DOM when a node will be removed from the current document.
209      */

210     public void nodeToBeRemoved(Node JavaDoc removedNode) {
211         if (state == INVALID) {
212             return;
213         }
214
215         Node JavaDoc node;
216         for (node = referenceNode;
217              node != null && node != root;
218              node = node.getParentNode()) {
219             if (node == removedNode) {
220                 break;
221             }
222         }
223         if (node == null || node == root) {
224             return;
225         }
226
227         if (state == BACKWARD) {
228             // Go to the first child
229
if (node.getNodeType() != Node.ENTITY_REFERENCE_NODE ||
230                 expandEntityReferences) {
231                 Node JavaDoc n = node.getFirstChild();
232                 if (n != null) {
233                     referenceNode = n;
234                     return;
235                 }
236             }
237
238             // Go to the next sibling
239
Node JavaDoc n = node.getNextSibling();
240             if (n != null) {
241                 referenceNode = n;
242                 return;
243             }
244
245             // Go to the first sibling of one of the ancestors
246
n = node;
247             while ((n = n.getParentNode()) != null && n != root) {
248                 Node JavaDoc t = n.getNextSibling();
249                 if (t != null) {
250                     referenceNode = t;
251                     return;
252                 }
253             }
254
255             referenceNode = null;
256         } else {
257             Node JavaDoc n = node.getPreviousSibling();
258
259             // Go to the parent of a first child
260
if (n == null) {
261                 referenceNode = node.getParentNode();
262                 return;
263             }
264
265             // Go to the last child of child...
266
if (n.getNodeType() != Node.ENTITY_REFERENCE_NODE ||
267                 expandEntityReferences) {
268                 Node JavaDoc t;
269                 while ((t = n.getLastChild()) != null) {
270                     n = t;
271                 }
272             }
273
274             referenceNode = n;
275         }
276     }
277
278     /**
279      * Sets the reference node to the next node, unfiltered.
280      */

281     protected void unfilteredNextNode() {
282         if (referenceNode == null) {
283             return;
284         }
285
286         // Go to the first child
287
if (referenceNode.getNodeType() != Node.ENTITY_REFERENCE_NODE ||
288             expandEntityReferences) {
289             Node JavaDoc n = referenceNode.getFirstChild();
290             if (n != null) {
291                 referenceNode = n;
292                 return;
293             }
294         }
295
296         // Go to the next sibling
297
Node JavaDoc n = referenceNode.getNextSibling();
298         if (n != null) {
299             referenceNode = n;
300             return;
301         }
302
303         // Go to the first sibling of one of the ancestors
304
n = referenceNode;
305         while ((n = n.getParentNode()) != null && n != root) {
306             Node JavaDoc t = n.getNextSibling();
307             if (t != null) {
308                 referenceNode = t;
309                 return;
310             }
311         }
312         referenceNode = null;
313     }
314
315     /**
316      * Sets the reference node to the previous node, unfiltered.
317      */

318     protected void unfilteredPreviousNode() {
319         if (referenceNode == null) {
320             return;
321         }
322
323         // The previous of root is null
324
if (referenceNode == root) {
325             referenceNode = null;
326             return;
327         }
328         
329         Node JavaDoc n = referenceNode.getPreviousSibling();
330
331         // Go to the parent of a first child
332
if (n == null) {
333             referenceNode = referenceNode.getParentNode();
334             return;
335         }
336
337         // Go to the last child of child...
338
if (n.getNodeType() != Node.ENTITY_REFERENCE_NODE ||
339             expandEntityReferences) {
340             Node JavaDoc t;
341             while ((t = n.getLastChild()) != null) {
342                 n = t;
343             }
344         }
345
346         referenceNode = n;
347     }
348 }
349
Popular Tags