1 57 58 package org.xquark.xpath.datamodel.xerces.dom; 59 60 import org.w3c.dom.DOMException ; 61 import org.w3c.dom.Node ; 62 import org.w3c.dom.traversal.NodeFilter; 63 import org.w3c.dom.traversal.NodeIterator; 64 65 75 public class NodeIteratorImpl implements NodeIterator { 76 77 81 82 private DocumentImpl fDocument; 83 84 private Node fRoot; 85 86 private int fWhatToShow = NodeFilter.SHOW_ALL; 87 88 private NodeFilter fNodeFilter; 89 90 private boolean fDetach = false; 91 92 105 106 private Node fCurrentNode; 107 108 114 private boolean fForward = true; 115 116 117 private boolean fEntityReferenceExpansion; 118 119 123 124 public NodeIteratorImpl( DocumentImpl document, 125 Node root, 126 int whatToShow, 127 NodeFilter nodeFilter, 128 boolean entityReferenceExpansion) { 129 fDocument = document; 130 fRoot = root; 131 fCurrentNode = null; 132 fWhatToShow = whatToShow; 133 fNodeFilter = nodeFilter; 134 fEntityReferenceExpansion = entityReferenceExpansion; 135 } 136 137 public Node getRoot() { 138 return fRoot; 139 } 140 141 145 146 public int getWhatToShow() { 147 return fWhatToShow; 148 } 149 150 151 public NodeFilter getFilter() { 152 return fNodeFilter; 153 } 154 155 156 public boolean getExpandEntityReferences() { 157 return fEntityReferenceExpansion; 158 } 159 160 164 public Node nextNode() { 165 166 if( fDetach) { 167 throw new DOMException ( 168 DOMException.INVALID_STATE_ERR, 169 "DOM011 Invalid state"); 170 } 171 172 if (fRoot == null) return null; 174 175 Node nextNode = fCurrentNode; 176 boolean accepted = false; 178 accepted_loop: 179 while (!accepted) { 180 181 if (!fForward && nextNode!=null) { 183 nextNode = fCurrentNode; 185 } else { 186 if (!fEntityReferenceExpansion 188 && nextNode != null 189 && nextNode.getNodeType() == Node.ENTITY_REFERENCE_NODE) { 190 nextNode = nextNode(nextNode, false); 191 } else { 192 nextNode = nextNode(nextNode, true); 193 } 194 } 195 196 fForward = true; 198 if (nextNode == null) return null; 200 201 accepted = acceptNode(nextNode); 203 if (accepted) { 204 fCurrentNode = nextNode; 206 return fCurrentNode; 207 } else 208 continue accepted_loop; 209 210 } 212 return null; 214 215 } 216 217 220 public Node previousNode() { 221 222 if( fDetach) { 223 throw new DOMException ( 224 DOMException.INVALID_STATE_ERR, 225 "DOM011 Invalid state"); 226 } 227 228 if (fRoot == null || fCurrentNode == null) return null; 230 231 Node previousNode = fCurrentNode; 232 boolean accepted = false; 233 234 accepted_loop: 235 while (!accepted) { 236 237 if (fForward && previousNode != null) { 238 previousNode = fCurrentNode; 240 } else { 241 previousNode = previousNode(previousNode); 243 } 244 245 fForward = false; 247 248 if (previousNode == null) return null; 251 252 accepted = acceptNode(previousNode); 254 if (accepted) { 255 fCurrentNode = previousNode; 257 return fCurrentNode; 258 } else 259 continue accepted_loop; 260 } 261 return null; 263 } 264 265 266 boolean acceptNode(Node node) { 267 268 if (fNodeFilter == null) { 269 return ( fWhatToShow & (1 << node.getNodeType()-1)) != 0 ; 270 } else { 271 return ((fWhatToShow & (1 << node.getNodeType()-1)) != 0 ) 272 && fNodeFilter.acceptNode(node) == NodeFilter.FILTER_ACCEPT; 273 } 274 } 275 276 277 Node matchNodeOrParent(Node node) { 278 for (Node n = node; n != fRoot; n = n.getParentNode()) { 279 if (node == n) return n; 280 } 281 return null; 282 } 283 284 290 Node nextNode(Node node, boolean visitChildren) { 291 292 if (node == null) return fRoot; 293 294 Node result; 295 if (visitChildren) { 297 if (node.hasChildNodes()) { 299 result = node.getFirstChild(); 300 return result; 301 } 302 } 303 304 if (node == fRoot) { return null; 306 } 307 308 result = node.getNextSibling(); 310 if (result != null) return result; 311 312 313 Node parent = node.getParentNode(); 315 while (parent != null && parent != fRoot) { 316 result = parent.getNextSibling(); 317 if (result != null) { 318 return result; 319 } else { 320 parent = parent.getParentNode(); 321 } 322 323 } 325 return null; 327 } 328 329 332 Node previousNode(Node node) { 333 334 Node result; 335 336 if (node == fRoot) return null; 338 339 result = node.getPreviousSibling(); 341 if (result == null) { 342 result = node.getParentNode(); 344 return result; 345 } 346 347 if (result.hasChildNodes() 349 && !(!fEntityReferenceExpansion 350 && result != null 351 && result.getNodeType() == Node.ENTITY_REFERENCE_NODE)) 352 353 { 354 while (result.hasChildNodes()) { 355 result = result.getLastChild(); 356 } 357 } 358 359 return result; 360 } 361 362 365 public void removeNode(Node node) { 366 367 370 if (node == null) return; 371 372 Node deleted = matchNodeOrParent(node); 373 374 if (deleted == null) return; 375 376 if (fForward) { 377 fCurrentNode = previousNode(deleted); 378 } else 379 { 381 Node next = nextNode(deleted, false); 382 if (next!=null) { 383 fCurrentNode = next; 385 } else { 386 fCurrentNode = previousNode(deleted); 389 fForward = true; 390 } 391 392 } 393 394 } 395 396 public void detach() { 397 fDetach = true; 398 fDocument.removeNodeIterator(this); 399 } 400 401 } 402 | Popular Tags |