1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration.tree.xpath;
18
19 import java.util.List;
20
21 import org.apache.commons.configuration.tree.ConfigurationNode;
22 import org.apache.commons.jxpath.ri.model.NodeIterator;
23 import org.apache.commons.jxpath.ri.model.NodePointer;
24
25 /***
26 * <p>
27 * A base class for implementing iterators over configuration nodes.
28 * </p>
29 * <p>
30 * This class already provides common functionality for implementing the
31 * iteration process. Derived classes will implement specific behavior based on
32 * the concrete node type (child node or attribute node).
33 * </p>
34 *
35 * @since 1.3
36 * @author Oliver Heger
37 * @version $Id: ConfigurationNodeIteratorBase.java 439648 2006-09-02 20:42:10Z oheger $
38 */
39 abstract class ConfigurationNodeIteratorBase implements NodeIterator
40 {
41 /*** Stores the parent node pointer. */
42 private NodePointer parent;
43
44 /*** Stores the list with the sub nodes. */
45 private List subNodes;
46
47 /*** Stores the current position. */
48 private int position;
49
50 /*** Stores the start offset of the iterator. */
51 private int startOffset;
52
53 /*** Stores the reverse flag. */
54 private boolean reverse;
55
56 /***
57 * Creates a new instance of <code>ConfigurationNodeIteratorBase</code>
58 * and initializes it.
59 *
60 * @param parent the parent pointer
61 * @param reverse the reverse flag
62 */
63 protected ConfigurationNodeIteratorBase(NodePointer parent, boolean reverse)
64 {
65 this.parent = parent;
66 this.reverse = reverse;
67 }
68
69 /***
70 * Returns the position of the iteration.
71 *
72 * @return the position
73 */
74 public int getPosition()
75 {
76 return position;
77 }
78
79 /***
80 * Sets the position of the iteration.
81 *
82 * @param pos the new position
83 * @return a flag if this is a valid position
84 */
85 public boolean setPosition(int pos)
86 {
87 position = pos;
88 return pos >= 1 && pos <= getMaxPosition();
89 }
90
91 /***
92 * Returns the current node pointer.
93 *
94 * @return the current pointer in this iteration
95 */
96 public NodePointer getNodePointer()
97 {
98 if (getPosition() < 1 && !setPosition(1))
99 {
100 return null;
101 }
102
103 return createNodePointer((ConfigurationNode) subNodes
104 .get(positionToIndex(getPosition())));
105 }
106
107 /***
108 * Returns the parent node pointer.
109 *
110 * @return the parent node pointer
111 */
112 protected NodePointer getParent()
113 {
114 return parent;
115 }
116
117 /***
118 * Returns the start offset of the iteration.
119 *
120 * @return the start offset
121 */
122 protected int getStartOffset()
123 {
124 return startOffset;
125 }
126
127 /***
128 * Sets the start offset of the iteration. This is used when a start element
129 * was set.
130 *
131 * @param startOffset the start offset
132 */
133 protected void setStartOffset(int startOffset)
134 {
135 this.startOffset = startOffset;
136 if (reverse)
137 {
138 this.startOffset--;
139 }
140 else
141 {
142 this.startOffset++;
143 }
144 }
145
146 /***
147 * Initializes the list of sub nodes for the iteration. This method must be
148 * called during initialization phase.
149 *
150 * @param nodes the list with the sub nodes
151 */
152 protected void initSubNodeList(List nodes)
153 {
154 subNodes = nodes;
155 if (reverse)
156 {
157 setStartOffset(subNodes.size());
158 }
159 }
160
161 /***
162 * Returns the maximum position for this iterator.
163 *
164 * @return the maximum allowed position
165 */
166 protected int getMaxPosition()
167 {
168 return reverse ? getStartOffset() + 1 : subNodes.size()
169 - getStartOffset();
170 }
171
172 /***
173 * Creates the configuration node pointer for the current position. This
174 * method is called by <code>getNodePointer()</code>. Derived classes
175 * must create the correct pointer object.
176 *
177 * @param node the current configuration node
178 * @return the node pointer
179 */
180 protected NodePointer createNodePointer(ConfigurationNode node)
181 {
182 return new ConfigurationNodePointer(getParent(), node);
183 }
184
185 /***
186 * Returns the index in the data list for the given position. This method
187 * also checks the reverse flag.
188 *
189 * @param pos the position (1-based)
190 * @return the corresponding list index
191 */
192 protected int positionToIndex(int pos)
193 {
194 return (reverse ? 1 - pos : pos - 1) + getStartOffset();
195 }
196 }