1 28 29 package com.caucho.xml; 30 31 import com.caucho.xpath.pattern.NodeListIterator; 32 33 import org.w3c.dom.Node ; 34 import org.w3c.dom.NodeList ; 35 36 import java.util.Iterator ; 37 38 public class QDeepNodeList implements NodeList { 39 QNode _top; 40 QNodePredicate _predicate; 41 QAbstractNode _first; 42 QAbstractNode _node; 43 int _index = -2; 44 int _length = -2; 45 int _changeCount; 46 47 QDeepNodeList(QNode top, QAbstractNode first, QNodePredicate predicate) 48 { 49 _top = top; 50 _first = first; 51 _predicate = predicate; 52 } 53 54 public Node item(int index) 55 { 56 QAbstractNode next = _node; 57 58 int i = _index; 59 60 if (next == null || index < i || 61 _changeCount != _top._owner._changeCount) { 62 _changeCount = _top._owner._changeCount; 63 next = _first; 64 i = _predicate != null && _predicate.isMatch(next) ? 0 : -1; 65 } 66 67 QAbstractNode end = getEnd(); 68 while (i < index && next != end) { 69 next = next.getNextPreorder(); 70 if (next != end && _predicate.isMatch(next)) { 71 i++; 72 } 73 } 74 75 if (next == end) { 76 next = null; 77 i = -1; 78 } 79 _index = i; 80 _node = next; 81 82 return i == _index ? next : null; 83 } 84 85 public int getLength() 86 { 87 if (_changeCount != _top._owner._changeCount) 88 _length = -1; 89 90 if (_length >= 0) 91 return _length; 92 93 QAbstractNode end = getEnd(); 94 _length = 0; 95 for (QAbstractNode ptr = _first; ptr != end; ptr = ptr.getNextPreorder()) { 96 if (_predicate.isMatch(ptr)) 97 _length++; 98 } 99 100 return _length; 101 } 102 103 106 QAbstractNode getEnd() 107 { 108 QAbstractNode end = _top; 109 110 if (_first == null) 111 return null; 112 113 while (end != null && end._next == null) 114 end = end._parent; 115 116 return end == null ? null : end._next; 117 } 118 119 public Iterator<Node > iterator() 121 { 122 return new NodeListIterator(null, this); 123 } 124 } 125 | Popular Tags |