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.beans;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import org.apache.commons.jxpath.JXPathException;
  20. import org.apache.commons.jxpath.ri.model.NodeIterator;
  21. import org.apache.commons.jxpath.ri.model.NodePointer;
  22. /**
  23. * Combines node iterators of all elements of a collection into one
  24. * aggregate node iterator.
  25. *
  26. * @author Dmitri Plotnikov
  27. * @version $Revision: 1.3 $ $Date: 2004/02/29 14:17:41 $
  28. */
  29. public abstract class CollectionNodeIterator implements NodeIterator {
  30. private CollectionPointer pointer;
  31. private boolean reverse;
  32. private NodePointer startWith;
  33. private int position;
  34. private List collection;
  35. protected CollectionNodeIterator(
  36. CollectionPointer pointer,
  37. boolean reverse,
  38. NodePointer startWith)
  39. {
  40. this.pointer = pointer;
  41. this.reverse = reverse;
  42. this.startWith = startWith;
  43. }
  44. /**
  45. * Implemened by subclasses to produce child/attribute node iterators.
  46. */
  47. protected abstract NodeIterator
  48. getElementNodeIterator(NodePointer elementPointer);
  49. public int getPosition() {
  50. return position;
  51. }
  52. public boolean setPosition(int position) {
  53. if (collection == null) {
  54. prepare();
  55. }
  56. if (position < 1 || position > collection.size()) {
  57. return false;
  58. }
  59. this.position = position;
  60. return true;
  61. }
  62. public NodePointer getNodePointer() {
  63. if (position == 0) {
  64. return null;
  65. }
  66. return (NodePointer) collection.get(position - 1);
  67. }
  68. private void prepare() {
  69. collection = new ArrayList();
  70. NodePointer ptr = (NodePointer) pointer.clone();
  71. int length = ptr.getLength();
  72. for (int i = 0; i < length; i++) {
  73. ptr.setIndex(i);
  74. NodePointer elementPointer = ptr.getValuePointer();
  75. NodeIterator iter = getElementNodeIterator(elementPointer);
  76. for (int j = 1; iter.setPosition(j); j++) {
  77. NodePointer childPointer = iter.getNodePointer();
  78. if (reverse) {
  79. collection.add(0, childPointer);
  80. }
  81. else {
  82. collection.add(childPointer);
  83. }
  84. }
  85. }
  86. if (startWith != null) {
  87. int index = collection.indexOf(startWith);
  88. if (index == -1) {
  89. throw new JXPathException(
  90. "Invalid starting pointer for iterator: " + startWith);
  91. }
  92. while (collection.size() > index) {
  93. if (!reverse) {
  94. collection.remove(collection.size() - 1);
  95. }
  96. else {
  97. collection.remove(0);
  98. }
  99. }
  100. }
  101. }
  102. }