OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / libcore / luni / src / main / java / org / apache / xml / dtm / ref / DTMNodeIterator.java
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id: DTMNodeIterator.java 468653 2006-10-28 07:07:05Z minchau $
20  */
21 package org.apache.xml.dtm.ref;
22
23 import org.apache.xml.dtm.DTM;
24 import org.apache.xml.dtm.DTMDOMException;
25 import org.apache.xml.dtm.DTMIterator;
26
27 import org.w3c.dom.DOMException;
28 import org.w3c.dom.Node;
29 import org.w3c.dom.traversal.NodeFilter;
30
31 /**
32  * <code>DTMNodeIterator</code> gives us an implementation of the 
33  * DTMNodeIterator which returns DOM nodes.
34  *
35  * Please note that this is not necessarily equivlaent to a DOM
36  * NodeIterator operating over the same document. In particular:
37  * <ul>
38  *
39  * <li>If there are several Text nodes in logical succession (ie,
40  * across CDATASection and EntityReference boundaries), we will return
41  * only the first; the caller is responsible for stepping through
42  * them.
43  * (%REVIEW% Provide a convenience routine here to assist, pending
44  * proposed DOM Level 3 getAdjacentText() operation?) </li>
45  *
46  * <li>Since the whole XPath/XSLT architecture assumes that the source
47  * document is not altered while we're working with it, we do not
48  * promise to implement the DOM NodeIterator's "maintain current
49  * position" response to document mutation. </li>
50  *
51  * <li>Since our design for XPath NodeIterators builds a stateful
52  * filter directly into the traversal object, getNodeFilter() is not
53  * supported.</li>
54  *
55  * </ul>
56  *
57  * <p>State: In progress!!</p>
58  * */
59 public class DTMNodeIterator implements org.w3c.dom.traversal.NodeIterator
60 {
61   private DTMIterator dtm_iter;
62   private boolean valid=true;
63
64   //================================================================
65   // Methods unique to this class
66
67   /** Public constructor: Wrap a DTMNodeIterator around an existing
68    * and preconfigured DTMIterator
69    * */
70   public DTMNodeIterator(DTMIterator dtmIterator)
71     {
72       try
73       {
74         dtm_iter=(DTMIterator)dtmIterator.clone();
75       }
76       catch(CloneNotSupportedException cnse)
77       {
78         throw new org.apache.xml.utils.WrappedRuntimeException(cnse);
79       }
80     }
81
82   /** Access the wrapped DTMIterator. I'm not sure whether anyone will
83    * need this or not, but let's write it and think about it.
84    * */
85   public DTMIterator getDTMIterator()
86     {
87       return dtm_iter;
88     }
89   
90
91   //================================================================
92   // org.w3c.dom.traversal.NodeFilter API follows
93
94   /** Detaches the NodeIterator from the set which it iterated over,
95    * releasing any computational resources and placing the iterator in
96    * the INVALID state.
97    * */
98   public void detach() 
99     {
100       // Theoretically, we could release dtm_iter at this point. But
101       // some of the operations may still want to consult it even though
102       // navigation is now invalid.
103       valid=false;
104     }
105
106   /** The value of this flag determines whether the children
107    * of entity reference nodes are visible to the iterator.
108    *
109    * @return false, always (the DTM model flattens entity references)
110    * */
111   public boolean getExpandEntityReferences()
112     {
113       return false;
114     }
115   
116   /** Return a handle to the filter used to screen nodes.
117    *
118    * This is ill-defined in Xalan's usage of Nodeiterator, where we have
119    * built stateful XPath-based filtering directly into the traversal
120    * object. We could return something which supports the NodeFilter interface
121    * and allows querying whether a given node would be permitted if it appeared
122    * as our next node, but in the current implementation that would be very
123    * complex -- and just isn't all that useful.
124    * 
125    * @throws DOMException -- NOT_SUPPORTED_ERROR because I can't think
126    * of anything more useful to do in this case
127    * */
128   public NodeFilter getFilter() 
129     {
130       throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
131     }
132   
133
134   /** @return The root node of the NodeIterator, as specified
135    * when it was created.
136    * */
137   public Node getRoot()
138     {
139       int handle=dtm_iter.getRoot();
140       return dtm_iter.getDTM(handle).getNode(handle);
141     }
142   
143
144   /** Return a mask describing which node types are presented via the
145    * iterator.
146    **/
147   public int getWhatToShow()
148     {
149       return dtm_iter.getWhatToShow();
150     }
151
152   /** @return the next node in the set and advance the position of the
153    * iterator in the set.
154    *
155    * @throws DOMException - INVALID_STATE_ERR Raised if this method is
156    * called after the detach method was invoked.
157    *  */
158   public Node nextNode() throws DOMException
159     {
160       if(!valid)
161         throw new DTMDOMException(DOMException.INVALID_STATE_ERR);
162       
163       int handle=dtm_iter.nextNode();
164       if (handle==DTM.NULL)
165         return null;
166       return dtm_iter.getDTM(handle).getNode(handle);
167     }
168   
169
170   /** @return the next previous in the set and advance the position of the
171    * iterator in the set.
172    *
173    * @throws DOMException - INVALID_STATE_ERR Raised if this method is
174    * called after the detach method was invoked.
175    *  */
176   public Node previousNode() 
177     {
178       if(!valid)
179         throw new DTMDOMException(DOMException.INVALID_STATE_ERR);
180       
181       int handle=dtm_iter.previousNode();
182       if (handle==DTM.NULL)
183         return null;      
184       return dtm_iter.getDTM(handle).getNode(handle);
185     }
186 }