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.File; |
20 | |
import java.io.FileNotFoundException; |
21 | |
import java.io.InputStream; |
22 | |
import java.io.OutputStream; |
23 | |
import java.io.Reader; |
24 | |
import java.io.Writer; |
25 | |
import java.math.BigDecimal; |
26 | |
import java.math.BigInteger; |
27 | |
import java.net.MalformedURLException; |
28 | |
import java.net.URL; |
29 | |
import java.util.Collection; |
30 | |
import java.util.HashMap; |
31 | |
import java.util.Iterator; |
32 | |
import java.util.List; |
33 | |
import java.util.Map; |
34 | |
import java.util.Properties; |
35 | |
|
36 | |
import org.apache.commons.configuration.event.ConfigurationErrorEvent; |
37 | |
import org.apache.commons.configuration.event.ConfigurationErrorListener; |
38 | |
import org.apache.commons.configuration.event.ConfigurationEvent; |
39 | |
import org.apache.commons.configuration.event.ConfigurationListener; |
40 | |
import org.apache.commons.configuration.tree.ConfigurationNode; |
41 | |
import org.apache.commons.configuration.tree.ExpressionEngine; |
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
|
52 | |
|
53 | |
|
54 | |
|
55 | |
public class MultiFileHierarchicalConfiguration extends AbstractHierarchicalFileConfiguration |
56 | |
implements ConfigurationListener, ConfigurationErrorListener |
57 | |
{ |
58 | |
|
59 | |
private static final String FILE_URL_PREFIX = "file:"; |
60 | |
|
61 | |
|
62 | |
|
63 | |
|
64 | 2 | private static ThreadLocal recursive = new ThreadLocal() |
65 | |
{ |
66 | 2 | protected synchronized Object initialValue() |
67 | |
{ |
68 | 0 | return Boolean.FALSE; |
69 | |
} |
70 | |
}; |
71 | |
|
72 | |
|
73 | 2 | private final Map configurationsMap = new HashMap(); |
74 | |
|
75 | |
|
76 | |
private String pattern; |
77 | |
|
78 | |
|
79 | |
private boolean init; |
80 | |
|
81 | |
|
82 | |
|
83 | |
|
84 | |
public MultiFileHierarchicalConfiguration() |
85 | |
{ |
86 | 0 | super(); |
87 | 0 | this.init = true; |
88 | 0 | } |
89 | |
|
90 | |
|
91 | |
|
92 | |
|
93 | |
|
94 | |
public MultiFileHierarchicalConfiguration(String pathPattern) |
95 | |
{ |
96 | 2 | super(); |
97 | 2 | this.pattern = pathPattern; |
98 | 2 | this.init = true; |
99 | 2 | } |
100 | |
|
101 | |
|
102 | |
|
103 | |
|
104 | |
|
105 | |
public void setFilePattern(String pathPattern) |
106 | |
{ |
107 | 0 | this.pattern = pathPattern; |
108 | 0 | } |
109 | |
|
110 | |
|
111 | |
|
112 | |
|
113 | |
|
114 | |
|
115 | |
|
116 | |
|
117 | |
|
118 | |
|
119 | |
protected FileConfigurationDelegate createDelegate() |
120 | |
{ |
121 | 2 | return new FileConfigurationDelegate(); |
122 | |
} |
123 | |
|
124 | |
public void addProperty(String key, Object value) |
125 | |
{ |
126 | 0 | this.getConfiguration().addProperty(key, value); |
127 | 0 | } |
128 | |
|
129 | |
public void clear() |
130 | |
{ |
131 | 0 | this.getConfiguration().clear(); |
132 | 0 | } |
133 | |
|
134 | |
public void clearProperty(String key) |
135 | |
{ |
136 | 0 | this.getConfiguration().clearProperty(key); |
137 | 0 | } |
138 | |
|
139 | |
public boolean containsKey(String key) |
140 | |
{ |
141 | 0 | return this.getConfiguration().containsKey(key); |
142 | |
} |
143 | |
|
144 | |
public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) |
145 | |
{ |
146 | 0 | return this.getConfiguration().getBigDecimal(key, defaultValue); |
147 | |
} |
148 | |
|
149 | |
public BigDecimal getBigDecimal(String key) |
150 | |
{ |
151 | 0 | return this.getConfiguration().getBigDecimal(key); |
152 | |
} |
153 | |
|
154 | |
public BigInteger getBigInteger(String key, BigInteger defaultValue) |
155 | |
{ |
156 | 0 | return this.getConfiguration().getBigInteger(key, defaultValue); |
157 | |
} |
158 | |
|
159 | |
public BigInteger getBigInteger(String key) |
160 | |
{ |
161 | 0 | return this.getConfiguration().getBigInteger(key); |
162 | |
} |
163 | |
|
164 | |
public boolean getBoolean(String key, boolean defaultValue) |
165 | |
{ |
166 | 0 | return this.getConfiguration().getBoolean(key, defaultValue); |
167 | |
} |
168 | |
|
169 | |
public Boolean getBoolean(String key, Boolean defaultValue) |
170 | |
{ |
171 | 0 | return this.getConfiguration().getBoolean(key, defaultValue); |
172 | |
} |
173 | |
|
174 | |
public boolean getBoolean(String key) |
175 | |
{ |
176 | 0 | return this.getConfiguration().getBoolean(key); |
177 | |
} |
178 | |
|
179 | |
public byte getByte(String key, byte defaultValue) |
180 | |
{ |
181 | 0 | return this.getConfiguration().getByte(key, defaultValue); |
182 | |
} |
183 | |
|
184 | |
public Byte getByte(String key, Byte defaultValue) |
185 | |
{ |
186 | 0 | return this.getConfiguration().getByte(key, defaultValue); |
187 | |
} |
188 | |
|
189 | |
public byte getByte(String key) |
190 | |
{ |
191 | 0 | return this.getConfiguration().getByte(key); |
192 | |
} |
193 | |
|
194 | |
public double getDouble(String key, double defaultValue) |
195 | |
{ |
196 | 0 | return this.getConfiguration().getDouble(key, defaultValue); |
197 | |
} |
198 | |
|
199 | |
public Double getDouble(String key, Double defaultValue) |
200 | |
{ |
201 | 0 | return this.getConfiguration().getDouble(key, defaultValue); |
202 | |
} |
203 | |
|
204 | |
public double getDouble(String key) |
205 | |
{ |
206 | 0 | return this.getConfiguration().getDouble(key); |
207 | |
} |
208 | |
|
209 | |
public float getFloat(String key, float defaultValue) |
210 | |
{ |
211 | 0 | return this.getConfiguration().getFloat(key, defaultValue); |
212 | |
} |
213 | |
|
214 | |
public Float getFloat(String key, Float defaultValue) |
215 | |
{ |
216 | 0 | return this.getConfiguration().getFloat(key, defaultValue); |
217 | |
} |
218 | |
|
219 | |
public float getFloat(String key) |
220 | |
{ |
221 | 0 | return this.getConfiguration().getFloat(key); |
222 | |
} |
223 | |
|
224 | |
public int getInt(String key, int defaultValue) |
225 | |
{ |
226 | 0 | return this.getConfiguration().getInt(key, defaultValue); |
227 | |
} |
228 | |
|
229 | |
public int getInt(String key) |
230 | |
{ |
231 | 3 | return this.getConfiguration().getInt(key); |
232 | |
} |
233 | |
|
234 | |
public Integer getInteger(String key, Integer defaultValue) |
235 | |
{ |
236 | 0 | return this.getConfiguration().getInteger(key, defaultValue); |
237 | |
} |
238 | |
|
239 | |
public Iterator getKeys() |
240 | |
{ |
241 | 0 | return this.getConfiguration().getKeys(); |
242 | |
} |
243 | |
|
244 | |
public Iterator getKeys(String prefix) |
245 | |
{ |
246 | 0 | return this.getConfiguration().getKeys(prefix); |
247 | |
} |
248 | |
|
249 | |
public List getList(String key, List defaultValue) |
250 | |
{ |
251 | 0 | return this.getConfiguration().getList(key, defaultValue); |
252 | |
} |
253 | |
|
254 | |
public List getList(String key) |
255 | |
{ |
256 | 0 | return this.getConfiguration().getList(key); |
257 | |
} |
258 | |
|
259 | |
public long getLong(String key, long defaultValue) |
260 | |
{ |
261 | 0 | return this.getConfiguration().getLong(key, defaultValue); |
262 | |
} |
263 | |
|
264 | |
public Long getLong(String key, Long defaultValue) |
265 | |
{ |
266 | 0 | return this.getConfiguration().getLong(key, defaultValue); |
267 | |
} |
268 | |
|
269 | |
public long getLong(String key) |
270 | |
{ |
271 | 0 | return this.getConfiguration().getLong(key); |
272 | |
} |
273 | |
|
274 | |
public Properties getProperties(String key) |
275 | |
{ |
276 | 0 | return this.getConfiguration().getProperties(key); |
277 | |
} |
278 | |
|
279 | |
public Object getProperty(String key) |
280 | |
{ |
281 | 0 | return this.getConfiguration().getProperty(key); |
282 | |
} |
283 | |
|
284 | |
public short getShort(String key, short defaultValue) |
285 | |
{ |
286 | 0 | return this.getConfiguration().getShort(key, defaultValue); |
287 | |
} |
288 | |
|
289 | |
public Short getShort(String key, Short defaultValue) |
290 | |
{ |
291 | 0 | return this.getConfiguration().getShort(key, defaultValue); |
292 | |
} |
293 | |
|
294 | |
public short getShort(String key) |
295 | |
{ |
296 | 0 | return this.getConfiguration().getShort(key); |
297 | |
} |
298 | |
|
299 | |
public String getString(String key, String defaultValue) |
300 | |
{ |
301 | 0 | return this.getConfiguration().getString(key, defaultValue); |
302 | |
} |
303 | |
|
304 | |
public String getString(String key) |
305 | |
{ |
306 | 0 | return this.getConfiguration().getString(key); |
307 | |
} |
308 | |
|
309 | |
public String[] getStringArray(String key) |
310 | |
{ |
311 | 0 | return this.getConfiguration().getStringArray(key); |
312 | |
} |
313 | |
|
314 | |
public boolean isEmpty() |
315 | |
{ |
316 | 0 | return this.getConfiguration().isEmpty(); |
317 | |
} |
318 | |
|
319 | |
public void setProperty(String key, Object value) |
320 | |
{ |
321 | 0 | if (init) |
322 | |
{ |
323 | 0 | this.getConfiguration().setProperty(key, value); |
324 | |
} |
325 | 0 | } |
326 | |
|
327 | |
public Configuration subset(String prefix) |
328 | |
{ |
329 | 0 | return this.getConfiguration().subset(prefix); |
330 | |
} |
331 | |
|
332 | |
public Node getRoot() |
333 | |
{ |
334 | 0 | return this.getConfiguration().getRoot(); |
335 | |
} |
336 | |
|
337 | |
public void setRoot(Node node) |
338 | |
{ |
339 | 0 | if (init) |
340 | |
{ |
341 | 0 | this.getConfiguration().setRoot(node); |
342 | |
} |
343 | |
else |
344 | |
{ |
345 | 0 | super.setRoot(node); |
346 | |
} |
347 | 0 | } |
348 | |
|
349 | |
public ConfigurationNode getRootNode() |
350 | |
{ |
351 | 12 | return this.getConfiguration().getRootNode(); |
352 | |
} |
353 | |
|
354 | |
public void setRootNode(ConfigurationNode rootNode) |
355 | |
{ |
356 | 2 | if (init) |
357 | |
{ |
358 | 0 | this.getConfiguration().setRootNode(rootNode); |
359 | |
} |
360 | |
else |
361 | |
{ |
362 | 2 | super.setRootNode(rootNode); |
363 | |
} |
364 | 2 | } |
365 | |
|
366 | |
public ExpressionEngine getExpressionEngine() |
367 | |
{ |
368 | 7 | return super.getExpressionEngine(); |
369 | |
} |
370 | |
|
371 | |
public void setExpressionEngine(ExpressionEngine expressionEngine) |
372 | |
{ |
373 | 0 | super.setExpressionEngine(expressionEngine); |
374 | 0 | } |
375 | |
|
376 | |
public void addNodes(String key, Collection nodes) |
377 | |
{ |
378 | 0 | this.getConfiguration().addNodes(key, nodes); |
379 | 0 | } |
380 | |
|
381 | |
public SubnodeConfiguration configurationAt(String key, boolean supportUpdates) |
382 | |
{ |
383 | 0 | return this.getConfiguration().configurationAt(key, supportUpdates); |
384 | |
} |
385 | |
|
386 | |
public SubnodeConfiguration configurationAt(String key) |
387 | |
{ |
388 | 0 | return this.getConfiguration().configurationAt(key); |
389 | |
} |
390 | |
|
391 | |
public List configurationsAt(String key) |
392 | |
{ |
393 | 0 | return this.getConfiguration().configurationsAt(key); |
394 | |
} |
395 | |
|
396 | |
public void clearTree(String key) |
397 | |
{ |
398 | 0 | this.getConfiguration().clearTree(key); |
399 | 0 | } |
400 | |
|
401 | |
public int getMaxIndex(String key) |
402 | |
{ |
403 | 0 | return this.getConfiguration().getMaxIndex(key); |
404 | |
} |
405 | |
|
406 | |
public Configuration interpolatedConfiguration() |
407 | |
{ |
408 | 0 | return this.getConfiguration().interpolatedConfiguration(); |
409 | |
} |
410 | |
|
411 | |
public void addConfigurationListener(ConfigurationListener l) |
412 | |
{ |
413 | 4 | super.addConfigurationListener(l); |
414 | 4 | } |
415 | |
|
416 | |
public boolean removeConfigurationListener(ConfigurationListener l) |
417 | |
{ |
418 | 0 | return super.removeConfigurationListener(l); |
419 | |
} |
420 | |
|
421 | |
public Collection getConfigurationListeners() |
422 | |
{ |
423 | 0 | return super.getConfigurationListeners(); |
424 | |
} |
425 | |
|
426 | |
public void clearConfigurationListeners() |
427 | |
{ |
428 | 0 | super.clearConfigurationListeners(); |
429 | 0 | } |
430 | |
|
431 | |
public void addErrorListener(ConfigurationErrorListener l) |
432 | |
{ |
433 | 0 | super.addErrorListener(l); |
434 | 0 | } |
435 | |
|
436 | |
public boolean removeErrorListener(ConfigurationErrorListener l) |
437 | |
{ |
438 | 0 | return super.removeErrorListener(l); |
439 | |
} |
440 | |
|
441 | |
public void clearErrorListeners() |
442 | |
{ |
443 | 0 | super.clearErrorListeners(); |
444 | 0 | } |
445 | |
|
446 | |
public Collection getErrorListeners() |
447 | |
{ |
448 | 0 | return super.getErrorListeners(); |
449 | |
} |
450 | |
|
451 | |
public void save(Writer writer) throws ConfigurationException |
452 | |
{ |
453 | 0 | if (init) |
454 | |
{ |
455 | 0 | this.getConfiguration().save(writer); |
456 | |
} |
457 | 0 | } |
458 | |
|
459 | |
public void load(Reader reader) throws ConfigurationException |
460 | |
{ |
461 | 0 | if (init) |
462 | |
{ |
463 | 0 | this.getConfiguration().load(reader); |
464 | |
} |
465 | 0 | } |
466 | |
|
467 | |
public void load() throws ConfigurationException |
468 | |
{ |
469 | 0 | this.getConfiguration().load(); |
470 | 0 | } |
471 | |
|
472 | |
public void load(String fileName) throws ConfigurationException |
473 | |
{ |
474 | 0 | this.getConfiguration().load(fileName); |
475 | 0 | } |
476 | |
|
477 | |
public void load(File file) throws ConfigurationException |
478 | |
{ |
479 | 0 | this.getConfiguration().load(file); |
480 | 0 | } |
481 | |
|
482 | |
public void load(URL url) throws ConfigurationException |
483 | |
{ |
484 | 0 | this.getConfiguration().load(url); |
485 | 0 | } |
486 | |
|
487 | |
public void load(InputStream in) throws ConfigurationException |
488 | |
{ |
489 | 0 | this.getConfiguration().load(in); |
490 | 0 | } |
491 | |
|
492 | |
public void load(InputStream in, String encoding) throws ConfigurationException |
493 | |
{ |
494 | 0 | this.getConfiguration().load(in, encoding); |
495 | 0 | } |
496 | |
|
497 | |
public void save() throws ConfigurationException |
498 | |
{ |
499 | 0 | this.getConfiguration().save(); |
500 | 0 | } |
501 | |
|
502 | |
public void save(String fileName) throws ConfigurationException |
503 | |
{ |
504 | 0 | this.getConfiguration().save(fileName); |
505 | 0 | } |
506 | |
|
507 | |
public void save(File file) throws ConfigurationException |
508 | |
{ |
509 | 0 | this.getConfiguration().save(file); |
510 | 0 | } |
511 | |
|
512 | |
public void save(URL url) throws ConfigurationException |
513 | |
{ |
514 | 0 | this.getConfiguration().save(url); |
515 | 0 | } |
516 | |
|
517 | |
public void save(OutputStream out) throws ConfigurationException |
518 | |
{ |
519 | 0 | this.getConfiguration().save(out); |
520 | 0 | } |
521 | |
|
522 | |
public void save(OutputStream out, String encoding) throws ConfigurationException |
523 | |
{ |
524 | 0 | this.getConfiguration().save(out, encoding); |
525 | 0 | } |
526 | |
|
527 | |
public void configurationChanged(ConfigurationEvent event) |
528 | |
{ |
529 | 0 | if (event.getSource() instanceof XMLConfiguration) |
530 | |
{ |
531 | 0 | Iterator iter = getConfigurationListeners().iterator(); |
532 | 0 | while (iter.hasNext()) |
533 | |
{ |
534 | 0 | ConfigurationListener listener = (ConfigurationListener) iter.next(); |
535 | 0 | listener.configurationChanged(event); |
536 | |
} |
537 | |
} |
538 | 0 | } |
539 | |
|
540 | |
public void configurationError(ConfigurationErrorEvent event) |
541 | |
{ |
542 | 0 | if (event.getSource() instanceof XMLConfiguration) |
543 | |
{ |
544 | 0 | Iterator iter = getErrorListeners().iterator(); |
545 | 0 | while (iter.hasNext()) |
546 | |
{ |
547 | 0 | ConfigurationErrorListener listener = (ConfigurationErrorListener) iter.next(); |
548 | 0 | listener.configurationError(event); |
549 | |
} |
550 | |
} |
551 | 0 | } |
552 | |
|
553 | |
|
554 | |
|
555 | |
|
556 | |
|
557 | |
|
558 | |
protected Object resolveContainerStore(String key) |
559 | |
{ |
560 | 0 | if (((Boolean) recursive.get()).booleanValue()) |
561 | |
{ |
562 | 0 | return null; |
563 | |
} |
564 | 0 | recursive.set(Boolean.TRUE); |
565 | |
try |
566 | |
{ |
567 | 0 | return super.resolveContainerStore(key); |
568 | |
} |
569 | |
finally |
570 | |
{ |
571 | 0 | recursive.set(Boolean.FALSE); |
572 | |
} |
573 | |
} |
574 | |
|
575 | |
|
576 | |
|
577 | |
|
578 | |
public void removeConfiguration() |
579 | |
{ |
580 | 0 | String path = getSubstitutor().replace(pattern); |
581 | 0 | synchronized (configurationsMap) |
582 | |
{ |
583 | 0 | configurationsMap.remove(path); |
584 | 0 | } |
585 | 0 | } |
586 | |
|
587 | |
|
588 | |
|
589 | |
|
590 | |
|
591 | |
|
592 | |
|
593 | |
private AbstractHierarchicalFileConfiguration getConfiguration() |
594 | |
{ |
595 | 15 | if (pattern == null) |
596 | |
{ |
597 | 0 | throw new ConfigurationRuntimeException("File pattern must be defined"); |
598 | |
} |
599 | 15 | String path = getSubstitutor().replace(pattern); |
600 | 15 | synchronized (configurationsMap) |
601 | |
{ |
602 | 15 | if (configurationsMap.containsKey(path)) |
603 | |
{ |
604 | 8 | return (AbstractHierarchicalFileConfiguration) configurationsMap.get(path); |
605 | |
} |
606 | 7 | } |
607 | |
|
608 | 7 | if (path.equals(pattern)) |
609 | |
{ |
610 | 0 | XMLConfiguration configuration = new XMLConfiguration() |
611 | |
{ |
612 | |
public void load() throws ConfigurationException |
613 | |
{ |
614 | 0 | } |
615 | 0 | public void save() throws ConfigurationException |
616 | |
{ |
617 | 0 | } |
618 | |
}; |
619 | 0 | synchronized (configurationsMap) |
620 | |
{ |
621 | 0 | configurationsMap.put(pattern, configuration); |
622 | 0 | } |
623 | 0 | return configuration; |
624 | |
} |
625 | |
|
626 | 7 | XMLConfiguration configuration = new XMLConfiguration(); |
627 | |
try |
628 | |
{ |
629 | 7 | URL url = getURL(path); |
630 | 7 | configuration.setURL(url); |
631 | 7 | configuration.load(); |
632 | 7 | configuration.setExpressionEngine(getExpressionEngine()); |
633 | 7 | configuration.setReloadingStrategy(getReloadingStrategy()); |
634 | 7 | configuration.addConfigurationListener(this); |
635 | 7 | configuration.addErrorListener(this); |
636 | 7 | synchronized (configurationsMap) |
637 | |
{ |
638 | 7 | if (!configurationsMap.containsKey(path)) |
639 | |
{ |
640 | 7 | configurationsMap.put(path, configuration); |
641 | |
} |
642 | 7 | } |
643 | |
} |
644 | 0 | catch (ConfigurationException ce) |
645 | |
{ |
646 | 0 | throw new ConfigurationRuntimeException(ce); |
647 | |
} |
648 | 0 | catch (FileNotFoundException fnfe) |
649 | |
{ |
650 | 0 | throw new ConfigurationRuntimeException(fnfe); |
651 | 7 | } |
652 | |
|
653 | 7 | return configuration; |
654 | |
} |
655 | |
|
656 | |
private URL getURL(String resourceLocation) throws FileNotFoundException |
657 | |
{ |
658 | 7 | if (resourceLocation == null) |
659 | |
{ |
660 | 0 | throw new IllegalArgumentException("A path pattern must be configured"); |
661 | |
} |
662 | |
try |
663 | |
{ |
664 | |
|
665 | 7 | return new URL(resourceLocation); |
666 | |
} |
667 | 7 | catch (MalformedURLException ex) |
668 | |
{ |
669 | |
|
670 | |
try |
671 | |
{ |
672 | 7 | return new URL(FILE_URL_PREFIX + resourceLocation); |
673 | |
} |
674 | 0 | catch (MalformedURLException ex2) |
675 | |
{ |
676 | 0 | throw new FileNotFoundException("Resource location [" + resourceLocation |
677 | |
+ "] is not a URL or a well-formed file path"); |
678 | |
} |
679 | |
} |
680 | |
} |
681 | |
} |