KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > 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.enhydra.apache.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     public void setWhatShow(int whatToShow){
115         fWhatToShow = whatToShow;
116     }
117     /** Return the NodeFilter */
118     public NodeFilter getFilter() {
119         return fNodeFilter;
120     }
121     
122     /** Return whether children entity references are included in the iterator. */
123     public boolean getExpandEntityReferences() {
124         return fEntityReferenceExpansion;
125     }
126             
127     /** Return the current Node. */
128     public Node JavaDoc getCurrentNode() {
129         return fCurrentNode;
130     }
131     /** Return the current Node. */
132     public void setCurrentNode(Node JavaDoc node) {
133         fCurrentNode = node;
134     }
135     
136     /** Return the parent Node from the current node,
137      * after applying filter, whatToshow.
138      * If result is not null, set the current Node.
139      */

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

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

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

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

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

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

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

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

325     Node JavaDoc getNextSibling(Node JavaDoc node) {
326         return getNextSibling(node, fRoot);
327     }
328
329     /** Internal function.
330      * Return the nextSibling Node, from the input node
331      * after applying filter, whatToshow.
332      * NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE.
333      * The current node is not consulted or set.
334      */

335     Node JavaDoc getNextSibling(Node JavaDoc node, Node JavaDoc root) {
336         
337         if (node == null || node == root) return null;
338         
339         Node JavaDoc newNode = node.getNextSibling();
340         if (newNode == null) {
341                 
342             newNode = node.getParentNode();
343                 
344             if (newNode == null || newNode == root) return null;
345                 
346             int parentAccept = acceptNode(newNode);
347                 
348             if (parentAccept==NodeFilter.FILTER_SKIP) {
349                 return getNextSibling(newNode, root);
350             }
351                 
352             return null;
353         }
354         
355         int accept = acceptNode(newNode);
356         
357         if (accept == NodeFilter.FILTER_ACCEPT)
358             return newNode;
359         else
360         if (accept == NodeFilter.FILTER_SKIP) {
361             Node JavaDoc fChild = getFirstChild(newNode);
362             if (fChild == null) {
363                 return getNextSibling(newNode, root);
364             }
365             return fChild;
366         }
367         else
368         //if (accept == NodeFilter.REJECT_NODE)
369
{
370             return getNextSibling(newNode, root);
371         }
372         
373     } // getNextSibling(Node node) {
374

375     /** Internal function.
376      * Return the previous sibling Node, from the input node
377      * after applying filter, whatToshow.
378      * The current node is not consulted or set.
379      */

380     Node JavaDoc getPreviousSibling(Node JavaDoc node) {
381         return getPreviousSibling(node, fRoot);
382     }
383
384     /** Internal function.
385      * Return the previousSibling Node, from the input node
386      * after applying filter, whatToshow.
387      * NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE.
388      * The current node is not consulted or set.
389      */

390     Node JavaDoc getPreviousSibling(Node JavaDoc node, Node JavaDoc root) {
391         
392         if (node == null || node == root) return null;
393         
394         Node JavaDoc newNode = node.getPreviousSibling();
395         if (newNode == null) {
396                 
397             newNode = node.getParentNode();
398             if (newNode == null || newNode == root) return null;
399                 
400             int parentAccept = acceptNode(newNode);
401                 
402             if (parentAccept==NodeFilter.FILTER_SKIP) {
403                 return getPreviousSibling(newNode, root);
404             }
405             
406             return null;
407         }
408         
409         int accept = acceptNode(newNode);
410         
411         if (accept == NodeFilter.FILTER_ACCEPT)
412             return newNode;
413         else
414         if (accept == NodeFilter.FILTER_SKIP) {
415             Node JavaDoc fChild = getLastChild(newNode);
416             if (fChild == null) {
417                 return getPreviousSibling(newNode, root);
418             }
419             return fChild;
420         }
421         else
422         //if (accept == NodeFilter.REJECT_NODE)
423
{
424             return getPreviousSibling(newNode, root);
425         }
426         
427     } // getPreviousSibling(Node node) {
428

429     /** Internal function.
430      * Return the first child Node, from the input node
431      * after applying filter, whatToshow.
432      * The current node is not consulted or set.
433      */

434     Node JavaDoc getFirstChild(Node JavaDoc node) {
435         if (node == null) return null;
436         
437         if ( !fEntityReferenceExpansion
438              && node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
439             return null;
440         Node JavaDoc newNode = node.getFirstChild();
441         if (newNode == null) return null;
442         int accept = acceptNode(newNode);
443         
444         if (accept == NodeFilter.FILTER_ACCEPT)
445             return newNode;
446         else
447         if (accept == NodeFilter.FILTER_SKIP
448             && newNode.hasChildNodes())
449         {
450             Node JavaDoc fChild = getFirstChild(newNode);
451             
452             if (fChild == null) {
453                 return getNextSibling(newNode, node);
454             }
455             return fChild;
456         }
457         else
458         //if (accept == NodeFilter.REJECT_NODE)
459
{
460             return getNextSibling(newNode, node);
461         }
462         
463         
464     }
465    
466     /** Internal function.
467      * Return the last child Node, from the input node
468      * after applying filter, whatToshow.
469      * The current node is not consulted or set.
470      */

471     Node JavaDoc getLastChild(Node JavaDoc node) {
472         
473         if (node == null) return null;
474         
475         if ( !fEntityReferenceExpansion
476              && node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
477             return null;
478             
479         Node JavaDoc newNode = node.getLastChild();
480         if (newNode == null) return null;
481         
482         int accept = acceptNode(newNode);
483         
484         if (accept == NodeFilter.FILTER_ACCEPT)
485             return newNode;
486         else
487         if (accept == NodeFilter.FILTER_SKIP
488             && newNode.hasChildNodes())
489         {
490             Node JavaDoc lChild = getLastChild(newNode);
491             if (lChild == null) {
492                 return getPreviousSibling(newNode, node);
493             }
494             return lChild;
495         }
496         else
497         //if (accept == NodeFilter.REJECT_NODE)
498
{
499             return getPreviousSibling(newNode, node);
500         }
501         
502         
503     }
504     
505     /** Internal function.
506      * The node whatToShow and the filter are combined into one result. */

507     short acceptNode(Node JavaDoc node) {
508         /***
509          7.1.2.4. Filters and whatToShow flags
510
511          Iterator and TreeWalker apply whatToShow flags before applying Filters. If a node is rejected by the
512          active whatToShow flags, a Filter will not be called to evaluate that node. When a node is rejected by
513          the active whatToShow flags, children of that node will still be considered, and Filters may be called to
514          evaluate them.
515          ***/

516                 
517         if (fNodeFilter == null) {
518             if ( ( fWhatToShow & (1 << node.getNodeType()-1)) != 0) {
519                 return NodeFilter.FILTER_ACCEPT;
520             } else {
521                 return NodeFilter.FILTER_SKIP;
522             }
523         } else {
524             if ((fWhatToShow & (1 << node.getNodeType()-1)) != 0 ) {
525                 return fNodeFilter.acceptNode(node);
526             } else {
527                 // What to show has failed. See above excerpt from spec.
528
// Equivalent to FILTER_SKIP.
529
return NodeFilter.FILTER_SKIP;
530             }
531         }
532     }
533 }
534
Popular Tags