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 * Wraps a HierarchicalConfiguration and allows subtrees to be access via a configured path with
35 * replaceable tokens derived from the ConfigurationInterpolator. When used with injection frameworks
36 * such as Spring it allows components to be injected with subtrees of the configuration.
37 * @since 1.6
38 * @author <a
39 * href="http://commons.apache.org/configuration/team-list.html">Commons
40 * Configuration team</a>
41 * @version $Id: PatternSubtreeConfigurationWrapper.java 727958 2008-12-19 07:19:24Z oheger $
42 */
43 public class PatternSubtreeConfigurationWrapper extends AbstractHierarchicalFileConfiguration
44 {
45 /***
46 * Prevent recursion while resolving unprefixed properties.
47 */
48 private static ThreadLocal recursive = new ThreadLocal()
49 {
50 protected synchronized Object initialValue()
51 {
52 return Boolean.FALSE;
53 }
54 };
55
56 /*** The wrapped configuration */
57 private final AbstractHierarchicalFileConfiguration config;
58
59 /*** The path to the subtree */
60 private final String path;
61
62 /*** True if the path ends with '/', false otherwise */
63 private final boolean trailing;
64
65 /*** True if the constructor has finished */
66 private boolean init;
67
68 /***
69 * Constructor
70 * @param config The Configuration to be wrapped.
71 * @param path The base path pattern.
72 */
73 public PatternSubtreeConfigurationWrapper(AbstractHierarchicalFileConfiguration config, String path)
74 {
75 this.config = config;
76 this.path = path;
77 this.trailing = path.endsWith("/");
78 this.init = true;
79 }
80
81 public void addProperty(String key, Object value)
82 {
83 config.addProperty(makePath(key), value);
84 }
85
86 public void clear()
87 {
88 getConfig().clear();
89 }
90
91 public void clearProperty(String key)
92 {
93 config.clearProperty(makePath(key));
94 }
95
96 public boolean containsKey(String key)
97 {
98 return config.containsKey(makePath(key));
99 }
100
101 public BigDecimal getBigDecimal(String key, BigDecimal defaultValue)
102 {
103 return config.getBigDecimal(makePath(key), defaultValue);
104 }
105
106 public BigDecimal getBigDecimal(String key)
107 {
108 return config.getBigDecimal(makePath(key));
109 }
110
111 public BigInteger getBigInteger(String key, BigInteger defaultValue)
112 {
113 return config.getBigInteger(makePath(key), defaultValue);
114 }
115
116 public BigInteger getBigInteger(String key)
117 {
118 return config.getBigInteger(makePath(key));
119 }
120
121 public boolean getBoolean(String key, boolean defaultValue)
122 {
123 return config.getBoolean(makePath(key), defaultValue);
124 }
125
126 public Boolean getBoolean(String key, Boolean defaultValue)
127 {
128 return config.getBoolean(makePath(key), defaultValue);
129 }
130
131 public boolean getBoolean(String key)
132 {
133 return config.getBoolean(makePath(key));
134 }
135
136 public byte getByte(String key, byte defaultValue)
137 {
138 return config.getByte(makePath(key), defaultValue);
139 }
140
141 public Byte getByte(String key, Byte defaultValue)
142 {
143 return config.getByte(makePath(key), defaultValue);
144 }
145
146 public byte getByte(String key)
147 {
148 return config.getByte(makePath(key));
149 }
150
151 public double getDouble(String key, double defaultValue)
152 {
153 return config.getDouble(makePath(key), defaultValue);
154 }
155
156 public Double getDouble(String key, Double defaultValue)
157 {
158 return config.getDouble(makePath(key), defaultValue);
159 }
160
161 public double getDouble(String key)
162 {
163 return config.getDouble(makePath(key));
164 }
165
166 public float getFloat(String key, float defaultValue)
167 {
168 return config.getFloat(makePath(key), defaultValue);
169 }
170
171 public Float getFloat(String key, Float defaultValue)
172 {
173 return config.getFloat(makePath(key), defaultValue);
174 }
175
176 public float getFloat(String key)
177 {
178 return config.getFloat(makePath(key));
179 }
180
181 public int getInt(String key, int defaultValue)
182 {
183 return config.getInt(makePath(key), defaultValue);
184 }
185
186 public int getInt(String key)
187 {
188 return config.getInt(makePath(key));
189 }
190
191 public Integer getInteger(String key, Integer defaultValue)
192 {
193 return config.getInteger(makePath(key), defaultValue);
194 }
195
196 public Iterator getKeys()
197 {
198 return config.getKeys(makePath());
199 }
200
201 public Iterator getKeys(String prefix)
202 {
203 return config.getKeys(makePath(prefix));
204 }
205
206 public List getList(String key, List defaultValue)
207 {
208 return config.getList(makePath(key), defaultValue);
209 }
210
211 public List getList(String key)
212 {
213 return config.getList(makePath(key));
214 }
215
216 public long getLong(String key, long defaultValue)
217 {
218 return config.getLong(makePath(key), defaultValue);
219 }
220
221 public Long getLong(String key, Long defaultValue)
222 {
223 return config.getLong(makePath(key), defaultValue);
224 }
225
226 public long getLong(String key)
227 {
228 return config.getLong(makePath(key));
229 }
230
231 public Properties getProperties(String key)
232 {
233 return config.getProperties(makePath(key));
234 }
235
236 public Object getProperty(String key)
237 {
238 return config.getProperty(makePath(key));
239 }
240
241 public short getShort(String key, short defaultValue)
242 {
243 return config.getShort(makePath(key), defaultValue);
244 }
245
246 public Short getShort(String key, Short defaultValue)
247 {
248 return config.getShort(makePath(key), defaultValue);
249 }
250
251 public short getShort(String key)
252 {
253 return config.getShort(makePath(key));
254 }
255
256 public String getString(String key, String defaultValue)
257 {
258 return config.getString(makePath(key), defaultValue);
259 }
260
261 public String getString(String key)
262 {
263 return config.getString(makePath(key));
264 }
265
266 public String[] getStringArray(String key)
267 {
268 return config.getStringArray(makePath(key));
269 }
270
271 public boolean isEmpty()
272 {
273 return getConfig().isEmpty();
274 }
275
276 public void setProperty(String key, Object value)
277 {
278 getConfig().setProperty(key, value);
279 }
280
281 public Configuration subset(String prefix)
282 {
283 return getConfig().subset(prefix);
284 }
285
286 public Node getRoot()
287 {
288 return getConfig().getRoot();
289 }
290
291 public void setRoot(Node node)
292 {
293 if (init)
294 {
295 getConfig().setRoot(node);
296 }
297 else
298 {
299 super.setRoot(node);
300 }
301 }
302
303 public ConfigurationNode getRootNode()
304 {
305 return getConfig().getRootNode();
306 }
307
308 public void setRootNode(ConfigurationNode rootNode)
309 {
310 if (init)
311 {
312 getConfig().setRootNode(rootNode);
313 }
314 else
315 {
316 super.setRootNode(rootNode);
317 }
318 }
319
320 public ExpressionEngine getExpressionEngine()
321 {
322 return config.getExpressionEngine();
323 }
324
325 public void setExpressionEngine(ExpressionEngine expressionEngine)
326 {
327 if (init)
328 {
329 config.setExpressionEngine(expressionEngine);
330 }
331 else
332 {
333 super.setExpressionEngine(expressionEngine);
334 }
335 }
336
337 public void addNodes(String key, Collection nodes)
338 {
339 getConfig().addNodes(key, nodes);
340 }
341
342 public SubnodeConfiguration configurationAt(String key, boolean supportUpdates)
343 {
344 return config.configurationAt(makePath(key), supportUpdates);
345 }
346
347 public SubnodeConfiguration configurationAt(String key)
348 {
349 return config.configurationAt(makePath(key));
350 }
351
352 public List configurationsAt(String key)
353 {
354 return config.configurationsAt(makePath(key));
355 }
356
357 public void clearTree(String key)
358 {
359 config.clearTree(makePath(key));
360 }
361
362 public int getMaxIndex(String key)
363 {
364 return config.getMaxIndex(makePath(key));
365 }
366
367 public Configuration interpolatedConfiguration()
368 {
369 return getConfig().interpolatedConfiguration();
370 }
371
372 public void addConfigurationListener(ConfigurationListener l)
373 {
374 getConfig().addConfigurationListener(l);
375 }
376
377 public boolean removeConfigurationListener(ConfigurationListener l)
378 {
379 return getConfig().removeConfigurationListener(l);
380 }
381
382 public Collection getConfigurationListeners()
383 {
384 return getConfig().getConfigurationListeners();
385 }
386
387 public void clearConfigurationListeners()
388 {
389 getConfig().clearConfigurationListeners();
390 }
391
392 public void addErrorListener(ConfigurationErrorListener l)
393 {
394 getConfig().addErrorListener(l);
395 }
396
397 public boolean removeErrorListener(ConfigurationErrorListener l)
398 {
399 return getConfig().removeErrorListener(l);
400 }
401
402 public void clearErrorListeners()
403 {
404 getConfig().clearErrorListeners();
405 }
406
407 public void save(Writer writer) throws ConfigurationException
408 {
409 config.save(writer);
410 }
411
412 public void load(Reader reader) throws ConfigurationException
413 {
414 config.load(reader);
415 }
416
417 public Collection getErrorListeners()
418 {
419 return getConfig().getErrorListeners();
420 }
421
422 protected Object resolveContainerStore(String key)
423 {
424 if (((Boolean) recursive.get()).booleanValue())
425 {
426 return null;
427 }
428 recursive.set(Boolean.TRUE);
429 try
430 {
431 return super.resolveContainerStore(key);
432 }
433 finally
434 {
435 recursive.set(Boolean.FALSE);
436 }
437 }
438
439 private HierarchicalConfiguration getConfig()
440 {
441 return config.configurationAt(makePath());
442 }
443
444 private String makePath()
445 {
446 String pathPattern = trailing ? path.substring(0, path.length() - 1) : path;
447 return getSubstitutor().replace(pathPattern);
448 }
449
450
451
452
453
454 private String makePath(String item)
455 {
456 String pathPattern;
457 if ((item.length() == 0 || item.startsWith("/")) && trailing)
458 {
459 pathPattern = path.substring(0, path.length() - 1);
460 }
461 else if (!item.startsWith("/") || !trailing)
462 {
463 pathPattern = path + "/";
464 }
465 else
466 {
467 pathPattern = path;
468 }
469 return getSubstitutor().replace(pathPattern) + item;
470 }
471 }