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