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.*;
20 import java.net.MalformedURLException;
21 import java.net.URL;
22 import java.util.Iterator;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 /***
29 * Miscellaneous utility methods for configurations.
30 *
31 * @author <a href="mailto:herve.quiroz@esil.univ-mrs.fr">Herve Quiroz</a>
32 * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
33 * @author Emmanuel Bourg
34 * @version $Revision: 155408 $, $Date: 2005-02-26 13:56:39 +0100 (Sa, 26 Feb 2005) $
35 */
36 public final class ConfigurationUtils
37 {
38 /*** Constant for the file URL protocol.*/
39 static final String PROTOCOL_FILE = "file";
40
41 private static Log log = LogFactory.getLog(ConfigurationUtils.class);
42
43 private ConfigurationUtils()
44 {
45
46 }
47
48 /***
49 * Dump the configuration key/value mappings to some ouput stream.
50 *
51 * @param configuration the configuration
52 * @param out the output stream to dump the configuration to
53 */
54 public static void dump(Configuration configuration, PrintStream out)
55 {
56 dump(configuration, new PrintWriter(out));
57 }
58
59 /***
60 * Dump the configuration key/value mappings to some writer.
61 *
62 * @param configuration the configuration
63 * @param out the writer to dump the configuration to
64 */
65 public static void dump(Configuration configuration, PrintWriter out)
66 {
67 Iterator keys = configuration.getKeys();
68 while (keys.hasNext())
69 {
70 String key = (String) keys.next();
71 Object value = configuration.getProperty(key);
72 out.print(key);
73 out.print("=");
74 out.print(value);
75
76 if (keys.hasNext())
77 {
78 out.println();
79 }
80 }
81
82 out.flush();
83 }
84
85 /***
86 * Get a string representation of the key/value mappings of a
87 * configuration.
88 *
89 * @param configuration the configuration
90 * @return a string representation of the configuration
91 */
92 public static String toString(Configuration configuration)
93 {
94 StringWriter writer = new StringWriter();
95 dump(configuration, new PrintWriter(writer));
96 return writer.toString();
97 }
98
99 /***
100 * Copy all properties from the source configuration to the target
101 * configuration. Properties in the target configuration are replaced with
102 * the properties with the same key in the source configuration.
103 *
104 * @param source the source configuration
105 * @param target the target configuration
106 * @since 1.1
107 */
108 public static void copy(Configuration source, Configuration target)
109 {
110 Iterator keys = source.getKeys();
111 while (keys.hasNext())
112 {
113 String key = (String) keys.next();
114 target.setProperty(key, source.getProperty(key));
115 }
116 }
117
118 /***
119 * Append all properties from the source configuration to the target
120 * configuration. Properties in the source configuration are appended to
121 * the properties with the same key in the target configuration.
122 *
123 * @param source the source configuration
124 * @param target the target configuration
125 * @since 1.1
126 */
127 public static void append(Configuration source, Configuration target)
128 {
129 Iterator keys = source.getKeys();
130 while (keys.hasNext())
131 {
132 String key = (String) keys.next();
133 target.addProperty(key, source.getProperty(key));
134 }
135 }
136
137 /***
138 * Constructs a URL from a base path and a file name. The file name can
139 * be absolute, relative or a full URL. If necessary the base path URL is
140 * applied.
141 *
142 * @param basePath the base path URL (can be <b>null</b>)
143 * @param file the file name
144 * @return the resulting URL
145 * @throws MalformedURLException if URLs are invalid
146 */
147 public static URL getURL(String basePath, String file) throws MalformedURLException
148 {
149 File f = new File(file);
150 if (f.isAbsolute())
151 {
152 return f.toURL();
153 }
154
155 try
156 {
157 if (basePath == null)
158 {
159 return new URL(file);
160 }
161 else
162 {
163 URL base = new URL(basePath);
164 return new URL(base, file);
165 }
166 }
167 catch (MalformedURLException uex)
168 {
169 return constructFile(basePath, file).toURL();
170 }
171 }
172
173 /***
174 * Helper method for constructing a file object from a base path and a
175 * file name. This method is called if the base path passed to
176 * <code>getURL()</code> does not seem to be a valid URL.
177 *
178 * @param basePath the base path
179 * @param fileName the file name
180 * @return the resulting file
181 */
182 static File constructFile(String basePath, String fileName)
183 {
184 File file = null;
185
186 File absolute = null;
187 if (fileName != null)
188 {
189 absolute = new File(fileName);
190 }
191
192 if (StringUtils.isEmpty(basePath) || (absolute != null && absolute.isAbsolute()))
193 {
194 file = new File(fileName);
195 }
196 else
197 {
198 StringBuffer fName = new StringBuffer();
199 fName.append(basePath);
200
201
202 if (!basePath.endsWith(File.separator))
203 {
204 fName.append(File.separator);
205 }
206
207
208
209
210
211
212
213 if (fileName.startsWith("." + File.separator))
214 {
215 fName.append(fileName.substring(2));
216 }
217 else
218 {
219 fName.append(fileName);
220 }
221
222 file = new File(fName.toString());
223 }
224
225 return file;
226 }
227
228 /***
229 * Return the location of the specified resource by searching the user home
230 * directory, the current classpath and the system classpath.
231 *
232 * @param name the name of the resource
233 *
234 * @return the location of the resource
235 */
236 public static URL locate(String name)
237 {
238 return locate(null, name);
239 }
240
241 /***
242 * Return the location of the specified resource by searching the user home
243 * directory, the current classpath and the system classpath.
244 *
245 * @param base the base path of the resource
246 * @param name the name of the resource
247 *
248 * @return the location of the resource
249 */
250 public static URL locate(String base, String name)
251 {
252 URL url = null;
253
254
255 try
256 {
257 if (base == null)
258 {
259 url = new URL(name);
260 }
261 else
262 {
263 URL baseURL = new URL(base);
264 url = new URL(baseURL, name);
265
266
267 InputStream in = null;
268 try
269 {
270 in = url.openStream();
271 }
272 finally
273 {
274 if (in != null)
275 {
276 in.close();
277 }
278 }
279 }
280
281 log.debug("Configuration loaded from the URL " + url);
282 }
283 catch (IOException e)
284 {
285 url = null;
286 }
287
288
289 if (url == null)
290 {
291 File file = new File(name);
292 if (file.isAbsolute() && file.exists())
293 {
294 try
295 {
296 url = file.toURL();
297 log.debug("Configuration loaded from the absolute path " + name);
298 }
299 catch (MalformedURLException e)
300 {
301 e.printStackTrace();
302 }
303 }
304 }
305
306
307 if (url == null)
308 {
309 try
310 {
311 File file = constructFile(base, name);
312 if (file != null && file.exists())
313 {
314 url = file.toURL();
315 }
316
317 if (url != null)
318 {
319 log.debug("Configuration loaded from the base path " + name);
320 }
321 }
322 catch (IOException e)
323 {
324 e.printStackTrace();
325 }
326 }
327
328
329 if (url == null)
330 {
331 try
332 {
333 File file = constructFile(System.getProperty("user.home"), name);
334 if (file != null && file.exists())
335 {
336 url = file.toURL();
337 }
338
339 if (url != null)
340 {
341 log.debug("Configuration loaded from the home path " + name);
342 }
343
344 }
345 catch (IOException e)
346 {
347 e.printStackTrace();
348 }
349 }
350
351
352 if (url == null)
353 {
354 ClassLoader loader = Thread.currentThread().getContextClassLoader();
355 url = loader.getResource(name);
356
357 if (url != null)
358 {
359 log.debug("Configuration loaded from the context classpath (" + name + ")");
360 }
361 }
362
363
364 if (url == null)
365 {
366 url = ClassLoader.getSystemResource(name);
367
368 if (url != null)
369 {
370 log.debug("Configuration loaded from the system classpath (" + name + ")");
371 }
372 }
373
374 return url;
375 }
376
377 /***
378 * Return the path without the file name, for example http://xyz.net/foo/bar.xml
379 * results in http://xyz.net/foo/
380 *
381 * @param url
382 * @return
383 */
384 static String getBasePath(URL url)
385 {
386 if (url == null)
387 {
388 return null;
389 }
390
391 String s = url.toString();
392
393 if (s.endsWith("/") || StringUtils.isEmpty(url.getPath()))
394 {
395 return s;
396 }
397 else
398 {
399 return s.substring(0, s.lastIndexOf("/") + 1);
400 }
401 }
402
403 /***
404 * Extract the file name from the specified URL.
405 */
406 static String getFileName(URL url)
407 {
408 if (url == null)
409 {
410 return null;
411 }
412
413 String path = url.getPath();
414
415 if (path.endsWith("/") || StringUtils.isEmpty(path))
416 {
417 return null;
418 }
419 else
420 {
421 return path.substring(path.lastIndexOf("/") + 1);
422 }
423 }
424
425 /***
426 * Tries to convert the specified base path and file name into a file object.
427 * This method is called e.g. by the save() methods of file based
428 * configurations. The parameter strings can be relative files, absolute
429 * files and URLs as well.
430 *
431 * @param basePath the base path
432 * @param fileName the file name
433 * @return the file object (<b>null</b> if no file can be obtained)
434 */
435 public static File getFile(String basePath, String fileName)
436 {
437
438 URL url;
439 try
440 {
441 url = new URL(new URL(basePath), fileName);
442 }
443 catch (MalformedURLException mex1)
444 {
445 try
446 {
447 url = new URL(fileName);
448 }
449 catch (MalformedURLException mex2)
450 {
451 url = null;
452 }
453 }
454
455 if (url != null)
456 {
457 return fileFromURL(url);
458 }
459
460 return constructFile(basePath, fileName);
461 }
462
463 /***
464 * Tries to convert the specified URL to a file object. If this fails,
465 * <b>null</b> is returned.
466 *
467 * @param url the URL
468 * @return the resulting file object
469 */
470 static File fileFromURL(URL url)
471 {
472 if (PROTOCOL_FILE.equals(url.getProtocol()))
473 {
474 return new File(url.getPath());
475 }
476 else
477 {
478 return null;
479 }
480 }
481 }