1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jxpath.ri.model.beans;
19
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import org.apache.commons.jxpath.JXPathException;
24 import org.apache.commons.jxpath.ri.model.NodeIterator;
25 import org.apache.commons.jxpath.ri.model.NodePointer;
26
27
28
29
30 public abstract class CollectionNodeIterator implements NodeIterator {
31
32 private final CollectionPointer pointer;
33 private final boolean reverse;
34 private final NodePointer startWith;
35 private int position;
36 private List<NodePointer> collection;
37
38
39
40
41
42
43
44
45 protected CollectionNodeIterator(final CollectionPointer pointer, final boolean reverse, final NodePointer startWith) {
46 this.pointer = pointer;
47 this.reverse = reverse;
48 this.startWith = startWith;
49 }
50
51
52
53
54
55
56
57 protected abstract NodeIterator getElementNodeIterator(NodePointer elementPointer);
58
59 @Override
60 public NodePointer getNodePointer() {
61 if (position == 0) {
62 return null;
63 }
64 return collection.get(position - 1);
65 }
66
67 @Override
68 public int getPosition() {
69 return position;
70 }
71
72
73
74
75 private void prepare() {
76 collection = new ArrayList<>();
77 final NodePointer ptr = (NodePointer) pointer.clone();
78 final int length = ptr.getLength();
79 for (int i = 0; i < length; i++) {
80 ptr.setIndex(i);
81 final NodePointer elementPointer = ptr.getValuePointer();
82 final NodeIterator iter = getElementNodeIterator(elementPointer);
83 for (int j = 1; iter.setPosition(j); j++) {
84 final NodePointer childPointer = iter.getNodePointer();
85 if (reverse) {
86 collection.add(0, childPointer);
87 } else {
88 collection.add(childPointer);
89 }
90 }
91 }
92 if (startWith != null) {
93 final int index = collection.indexOf(startWith);
94 if (index == -1) {
95 throw new JXPathException("Invalid starting pointer for iterator: " + startWith);
96 }
97 while (collection.size() > index) {
98 if (!reverse) {
99 collection.remove(collection.size() - 1);
100 } else {
101 collection.remove(0);
102 }
103 }
104 }
105 }
106
107 @Override
108 public boolean setPosition(final int position) {
109 if (collection == null) {
110 prepare();
111 }
112 if (position < 1 || position > collection.size()) {
113 return false;
114 }
115 this.position = position;
116 return true;
117 }
118 }