View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 1999-2004 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  /*
21   * $Id: DTMAxisIterNodeList.java,v 1.2.4.1 2005/09/15 08:14:59 suresh_emailid Exp $
22   */
23  package com.sun.org.apache.xml.internal.dtm.ref;
24  
25  import com.sun.org.apache.xml.internal.dtm.DTM;
26  import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
27  import com.sun.org.apache.xml.internal.utils.IntVector;
28  
29  import org.w3c.dom.Node;
30  
31  /**
32   * <code>DTMAxisNodeList</code> gives us an implementation of the DOM's
33   * NodeList interface wrapped around a DTM Iterator. The author
34   * considers this something of an abominations, since NodeList was not
35   * intended to be a general purpose "list of nodes" API and is
36   * generally considered by the DOM WG to have be a mistake... but I'm
37   * told that some of the XPath/XSLT folks say they must have this
38   * solution.
39   *
40   * Please note that this is not necessarily equivlaent to a DOM
41   * NodeList operating over the same document. In particular:
42   * <ul>
43   *
44   * <li>If there are several Text nodes in logical succession (ie,
45   * across CDATASection and EntityReference boundaries), we will return
46   * only the first; the caller is responsible for stepping through
47   * them.
48   * (%REVIEW% Provide a convenience routine here to assist, pending
49   * proposed DOM Level 3 getAdjacentText() operation?) </li>
50   *
51   * <li>Since the whole XPath/XSLT architecture assumes that the source
52   * document is not altered while we're working with it, we do not
53   * promise to implement the DOM NodeList's "live view" response to
54   * document mutation. </li>
55   *
56   * </ul>
57   *
58   * <p>State: In progress!!</p>
59   * */
60  public class DTMAxisIterNodeList extends DTMNodeListBase {
61      private DTM m_dtm;
62      private DTMAxisIterator m_iter;
63      private IntVector m_cachedNodes;
64      private int m_last = -1;
65      //================================================================
66      // Methods unique to this class
67      private DTMAxisIterNodeList() {
68      }
69  
70      /**
71       * Public constructor: Wrap a DTMNodeList around an existing
72       * and preconfigured DTMAxisIterator
73       */
74      public DTMAxisIterNodeList(DTM dtm, DTMAxisIterator dtmAxisIterator) {
75          if (dtmAxisIterator == null) {
76              m_last = 0;
77          } else {
78              m_cachedNodes = new IntVector();
79              m_dtm = dtm;
80          }
81          m_iter = dtmAxisIterator;
82      }
83  
84      /**
85       * Access the wrapped DTMIterator. I'm not sure whether anyone will
86       * need this or not, but let's write it and think about it.
87       *
88       */
89      public DTMAxisIterator getDTMAxisIterator() {
90          return m_iter;
91      }
92  
93  
94      //================================================================
95      // org.w3c.dom.NodeList API follows
96  
97      /**
98       * Returns the <code>index</code>th item in the collection. If
99       * <code>index</code> is greater than or equal to the number of nodes in
100      * the list, this returns <code>null</code>.
101      * @param index Index into the collection.
102      * @return The node at the <code>index</code>th position in the
103      *   <code>NodeList</code>, or <code>null</code> if that is not a valid
104      *   index.
105      */
106     public Node item(int index) {
107         if (m_iter != null) {
108             int node = 0;
109             int count = m_cachedNodes.size();
110 
111             if (count > index) {
112                 node = m_cachedNodes.elementAt(index);
113                 return m_dtm.getNode(node);
114             } else if (m_last == -1) {
115                 while (count <= index
116                         && ((node = m_iter.next()) != DTMAxisIterator.END)) {
117                     m_cachedNodes.addElement(node);
118                     count++;
119                 }
120                 if (node == DTMAxisIterator.END) {
121                     m_last = count;
122                 } else {
123                     return m_dtm.getNode(node);
124                 }
125             }
126         }
127         return null;
128     }
129 
130     /**
131      * The number of nodes in the list. The range of valid child node indices
132      * is 0 to <code>length-1</code> inclusive.
133      */
134     public int getLength() {
135         if (m_last == -1) {
136             int node;
137             while ((node = m_iter.next()) != DTMAxisIterator.END) {
138                 m_cachedNodes.addElement(node);
139             }
140             m_last = m_cachedNodes.size();
141         }
142         return m_last;
143     }
144 }