KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > dom > TreeWalkerImpl


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2002 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 com.sun.org.apache.xerces.internal.dom;
59
60 import org.w3c.dom.DOMException JavaDoc;
61 import org.w3c.dom.Node JavaDoc;
62 import org.w3c.dom.traversal.NodeFilter;
63 import org.w3c.dom.traversal.TreeWalker;
64
65 /** This class implements the TreeWalker interface. */
66 /**
67  * @version $Id: TreeWalkerImpl.java,v 1.8 2003/07/29 18:29:40 elena Exp $
68  */

69
70 public class TreeWalkerImpl implements TreeWalker {
71     
72     //
73
// Data
74
//
75

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

93     
94     //
95
// Constructor
96
//
97

98     /** Public constructor */
99     public TreeWalkerImpl(Node JavaDoc root,
100                           int whatToShow,
101                           NodeFilter nodeFilter,
102                           boolean entityReferenceExpansion) {
103         fCurrentNode = root;
104         fRoot = root;
105         fWhatToShow = whatToShow;
106         fNodeFilter = nodeFilter;
107         fEntityReferenceExpansion = entityReferenceExpansion;
108     }
109     
110     public Node JavaDoc getRoot() {
111     return fRoot;
112     }
113
114     /** Return the whatToShow value */
115     public int getWhatToShow() {
116         return fWhatToShow;
117     }
118
119     public void setWhatShow(int whatToShow){
120         fWhatToShow = whatToShow;
121     }
122     /** Return the NodeFilter */
123     public NodeFilter getFilter() {
124         return fNodeFilter;
125     }
126     
127     /** Return whether children entity references are included in the iterator. */
128     public boolean getExpandEntityReferences() {
129         return fEntityReferenceExpansion;
130     }
131             
132     /** Return the current Node. */
133     public Node JavaDoc getCurrentNode() {
134         return fCurrentNode;
135     }
136     /** Return the current Node. */
137     public void setCurrentNode(Node JavaDoc node) {
138         if (node == null) {
139             String JavaDoc msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
140               throw new DOMException JavaDoc(DOMException.NOT_SUPPORTED_ERR, msg);
141         }
142
143         fCurrentNode = node;
144     }
145     
146     /** Return the parent Node from the current node,
147      * after applying filter, whatToshow.
148      * If result is not null, set the current Node.
149      */

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

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

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

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

210     public Node JavaDoc nextSibling(){
211         if (fCurrentNode == null) return null;
212                 
213         Node JavaDoc node = getNextSibling(fCurrentNode);
214         if (node !=null) {
215             fCurrentNode = node;
216         }
217         return node;
218     }
219     
220     /** Return the previous Node from the current node,
221      * after applying filter, whatToshow.
222      * If result is not null, set the current Node.
223      */

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

271     public Node JavaDoc nextNode() {
272         
273         if (fCurrentNode == null) return null;
274         
275         Node JavaDoc result = getFirstChild(fCurrentNode);
276         
277         if (result != null) {
278             fCurrentNode = result;
279             return result;
280         }
281         
282         result = getNextSibling(fCurrentNode);
283         
284         if (result != null) {
285             fCurrentNode = result;
286             return result;
287         }
288                 
289         // return parent's 1st sibling.
290
Node JavaDoc parent = getParentNode(fCurrentNode);
291         while (parent != null) {
292             result = getNextSibling(parent);
293             if (result != null) {
294                 fCurrentNode = result;
295                 return result;
296             } else {
297                 parent = getParentNode(parent);
298             }
299         }
300         
301         // end , return null
302
return null;
303     }
304     
305     /** Internal function.
306      * Return the parent Node, from the input node
307      * after applying filter, whatToshow.
308      * The current node is not consulted or set.
309      */

310     Node JavaDoc getParentNode(Node JavaDoc node) {
311         
312         if (node == null || node == fRoot) return null;
313         
314         Node JavaDoc newNode = node.getParentNode();
315         if (newNode == null) return null;
316                         
317         int accept = acceptNode(newNode);
318         
319         if (accept == NodeFilter.FILTER_ACCEPT)
320             return newNode;
321         else
322         //if (accept == NodeFilter.SKIP_NODE) // and REJECT too.
323
{
324             return getParentNode(newNode);
325         }
326         
327         
328     }
329     
330     /** Internal function.
331      * Return the nextSibling Node, from the input node
332      * after applying filter, whatToshow.
333      * The current node is not consulted or set.
334      */

335     Node JavaDoc getNextSibling(Node JavaDoc node) {
336         return getNextSibling(node, fRoot);
337     }
338
339     /** Internal function.
340      * Return the nextSibling Node, from the input node
341      * after applying filter, whatToshow.
342      * NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE.
343      * The current node is not consulted or set.
344      */

345     Node JavaDoc getNextSibling(Node JavaDoc node, Node JavaDoc root) {
346         
347         if (node == null || node == root) return null;
348         
349         Node JavaDoc newNode = node.getNextSibling();
350         if (newNode == null) {
351                 
352             newNode = node.getParentNode();
353                 
354             if (newNode == null || newNode == root) return null;
355                 
356             int parentAccept = acceptNode(newNode);
357                 
358             if (parentAccept==NodeFilter.FILTER_SKIP) {
359                 return getNextSibling(newNode, root);
360             }
361                 
362             return null;
363         }
364         
365         int accept = acceptNode(newNode);
366         
367         if (accept == NodeFilter.FILTER_ACCEPT)
368             return newNode;
369         else
370         if (accept == NodeFilter.FILTER_SKIP) {
371             Node JavaDoc fChild = getFirstChild(newNode);
372             if (fChild == null) {
373                 return getNextSibling(newNode, root);
374             }
375             return fChild;
376         }
377         else
378         //if (accept == NodeFilter.REJECT_NODE)
379
{
380             return getNextSibling(newNode, root);
381         }
382         
383     } // getNextSibling(Node node) {
384

385     /** Internal function.
386      * Return the previous sibling Node, from the input node
387      * after applying filter, whatToshow.
388      * The current node is not consulted or set.
389      */

390     Node JavaDoc getPreviousSibling(Node JavaDoc node) {
391         return getPreviousSibling(node, fRoot);
392     }
393
394     /** Internal function.
395      * Return the previousSibling Node, from the input node
396      * after applying filter, whatToshow.
397      * NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE.
398      * The current node is not consulted or set.
399      */

400     Node JavaDoc getPreviousSibling(Node JavaDoc node, Node JavaDoc root) {
401         
402         if (node == null || node == root) return null;
403         
404         Node JavaDoc newNode = node.getPreviousSibling();
405         if (newNode == null) {
406                 
407             newNode = node.getParentNode();
408             if (newNode == null || newNode == root) return null;
409                 
410             int parentAccept = acceptNode(newNode);
411                 
412             if (parentAccept==NodeFilter.FILTER_SKIP) {
413                 return getPreviousSibling(newNode, root);
414             }
415             
416             return null;
417         }
418         
419         int accept = acceptNode(newNode);
420         
421         if (accept == NodeFilter.FILTER_ACCEPT)
422             return newNode;
423         else
424         if (accept == NodeFilter.FILTER_SKIP) {
425             Node JavaDoc fChild = getLastChild(newNode);
426             if (fChild == null) {
427                 return getPreviousSibling(newNode, root);
428             }
429             return fChild;
430         }
431         else
432         //if (accept == NodeFilter.REJECT_NODE)
433
{
434             return getPreviousSibling(newNode, root);
435         }
436         
437     } // getPreviousSibling(Node node) {
438

439     /** Internal function.
440      * Return the first child Node, from the input node
441      * after applying filter, whatToshow.
442      * The current node is not consulted or set.
443      */

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

481     Node JavaDoc getLastChild(Node JavaDoc node) {
482         
483         if (node == null) return null;
484         
485         if ( !fEntityReferenceExpansion
486              && node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
487             return null;
488             
489         Node JavaDoc newNode = node.getLastChild();
490         if (newNode == null) return null;
491         
492         int accept = acceptNode(newNode);
493         
494         if (accept == NodeFilter.FILTER_ACCEPT)
495             return newNode;
496         else
497         if (accept == NodeFilter.FILTER_SKIP
498             && newNode.hasChildNodes())
499         {
500             Node JavaDoc lChild = getLastChild(newNode);
501             if (lChild == null) {
502                 return getPreviousSibling(newNode, node);
503             }
504             return lChild;
505         }
506         else
507         //if (accept == NodeFilter.REJECT_NODE)
508
{
509             return getPreviousSibling(newNode, node);
510         }
511         
512         
513     }
514     
515     /** Internal function.
516      * The node whatToShow and the filter are combined into one result. */

517     short acceptNode(Node JavaDoc node) {
518         /***
519          7.1.2.4. Filters and whatToShow flags
520
521          Iterator and TreeWalker apply whatToShow flags before applying Filters. If a node is rejected by the
522          active whatToShow flags, a Filter will not be called to evaluate that node. When a node is rejected by
523          the active whatToShow flags, children of that node will still be considered, and Filters may be called to
524          evaluate them.
525          ***/

526                 
527         if (fNodeFilter == null) {
528             if ( ( fWhatToShow & (1 << node.getNodeType()-1)) != 0) {
529                 return NodeFilter.FILTER_ACCEPT;
530             } else {
531                 return NodeFilter.FILTER_SKIP;
532             }
533         } else {
534             if ((fWhatToShow & (1 << node.getNodeType()-1)) != 0 ) {
535                 return fNodeFilter.acceptNode(node);
536             } else {
537                 // What to show has failed. See above excerpt from spec.
538
// Equivalent to FILTER_SKIP.
539
return NodeFilter.FILTER_SKIP;
540             }
541         }
542     }
543 }
544
Popular Tags