1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.configuration;
19
20 import java.io.File;
21 import java.io.PrintStream;
22 import java.io.PrintWriter;
23 import java.io.StringWriter;
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.net.MalformedURLException;
27 import java.net.URL;
28 import java.util.Iterator;
29
30 import org.apache.commons.configuration.event.ConfigurationErrorEvent;
31 import org.apache.commons.configuration.event.ConfigurationErrorListener;
32 import org.apache.commons.configuration.event.EventSource;
33 import org.apache.commons.configuration.reloading.Reloadable;
34 import org.apache.commons.configuration.tree.ExpressionEngine;
35 import org.apache.commons.lang.StringUtils;
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39
40
41
42
43
44
45
46
47
48 public final class ConfigurationUtils
49 {
50
51 static final String PROTOCOL_FILE = "file";
52
53
54 static final String RESOURCE_PATH_SEPARATOR = "/";
55
56
57 private static final String FILE_SCHEME = "file:";
58
59
60 private static final String METHOD_CLONE = "clone";
61
62
63 private static final int HEX = 16;
64
65
66 private static final Log LOG = LogFactory.getLog(ConfigurationUtils.class);
67
68
69
70
71 private ConfigurationUtils()
72 {
73
74 }
75
76
77
78
79
80
81
82 public static void dump(Configuration configuration, PrintStream out)
83 {
84 dump(configuration, new PrintWriter(out));
85 }
86
87
88
89
90
91
92
93 public static void dump(Configuration configuration, PrintWriter out)
94 {
95 for (Iterator<String> keys = configuration.getKeys(); keys.hasNext();)
96 {
97 String key = keys.next();
98 Object value = configuration.getProperty(key);
99 out.print(key);
100 out.print("=");
101 out.print(value);
102
103 if (keys.hasNext())
104 {
105 out.println();
106 }
107 }
108
109 out.flush();
110 }
111
112
113
114
115
116
117
118
119 public static String toString(Configuration configuration)
120 {
121 StringWriter writer = new StringWriter();
122 dump(configuration, new PrintWriter(writer));
123 return writer.toString();
124 }
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public static void copy(Configuration source, Configuration target)
141 {
142 for (Iterator<String> keys = source.getKeys(); keys.hasNext();)
143 {
144 String key = keys.next();
145 target.setProperty(key, source.getProperty(key));
146 }
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 public static void append(Configuration source, Configuration target)
164 {
165 for (Iterator<String> keys = source.getKeys(); keys.hasNext();)
166 {
167 String key = keys.next();
168 target.addProperty(key, source.getProperty(key));
169 }
170 }
171
172
173
174
175
176
177
178
179
180
181
182 public static HierarchicalConfiguration convertToHierarchical(
183 Configuration conf)
184 {
185 return convertToHierarchical(conf, null);
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 public static HierarchicalConfiguration convertToHierarchical(
212 Configuration conf, ExpressionEngine engine)
213 {
214 if (conf == null)
215 {
216 return null;
217 }
218
219 if (conf instanceof HierarchicalConfiguration)
220 {
221 HierarchicalConfiguration hc;
222 if (conf instanceof Reloadable)
223 {
224 Object lock = ((Reloadable) conf).getReloadLock();
225 synchronized (lock)
226 {
227 hc = new HierarchicalConfiguration((HierarchicalConfiguration) conf);
228 }
229 }
230 else
231 {
232 hc = (HierarchicalConfiguration) conf;
233 }
234 if (engine != null)
235 {
236 hc.setExpressionEngine(engine);
237 }
238
239 return hc;
240 }
241 else
242 {
243 HierarchicalConfiguration hc = new HierarchicalConfiguration();
244 if (engine != null)
245 {
246 hc.setExpressionEngine(engine);
247 }
248
249
250 boolean delimiterParsingStatus = hc.isDelimiterParsingDisabled();
251 hc.setDelimiterParsingDisabled(true);
252 hc.append(conf);
253 hc.setDelimiterParsingDisabled(delimiterParsingStatus);
254 return hc;
255 }
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 public static Configuration cloneConfiguration(Configuration config)
272 throws ConfigurationRuntimeException
273 {
274 if (config == null)
275 {
276 return null;
277 }
278 else
279 {
280 try
281 {
282 return (Configuration) clone(config);
283 }
284 catch (CloneNotSupportedException cnex)
285 {
286 throw new ConfigurationRuntimeException(cnex);
287 }
288 }
289 }
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304 static Object clone(Object obj) throws CloneNotSupportedException
305 {
306 if (obj instanceof Cloneable)
307 {
308 try
309 {
310 Method m = obj.getClass().getMethod(METHOD_CLONE);
311 return m.invoke(obj);
312 }
313 catch (NoSuchMethodException nmex)
314 {
315 throw new CloneNotSupportedException(
316 "No clone() method found for class"
317 + obj.getClass().getName());
318 }
319 catch (IllegalAccessException iaex)
320 {
321 throw new ConfigurationRuntimeException(iaex);
322 }
323 catch (InvocationTargetException itex)
324 {
325 throw new ConfigurationRuntimeException(itex);
326 }
327 }
328 else
329 {
330 throw new CloneNotSupportedException(obj.getClass().getName()
331 + " does not implement Cloneable");
332 }
333 }
334
335
336
337
338
339
340
341
342
343
344
345 public static URL getURL(String basePath, String file) throws MalformedURLException
346 {
347 return FileSystem.getDefaultFileSystem().getURL(basePath, file);
348 }
349
350
351
352
353
354
355
356
357
358
359 static File constructFile(String basePath, String fileName)
360 {
361 File file;
362
363 File absolute = null;
364 if (fileName != null)
365 {
366 absolute = new File(fileName);
367 }
368
369 if (StringUtils.isEmpty(basePath) || (absolute != null && absolute.isAbsolute()))
370 {
371 file = new File(fileName);
372 }
373 else
374 {
375 StringBuilder fName = new StringBuilder();
376 fName.append(basePath);
377
378
379 if (!basePath.endsWith(File.separator))
380 {
381 fName.append(File.separator);
382 }
383
384
385
386
387
388
389
390 if (fileName.startsWith("." + File.separator))
391 {
392 fName.append(fileName.substring(2));
393 }
394 else
395 {
396 fName.append(fileName);
397 }
398
399 file = new File(fName.toString());
400 }
401
402 return file;
403 }
404
405
406
407
408
409
410
411
412
413 public static URL locate(String name)
414 {
415 return locate(null, name);
416 }
417
418
419
420
421
422
423
424
425
426
427 public static URL locate(String base, String name)
428 {
429 return locate(FileSystem.getDefaultFileSystem(), base, name);
430 }
431
432
433
434
435
436
437
438
439
440
441
442 public static URL locate(FileSystem fileSystem, String base, String name)
443 {
444 if (LOG.isDebugEnabled())
445 {
446 StringBuilder buf = new StringBuilder();
447 buf.append("ConfigurationUtils.locate(): base is ").append(base);
448 buf.append(", name is ").append(name);
449 LOG.debug(buf.toString());
450 }
451
452 if (name == null)
453 {
454
455 return null;
456 }
457
458
459
460 URL url = fileSystem.locateFromURL(base, name);
461
462
463 if (url == null)
464 {
465 File file = new File(name);
466 if (file.isAbsolute() && file.exists())
467 {
468 try
469 {
470 url = toURL(file);
471 LOG.debug("Loading configuration from the absolute path " + name);
472 }
473 catch (MalformedURLException e)
474 {
475 LOG.warn("Could not obtain URL from file", e);
476 }
477 }
478 }
479
480
481 if (url == null)
482 {
483 try
484 {
485 File file = constructFile(base, name);
486 if (file != null && file.exists())
487 {
488 url = toURL(file);
489 }
490
491 if (url != null)
492 {
493 LOG.debug("Loading configuration from the path " + file);
494 }
495 }
496 catch (MalformedURLException e)
497 {
498 LOG.warn("Could not obtain URL from file", e);
499 }
500 }
501
502
503 if (url == null)
504 {
505 try
506 {
507 File file = constructFile(System.getProperty("user.home"), name);
508 if (file != null && file.exists())
509 {
510 url = toURL(file);
511 }
512
513 if (url != null)
514 {
515 LOG.debug("Loading configuration from the home path " + file);
516 }
517
518 }
519 catch (MalformedURLException e)
520 {
521 LOG.warn("Could not obtain URL from file", e);
522 }
523 }
524
525
526 if (url == null)
527 {
528 url = locateFromClasspath(name);
529 }
530 return url;
531 }
532
533
534
535
536
537
538
539 static URL locateFromClasspath(String resourceName)
540 {
541 URL url = null;
542
543 ClassLoader loader = Thread.currentThread().getContextClassLoader();
544 if (loader != null)
545 {
546 url = loader.getResource(resourceName);
547
548 if (url != null)
549 {
550 LOG.debug("Loading configuration from the context classpath (" + resourceName + ")");
551 }
552 }
553
554
555 if (url == null)
556 {
557 url = ClassLoader.getSystemResource(resourceName);
558
559 if (url != null)
560 {
561 LOG.debug("Loading configuration from the system classpath (" + resourceName + ")");
562 }
563 }
564 return url;
565 }
566
567
568
569
570
571
572
573
574 static String getBasePath(URL url)
575 {
576 if (url == null)
577 {
578 return null;
579 }
580
581 String s = url.toString();
582 if (s.startsWith(FILE_SCHEME) && !s.startsWith("file://"))
583 {
584 s = "file://" + s.substring(FILE_SCHEME.length());
585 }
586
587 if (s.endsWith("/") || StringUtils.isEmpty(url.getPath()))
588 {
589 return s;
590 }
591 else
592 {
593 return s.substring(0, s.lastIndexOf("/") + 1);
594 }
595 }
596
597
598
599
600
601
602
603 static String getFileName(URL url)
604 {
605 if (url == null)
606 {
607 return null;
608 }
609
610 String path = url.getPath();
611
612 if (path.endsWith("/") || StringUtils.isEmpty(path))
613 {
614 return null;
615 }
616 else
617 {
618 return path.substring(path.lastIndexOf("/") + 1);
619 }
620 }
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647 public static File getFile(String basePath, String fileName)
648 {
649
650 File f = new File(fileName);
651 if (f.isAbsolute())
652 {
653 return f;
654 }
655
656
657 URL url;
658 try
659 {
660 url = new URL(new URL(basePath), fileName);
661 }
662 catch (MalformedURLException mex1)
663 {
664 try
665 {
666 url = new URL(fileName);
667 }
668 catch (MalformedURLException mex2)
669 {
670 url = null;
671 }
672 }
673
674 if (url != null)
675 {
676 return fileFromURL(url);
677 }
678
679 return constructFile(basePath, fileName);
680 }
681
682
683
684
685
686
687
688
689
690 public static File fileFromURL(URL url)
691 {
692 if (url == null || !url.getProtocol().equals(PROTOCOL_FILE))
693 {
694 return null;
695 }
696 else
697 {
698 String filename = url.getFile().replace('/', File.separatorChar);
699 int pos = 0;
700 while ((pos = filename.indexOf('%', pos)) >= 0)
701 {
702 if (pos + 2 < filename.length())
703 {
704 String hexStr = filename.substring(pos + 1, pos + 3);
705 char ch = (char) Integer.parseInt(hexStr, HEX);
706 filename = filename.substring(0, pos) + ch
707 + filename.substring(pos + 3);
708 }
709 }
710 return new File(filename);
711 }
712 }
713
714
715
716
717
718
719
720
721
722
723
724 static URL toURL(File file) throws MalformedURLException
725 {
726 return file.toURI().toURL();
727 }
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743 public static void enableRuntimeExceptions(Configuration src)
744 {
745 if (!(src instanceof EventSource))
746 {
747 throw new IllegalArgumentException(
748 "Configuration must be derived from EventSource!");
749 }
750 ((EventSource) src).addErrorListener(new ConfigurationErrorListener()
751 {
752 public void configurationError(ConfigurationErrorEvent event)
753 {
754
755 throw new ConfigurationRuntimeException(event.getCause());
756 }
757 });
758 }
759 }