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
80
81
82 private List<T> createSubNodeList(final T node, final NodeTest test) {
83 if (test == null) {
84 return getNodeHandler().getChildren(node);
85 }
86 if (test instanceof NodeNameTest) {
87 final NodeNameTest nameTest = (NodeNameTest) test;
88 final QName name = nameTest.getNodeName();
89 return nameTest.isWildcard() ? createSubNodeListForWildcardName(node, name) : createSubNodeListForName(node, name);
90 }
91 if (test instanceof NodeTypeTest) {
92 final NodeTypeTest typeTest = (NodeTypeTest) test;
93 if (typeTest.getNodeType() == Compiler.NODE_TYPE_NODE || typeTest.getNodeType() == Compiler.NODE_TYPE_TEXT) {
94 return getNodeHandler().getChildren(node);
95 }
96 }
97
98 return Collections.emptyList();
99 }
100
101
102
103
104
105
106
107
108 private List<T> createSubNodeListForName(final T node, final QName name) {
109 final String compareName = qualifiedName(name);
110 final List<T> result = new ArrayList<>();
111 getNodeHandler().getChildren(node).forEach(child -> {
112 if (StringUtils.equals(compareName, getNodeHandler().nodeName(child))) {
113 result.add(child);
114 }
115 });
116 return result;
117 }
118
119
120
121
122
123
124
125
126 private List<T> createSubNodeListForWildcardName(final T node, final QName name) {
127 final List<T> children = getNodeHandler().getChildren(node);
128 if (name.getPrefix() == null) {
129 return children;
130 }
131 final List<T> prefixChildren = new ArrayList<>(children.size());
132 final String prefix = prefixName(name.getPrefix(), null);
133 children.forEach(child -> {
134 if (StringUtils.startsWith(getNodeHandler().nodeName(child), prefix)) {
135 prefixChildren.add(child);
136 }
137 });
138 return prefixChildren;
139 }
140
141
142
143
144
145
146
147
148
149 private int findStartIndex(final List<T> children, final T startNode) {
150 int index = 0;
151 for (final T child : children) {
152 if (child == startNode) {
153 return index;
154 }
155 index++;
156 }
157
158 return -1;
159 }
160
161
162
163
164
165
166 @Override
167 protected int size() {
168 return subNodes.size();
169 }
170
171 }