Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ConfigurationUtils |
|
| 4.65;4,65 | ||||
ConfigurationUtils$1 |
|
| 4.65;4,65 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | */ | |
17 | ||
18 | package org.apache.commons.configuration; | |
19 | ||
20 | import java.io.File; | |
21 | import java.io.IOException; | |
22 | import java.io.InputStream; | |
23 | import java.io.PrintStream; | |
24 | import java.io.PrintWriter; | |
25 | import java.io.StringWriter; | |
26 | import java.lang.reflect.InvocationTargetException; | |
27 | import java.lang.reflect.Method; | |
28 | import java.net.MalformedURLException; | |
29 | import java.net.URL; | |
30 | import java.net.URLDecoder; | |
31 | import java.util.Iterator; | |
32 | ||
33 | import org.apache.commons.configuration.event.ConfigurationErrorEvent; | |
34 | import org.apache.commons.configuration.event.ConfigurationErrorListener; | |
35 | import org.apache.commons.configuration.event.EventSource; | |
36 | import org.apache.commons.lang.StringUtils; | |
37 | import org.apache.commons.logging.Log; | |
38 | import org.apache.commons.logging.LogFactory; | |
39 | ||
40 | /** | |
41 | * Miscellaneous utility methods for configurations. | |
42 | * | |
43 | * @see ConfigurationConverter Utility methods to convert configurations. | |
44 | * | |
45 | * @author <a href="mailto:herve.quiroz@esil.univ-mrs.fr">Herve Quiroz</a> | |
46 | * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a> | |
47 | * @author Emmanuel Bourg | |
48 | * @version $Revision: 503227 $, $Date: 2007-02-03 17:19:15 +0100 (Sa, 03 Feb 2007) $ | |
49 | */ | |
50 | 29 | public final class ConfigurationUtils |
51 | { | |
52 | /** Constant for the file URL protocol.*/ | |
53 | static final String PROTOCOL_FILE = "file"; | |
54 | ||
55 | /** Constant for the resource path separator.*/ | |
56 | static final String RESOURCE_PATH_SEPARATOR = "/"; | |
57 | ||
58 | /** Constant for the name of the clone() method.*/ | |
59 | private static final String METHOD_CLONE = "clone"; | |
60 | ||
61 | /** The logger.*/ | |
62 | 29 | private static Log log = LogFactory.getLog(ConfigurationUtils.class); |
63 | ||
64 | /** | |
65 | * Private constructor. Prevents instances from being created. | |
66 | */ | |
67 | private ConfigurationUtils() | |
68 | 0 | { |
69 | // to prevent instanciation... | |
70 | 0 | } |
71 | ||
72 | /** | |
73 | * Dump the configuration key/value mappings to some ouput stream. | |
74 | * | |
75 | * @param configuration the configuration | |
76 | * @param out the output stream to dump the configuration to | |
77 | */ | |
78 | public static void dump(Configuration configuration, PrintStream out) | |
79 | { | |
80 | 0 | dump(configuration, new PrintWriter(out)); |
81 | 0 | } |
82 | ||
83 | /** | |
84 | * Dump the configuration key/value mappings to some writer. | |
85 | * | |
86 | * @param configuration the configuration | |
87 | * @param out the writer to dump the configuration to | |
88 | */ | |
89 | public static void dump(Configuration configuration, PrintWriter out) | |
90 | { | |
91 | 5 | Iterator keys = configuration.getKeys(); |
92 | 16 | while (keys.hasNext()) |
93 | { | |
94 | 6 | String key = (String) keys.next(); |
95 | 6 | Object value = configuration.getProperty(key); |
96 | 6 | out.print(key); |
97 | 6 | out.print("="); |
98 | 6 | out.print(value); |
99 | ||
100 | 6 | if (keys.hasNext()) |
101 | { | |
102 | 2 | out.println(); |
103 | } | |
104 | } | |
105 | ||
106 | 5 | out.flush(); |
107 | 5 | } |
108 | ||
109 | /** | |
110 | * Get a string representation of the key/value mappings of a | |
111 | * configuration. | |
112 | * | |
113 | * @param configuration the configuration | |
114 | * @return a string representation of the configuration | |
115 | */ | |
116 | public static String toString(Configuration configuration) | |
117 | { | |
118 | 5 | StringWriter writer = new StringWriter(); |
119 | 5 | dump(configuration, new PrintWriter(writer)); |
120 | 5 | return writer.toString(); |
121 | } | |
122 | ||
123 | /** | |
124 | * Copy all properties from the source configuration to the target | |
125 | * configuration. Properties in the target configuration are replaced with | |
126 | * the properties with the same key in the source configuration. | |
127 | * <em>Note:</em> This method won't work well on hierarchical configurations | |
128 | * because it is not able to copy information about the properties' | |
129 | * structure. So when dealing with hierarchical configuration objects their | |
130 | * <code>{@link HierarchicalConfiguration#clone() clone()}</code> methods | |
131 | * should be used. | |
132 | * | |
133 | * @param source the source configuration | |
134 | * @param target the target configuration | |
135 | * @since 1.1 | |
136 | */ | |
137 | public static void copy(Configuration source, Configuration target) | |
138 | { | |
139 | 46 | Iterator keys = source.getKeys(); |
140 | 1191 | while (keys.hasNext()) |
141 | { | |
142 | 1099 | String key = (String) keys.next(); |
143 | 1099 | target.setProperty(key, source.getProperty(key)); |
144 | } | |
145 | 46 | } |
146 | ||
147 | /** | |
148 | * Append all properties from the source configuration to the target | |
149 | * configuration. Properties in the source configuration are appended to | |
150 | * the properties with the same key in the target configuration. | |
151 | * | |
152 | * @param source the source configuration | |
153 | * @param target the target configuration | |
154 | * @since 1.1 | |
155 | */ | |
156 | public static void append(Configuration source, Configuration target) | |
157 | { | |
158 | 1 | Iterator keys = source.getKeys(); |
159 | 4 | while (keys.hasNext()) |
160 | { | |
161 | 2 | String key = (String) keys.next(); |
162 | 2 | target.addProperty(key, source.getProperty(key)); |
163 | } | |
164 | 1 | } |
165 | ||
166 | /** | |
167 | * Converts the passed in configuration to a hierarchical one. If the | |
168 | * configuration is already hierarchical, it is directly returned. Otherwise | |
169 | * all properties are copied into a new hierarchical configuration. | |
170 | * | |
171 | * @param conf the configuration to convert | |
172 | * @return the new hierarchical configuration (the result is <b>null</b> if | |
173 | * and only if the passed in configuration is <b>null</b>) | |
174 | * @since 1.3 | |
175 | */ | |
176 | public static HierarchicalConfiguration convertToHierarchical( | |
177 | Configuration conf) | |
178 | { | |
179 | 79 | if (conf == null) |
180 | { | |
181 | 1 | return null; |
182 | } | |
183 | ||
184 | 78 | if (conf instanceof HierarchicalConfiguration) |
185 | { | |
186 | 41 | return (HierarchicalConfiguration) conf; |
187 | } | |
188 | else | |
189 | { | |
190 | 37 | HierarchicalConfiguration hc = new HierarchicalConfiguration(); |
191 | 37 | ConfigurationUtils.copy(conf, hc); |
192 | 37 | return hc; |
193 | } | |
194 | } | |
195 | ||
196 | /** | |
197 | * Clones the given configuration object if this is possible. If the passed | |
198 | * in configuration object implements the <code>Cloneable</code> | |
199 | * interface, its <code>clone()</code> method will be invoked. Otherwise | |
200 | * an exception will be thrown. | |
201 | * | |
202 | * @param config the configuration object to be cloned (can be <b>null</b>) | |
203 | * @return the cloned configuration (<b>null</b> if the argument was | |
204 | * <b>null</b>, too) | |
205 | * @throws ConfigurationRuntimeException if cloning is not supported for | |
206 | * this object | |
207 | * @since 1.3 | |
208 | */ | |
209 | public static Configuration cloneConfiguration(Configuration config) | |
210 | throws ConfigurationRuntimeException | |
211 | { | |
212 | 11 | if (config == null) |
213 | { | |
214 | 1 | return null; |
215 | } | |
216 | else | |
217 | { | |
218 | try | |
219 | { | |
220 | 10 | return (Configuration) clone(config); |
221 | } | |
222 | catch (CloneNotSupportedException cnex) | |
223 | { | |
224 | 2 | throw new ConfigurationRuntimeException(cnex); |
225 | } | |
226 | } | |
227 | } | |
228 | ||
229 | /** | |
230 | * An internally used helper method for cloning objects. This implementation | |
231 | * is not very sophisticated nor efficient. Maybe it can be replaced by an | |
232 | * implementation from Commons Lang later. The method checks whether the | |
233 | * passed in object implements the <code>Cloneable</code> interface. If | |
234 | * this is the case, the <code>clone()</code> method is invoked by | |
235 | * reflection. Errors that occur during the cloning process are re-thrown as | |
236 | * runtime exceptions. | |
237 | * | |
238 | * @param obj the object to be cloned | |
239 | * @return the cloned object | |
240 | * @throws CloneNotSupportedException if the object cannot be cloned | |
241 | */ | |
242 | static Object clone(Object obj) throws CloneNotSupportedException | |
243 | { | |
244 | 21 | if (obj instanceof Cloneable) |
245 | { | |
246 | try | |
247 | { | |
248 | 19 | Method m = obj.getClass().getMethod(METHOD_CLONE, null); |
249 | 19 | return m.invoke(obj, null); |
250 | } | |
251 | catch (NoSuchMethodException nmex) | |
252 | { | |
253 | 0 | throw new CloneNotSupportedException( |
254 | "No clone() method found for class" | |
255 | + obj.getClass().getName()); | |
256 | } | |
257 | catch (IllegalAccessException iaex) | |
258 | { | |
259 | 0 | throw new ConfigurationRuntimeException(iaex); |
260 | } | |
261 | catch (InvocationTargetException itex) | |
262 | { | |
263 | 0 | throw new ConfigurationRuntimeException(itex); |
264 | } | |
265 | } | |
266 | else | |
267 | { | |
268 | 2 | throw new CloneNotSupportedException(obj.getClass().getName() |
269 | + " does not implement Cloneable"); | |
270 | } | |
271 | } | |
272 | ||
273 | /** | |
274 | * Constructs a URL from a base path and a file name. The file name can | |
275 | * be absolute, relative or a full URL. If necessary the base path URL is | |
276 | * applied. | |
277 | * | |
278 | * @param basePath the base path URL (can be <b>null</b>) | |
279 | * @param file the file name | |
280 | * @return the resulting URL | |
281 | * @throws MalformedURLException if URLs are invalid | |
282 | */ | |
283 | public static URL getURL(String basePath, String file) throws MalformedURLException | |
284 | { | |
285 | 8 | File f = new File(file); |
286 | 8 | if (f.isAbsolute()) // already absolute? |
287 | { | |
288 | 2 | return f.toURL(); |
289 | } | |
290 | ||
291 | try | |
292 | { | |
293 | 6 | if (basePath == null) |
294 | { | |
295 | 2 | return new URL(file); |
296 | } | |
297 | else | |
298 | { | |
299 | 4 | URL base = new URL(basePath); |
300 | 3 | return new URL(base, file); |
301 | } | |
302 | } | |
303 | catch (MalformedURLException uex) | |
304 | { | |
305 | 2 | return constructFile(basePath, file).toURL(); |
306 | } | |
307 | } | |
308 | ||
309 | /** | |
310 | * Helper method for constructing a file object from a base path and a | |
311 | * file name. This method is called if the base path passed to | |
312 | * <code>getURL()</code> does not seem to be a valid URL. | |
313 | * | |
314 | * @param basePath the base path | |
315 | * @param fileName the file name | |
316 | * @return the resulting file | |
317 | */ | |
318 | static File constructFile(String basePath, String fileName) | |
319 | { | |
320 | 441 | File file = null; |
321 | ||
322 | 441 | File absolute = null; |
323 | 441 | if (fileName != null) |
324 | { | |
325 | 441 | absolute = new File(fileName); |
326 | } | |
327 | ||
328 | 441 | if (StringUtils.isEmpty(basePath) || (absolute != null && absolute.isAbsolute())) |
329 | { | |
330 | 46 | file = new File(fileName); |
331 | } | |
332 | else | |
333 | { | |
334 | 395 | StringBuffer fName = new StringBuffer(); |
335 | 395 | fName.append(basePath); |
336 | ||
337 | // My best friend. Paranoia. | |
338 | 395 | if (!basePath.endsWith(File.separator)) |
339 | { | |
340 | 395 | fName.append(File.separator); |
341 | } | |
342 | ||
343 | // | |
344 | // We have a relative path, and we have | |
345 | // two possible forms here. If we have the | |
346 | // "./" form then just strip that off first | |
347 | // before continuing. | |
348 | // | |
349 | 395 | if (fileName.startsWith("." + File.separator)) |
350 | { | |
351 | 0 | fName.append(fileName.substring(2)); |
352 | } | |
353 | else | |
354 | { | |
355 | 395 | fName.append(fileName); |
356 | } | |
357 | ||
358 | 395 | file = new File(fName.toString()); |
359 | } | |
360 | ||
361 | 441 | return file; |
362 | } | |
363 | ||
364 | /** | |
365 | * Return the location of the specified resource by searching the user home | |
366 | * directory, the current classpath and the system classpath. | |
367 | * | |
368 | * @param name the name of the resource | |
369 | * | |
370 | * @return the location of the resource | |
371 | */ | |
372 | public static URL locate(String name) | |
373 | { | |
374 | 0 | return locate(null, name); |
375 | } | |
376 | ||
377 | /** | |
378 | * Return the location of the specified resource by searching the user home | |
379 | * directory, the current classpath and the system classpath. | |
380 | * | |
381 | * @param base the base path of the resource | |
382 | * @param name the name of the resource | |
383 | * | |
384 | * @return the location of the resource | |
385 | */ | |
386 | public static URL locate(String base, String name) | |
387 | { | |
388 | 1000 | if (log.isDebugEnabled()) |
389 | { | |
390 | 0 | StringBuffer buf = new StringBuffer(); |
391 | 0 | buf.append("ConfigurationUtils.locate(): base is ").append(base); |
392 | 0 | buf.append(", name is ").append(name); |
393 | 0 | log.debug(buf.toString()); |
394 | } | |
395 | ||
396 | 1000 | if (name == null) |
397 | { | |
398 | // undefined, always return null | |
399 | 4 | return null; |
400 | } | |
401 | ||
402 | 996 | URL url = null; |
403 | ||
404 | // attempt to create an URL directly | |
405 | try | |
406 | { | |
407 | 996 | if (base == null) |
408 | { | |
409 | 293 | url = new URL(name); |
410 | } | |
411 | else | |
412 | { | |
413 | 703 | URL baseURL = new URL(base); |
414 | 395 | url = new URL(baseURL, name); |
415 | ||
416 | // check if the file exists | |
417 | 394 | InputStream in = null; |
418 | try | |
419 | { | |
420 | 394 | in = url.openStream(); |
421 | 375 | } |
422 | finally | |
423 | { | |
424 | 19 | if (in != null) |
425 | { | |
426 | 375 | in.close(); |
427 | } | |
428 | } | |
429 | } | |
430 | ||
431 | 375 | log.debug("Loading configuration from the URL " + url); |
432 | 375 | } |
433 | catch (IOException e) | |
434 | { | |
435 | 621 | url = null; |
436 | } | |
437 | ||
438 | // attempt to load from an absolute path | |
439 | 996 | if (url == null) |
440 | { | |
441 | 621 | File file = new File(name); |
442 | 621 | if (file.isAbsolute() && file.exists()) // already absolute? |
443 | { | |
444 | try | |
445 | { | |
446 | 250 | url = file.toURL(); |
447 | 250 | log.debug("Loading configuration from the absolute path " + name); |
448 | 250 | } |
449 | catch (MalformedURLException e) | |
450 | { | |
451 | 0 | log.warn("Could not obtain URL from file", e); |
452 | } | |
453 | } | |
454 | } | |
455 | ||
456 | // attempt to load from the base directory | |
457 | 996 | if (url == null) |
458 | { | |
459 | try | |
460 | { | |
461 | 371 | File file = constructFile(base, name); |
462 | 371 | if (file != null && file.exists()) |
463 | { | |
464 | 321 | url = file.toURL(); |
465 | } | |
466 | ||
467 | 371 | if (url != null) |
468 | { | |
469 | 321 | log.debug("Loading configuration from the path " + file); |
470 | } | |
471 | 371 | } |
472 | catch (MalformedURLException e) | |
473 | { | |
474 | 0 | log.warn("Could not obtain URL from file", e); |
475 | } | |
476 | } | |
477 | ||
478 | // attempt to load from the user home directory | |
479 | 996 | if (url == null) |
480 | { | |
481 | try | |
482 | { | |
483 | 50 | File file = constructFile(System.getProperty("user.home"), name); |
484 | 50 | if (file != null && file.exists()) |
485 | { | |
486 | 1 | url = file.toURL(); |
487 | } | |
488 | ||
489 | 50 | if (url != null) |
490 | { | |
491 | 1 | log.debug("Loading configuration from the home path " + file); |
492 | } | |
493 | ||
494 | 50 | } |
495 | catch (MalformedURLException e) | |
496 | { | |
497 | 0 | log.warn("Could not obtain URL from file", e); |
498 | } | |
499 | } | |
500 | ||
501 | // attempt to load from classpath | |
502 | 996 | if (url == null) |
503 | { | |
504 | 49 | url = locateFromClasspath(name); |
505 | } | |
506 | 996 | return url; |
507 | } | |
508 | ||
509 | /** | |
510 | * Tries to find a resource with the given name in the classpath. | |
511 | * @param resourceName the name of the resource | |
512 | * @return the URL to the found resource or <b>null</b> if the resource | |
513 | * cannot be found | |
514 | */ | |
515 | static URL locateFromClasspath(String resourceName) | |
516 | { | |
517 | 49 | URL url = null; |
518 | // attempt to load from the context classpath | |
519 | 49 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); |
520 | 49 | if (loader != null) |
521 | { | |
522 | 48 | url = loader.getResource(resourceName); |
523 | ||
524 | 48 | if (url != null) |
525 | { | |
526 | 19 | log.debug("Loading configuration from the context classpath (" + resourceName + ")"); |
527 | } | |
528 | } | |
529 | ||
530 | // attempt to load from the system classpath | |
531 | 49 | if (url == null) |
532 | { | |
533 | 30 | url = ClassLoader.getSystemResource(resourceName); |
534 | ||
535 | 30 | if (url != null) |
536 | { | |
537 | 0 | log.debug("Loading configuration from the system classpath (" + resourceName + ")"); |
538 | } | |
539 | } | |
540 | 49 | return url; |
541 | } | |
542 | ||
543 | /** | |
544 | * Return the path without the file name, for example http://xyz.net/foo/bar.xml | |
545 | * results in http://xyz.net/foo/ | |
546 | * | |
547 | * @param url the URL from which to extract the path | |
548 | * @return the path component of the passed in URL | |
549 | */ | |
550 | static String getBasePath(URL url) | |
551 | { | |
552 | 19 | if (url == null) |
553 | { | |
554 | 0 | return null; |
555 | } | |
556 | ||
557 | 19 | String s = url.toString(); |
558 | ||
559 | 19 | if (s.endsWith("/") || StringUtils.isEmpty(url.getPath())) |
560 | { | |
561 | 3 | return s; |
562 | } | |
563 | else | |
564 | { | |
565 | 16 | return s.substring(0, s.lastIndexOf("/") + 1); |
566 | } | |
567 | } | |
568 | ||
569 | /** | |
570 | * Extract the file name from the specified URL. | |
571 | * | |
572 | * @param url the URL from which to extract the file name | |
573 | * @return the extracted file name | |
574 | */ | |
575 | static String getFileName(URL url) | |
576 | { | |
577 | 17 | if (url == null) |
578 | { | |
579 | 1 | return null; |
580 | } | |
581 | ||
582 | 16 | String path = url.getPath(); |
583 | ||
584 | 16 | if (path.endsWith("/") || StringUtils.isEmpty(path)) |
585 | { | |
586 | 1 | return null; |
587 | } | |
588 | else | |
589 | { | |
590 | 15 | return path.substring(path.lastIndexOf("/") + 1); |
591 | } | |
592 | } | |
593 | ||
594 | /** | |
595 | * Tries to convert the specified base path and file name into a file object. | |
596 | * This method is called e.g. by the save() methods of file based | |
597 | * configurations. The parameter strings can be relative files, absolute | |
598 | * files and URLs as well. This implementation checks first whether the passed in | |
599 | * file name is absolute. If this is the case, it is returned. Otherwise | |
600 | * further checks are performed whether the base path and file name can be | |
601 | * combined to a valid URL or a valid file name. <em>Note:</em> The test | |
602 | * if the passed in file name is absolute is performed using | |
603 | * <code>java.io.File.isAbsolute()</code>. If the file name starts with a | |
604 | * slash, this method will return <b>true</b> on Unix, but <b>false</b> on | |
605 | * Windows. So to ensure correct behavior for relative file names on all | |
606 | * platforms you should never let relative paths start with a slash. E.g. | |
607 | * in a configuration definition file do not use something like that: | |
608 | * <pre> | |
609 | * <properties fileName="/subdir/my.properties"/> | |
610 | * </pre> | |
611 | * Under Windows this path would be resolved relative to the configuration | |
612 | * definition file. Under Unix this would be treated as an absolute path | |
613 | * name. | |
614 | * | |
615 | * @param basePath the base path | |
616 | * @param fileName the file name | |
617 | * @return the file object (<b>null</b> if no file can be obtained) | |
618 | */ | |
619 | public static File getFile(String basePath, String fileName) | |
620 | { | |
621 | // Check if the file name is absolute | |
622 | 31 | File f = new File(fileName); |
623 | 31 | if (f.isAbsolute()) |
624 | { | |
625 | 8 | return f; |
626 | } | |
627 | ||
628 | // Check if URLs are involved | |
629 | URL url; | |
630 | try | |
631 | { | |
632 | 23 | url = new URL(new URL(basePath), fileName); |
633 | 3 | } |
634 | catch (MalformedURLException mex1) | |
635 | { | |
636 | 20 | try |
637 | { | |
638 | 20 | url = new URL(fileName); |
639 | 2 | } |
640 | catch (MalformedURLException mex2) | |
641 | { | |
642 | 18 | url = null; |
643 | } | |
644 | } | |
645 | ||
646 | 23 | if (url != null) |
647 | { | |
648 | 5 | return fileFromURL(url); |
649 | } | |
650 | ||
651 | 18 | return constructFile(basePath, fileName); |
652 | } | |
653 | ||
654 | /** | |
655 | * Tries to convert the specified URL to a file object. If this fails, | |
656 | * <b>null</b> is returned. | |
657 | * | |
658 | * @param url the URL | |
659 | * @return the resulting file object | |
660 | */ | |
661 | public static File fileFromURL(URL url) | |
662 | { | |
663 | 1255 | if (PROTOCOL_FILE.equals(url.getProtocol())) |
664 | { | |
665 | 1253 | return new File(URLDecoder.decode(url.getPath())); |
666 | } | |
667 | else | |
668 | { | |
669 | 2 | return null; |
670 | } | |
671 | } | |
672 | ||
673 | /** | |
674 | * Enables runtime exceptions for the specified configuration object. This | |
675 | * method can be used for configuration implementations that may face errors | |
676 | * on normal property access, e.g. <code>DatabaseConfiguration</code> or | |
677 | * <code>JNDIConfiguration</code>. Per default such errors are simply | |
678 | * logged and then ignored. This implementation will register a special | |
679 | * <code>{@link ConfigurationErrorListener}</code> that throws a runtime | |
680 | * exception (namely a <code>ConfigurationRuntimeException</code>) on | |
681 | * each received error event. | |
682 | * | |
683 | * @param src the configuration, for which runtime exceptions are to be | |
684 | * enabled; this configuration must be derived from | |
685 | * <code>{@link EventSource}</code> | |
686 | */ | |
687 | public static void enableRuntimeExceptions(Configuration src) | |
688 | { | |
689 | 3 | if (!(src instanceof EventSource)) |
690 | { | |
691 | 2 | throw new IllegalArgumentException( |
692 | "Configuration must be derived from EventSource!"); | |
693 | } | |
694 | 1 | ((EventSource) src).addErrorListener(new ConfigurationErrorListener() |
695 | { | |
696 | 1 | public void configurationError(ConfigurationErrorEvent event) |
697 | { | |
698 | // Throw a runtime exception | |
699 | 1 | throw new ConfigurationRuntimeException(event.getCause()); |
700 | } | |
701 | }); | |
702 | 1 | } |
703 | } |