1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration;
18
19 import java.io.Reader;
20 import java.io.Writer;
21 import java.math.BigDecimal;
22 import java.math.BigInteger;
23 import java.util.Collection;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Properties;
27
28 import org.apache.commons.configuration.event.ConfigurationErrorListener;
29 import org.apache.commons.configuration.event.ConfigurationListener;
30 import org.apache.commons.configuration.tree.ConfigurationNode;
31 import org.apache.commons.configuration.tree.ExpressionEngine;
32
33
34
35
36
37
38
39
40
41
42
43 public class PatternSubtreeConfigurationWrapper extends AbstractHierarchicalFileConfiguration
44 {
45
46
47
48 private static ThreadLocal<Boolean> recursive = new ThreadLocal<Boolean>()
49 {
50 @Override
51 protected synchronized Boolean initialValue()
52 {
53 return Boolean.FALSE;
54 }
55 };
56
57
58 private final AbstractHierarchicalFileConfiguration config;
59
60
61 private final String path;
62
63
64 private final boolean trailing;
65
66
67 private boolean init;
68
69
70
71
72
73
74 public PatternSubtreeConfigurationWrapper(AbstractHierarchicalFileConfiguration config, String path)
75 {
76 this.config = config;
77 this.path = path;
78 this.trailing = path.endsWith("/");
79 this.init = true;
80 }
81
82 @Override
83 public Object getReloadLock()
84 {
85 return config.getReloadLock();
86 }
87
88 @Override
89 public void addProperty(String key, Object value)
90 {
91 config.addProperty(makePath(key), value);
92 }
93
94 @Override
95 public void clear()
96 {
97 getConfig().clear();
98 }
99
100 @Override
101 public void clearProperty(String key)
102 {
103 config.clearProperty(makePath(key));
104 }
105
106 @Override
107 public boolean containsKey(String key)
108 {
109 return config.containsKey(makePath(key));
110 }
111
112 @Override
113 public BigDecimal getBigDecimal(String key, BigDecimal defaultValue)
114 {
115 return config.getBigDecimal(makePath(key), defaultValue);
116 }
117
118 @Override
119 public BigDecimal getBigDecimal(String key)
120 {
121 return config.getBigDecimal(makePath(key));
122 }
123
124 @Override
125 public BigInteger getBigInteger(String key, BigInteger defaultValue)
126 {
127 return config.getBigInteger(makePath(key), defaultValue);
128 }
129
130 @Override
131 public BigInteger getBigInteger(String key)
132 {
133 return config.getBigInteger(makePath(key));
134 }
135
136 @Override
137 public boolean getBoolean(String key, boolean defaultValue)
138 {
139 return config.getBoolean(makePath(key), defaultValue);
140 }
141
142 @Override
143 public Boolean getBoolean(String key, Boolean defaultValue)
144 {
145 return config.getBoolean(makePath(key), defaultValue);
146 }
147
148 @Override
149 public boolean getBoolean(String key)
150 {
151 return config.getBoolean(makePath(key));
152 }
153
154 @Override
155 public byte getByte(String key, byte defaultValue)
156 {
157 return config.getByte(makePath(key), defaultValue);
158 }
159
160 @Override
161 public Byte getByte(String key, Byte defaultValue)
162 {
163 return config.getByte(makePath(key), defaultValue);
164 }
165
166 @Override
167 public byte getByte(String key)
168 {
169 return config.getByte(makePath(key));
170 }
171
172 @Override
173 public double getDouble(String key, double defaultValue)
174 {
175 return config.getDouble(makePath(key), defaultValue);
176 }
177
178 @Override
179 public Double getDouble(String key, Double defaultValue)
180 {
181 return config.getDouble(makePath(key), defaultValue);
182 }
183
184 @Override
185 public double getDouble(String key)
186 {
187 return config.getDouble(makePath(key));
188 }
189
190 @Override
191 public float getFloat(String key, float defaultValue)
192 {
193 return config.getFloat(makePath(key), defaultValue);
194 }
195
196 @Override
197 public Float getFloat(String key, Float defaultValue)
198 {
199 return config.getFloat(makePath(key), defaultValue);
200 }
201
202 @Override
203 public float getFloat(String key)
204 {
205 return config.getFloat(makePath(key));
206 }
207
208 @Override
209 public int getInt(String key, int defaultValue)
210 {
211 return config.getInt(makePath(key), defaultValue);
212 }
213
214 @Override
215 public int getInt(String key)
216 {
217 return config.getInt(makePath(key));
218 }
219
220 @Override
221 public Integer getInteger(String key, Integer defaultValue)
222 {
223 return config.getInteger(makePath(key), defaultValue);
224 }
225
226 @Override
227 public Iterator<String> getKeys()
228 {
229 return config.getKeys(makePath());
230 }
231
232 @Override
233 public Iterator<String> getKeys(String prefix)
234 {
235 return config.getKeys(makePath(prefix));
236 }
237
238 @Override
239 public List<Object> getList(String key, List<Object> defaultValue)
240 {
241 return config.getList(makePath(key), defaultValue);
242 }
243
244 @Override
245 public List<Object> getList(String key)
246 {
247 return config.getList(makePath(key));
248 }
249
250 @Override
251 public long getLong(String key, long defaultValue)
252 {
253 return config.getLong(makePath(key), defaultValue);
254 }
255
256 @Override
257 public Long getLong(String key, Long defaultValue)
258 {
259 return config.getLong(makePath(key), defaultValue);
260 }
261
262 @Override
263 public long getLong(String key)
264 {
265 return config.getLong(makePath(key));
266 }
267
268 @Override
269 public Properties getProperties(String key)
270 {
271 return config.getProperties(makePath(key));
272 }
273
274 @Override
275 public Object getProperty(String key)
276 {
277 return config.getProperty(makePath(key));
278 }
279
280 @Override
281 public short getShort(String key, short defaultValue)
282 {
283 return config.getShort(makePath(key), defaultValue);
284 }
285
286 @Override
287 public Short getShort(String key, Short defaultValue)
288 {
289 return config.getShort(makePath(key), defaultValue);
290 }
291
292 @Override
293 public short getShort(String key)
294 {
295 return config.getShort(makePath(key));
296 }
297
298 @Override
299 public String getString(String key, String defaultValue)
300 {
301 return config.getString(makePath(key), defaultValue);
302 }
303
304 @Override
305 public String getString(String key)
306 {
307 return config.getString(makePath(key));
308 }
309
310 @Override
311 public String[] getStringArray(String key)
312 {
313 return config.getStringArray(makePath(key));
314 }
315
316 @Override
317 public boolean isEmpty()
318 {
319 return getConfig().isEmpty();
320 }
321
322 @Override
323 public void setProperty(String key, Object value)
324 {
325 getConfig().setProperty(key, value);
326 }
327
328 @Override
329 public Configuration subset(String prefix)
330 {
331 return getConfig().subset(prefix);
332 }
333
334 @Override
335 public Node getRoot()
336 {
337 return getConfig().getRoot();
338 }
339
340 @Override
341 public void setRoot(Node node)
342 {
343 if (init)
344 {
345 getConfig().setRoot(node);
346 }
347 else
348 {
349 super.setRoot(node);
350 }
351 }
352
353 @Override
354 public ConfigurationNode getRootNode()
355 {
356 return getConfig().getRootNode();
357 }
358
359 @Override
360 public void setRootNode(ConfigurationNode rootNode)
361 {
362 if (init)
363 {
364 getConfig().setRootNode(rootNode);
365 }
366 else
367 {
368 super.setRootNode(rootNode);
369 }
370 }
371
372 @Override
373 public ExpressionEngine getExpressionEngine()
374 {
375 return config.getExpressionEngine();
376 }
377
378 @Override
379 public void setExpressionEngine(ExpressionEngine expressionEngine)
380 {
381 if (init)
382 {
383 config.setExpressionEngine(expressionEngine);
384 }
385 else
386 {
387 super.setExpressionEngine(expressionEngine);
388 }
389 }
390
391 @Override
392 public void addNodes(String key, Collection<? extends ConfigurationNode> nodes)
393 {
394 getConfig().addNodes(key, nodes);
395 }
396
397 @Override
398 public SubnodeConfiguration configurationAt(String key, boolean supportUpdates)
399 {
400 return config.configurationAt(makePath(key), supportUpdates);
401 }
402
403 @Override
404 public SubnodeConfiguration configurationAt(String key)
405 {
406 return config.configurationAt(makePath(key));
407 }
408
409 @Override
410 public List<HierarchicalConfiguration> configurationsAt(String key)
411 {
412 return config.configurationsAt(makePath(key));
413 }
414
415 @Override
416 public void clearTree(String key)
417 {
418 config.clearTree(makePath(key));
419 }
420
421 @Override
422 public int getMaxIndex(String key)
423 {
424 return config.getMaxIndex(makePath(key));
425 }
426
427 @Override
428 public Configuration interpolatedConfiguration()
429 {
430 return getConfig().interpolatedConfiguration();
431 }
432
433 @Override
434 public void addConfigurationListener(ConfigurationListener l)
435 {
436 getConfig().addConfigurationListener(l);
437 }
438
439 @Override
440 public boolean removeConfigurationListener(ConfigurationListener l)
441 {
442 return getConfig().removeConfigurationListener(l);
443 }
444
445 @Override
446 public Collection<ConfigurationListener> getConfigurationListeners()
447 {
448 return getConfig().getConfigurationListeners();
449 }
450
451 @Override
452 public void clearConfigurationListeners()
453 {
454 getConfig().clearConfigurationListeners();
455 }
456
457 @Override
458 public void addErrorListener(ConfigurationErrorListener l)
459 {
460 getConfig().addErrorListener(l);
461 }
462
463 @Override
464 public boolean removeErrorListener(ConfigurationErrorListener l)
465 {
466 return getConfig().removeErrorListener(l);
467 }
468
469 @Override
470 public void clearErrorListeners()
471 {
472 getConfig().clearErrorListeners();
473 }
474
475 public void save(Writer writer) throws ConfigurationException
476 {
477 config.save(writer);
478 }
479
480 public void load(Reader reader) throws ConfigurationException
481 {
482 config.load(reader);
483 }
484
485 @Override
486 public Collection<ConfigurationErrorListener> getErrorListeners()
487 {
488 return getConfig().getErrorListeners();
489 }
490
491 @Override
492 protected Object resolveContainerStore(String key)
493 {
494 if (recursive.get().booleanValue())
495 {
496 return null;
497 }
498 recursive.set(Boolean.TRUE);
499 try
500 {
501 return super.resolveContainerStore(key);
502 }
503 finally
504 {
505 recursive.set(Boolean.FALSE);
506 }
507 }
508
509 private HierarchicalConfiguration getConfig()
510 {
511 return config.configurationAt(makePath());
512 }
513
514 private String makePath()
515 {
516 String pathPattern = trailing ? path.substring(0, path.length() - 1) : path;
517 return getSubstitutor().replace(pathPattern);
518 }
519
520
521
522
523
524 private String makePath(String item)
525 {
526 String pathPattern;
527 if ((item.length() == 0 || item.startsWith("/")) && trailing)
528 {
529 pathPattern = path.substring(0, path.length() - 1);
530 }
531 else if (!item.startsWith("/") || !trailing)
532 {
533 pathPattern = path + "/";
534 }
535 else
536 {
537 pathPattern = path;
538 }
539 return getSubstitutor().replace(pathPattern) + item;
540 }
541 }