1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration2.tree.xpath;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.apache.commons.jxpath.ri.Compiler;
24 import org.apache.commons.jxpath.ri.QName;
25 import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
26 import org.apache.commons.jxpath.ri.compiler.NodeTest;
27 import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
28 import org.apache.commons.jxpath.ri.model.NodePointer;
29 import org.apache.commons.lang3.StringUtils;
30
31
32
33
34
35
36
37 final class ConfigurationNodeIteratorChildren<T> extends AbstractConfigurationNodeIterator<T> {
38
39
40 private final List<T> subNodes;
41
42
43
44
45
46
47
48
49
50 public ConfigurationNodeIteratorChildren(final ConfigurationNodePointer<T> parent, final NodeTest nodeTest, final boolean reverse,
51 final ConfigurationNodePointer<T> startsWith) {
52 super(parent, reverse);
53 final T root = parent.getConfigurationNode();
54 subNodes = createSubNodeList(root, nodeTest);
55
56 if (startsWith != null) {
57 setStartOffset(findStartIndex(subNodes, startsWith.getConfigurationNode()));
58 } else if (reverse) {
59 setStartOffset(size());
60 }
61 }
62
63
64
65
66
67
68
69 @Override
70 protected NodePointer createNodePointer(final int position) {
71 return new ConfigurationNodePointer<>(getParent(), subNodes.get(position), getNodeHandler());
72 }
73
74
75
76
77
78
79 @Override
80 protected int size() {
81 return subNodes.size();
82 }
83
84
85
86
87
88
89
90
91
92 private List<T> createSubNodeList(final T node, final NodeTest test) {
93 if (test == null) {
94 return getNodeHandler().getChildren(node);
95 }
96 if (test instanceof NodeNameTest) {
97 final NodeNameTest nameTest = (NodeNameTest) test;
98 final QName name = nameTest.getNodeName();
99 return nameTest.isWildcard() ? createSubNodeListForWildcardName(node, name) : createSubNodeListForName(node, name);
100 }
101 if (test instanceof NodeTypeTest) {
102 final NodeTypeTest typeTest = (NodeTypeTest) test;
103 if (typeTest.getNodeType() == Compiler.NODE_TYPE_NODE || typeTest.getNodeType() == Compiler.NODE_TYPE_TEXT) {
104 return getNodeHandler().getChildren(node);
105 }
106 }
107
108 return Collections.emptyList();
109 }
110
111
112
113
114
115
116
117
118 private List<T> createSubNodeListForName(final T node, final QName name) {
119 final String compareName = qualifiedName(name);
120 final List<T> result = new ArrayList<>();
121 getNodeHandler().getChildren(node).forEach(child -> {
122 if (StringUtils.equals(compareName, getNodeHandler().nodeName(child))) {
123 result.add(child);
124 }
125 });
126 return result;
127 }
128
129
130
131
132
133
134
135
136 private List<T> createSubNodeListForWildcardName(final T node, final QName name) {
137 final List<T> children = getNodeHandler().getChildren(node);
138 if (name.getPrefix() == null) {
139 return children;
140 }
141 final List<T> prefixChildren = new ArrayList<>(children.size());
142 final String prefix = prefixName(name.getPrefix(), null);
143 children.forEach(child -> {
144 if (StringUtils.startsWith(getNodeHandler().nodeName(child), prefix)) {
145 prefixChildren.add(child);
146 }
147 });
148 return prefixChildren;
149 }
150
151
152
153
154
155
156
157
158
159 private int findStartIndex(final List<T> children, final T startNode) {
160 int index = 0;
161 for (final T child : children) {
162 if (child == startNode) {
163 return index;
164 }
165 index++;
166 }
167
168 return -1;
169 }
170
171 }