##### Coverage Report - org.apache.commons.configuration.ConfigurationUtils

Classes in this File | Line Coverage | Branch Coverage | Complexity
ConfigurationUtils |
92% | 136/148
100% | 37/37
| 4.722222222222222;4,722

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