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