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: 567771 $, $Date: 2007-08-20 19:57:08 +0200 (Mo, 20 Aug 2007) $ | |
49 | */ | |
50 | 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 | 64 | 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 | 11 | 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 | 6 | } |
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 | * <p>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.</p> | |
127 | * <p><em>Note:</em> This method is not able to handle some specifics of | |
128 | * configurations derived from <code>AbstractConfiguration</code> (e.g. | |
129 | * list delimiters). For a full support of all of these features the | |
130 | * <code>copy()</code> method of <code>AbstractConfiguration</code> should | |
131 | * be used. In a future release this method might become deprecated.</p> | |
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 | 54 | Iterator keys = source.getKeys(); |
140 | 1162 | while (keys.hasNext()) |
141 | { | |
142 | 1108 | String key = (String) keys.next(); |
143 | 1108 | target.setProperty(key, source.getProperty(key)); |
144 | 1108 | } |
145 | 54 | } |
146 | ||
147 | /** | |
148 | * <p>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.</p> | |
151 | * <p><em>Note:</em> This method is not able to handle some specifics of | |
152 | * configurations derived from <code>AbstractConfiguration</code> (e.g. | |
153 | * list delimiters). For a full support of all of these features the | |
154 | * <code>copy()</code> method of <code>AbstractConfiguration</code> should | |
155 | * be used. In a future release this method might become deprecated.</p> | |
156 | * | |
157 | * @param source the source configuration | |
158 | * @param target the target configuration | |
159 | * @since 1.1 | |
160 | */ | |
161 | public static void append(Configuration source, Configuration target) | |
162 | { | |
163 | 1 | Iterator keys = source.getKeys(); |
164 | 3 | while (keys.hasNext()) |
165 | { | |
166 | 2 | String key = (String) keys.next(); |
167 | 2 | target.addProperty(key, source.getProperty(key)); |
168 | 2 | } |
169 | 1 | } |
170 | ||
171 | /** | |
172 | * Converts the passed in configuration to a hierarchical one. If the | |
173 | * configuration is already hierarchical, it is directly returned. Otherwise | |
174 | * all properties are copied into a new hierarchical configuration. | |
175 | * | |
176 | * @param conf the configuration to convert | |
177 | * @return the new hierarchical configuration (the result is <b>null</b> if | |
178 | * and only if the passed in configuration is <b>null</b>) | |
179 | * @since 1.3 | |
180 | */ | |
181 | public static HierarchicalConfiguration convertToHierarchical( | |
182 | Configuration conf) | |
183 | { | |
184 | 94 | if (conf == null) |
185 | { | |
186 | 1 | return null; |
187 | } | |
188 | ||
189 | 93 | if (conf instanceof HierarchicalConfiguration) |
190 | { | |
191 | 48 | return (HierarchicalConfiguration) conf; |
192 | } | |
193 | else | |
194 | { | |
195 | 45 | HierarchicalConfiguration hc = new HierarchicalConfiguration(); |
196 | // Workaround for problem with copy() | |
197 | 45 | boolean delimiterParsingStatus = hc.isDelimiterParsingDisabled(); |
198 | 45 | hc.setDelimiterParsingDisabled(true); |
199 | 45 | ConfigurationUtils.copy(conf, hc); |
200 | 45 | hc.setDelimiterParsingDisabled(delimiterParsingStatus); |
201 | 45 | return hc; |
202 | } | |
203 | } | |
204 | ||
205 | /** | |
206 | * Clones the given configuration object if this is possible. If the passed | |
207 | * in configuration object implements the <code>Cloneable</code> | |
208 | * interface, its <code>clone()</code> method will be invoked. Otherwise | |
209 | * an exception will be thrown. | |
210 | * | |
211 | * @param config the configuration object to be cloned (can be <b>null</b>) | |
212 | * @return the cloned configuration (<b>null</b> if the argument was | |
213 | * <b>null</b>, too) | |
214 | * @throws ConfigurationRuntimeException if cloning is not supported for | |
215 | * this object | |
216 | * @since 1.3 | |
217 | */ | |
218 | public static Configuration cloneConfiguration(Configuration config) | |
219 | throws ConfigurationRuntimeException | |
220 | { | |
221 | 12 | if (config == null) |
222 | { | |
223 | 1 | return null; |
224 | } | |
225 | else | |
226 | { | |
227 | try | |
228 | { | |
229 | 11 | return (Configuration) clone(config); |
230 | } | |
231 | 2 | catch (CloneNotSupportedException cnex) |
232 | { | |
233 | 2 | throw new ConfigurationRuntimeException(cnex); |
234 | } | |
235 | } | |
236 | } | |
237 | ||
238 | /** | |
239 | * An internally used helper method for cloning objects. This implementation | |
240 | * is not very sophisticated nor efficient. Maybe it can be replaced by an | |
241 | * implementation from Commons Lang later. The method checks whether the | |
242 | * passed in object implements the <code>Cloneable</code> interface. If | |
243 | * this is the case, the <code>clone()</code> method is invoked by | |
244 | * reflection. Errors that occur during the cloning process are re-thrown as | |
245 | * runtime exceptions. | |
246 | * | |
247 | * @param obj the object to be cloned | |
248 | * @return the cloned object | |
249 | * @throws CloneNotSupportedException if the object cannot be cloned | |
250 | */ | |
251 | static Object clone(Object obj) throws CloneNotSupportedException | |
252 | { | |
253 | 23 | if (obj instanceof Cloneable) |
254 | { | |
255 | try | |
256 | { | |
257 | 21 | Method m = obj.getClass().getMethod(METHOD_CLONE, null); |
258 | 21 | return m.invoke(obj, null); |
259 | } | |
260 | 0 | catch (NoSuchMethodException nmex) |
261 | { | |
262 | 0 | throw new CloneNotSupportedException( |
263 | "No clone() method found for class" | |
264 | + obj.getClass().getName()); | |
265 | } | |
266 | 0 | catch (IllegalAccessException iaex) |
267 | { | |
268 | 0 | throw new ConfigurationRuntimeException(iaex); |
269 | } | |
270 | 0 | catch (InvocationTargetException itex) |
271 | { | |
272 | 0 | throw new ConfigurationRuntimeException(itex); |
273 | } | |
274 | } | |
275 | else | |
276 | { | |
277 | 2 | throw new CloneNotSupportedException(obj.getClass().getName() |
278 | + " does not implement Cloneable"); | |
279 | } | |
280 | } | |
281 | ||
282 | /** | |
283 | * Constructs a URL from a base path and a file name. The file name can | |
284 | * be absolute, relative or a full URL. If necessary the base path URL is | |
285 | * applied. | |
286 | * | |
287 | * @param basePath the base path URL (can be <b>null</b>) | |
288 | * @param file the file name | |
289 | * @return the resulting URL | |
290 | * @throws MalformedURLException if URLs are invalid | |
291 | */ | |
292 | public static URL getURL(String basePath, String file) throws MalformedURLException | |
293 | { | |
294 | 8 | File f = new File(file); |
295 | 8 | if (f.isAbsolute()) // already absolute? |
296 | { | |
297 | 2 | return f.toURL(); |
298 | } | |
299 | ||
300 | try | |
301 | { | |
302 | 6 | if (basePath == null) |
303 | { | |
304 | 2 | return new URL(file); |
305 | } | |
306 | else | |
307 | { | |
308 | 4 | URL base = new URL(basePath); |
309 | 3 | return new URL(base, file); |
310 | } | |
311 | } | |
312 | 2 | catch (MalformedURLException uex) |
313 | { | |
314 | 2 | return constructFile(basePath, file).toURL(); |
315 | } | |
316 | } | |
317 | ||
318 | /** | |
319 | * Helper method for constructing a file object from a base path and a | |
320 | * file name. This method is called if the base path passed to | |
321 | * <code>getURL()</code> does not seem to be a valid URL. | |
322 | * | |
323 | * @param basePath the base path | |
324 | * @param fileName the file name | |
325 | * @return the resulting file | |
326 | */ | |
327 | static File constructFile(String basePath, String fileName) | |
328 | { | |
329 | 553 | File file = null; |
330 | ||
331 | 553 | File absolute = null; |
332 | 553 | if (fileName != null) |
333 | { | |
334 | 553 | absolute = new File(fileName); |
335 | } | |
336 | ||
337 | 553 | if (StringUtils.isEmpty(basePath) || (absolute != null && absolute.isAbsolute())) |
338 | { | |
339 | 57 | file = new File(fileName); |
340 | 57 | } |
341 | else | |
342 | { | |
343 | 496 | StringBuffer fName = new StringBuffer(); |
344 | 496 | fName.append(basePath); |
345 | ||
346 | // My best friend. Paranoia. | |
347 | 496 | if (!basePath.endsWith(File.separator)) |
348 | { | |
349 | 496 | fName.append(File.separator); |
350 | } | |
351 | ||
352 | // | |
353 | // We have a relative path, and we have | |
354 | // two possible forms here. If we have the | |
355 | // "./" form then just strip that off first | |
356 | // before continuing. | |
357 | // | |
358 | 496 | if (fileName.startsWith("." + File.separator)) |
359 | { | |
360 | 0 | fName.append(fileName.substring(2)); |
361 | 0 | } |
362 | else | |
363 | { | |
364 | 496 | fName.append(fileName); |
365 | } | |
366 | ||
367 | 496 | file = new File(fName.toString()); |
368 | } | |
369 | ||
370 | 553 | return file; |
371 | } | |
372 | ||
373 | /** | |
374 | * Return the location of the specified resource by searching the user home | |
375 | * directory, the current classpath and the system classpath. | |
376 | * | |
377 | * @param name the name of the resource | |
378 | * | |
379 | * @return the location of the resource | |
380 | */ | |
381 | public static URL locate(String name) | |
382 | { | |
383 | 0 | return locate(null, name); |
384 | } | |
385 | ||
386 | /** | |
387 | * Return the location of the specified resource by searching the user home | |
388 | * directory, the current classpath and the system classpath. | |
389 | * | |
390 | * @param base the base path of the resource | |
391 | * @param name the name of the resource | |
392 | * | |
393 | * @return the location of the resource | |
394 | */ | |
395 | public static URL locate(String base, String name) | |
396 | { | |
397 | 1140 | if (log.isDebugEnabled()) |
398 | { | |
399 | 0 | StringBuffer buf = new StringBuffer(); |
400 | 0 | buf.append("ConfigurationUtils.locate(): base is ").append(base); |
401 | 0 | buf.append(", name is ").append(name); |
402 | 0 | log.debug(buf.toString()); |
403 | } | |
404 | ||
405 | 1140 | if (name == null) |
406 | { | |
407 | // undefined, always return null | |
408 | 4 | return null; |
409 | } | |
410 | ||
411 | 1136 | URL url = null; |
412 | ||
413 | // attempt to create an URL directly | |
414 | try | |
415 | { | |
416 | 1136 | if (base == null) |
417 | { | |
418 | 329 | url = new URL(name); |
419 | 0 | } |
420 | else | |
421 | { | |
422 | 807 | URL baseURL = new URL(base); |
423 | 410 | url = new URL(baseURL, name); |
424 | ||
425 | // check if the file exists | |
426 | 408 | InputStream in = null; |
427 | try | |
428 | { | |
429 | 408 | in = url.openStream(); |
430 | } | |
431 | finally | |
432 | { | |
433 | 408 | if (in != null) |
434 | { | |
435 | 390 | in.close(); |
436 | 390 | } |
437 | 18 | } |
438 | } | |
439 | ||
440 | 390 | log.debug("Loading configuration from the URL " + url); |
441 | } | |
442 | 746 | catch (IOException e) |
443 | { | |
444 | 746 | url = null; |
445 | 390 | } |
446 | ||
447 | // attempt to load from an absolute path | |
448 | 1136 | if (url == null) |
449 | { | |
450 | 746 | File file = new File(name); |
451 | 746 | if (file.isAbsolute() && file.exists()) // already absolute? |
452 | { | |
453 | try | |
454 | { | |
455 | 282 | url = file.toURL(); |
456 | 282 | log.debug("Loading configuration from the absolute path " + name); |
457 | } | |
458 | 0 | catch (MalformedURLException e) |
459 | { | |
460 | 0 | log.warn("Could not obtain URL from file", e); |
461 | 282 | } |
462 | } | |
463 | } | |
464 | ||
465 | // attempt to load from the base directory | |
466 | 1136 | if (url == null) |
467 | { | |
468 | try | |
469 | { | |
470 | 464 | File file = constructFile(base, name); |
471 | 464 | if (file != null && file.exists()) |
472 | { | |
473 | 413 | url = file.toURL(); |
474 | } | |
475 | ||
476 | 464 | if (url != null) |
477 | { | |
478 | 413 | log.debug("Loading configuration from the path " + file); |
479 | } | |
480 | } | |
481 | 0 | catch (MalformedURLException e) |
482 | { | |
483 | 0 | log.warn("Could not obtain URL from file", e); |
484 | 464 | } |
485 | } | |
486 | ||
487 | // attempt to load from the user home directory | |
488 | 1136 | if (url == null) |
489 | { | |
490 | try | |
491 | { | |
492 | 51 | File file = constructFile(System.getProperty("user.home"), name); |
493 | 51 | if (file != null && file.exists()) |
494 | { | |
495 | 1 | url = file.toURL(); |
496 | } | |
497 | ||
498 | 51 | if (url != null) |
499 | { | |
500 | 1 | log.debug("Loading configuration from the home path " + file); |
501 | } | |
502 | ||
503 | } | |
504 | 0 | catch (MalformedURLException e) |
505 | { | |
506 | 0 | log.warn("Could not obtain URL from file", e); |
507 | 51 | } |
508 | } | |
509 | ||
510 | // attempt to load from classpath | |
511 | 1136 | if (url == null) |
512 | { | |
513 | 50 | url = locateFromClasspath(name); |
514 | } | |
515 | 1136 | return url; |
516 | } | |
517 | ||
518 | /** | |
519 | * Tries to find a resource with the given name in the classpath. | |
520 | * @param resourceName the name of the resource | |
521 | * @return the URL to the found resource or <b>null</b> if the resource | |
522 | * cannot be found | |
523 | */ | |
524 | static URL locateFromClasspath(String resourceName) | |
525 | { | |
526 | 50 | URL url = null; |
527 | // attempt to load from the context classpath | |
528 | 50 | ClassLoader loader = Thread.currentThread().getContextClassLoader(); |
529 | 50 | if (loader != null) |
530 | { | |
531 | 49 | url = loader.getResource(resourceName); |
532 | ||
533 | 49 | if (url != null) |
534 | { | |
535 | 20 | log.debug("Loading configuration from the context classpath (" + resourceName + ")"); |
536 | } | |
537 | } | |
538 | ||
539 | // attempt to load from the system classpath | |
540 | 50 | if (url == null) |
541 | { | |
542 | 30 | url = ClassLoader.getSystemResource(resourceName); |
543 | ||
544 | 30 | if (url != null) |
545 | { | |
546 | 0 | log.debug("Loading configuration from the system classpath (" + resourceName + ")"); |
547 | } | |
548 | } | |
549 | 50 | return url; |
550 | } | |
551 | ||
552 | /** | |
553 | * Return the path without the file name, for example http://xyz.net/foo/bar.xml | |
554 | * results in http://xyz.net/foo/ | |
555 | * | |
556 | * @param url the URL from which to extract the path | |
557 | * @return the path component of the passed in URL | |
558 | */ | |
559 | static String getBasePath(URL url) | |
560 | { | |
561 | 20 | if (url == null) |
562 | { | |
563 | 0 | return null; |
564 | } | |
565 | ||
566 | 20 | String s = url.toString(); |
567 | ||
568 | 20 | if (s.endsWith("/") || StringUtils.isEmpty(url.getPath())) |
569 | { | |
570 | 3 | return s; |
571 | } | |
572 | else | |
573 | { | |
574 | 17 | return s.substring(0, s.lastIndexOf("/") + 1); |
575 | } | |
576 | } | |
577 | ||
578 | /** | |
579 | * Extract the file name from the specified URL. | |
580 | * | |
581 | * @param url the URL from which to extract the file name | |
582 | * @return the extracted file name | |
583 | */ | |
584 | static String getFileName(URL url) | |
585 | { | |
586 | 18 | if (url == null) |
587 | { | |
588 | 1 | return null; |
589 | } | |
590 | ||
591 | 17 | String path = url.getPath(); |
592 | ||
593 | 17 | if (path.endsWith("/") || StringUtils.isEmpty(path)) |
594 | { | |
595 | 1 | return null; |
596 | } | |
597 | else | |
598 | { | |
599 | 16 | return path.substring(path.lastIndexOf("/") + 1); |
600 | } | |
601 | } | |
602 | ||
603 | /** | |
604 | * Tries to convert the specified base path and file name into a file object. | |
605 | * This method is called e.g. by the save() methods of file based | |
606 | * configurations. The parameter strings can be relative files, absolute | |
607 | * files and URLs as well. This implementation checks first whether the passed in | |
608 | * file name is absolute. If this is the case, it is returned. Otherwise | |
609 | * further checks are performed whether the base path and file name can be | |
610 | * combined to a valid URL or a valid file name. <em>Note:</em> The test | |
611 | * if the passed in file name is absolute is performed using | |
612 | * <code>java.io.File.isAbsolute()</code>. If the file name starts with a | |
613 | * slash, this method will return <b>true</b> on Unix, but <b>false</b> on | |
614 | * Windows. So to ensure correct behavior for relative file names on all | |
615 | * platforms you should never let relative paths start with a slash. E.g. | |
616 | * in a configuration definition file do not use something like that: | |
617 | * <pre> | |
618 | * <properties fileName="/subdir/my.properties"/> | |
619 | * </pre> | |
620 | * Under Windows this path would be resolved relative to the configuration | |
621 | * definition file. Under Unix this would be treated as an absolute path | |
622 | * name. | |
623 | * | |
624 | * @param basePath the base path | |
625 | * @param fileName the file name | |
626 | * @return the file object (<b>null</b> if no file can be obtained) | |
627 | */ | |
628 | public static File getFile(String basePath, String fileName) | |
629 | { | |
630 | // Check if the file name is absolute | |
631 | 49 | File f = new File(fileName); |
632 | 49 | if (f.isAbsolute()) |
633 | { | |
634 | 8 | return f; |
635 | } | |
636 | ||
637 | // Check if URLs are involved | |
638 | URL url; | |
639 | try | |
640 | { | |
641 | 41 | url = new URL(new URL(basePath), fileName); |
642 | } | |
643 | 38 | catch (MalformedURLException mex1) |
644 | { | |
645 | try | |
646 | { | |
647 | 38 | url = new URL(fileName); |
648 | } | |
649 | 36 | catch (MalformedURLException mex2) |
650 | { | |
651 | 36 | url = null; |
652 | 2 | } |
653 | 3 | } |
654 | ||
655 | 41 | if (url != null) |
656 | { | |
657 | 5 | return fileFromURL(url); |
658 | } | |
659 | ||
660 | 36 | return constructFile(basePath, fileName); |
661 | } | |
662 | ||
663 | /** | |
664 | * Tries to convert the specified URL to a file object. If this fails, | |
665 | * <b>null</b> is returned. | |
666 | * | |
667 | * @param url the URL | |
668 | * @return the resulting file object | |
669 | */ | |
670 | public static File fileFromURL(URL url) | |
671 | { | |
672 | 1421 | if (PROTOCOL_FILE.equals(url.getProtocol())) |
673 | { | |
674 | 1415 | return new File(URLDecoder.decode(url.getPath())); |
675 | } | |
676 | else | |
677 | { | |
678 | 6 | return null; |
679 | } | |
680 | } | |
681 | ||
682 | /** | |
683 | * Enables runtime exceptions for the specified configuration object. This | |
684 | * method can be used for configuration implementations that may face errors | |
685 | * on normal property access, e.g. <code>DatabaseConfiguration</code> or | |
686 | * <code>JNDIConfiguration</code>. Per default such errors are simply | |
687 | * logged and then ignored. This implementation will register a special | |
688 | * <code>{@link ConfigurationErrorListener}</code> that throws a runtime | |
689 | * exception (namely a <code>ConfigurationRuntimeException</code>) on | |
690 | * each received error event. | |
691 | * | |
692 | * @param src the configuration, for which runtime exceptions are to be | |
693 | * enabled; this configuration must be derived from | |
694 | * <code>{@link EventSource}</code> | |
695 | */ | |
696 | public static void enableRuntimeExceptions(Configuration src) | |
697 | { | |
698 | 3 | if (!(src instanceof EventSource)) |
699 | { | |
700 | 2 | throw new IllegalArgumentException( |
701 | "Configuration must be derived from EventSource!"); | |
702 | } | |
703 | 1 | ((EventSource) src).addErrorListener(new ConfigurationErrorListener() |
704 | { | |
705 | 1 | public void configurationError(ConfigurationErrorEvent event) |
706 | { | |
707 | // Throw a runtime exception | |
708 | 1 | throw new ConfigurationRuntimeException(event.getCause()); |
709 | } | |
710 | }); | |
711 | 1 | } |
712 | } |