1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.configuration2;
19
20 import java.util.Iterator;
21 import java.util.Objects;
22
23 import org.apache.commons.configuration2.convert.ListDelimiterHandler;
24 import org.apache.commons.lang3.StringUtils;
25
26
27
28
29
30
31
32
33
34
35
36 public class SubsetConfiguration extends AbstractConfiguration {
37
38
39
40
41 private final class SubsetIterator implements Iterator<String> {
42
43 private final Iterator<String> parentIterator;
44
45
46
47
48
49
50 public SubsetIterator(final Iterator<String> it) {
51 parentIterator = it;
52 }
53
54
55
56
57
58
59 @Override
60 public boolean hasNext() {
61 return parentIterator.hasNext();
62 }
63
64
65
66
67
68
69
70 @Override
71 public String next() {
72 return getChildKey(parentIterator.next());
73 }
74
75
76
77
78 @Override
79 public void remove() {
80 parentIterator.remove();
81 }
82 }
83
84
85 protected Configuration parent;
86
87
88 protected String prefix;
89
90
91 protected String delimiter;
92
93
94
95
96
97
98
99
100 public SubsetConfiguration(final Configuration parent, final String prefix) {
101 this(parent, prefix, null);
102 }
103
104
105
106
107
108
109
110
111
112 public SubsetConfiguration(final Configuration parent, final String prefix, final String delimiter) {
113 this.parent = Objects.requireNonNull(parent, "parent");
114 this.prefix = prefix;
115 this.delimiter = delimiter;
116 initInterpolator();
117 }
118
119 @Override
120 public void addPropertyDirect(final String key, final Object value) {
121 parent.addProperty(getParentKey(key), value);
122 }
123
124 @Override
125 protected void clearPropertyDirect(final String key) {
126 parent.clearProperty(getParentKey(key));
127 }
128
129 @Override
130 protected boolean containsKeyInternal(final String key) {
131 return parent.containsKey(getParentKey(key));
132 }
133
134
135
136
137
138
139 @Override
140 protected boolean containsValueInternal(final Object value) {
141 return parent.containsValue(value);
142 }
143
144
145
146
147
148
149
150 protected String getChildKey(final String key) {
151 if (!key.startsWith(prefix)) {
152 throw new IllegalArgumentException("The parent key '" + key + "' is not in the subset.");
153 }
154 String modifiedKey = null;
155 if (key.length() == prefix.length()) {
156 modifiedKey = "";
157 } else {
158 final int i = prefix.length() + (delimiter != null ? delimiter.length() : 0);
159 modifiedKey = key.substring(i);
160 }
161
162 return modifiedKey;
163 }
164
165 @Override
166 protected Iterator<String> getKeysInternal() {
167 return new SubsetIterator(parent.getKeys(prefix, delimiter));
168 }
169
170 @Override
171 protected Iterator<String> getKeysInternal(final String prefix) {
172 return new SubsetIterator(parent.getKeys(getParentKey(prefix)));
173 }
174
175
176
177
178
179 @Override
180 public ListDelimiterHandler getListDelimiterHandler() {
181 return parent instanceof AbstractConfiguration ? ((AbstractConfiguration) parent).getListDelimiterHandler() : super.getListDelimiterHandler();
182 }
183
184
185
186
187
188
189 public Configuration getParent() {
190 return parent;
191 }
192
193
194
195
196
197
198
199 protected String getParentKey(final String key) {
200 if (StringUtils.isEmpty(key)) {
201 return prefix;
202 }
203 return delimiter == null ? prefix + key : prefix + delimiter + key;
204 }
205
206
207
208
209
210
211 public String getPrefix() {
212 return prefix;
213 }
214
215 @Override
216 protected Object getPropertyInternal(final String key) {
217 return parent.getProperty(getParentKey(key));
218 }
219
220
221
222
223
224
225 private void initInterpolator() {
226 getInterpolator().setParentInterpolator(getParent().getInterpolator());
227 }
228
229 @Override
230 protected boolean isEmptyInternal() {
231 return !getKeysInternal().hasNext();
232 }
233
234
235
236
237
238
239 @Override
240 public boolean isThrowExceptionOnMissing() {
241 if (parent instanceof AbstractConfiguration) {
242 return ((AbstractConfiguration) parent).isThrowExceptionOnMissing();
243 }
244 return super.isThrowExceptionOnMissing();
245 }
246
247
248
249
250
251 @Override
252 public void setListDelimiterHandler(final ListDelimiterHandler listDelimiterHandler) {
253 if (parent instanceof AbstractConfiguration) {
254 ((AbstractConfiguration) parent).setListDelimiterHandler(listDelimiterHandler);
255 } else {
256 super.setListDelimiterHandler(listDelimiterHandler);
257 }
258 }
259
260
261
262
263
264
265 public void setPrefix(final String prefix) {
266 this.prefix = prefix;
267 }
268
269
270
271
272
273
274 @Override
275 public void setThrowExceptionOnMissing(final boolean throwExceptionOnMissing) {
276 if (parent instanceof AbstractConfiguration) {
277 ((AbstractConfiguration) parent).setThrowExceptionOnMissing(throwExceptionOnMissing);
278 } else {
279 super.setThrowExceptionOnMissing(throwExceptionOnMissing);
280 }
281 }
282
283 @Override
284 public Configuration subset(final String prefix) {
285 return parent.subset(getParentKey(prefix));
286 }
287 }