KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > xpath > datamodel > xerces > dom > TreeWalkerImpl


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.xquark.xpath.datamodel.xerces.dom;
59
60 import org.w3c.dom.Node JavaDoc;
61 import org.w3c.dom.traversal.NodeFilter;
62 import org.w3c.dom.traversal.TreeWalker;
63
64 /** This class implements the TreeWalker interface. */
65 public class TreeWalkerImpl implements TreeWalker {
66     
67     //
68
// Data
69
//
70

71     /** When TRUE, the children of entites references are returned in the iterator. */
72     private boolean fEntityReferenceExpansion = false;
73     /** The whatToShow mask. */
74     int fWhatToShow = NodeFilter.SHOW_ALL;
75     /** The NodeFilter reference. */
76     NodeFilter fNodeFilter;
77     /** The current Node. */
78     Node JavaDoc fCurrentNode;
79     /** The root Node. */
80     Node JavaDoc fRoot;
81     
82     //
83
// Implementation Note: No state is kept except the data above
84
// (fWhatToShow, fNodeFilter, fCurrentNode, fRoot) such that
85
// setters could be created for these data values and the
86
// implementation will still work.
87

88     
89     //
90
// Constructor
91
//
92

93     /** Public constructor */
94     public TreeWalkerImpl(Node JavaDoc root,
95                           int whatToShow,
96                           NodeFilter nodeFilter,
97                           boolean entityReferenceExpansion) {
98         fCurrentNode = root;
99         fRoot = root;
100         fWhatToShow = whatToShow;
101         fNodeFilter = nodeFilter;
102         fEntityReferenceExpansion = entityReferenceExpansion;
103     }
104     
105     public Node JavaDoc getRoot() {
106     return fRoot;
107     }
108
109     /** Return the whatToShow value */
110     public int getWhatToShow() {
111         return fWhatToShow;
112     }
113
114     /** Return the NodeFilter */
115     public NodeFilter getFilter() {
116         return fNodeFilter;
117     }
118     
119     /** Return whether children entity references are included in the iterator. */
120     public boolean getExpandEntityReferences() {
121         return fEntityReferenceExpansion;
122     }
123             
124     /** Return the current Node. */
125     public Node JavaDoc getCurrentNode() {
126         return fCurrentNode;
127     }
128     /** Return the current Node. */
129     public void setCurrentNode(Node JavaDoc node) {
130         fCurrentNode = node;
131     }
132     
133     /** Return the parent Node from the current node,
134      * after applying filter, whatToshow.
135      * If result is not null, set the current Node.
136      */

137     public Node JavaDoc parentNode() {
138
139         if (fCurrentNode == null) return null;
140                 
141         Node JavaDoc node = getParentNode(fCurrentNode);
142         if (node !=null) {
143             fCurrentNode = node;
144         }
145         return node;
146         
147     }
148
149     /** Return the first child Node from the current node,
150      * after applying filter, whatToshow.
151      * If result is not null, set the current Node.
152      */

153     public Node JavaDoc firstChild() {
154         
155         if (fCurrentNode == null) return null;
156                 
157         Node JavaDoc node = getFirstChild(fCurrentNode);
158         if (node !=null) {
159             fCurrentNode = node;
160         }
161         return node;
162     }
163     /** Return the last child Node from the current node,
164      * after applying filter, whatToshow.
165      * If result is not null, set the current Node.
166      */

167     public Node JavaDoc lastChild() {
168
169         if (fCurrentNode == null) return null;
170                 
171         Node JavaDoc node = getLastChild(fCurrentNode);
172         if (node !=null) {
173             fCurrentNode = node;
174         }
175         return node;
176     }
177     
178     /** Return the previous sibling Node from the current node,
179      * after applying filter, whatToshow.
180      * If result is not null, set the current Node.
181      */

182     public Node JavaDoc previousSibling() {
183
184         if (fCurrentNode == null) return null;
185                 
186         Node JavaDoc node = getPreviousSibling(fCurrentNode);
187         if (node !=null) {
188             fCurrentNode = node;
189         }
190         return node;
191     }
192     
193     /** Return the next sibling Node from the current node,
194      * after applying filter, whatToshow.
195      * If result is not null, set the current Node.
196      */

197     public Node JavaDoc nextSibling(){
198         if (fCurrentNode == null) return null;
199                 
200         Node JavaDoc node = getNextSibling(fCurrentNode);
201         if (node !=null) {
202             fCurrentNode = node;
203         }
204         return node;
205     }
206     
207     /** Return the previous Node from the current node,
208      * after applying filter, whatToshow.
209      * If result is not null, set the current Node.
210      */

211     public Node JavaDoc previousNode() {
212         Node JavaDoc result;
213         
214         if (fCurrentNode == null) return null;
215         
216         // get sibling
217
result = getPreviousSibling(fCurrentNode);
218         if (result == null) {
219             result = getParentNode(fCurrentNode);
220             if (result != null) {
221                 fCurrentNode = result;
222                 return fCurrentNode;
223             }
224             return null;
225         }
226         
227         // get the lastChild of result.
228
Node JavaDoc lastChild = getLastChild(result);
229         
230         Node JavaDoc prev = lastChild ;
231         while (lastChild != null) {
232           prev = lastChild ;
233           lastChild = getLastChild(prev) ;
234         }
235
236         lastChild = prev ;
237         
238         // if there is a lastChild which passes filters return it.
239
if (lastChild != null) {
240             fCurrentNode = lastChild;
241             return fCurrentNode;
242         }
243         
244         // otherwise return the previous sibling.
245
if (result != null) {
246             fCurrentNode = result;
247             return fCurrentNode;
248         }
249         
250         // otherwise return null.
251
return null;
252     }
253     
254     /** Return the next Node from the current node,
255      * after applying filter, whatToshow.
256      * If result is not null, set the current Node.
257      */

258     public Node JavaDoc nextNode() {
259         
260         if (fCurrentNode == null) return null;
261         
262         Node JavaDoc result = getFirstChild(fCurrentNode);
263         
264         if (result != null) {
265             fCurrentNode = result;
266             return result;
267         }
268         
269         result = getNextSibling(fCurrentNode);
270         
271         if (result != null) {
272             fCurrentNode = result;
273             return result;
274         }
275                 
276         // return parent's 1st sibling.
277
Node JavaDoc parent = getParentNode(fCurrentNode);
278         while (parent != null) {
279             result = getNextSibling(parent);
280             if (result != null) {
281                 fCurrentNode = result;
282                 return result;
283             } else {
284                 parent = getParentNode(parent);
285             }
286         }
287         
288         // end , return null
289
return null;
290     }
291     
292     /** Internal function.
293      * Return the parent Node, from the input node
294      * after applying filter, whatToshow.
295      * The current node is not consulted or set.
296      */

297     Node JavaDoc getParentNode(Node JavaDoc node) {
298         
299         if (node == null || node == fRoot) return null;
300         
301         Node JavaDoc newNode = node.getParentNode();
302         if (newNode == null) return null;
303                         
304         int accept = acceptNode(newNode);
305         
306         if (accept == NodeFilter.FILTER_ACCEPT)
307             return newNode;
308         else
309         //if (accept == NodeFilter.SKIP_NODE) // and REJECT too.
310
{
311             return getParentNode(newNode);
312         }
313         
314         
315     }
316     
317     /** Internal function.
318      * Return the nextSibling Node, from the input node
319      * after applying filter, whatToshow.
320      * The current node is not consulted or set.
321      */

322     Node JavaDoc getNextSibling(Node JavaDoc node) {
323         
324         if (node == null || node == fRoot) return null;
325         
326         Node JavaDoc newNode = node.getNextSibling();
327         if (newNode == null) {
328                 
329             newNode = node.getParentNode();
330                 
331             if (newNode == null || node == fRoot) return null;
332                 
333             int parentAccept = acceptNode(newNode);
334                 
335             if (parentAccept==NodeFilter.FILTER_SKIP) {
336                 return getNextSibling(newNode);
337             }
338                 
339             return null;
340         }
341         
342         int accept = acceptNode(newNode);
343         
344         if (accept == NodeFilter.FILTER_ACCEPT)
345             return newNode;
346         else
347         if (accept == NodeFilter.FILTER_SKIP) {
348             Node JavaDoc fChild = getFirstChild(newNode);
349             if (fChild == null) {
350                 return getNextSibling(newNode);
351             }
352             return fChild;
353         }
354         else
355         //if (accept == NodeFilter.REJECT_NODE)
356
{
357             return getNextSibling(newNode);
358         }
359         
360     } // getNextSibling(Node node) {
361

362     /** Internal function.
363      * Return the previous sibling Node, from the input node
364      * after applying filter, whatToshow.
365      * The current node is not consulted or set.
366      */

367     Node JavaDoc getPreviousSibling(Node JavaDoc node) {
368         
369         if (node == null || node == fRoot) return null;
370         
371         Node JavaDoc newNode = node.getPreviousSibling();
372         if (newNode == null) {
373                 
374             newNode = node.getParentNode();
375             if (newNode == null || node == fRoot) return null;
376                 
377             int parentAccept = acceptNode(newNode);
378                 
379             if (parentAccept==NodeFilter.FILTER_SKIP) {
380                 return getPreviousSibling(newNode);
381             }
382             
383             return null;
384         }
385         
386         int accept = acceptNode(newNode);
387         
388         if (accept == NodeFilter.FILTER_ACCEPT)
389             return newNode;
390         else
391         if (accept == NodeFilter.FILTER_SKIP) {
392             Node JavaDoc fChild = getLastChild(newNode);
393             if (fChild == null) {
394                 return getPreviousSibling(newNode);
395             }
396             return fChild;
397         }
398         else
399         //if (accept == NodeFilter.REJECT_NODE)
400
{
401             return getPreviousSibling(newNode);
402         }
403         
404     } // getPreviousSibling(Node node) {
405

406     /** Internal function.
407      * Return the first child Node, from the input node
408      * after applying filter, whatToshow.
409      * The current node is not consulted or set.
410      */

411     Node JavaDoc getFirstChild(Node JavaDoc node) {
412         
413         if (node == null) return null;
414         
415         if ( !fEntityReferenceExpansion
416              && node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
417             return null;
418    
419         Node JavaDoc newNode = node.getFirstChild();
420         if (newNode == null) return null;
421         
422         int accept = acceptNode(newNode);
423         
424         if (accept == NodeFilter.FILTER_ACCEPT)
425             return newNode;
426         else
427         if (accept == NodeFilter.FILTER_SKIP
428             && newNode.hasChildNodes())
429         {
430             return getFirstChild(newNode);
431         }
432         else
433         //if (accept == NodeFilter.REJECT_NODE)
434
{
435             return getNextSibling(newNode);
436         }
437         
438         
439     }
440    
441     /** Internal function.
442      * Return the last child Node, from the input node
443      * after applying filter, whatToshow.
444      * The current node is not consulted or set.
445      */

446     Node JavaDoc getLastChild(Node JavaDoc node) {
447         
448         if (node == null) return null;
449         
450         if ( !fEntityReferenceExpansion
451              && node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
452             return null;
453             
454         Node JavaDoc newNode = node.getLastChild();
455         if (newNode == null) return null;
456         
457         int accept = acceptNode(newNode);
458         
459         if (accept == NodeFilter.FILTER_ACCEPT)
460             return newNode;
461         else
462         if (accept == NodeFilter.FILTER_SKIP
463             && newNode.hasChildNodes())
464         {
465             return getLastChild(newNode);
466         }
467         else
468         //if (accept == NodeFilter.REJECT_NODE)
469
{
470             return getPreviousSibling(newNode);
471         }
472         
473         
474     }
475     
476     /** Internal function.
477      * The node whatToShow and the filter are combined into one result. */

478     short acceptNode(Node JavaDoc node) {
479         /***
480          7.1.2.4. Filters and whatToShow flags
481
482          Iterator and TreeWalker apply whatToShow flags before applying Filters. If a node is rejected by the
483          active whatToShow flags, a Filter will not be called to evaluate that node. When a node is rejected by
484          the active whatToShow flags, children of that node will still be considered, and Filters may be called to
485          evaluate them.
486          ***/

487                 
488         if (fNodeFilter == null) {
489             if ( ( fWhatToShow & (1 << node.getNodeType()-1)) != 0) {
490                 return NodeFilter.FILTER_ACCEPT;
491             } else {
492                 return NodeFilter.FILTER_SKIP;
493             }
494         } else {
495             if ((fWhatToShow & (1 << node.getNodeType()-1)) != 0 ) {
496                 return fNodeFilter.acceptNode(node);
497             } else {
498                 // What to show has failed. See above excerpt from spec.
499
// Equivalent to FILTER_SKIP.
500
return NodeFilter.FILTER_SKIP;
501             }
502         }
503     }
504 }
505
Popular Tags