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.ArrayList;
20 import java.util.Collections;
21 import java.util.Iterator;
22 import java.util.List;
23
24 import org.apache.commons.configuration.tree.ConfigurationNode;
25 import org.apache.commons.jxpath.ri.Compiler;
26 import org.apache.commons.jxpath.ri.QName;
27 import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
28 import org.apache.commons.jxpath.ri.compiler.NodeTest;
29 import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
30 import org.apache.commons.jxpath.ri.model.NodePointer;
31 import org.apache.commons.lang.StringUtils;
32
33 /***
34 * A specialized iterator implementation for the child nodes of a configuration
35 * node.
36 *
37 * @since 1.3
38 * @author Oliver Heger
39 * @version $Id: ConfigurationNodeIteratorChildren.java 439648 2006-09-02 20:42:10Z oheger $
40 */
41 class ConfigurationNodeIteratorChildren extends ConfigurationNodeIteratorBase
42 {
43 /***
44 * Creates a new instance of <code>ConfigurationNodeIteratorChildren</code>
45 * and initializes it.
46 *
47 * @param parent the parent pointer
48 * @param nodeTest the test selecting the sub nodes
49 * @param reverse the reverse flag
50 * @param startsWith the first element of the iteration
51 */
52 public ConfigurationNodeIteratorChildren(NodePointer parent,
53 NodeTest nodeTest, boolean reverse, NodePointer startsWith)
54 {
55 super(parent, reverse);
56 ConfigurationNode root = (ConfigurationNode) parent.getNode();
57 List childNodes = createSubNodeList(root, nodeTest);
58 initSubNodeList(childNodes);
59 if (startsWith != null)
60 {
61 setStartOffset(findStartIndex(root,
62 (ConfigurationNode) startsWith.getNode()));
63 }
64 }
65
66 /***
67 * Creates the list with sub nodes. This method gets called during
68 * initialization phase. It finds out, based on the given test, which nodes
69 * must be iterated over.
70 *
71 * @param node the current node
72 * @param test the test object
73 * @return a list with the matching nodes
74 */
75 protected List createSubNodeList(ConfigurationNode node, NodeTest test)
76 {
77 List children = node.getChildren();
78
79 if (test == null)
80 {
81 return children;
82 }
83 else
84 {
85 if (test instanceof NodeNameTest)
86 {
87 NodeNameTest nameTest = (NodeNameTest) test;
88 QName name = nameTest.getNodeName();
89 if (name.getPrefix() == null)
90 {
91 if (nameTest.isWildcard())
92 {
93 return children;
94 }
95
96 List result = new ArrayList();
97 for (Iterator it = children.iterator(); it.hasNext();)
98 {
99 ConfigurationNode child = (ConfigurationNode) it.next();
100 if (StringUtils.equals(name.getName(), child.getName()))
101 {
102 result.add(child);
103 }
104 }
105 return result;
106 }
107 }
108
109 else if (test instanceof NodeTypeTest)
110 {
111 NodeTypeTest typeTest = (NodeTypeTest) test;
112 if (typeTest.getNodeType() == Compiler.NODE_TYPE_NODE
113 || typeTest.getNodeType() == Compiler.NODE_TYPE_TEXT)
114 {
115 return children;
116 }
117 }
118 }
119
120 return Collections.EMPTY_LIST;
121 }
122
123 /***
124 * Determines the start position of the iteration. Finds the index of the
125 * given start node in the children of the root node.
126 *
127 * @param node the root node
128 * @param startNode the start node
129 * @return the start node's index
130 */
131 protected int findStartIndex(ConfigurationNode node,
132 ConfigurationNode startNode)
133 {
134 for (int index = 0; index < node.getChildrenCount(); index++)
135 {
136 if (node.getChild(index) == startNode)
137 {
138 return index;
139 }
140 }
141
142 return -1;
143 }
144 }