1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.jxpath.ri.model.dom;
  17. import org.apache.commons.jxpath.ri.compiler.NodeTest;
  18. import org.apache.commons.jxpath.ri.model.NodeIterator;
  19. import org.apache.commons.jxpath.ri.model.NodePointer;
  20. import org.w3c.dom.Node;
  21. /**
  22. * An iterator of children of a DOM Node.
  23. *
  24. * @author Dmitri Plotnikov
  25. * @version $Revision: 1.11 $ $Date: 2004/04/01 02:55:32 $
  26. */
  27. public class DOMNodeIterator implements NodeIterator {
  28. private NodePointer parent;
  29. private NodeTest nodeTest;
  30. private Node node;
  31. private Node child = null;
  32. private boolean reverse;
  33. private int position = 0;
  34. public DOMNodeIterator(
  35. NodePointer parent,
  36. NodeTest nodeTest,
  37. boolean reverse,
  38. NodePointer startWith)
  39. {
  40. this.parent = parent;
  41. this.node = (Node) parent.getNode();
  42. if (startWith != null) {
  43. this.child = (Node) startWith.getNode();
  44. }
  45. this.nodeTest = nodeTest;
  46. this.reverse = reverse;
  47. }
  48. public NodePointer getNodePointer() {
  49. if (position == 0) {
  50. setPosition(1);
  51. }
  52. if (child == null) {
  53. return null;
  54. }
  55. return new DOMNodePointer(parent, child);
  56. }
  57. public int getPosition() {
  58. return position;
  59. }
  60. public boolean setPosition(int position) {
  61. while (this.position < position) {
  62. if (!next()) {
  63. return false;
  64. }
  65. }
  66. while (this.position > position) {
  67. if (!previous()) {
  68. return false;
  69. }
  70. }
  71. return true;
  72. }
  73. private boolean previous() {
  74. position--;
  75. if (!reverse) {
  76. if (position == 0) {
  77. child = null;
  78. }
  79. else if (child == null) {
  80. child = node.getLastChild();
  81. }
  82. else {
  83. child = child.getPreviousSibling();
  84. }
  85. while (child != null && !testChild()) {
  86. child = child.getPreviousSibling();
  87. }
  88. }
  89. else {
  90. child = child.getNextSibling();
  91. while (child != null && !testChild()) {
  92. child = child.getNextSibling();
  93. }
  94. }
  95. return child != null;
  96. }
  97. private boolean next() {
  98. position++;
  99. if (!reverse) {
  100. if (position == 1) {
  101. if (child == null) {
  102. child = node.getFirstChild();
  103. }
  104. else {
  105. child = child.getNextSibling();
  106. }
  107. }
  108. else {
  109. child = child.getNextSibling();
  110. }
  111. while (child != null && !testChild()) {
  112. child = child.getNextSibling();
  113. }
  114. }
  115. else {
  116. if (position == 1) {
  117. if (child == null) {
  118. child = node.getLastChild();
  119. }
  120. else {
  121. child = child.getPreviousSibling();
  122. }
  123. }
  124. else {
  125. child = child.getPreviousSibling();
  126. }
  127. while (child != null && !testChild()) {
  128. child = child.getPreviousSibling();
  129. }
  130. }
  131. return child != null;
  132. }
  133. private boolean testChild() {
  134. return DOMNodePointer.testNode(child, nodeTest);
  135. }
  136. }