1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 1999-2002,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 package com.sun.org.apache.xerces.internal.dom; 22 23 import org.w3c.dom.DOMException; 24 import org.w3c.dom.Node; 25 import org.w3c.dom.traversal.NodeFilter; 26 import org.w3c.dom.traversal.TreeWalker; 27 28 /** This class implements the TreeWalker interface. 29 * 30 * @xerces.internal 31 * 32 */ 33 34 public class TreeWalkerImpl implements TreeWalker { 35 36 // 37 // Data 38 // 39 40 /** When TRUE, the children of entites references are returned in the iterator. */ 41 private boolean fEntityReferenceExpansion = false; 42 /** The whatToShow mask. */ 43 int fWhatToShow = NodeFilter.SHOW_ALL; 44 /** The NodeFilter reference. */ 45 NodeFilter fNodeFilter; 46 /** The current Node. */ 47 Node fCurrentNode; 48 /** The root Node. */ 49 Node fRoot; 50 51 // 52 // Implementation Note: No state is kept except the data above 53 // (fWhatToShow, fNodeFilter, fCurrentNode, fRoot) such that 54 // setters could be created for these data values and the 55 // implementation will still work. 56 57 58 // 59 // Constructor 60 // 61 62 /** Public constructor */ 63 public TreeWalkerImpl(Node root, 64 int whatToShow, 65 NodeFilter nodeFilter, 66 boolean entityReferenceExpansion) { 67 fCurrentNode = root; 68 fRoot = root; 69 fWhatToShow = whatToShow; 70 fNodeFilter = nodeFilter; 71 fEntityReferenceExpansion = entityReferenceExpansion; 72 } 73 74 public Node getRoot() { 75 return fRoot; 76 } 77 78 /** Return the whatToShow value */ 79 public int getWhatToShow() { 80 return fWhatToShow; 81 } 82 83 public void setWhatShow(int whatToShow){ 84 fWhatToShow = whatToShow; 85 } 86 /** Return the NodeFilter */ 87 public NodeFilter getFilter() { 88 return fNodeFilter; 89 } 90 91 /** Return whether children entity references are included in the iterator. */ 92 public boolean getExpandEntityReferences() { 93 return fEntityReferenceExpansion; 94 } 95 96 /** Return the current Node. */ 97 public Node getCurrentNode() { 98 return fCurrentNode; 99 } 100 /** Return the current Node. */ 101 public void setCurrentNode(Node node) { 102 if (node == null) { 103 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null); 104 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 105 } 106 107 fCurrentNode = node; 108 } 109 110 /** Return the parent Node from the current node, 111 * after applying filter, whatToshow. 112 * If result is not null, set the current Node. 113 */ 114 public Node parentNode() { 115 116 if (fCurrentNode == null) return null; 117 118 Node node = getParentNode(fCurrentNode); 119 if (node !=null) { 120 fCurrentNode = node; 121 } 122 return node; 123 124 } 125 126 /** Return the first child Node from the current node, 127 * after applying filter, whatToshow. 128 * If result is not null, set the current Node. 129 */ 130 public Node firstChild() { 131 132 if (fCurrentNode == null) return null; 133 134 Node node = getFirstChild(fCurrentNode); 135 if (node !=null) { 136 fCurrentNode = node; 137 } 138 return node; 139 } 140 /** Return the last child Node from the current node, 141 * after applying filter, whatToshow. 142 * If result is not null, set the current Node. 143 */ 144 public Node lastChild() { 145 146 if (fCurrentNode == null) return null; 147 148 Node node = getLastChild(fCurrentNode); 149 if (node !=null) { 150 fCurrentNode = node; 151 } 152 return node; 153 } 154 155 /** Return the previous sibling Node from the current node, 156 * after applying filter, whatToshow. 157 * If result is not null, set the current Node. 158 */ 159 public Node previousSibling() { 160 161 if (fCurrentNode == null) return null; 162 163 Node node = getPreviousSibling(fCurrentNode); 164 if (node !=null) { 165 fCurrentNode = node; 166 } 167 return node; 168 } 169 170 /** Return the next sibling Node from the current node, 171 * after applying filter, whatToshow. 172 * If result is not null, set the current Node. 173 */ 174 public Node nextSibling(){ 175 if (fCurrentNode == null) return null; 176 177 Node node = getNextSibling(fCurrentNode); 178 if (node !=null) { 179 fCurrentNode = node; 180 } 181 return node; 182 } 183 184 /** Return the previous Node from the current node, 185 * after applying filter, whatToshow. 186 * If result is not null, set the current Node. 187 */ 188 public Node previousNode() { 189 Node result; 190 191 if (fCurrentNode == null) return null; 192 193 // get sibling 194 result = getPreviousSibling(fCurrentNode); 195 if (result == null) { 196 result = getParentNode(fCurrentNode); 197 if (result != null) { 198 fCurrentNode = result; 199 return fCurrentNode; 200 } 201 return null; 202 } 203 204 // get the lastChild of result. 205 Node lastChild = getLastChild(result); 206 207 Node prev = lastChild ; 208 while (lastChild != null) { 209 prev = lastChild ; 210 lastChild = getLastChild(prev) ; 211 } 212 213 lastChild = prev ; 214 215 // if there is a lastChild which passes filters return it. 216 if (lastChild != null) { 217 fCurrentNode = lastChild; 218 return fCurrentNode; 219 } 220 221 // otherwise return the previous sibling. 222 if (result != null) { 223 fCurrentNode = result; 224 return fCurrentNode; 225 } 226 227 // otherwise return null. 228 return null; 229 } 230 231 /** Return the next Node from the current node, 232 * after applying filter, whatToshow. 233 * If result is not null, set the current Node. 234 */ 235 public Node nextNode() { 236 237 if (fCurrentNode == null) return null; 238 239 Node result = getFirstChild(fCurrentNode); 240 241 if (result != null) { 242 fCurrentNode = result; 243 return result; 244 } 245 246 result = getNextSibling(fCurrentNode); 247 248 if (result != null) { 249 fCurrentNode = result; 250 return result; 251 } 252 253 // return parent's 1st sibling. 254 Node parent = getParentNode(fCurrentNode); 255 while (parent != null) { 256 result = getNextSibling(parent); 257 if (result != null) { 258 fCurrentNode = result; 259 return result; 260 } else { 261 parent = getParentNode(parent); 262 } 263 } 264 265 // end , return null 266 return null; 267 } 268 269 /** Internal function. 270 * Return the parent Node, from the input node 271 * after applying filter, whatToshow. 272 * The current node is not consulted or set. 273 */ 274 Node getParentNode(Node node) { 275 276 if (node == null || node == fRoot) return null; 277 278 Node newNode = node.getParentNode(); 279 if (newNode == null) return null; 280 281 int accept = acceptNode(newNode); 282 283 if (accept == NodeFilter.FILTER_ACCEPT) 284 return newNode; 285 else 286 //if (accept == NodeFilter.SKIP_NODE) // and REJECT too. 287 { 288 return getParentNode(newNode); 289 } 290 291 292 } 293 294 /** Internal function. 295 * Return the nextSibling Node, from the input node 296 * after applying filter, whatToshow. 297 * The current node is not consulted or set. 298 */ 299 Node getNextSibling(Node node) { 300 return getNextSibling(node, fRoot); 301 } 302 303 /** Internal function. 304 * Return the nextSibling Node, from the input node 305 * after applying filter, whatToshow. 306 * NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE. 307 * The current node is not consulted or set. 308 */ 309 Node getNextSibling(Node node, Node root) { 310 311 if (node == null || node == root) return null; 312 313 Node newNode = node.getNextSibling(); 314 if (newNode == null) { 315 316 newNode = node.getParentNode(); 317 318 if (newNode == null || newNode == root) return null; 319 320 int parentAccept = acceptNode(newNode); 321 322 if (parentAccept==NodeFilter.FILTER_SKIP) { 323 return getNextSibling(newNode, root); 324 } 325 326 return null; 327 } 328 329 int accept = acceptNode(newNode); 330 331 if (accept == NodeFilter.FILTER_ACCEPT) 332 return newNode; 333 else 334 if (accept == NodeFilter.FILTER_SKIP) { 335 Node fChild = getFirstChild(newNode); 336 if (fChild == null) { 337 return getNextSibling(newNode, root); 338 } 339 return fChild; 340 } 341 else 342 //if (accept == NodeFilter.REJECT_NODE) 343 { 344 return getNextSibling(newNode, root); 345 } 346 347 } // getNextSibling(Node node) { 348 349 /** Internal function. 350 * Return the previous sibling Node, from the input node 351 * after applying filter, whatToshow. 352 * The current node is not consulted or set. 353 */ 354 Node getPreviousSibling(Node node) { 355 return getPreviousSibling(node, fRoot); 356 } 357 358 /** Internal function. 359 * Return the previousSibling Node, from the input node 360 * after applying filter, whatToshow. 361 * NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE. 362 * The current node is not consulted or set. 363 */ 364 Node getPreviousSibling(Node node, Node root) { 365 366 if (node == null || node == root) return null; 367 368 Node newNode = node.getPreviousSibling(); 369 if (newNode == null) { 370 371 newNode = node.getParentNode(); 372 if (newNode == null || newNode == root) return null; 373 374 int parentAccept = acceptNode(newNode); 375 376 if (parentAccept==NodeFilter.FILTER_SKIP) { 377 return getPreviousSibling(newNode, root); 378 } 379 380 return null; 381 } 382 383 int accept = acceptNode(newNode); 384 385 if (accept == NodeFilter.FILTER_ACCEPT) 386 return newNode; 387 else 388 if (accept == NodeFilter.FILTER_SKIP) { 389 Node fChild = getLastChild(newNode); 390 if (fChild == null) { 391 return getPreviousSibling(newNode, root); 392 } 393 return fChild; 394 } 395 else 396 //if (accept == NodeFilter.REJECT_NODE) 397 { 398 return getPreviousSibling(newNode, root); 399 } 400 401 } // getPreviousSibling(Node node) { 402 403 /** Internal function. 404 * Return the first child Node, from the input node 405 * after applying filter, whatToshow. 406 * The current node is not consulted or set. 407 */ 408 Node getFirstChild(Node node) { 409 if (node == null) return null; 410 411 if ( !fEntityReferenceExpansion 412 && node.getNodeType() == Node.ENTITY_REFERENCE_NODE) 413 return null; 414 Node newNode = node.getFirstChild(); 415 if (newNode == null) return null; 416 int accept = acceptNode(newNode); 417 418 if (accept == NodeFilter.FILTER_ACCEPT) 419 return newNode; 420 else 421 if (accept == NodeFilter.FILTER_SKIP 422 && newNode.hasChildNodes()) 423 { 424 Node fChild = getFirstChild(newNode); 425 426 if (fChild == null) { 427 return getNextSibling(newNode, node); 428 } 429 return fChild; 430 } 431 else 432 //if (accept == NodeFilter.REJECT_NODE) 433 { 434 return getNextSibling(newNode, node); 435 } 436 437 438 } 439 440 /** Internal function. 441 * Return the last child Node, from the input node 442 * after applying filter, whatToshow. 443 * The current node is not consulted or set. 444 */ 445 Node getLastChild(Node node) { 446 447 if (node == null) return null; 448 449 if ( !fEntityReferenceExpansion 450 && node.getNodeType() == Node.ENTITY_REFERENCE_NODE) 451 return null; 452 453 Node newNode = node.getLastChild(); 454 if (newNode == null) return null; 455 456 int accept = acceptNode(newNode); 457 458 if (accept == NodeFilter.FILTER_ACCEPT) 459 return newNode; 460 else 461 if (accept == NodeFilter.FILTER_SKIP 462 && newNode.hasChildNodes()) 463 { 464 Node lChild = getLastChild(newNode); 465 if (lChild == null) { 466 return getPreviousSibling(newNode, node); 467 } 468 return lChild; 469 } 470 else 471 //if (accept == NodeFilter.REJECT_NODE) 472 { 473 return getPreviousSibling(newNode, node); 474 } 475 476 477 } 478 479 /** Internal function. 480 * The node whatToShow and the filter are combined into one result. */ 481 short acceptNode(Node node) { 482 /*** 483 7.1.2.4. Filters and whatToShow flags 484 485 Iterator and TreeWalker apply whatToShow flags before applying Filters. If a node is rejected by the 486 active whatToShow flags, a Filter will not be called to evaluate that node. When a node is rejected by 487 the active whatToShow flags, children of that node will still be considered, and Filters may be called to 488 evaluate them. 489 ***/ 490 491 if (fNodeFilter == null) { 492 if ( ( fWhatToShow & (1 << node.getNodeType()-1)) != 0) { 493 return NodeFilter.FILTER_ACCEPT; 494 } else { 495 return NodeFilter.FILTER_SKIP; 496 } 497 } else { 498 if ((fWhatToShow & (1 << node.getNodeType()-1)) != 0 ) { 499 return fNodeFilter.acceptNode(node); 500 } else { 501 // What to show has failed. See above excerpt from spec. 502 // Equivalent to FILTER_SKIP. 503 return NodeFilter.FILTER_SKIP; 504 } 505 } 506 } 507 }