| %line | %branch | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| org.apache.commons.configuration.AbstractFileConfiguration |
|
|
| 1 | /* |
|
| 2 | * Copyright 2004-2005 The Apache Software Foundation. |
|
| 3 | * |
|
| 4 | * Licensed under the Apache License, Version 2.0 (the "License") |
|
| 5 | * you may not use this file except in compliance with the License. |
|
| 6 | * You may obtain a copy of the License at |
|
| 7 | * |
|
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 | * |
|
| 10 | * Unless required by applicable law or agreed to in writing, software |
|
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 | * See the License for the specific language governing permissions and |
|
| 14 | * limitations under the License. |
|
| 15 | */ |
|
| 16 | ||
| 17 | package org.apache.commons.configuration; |
|
| 18 | ||
| 19 | import java.io.File; |
|
| 20 | import java.io.FileOutputStream; |
|
| 21 | import java.io.IOException; |
|
| 22 | import java.io.InputStream; |
|
| 23 | import java.io.InputStreamReader; |
|
| 24 | import java.io.OutputStream; |
|
| 25 | import java.io.OutputStreamWriter; |
|
| 26 | import java.io.Reader; |
|
| 27 | import java.io.UnsupportedEncodingException; |
|
| 28 | import java.io.Writer; |
|
| 29 | import java.net.URL; |
|
| 30 | import java.util.Iterator; |
|
| 31 | ||
| 32 | import org.apache.commons.configuration.reloading.InvariantReloadingStrategy; |
|
| 33 | import org.apache.commons.configuration.reloading.ReloadingStrategy; |
|
| 34 | ||
| 35 | /** |
|
| 36 | * <p>Partial implementation of the <code>FileConfiguration</code> interface. |
|
| 37 | * Developpers of file based configuration may want to extend this class, |
|
| 38 | * the two methods left to implement are {@see AbstractFileConfiguration#load(Reader)} |
|
| 39 | * and {@see AbstractFileConfiguration#save(Reader)}.</p> |
|
| 40 | * <p>This base class already implements a couple of ways to specify the location |
|
| 41 | * of the file this configuration is based on. The following possibilities |
|
| 42 | * exist: |
|
| 43 | * <ul><li>URLs: With the method <code>setURL()</code> a full URL to the |
|
| 44 | * configuration source can be specified. This is the most flexible way. Note |
|
| 45 | * that the <code>save()</code> methods support only <em>file:</em> URLs.</li> |
|
| 46 | * <li>Files: The <code>setFile()</code> method allows to specify the |
|
| 47 | * configuration source as a file. This can be either a relative or an |
|
| 48 | * absolute file. In the former case the file is resolved based on the current |
|
| 49 | * directory.</li> |
|
| 50 | * <li>As file paths in string form: With the <code>setPath()</code> method a |
|
| 51 | * full path to a configuration file can be provided as a string.</li> |
|
| 52 | * <li>Separated as base path and file name: This is the native form in which |
|
| 53 | * the location is stored. The base path is a string defining either a local |
|
| 54 | * directory or a URL. It can be set using the <code>setBasePath()</code> |
|
| 55 | * method. The file name, non surprisingly, defines the name of the configuration |
|
| 56 | * file.</li></ul></p> |
|
| 57 | * <p>Note that the <code>load()</code> methods do not wipe out the configuration's |
|
| 58 | * content before the new configuration file is loaded. Thus it is very easy to |
|
| 59 | * construct a union configuration by simply loading multiple configuration |
|
| 60 | * files, e.g.</p> |
|
| 61 | * <p><pre> |
|
| 62 | * config.load(configFile1); |
|
| 63 | * config.load(configFile2); |
|
| 64 | * </pre></p> |
|
| 65 | * <p>After executing this code fragment, the resulting configuration will |
|
| 66 | * contain both the properties of configFile1 and configFile2. On the other |
|
| 67 | * hand, if the current configuration file is to be reloaded, <code>clear()</code> |
|
| 68 | * should be called first. Otherwise the properties are doubled. This behavior |
|
| 69 | * is analogous to the behavior of the <code>load(InputStream)</code> method |
|
| 70 | * in <code>java.util.Properties</code>.</p> |
|
| 71 | * |
|
| 72 | 3033 | * @author Emmanuel Bourg |
| 73 | * @version $Revision: 156237 $, $Date: 2005-03-05 11:26:22 +0100 (Sa, 05 Mrz 2005) $ |
|
| 74 | * @since 1.0-rc2 |
|
| 75 | */ |
|
| 76 | public abstract class AbstractFileConfiguration extends BaseConfiguration implements FileConfiguration |
|
| 77 | { |
|
| 78 | protected String fileName; |
|
| 79 | ||
| 80 | protected String basePath; |
|
| 81 | ||
| 82 | 3033 | protected boolean autoSave; |
| 83 | 3033 | |
| 84 | 3033 | protected ReloadingStrategy strategy; |
| 85 | ||
| 86 | 4802 | private Object reloadLock = new Object(); |
| 87 | ||
| 88 | private String encoding; |
|
| 89 | ||
| 90 | /** |
|
| 91 | * Default constructor |
|
| 92 | * |
|
| 93 | * @since 1.1 |
|
| 94 | */ |
|
| 95 | public AbstractFileConfiguration() |
|
| 96 | 4802 | { |
| 97 | 6431 | setReloadingStrategy(new InvariantReloadingStrategy()); |
| 98 | 4802 | } |
| 99 | ||
| 100 | 1629 | /** |
| 101 | * Creates and loads the configuration from the specified file. The passed |
|
| 102 | * in string must be a valid file name, either absolute or relativ. |
|
| 103 | 1629 | * |
| 104 | 1620 | * @param fileName The name of the file to load. |
| 105 | * |
|
| 106 | * @throws ConfigurationException Error while loading the file |
|
| 107 | * @since 1.1 |
|
| 108 | */ |
|
| 109 | public AbstractFileConfiguration(String fileName) throws ConfigurationException |
|
| 110 | { |
|
| 111 | 2548 | this(); |
| 112 | ||
| 113 | // store the file name |
|
| 114 | 2548 | setPath(fileName); |
| 115 | 18 | |
| 116 | // load the file |
|
| 117 | 2548 | load(); |
| 118 | 2552 | } |
| 119 | ||
| 120 | /** |
|
| 121 | 18 | * Creates and loads the configuration from the specified file. |
| 122 | * |
|
| 123 | 9 | * @param file The file to load. |
| 124 | * @throws ConfigurationException Error while loading the file |
|
| 125 | 18 | * @since 1.1 |
| 126 | */ |
|
| 127 | public AbstractFileConfiguration(File file) throws ConfigurationException |
|
| 128 | { |
|
| 129 | 28 | this(); |
| 130 | ||
| 131 | // set the file and update the url, the base path and the file name |
|
| 132 | 28 | setFile(file); |
| 133 | ||
| 134 | // load the file |
|
| 135 | 28 | if (file.exists()) |
| 136 | { |
|
| 137 | 14 | load(); |
| 138 | } |
|
| 139 | 28 | } |
| 140 | ||
| 141 | /** |
|
| 142 | * Creates and loads the configuration from the specified URL. |
|
| 143 | * |
|
| 144 | * @param url The location of the file to load. |
|
| 145 | * @throws ConfigurationException Error while loading the file |
|
| 146 | * @since 1.1 |
|
| 147 | */ |
|
| 148 | public AbstractFileConfiguration(URL url) throws ConfigurationException |
|
| 149 | { |
|
| 150 | 0 | this(); |
| 151 | ||
| 152 | 2961 | // set the URL and update the base path and the file name |
| 153 | 2880 | setURL(url); |
| 154 | ||
| 155 | // load the file |
|
| 156 | 0 | load(); |
| 157 | 0 | } |
| 158 | ||
| 159 | /** |
|
| 160 | * Load the configuration from the underlying location. |
|
| 161 | * |
|
| 162 | * @throws ConfigurationException if loading of the configuration fails |
|
| 163 | */ |
|
| 164 | public void load() throws ConfigurationException |
|
| 165 | { |
|
| 166 | 7655 | load(getFileName()); |
| 167 | 7529 | } |
| 168 | ||
| 169 | 81 | /** |
| 170 | * Locate the specified file and load the configuration. |
|
| 171 | 2898 | * |
| 172 | * @param fileName the name of the file loaded |
|
| 173 | 81 | * |
| 174 | * @throws ConfigurationException |
|
| 175 | 81 | */ |
| 176 | public void load(String fileName) throws ConfigurationException |
|
| 177 | { |
|
| 178 | try |
|
| 179 | { |
|
| 180 | 7616 | URL url = ConfigurationUtils.locate(basePath, fileName); |
| 181 | 7616 | if (url == null) |
| 182 | { |
|
| 183 | 126 | throw new ConfigurationException("Cannot locate configuration source " + fileName); |
| 184 | } |
|
| 185 | 4592 | load(url); |
| 186 | } |
|
| 187 | 126 | catch (ConfigurationException e) |
| 188 | { |
|
| 189 | 126 | throw e; |
| 190 | } |
|
| 191 | 0 | catch (Exception e) |
| 192 | { |
|
| 193 | 0 | throw new ConfigurationException(e.getMessage(), e); |
| 194 | 4601 | } |
| 195 | 4592 | } |
| 196 | ||
| 197 | /** |
|
| 198 | * Load the configuration from the specified file. |
|
| 199 | * |
|
| 200 | * @param file the loaded file |
|
| 201 | * |
|
| 202 | * @throws ConfigurationException |
|
| 203 | 9 | */ |
| 204 | 9 | public void load(File file) throws ConfigurationException |
| 205 | { |
|
| 206 | try |
|
| 207 | { |
|
| 208 | 28 | load(file.toURL()); |
| 209 | } |
|
| 210 | 0 | catch (ConfigurationException e) |
| 211 | { |
|
| 212 | 0 | throw e; |
| 213 | } |
|
| 214 | 0 | catch (Exception e) |
| 215 | 4086 | { |
| 216 | 0 | throw new ConfigurationException(e.getMessage(), e); |
| 217 | 28 | } |
| 218 | 28 | } |
| 219 | 4086 | |
| 220 | 4086 | /** |
| 221 | 4086 | * Load the configuration from the specified URL. |
| 222 | * |
|
| 223 | * @param url the URL of the file loaded |
|
| 224 | * |
|
| 225 | * @throws ConfigurationException |
|
| 226 | */ |
|
| 227 | public void load(URL url) throws ConfigurationException |
|
| 228 | { |
|
| 229 | 6482 | InputStream in = null; |
| 230 | ||
| 231 | try |
|
| 232 | { |
|
| 233 | 6482 | in = url.openStream(); |
| 234 | 6482 | load(in); |
| 235 | 10568 | } |
| 236 | 0 | catch (ConfigurationException e) |
| 237 | 4086 | { |
| 238 | 0 | throw e; |
| 239 | } |
|
| 240 | 0 | catch (Exception e) |
| 241 | { |
|
| 242 | 0 | throw new ConfigurationException(e.getMessage(), e); |
| 243 | 8172 | } |
| 244 | 4086 | finally |
| 245 | 4086 | { |
| 246 | // close the input stream |
|
| 247 | 0 | try |
| 248 | { |
|
| 249 | 6482 | if (in != null) |
| 250 | { |
|
| 251 | 6482 | in.close(); |
| 252 | } |
|
| 253 | } |
|
| 254 | 0 | catch (IOException e) |
| 255 | { |
|
| 256 | 0 | e.printStackTrace(); |
| 257 | 17050 | } |
| 258 | 10568 | } |
| 259 | 6482 | } |
| 260 | ||
| 261 | /** |
|
| 262 | * Load the configuration from the specified stream, using the encoding |
|
| 263 | * returned by {@link #getEncoding()}. |
|
| 264 | * |
|
| 265 | * @param in the input stream |
|
| 266 | * |
|
| 267 | * @throws ConfigurationException |
|
| 268 | */ |
|
| 269 | public void load(InputStream in) throws ConfigurationException |
|
| 270 | { |
|
| 271 | 10568 | load(in, getEncoding()); |
| 272 | 6482 | } |
| 273 | 4086 | |
| 274 | /** |
|
| 275 | * Load the configuration from the specified stream, using the specified |
|
| 276 | * encoding. If the encoding is null the default encoding is used. |
|
| 277 | * |
|
| 278 | * @param in the input stream |
|
| 279 | * @param encoding the encoding used. <code>null</code> to use the default encoding |
|
| 280 | * |
|
| 281 | * @throws ConfigurationException |
|
| 282 | */ |
|
| 283 | public void load(InputStream in, String encoding) throws ConfigurationException |
|
| 284 | { |
|
| 285 | 6482 | Reader reader = null; |
| 286 | 4086 | |
| 287 | 6482 | if (encoding != null) |
| 288 | 4086 | { |
| 289 | try |
|
| 290 | { |
|
| 291 | 4086 | reader = new InputStreamReader(in, encoding); |
| 292 | 4086 | } |
| 293 | 0 | catch (UnsupportedEncodingException e) |
| 294 | { |
|
| 295 | 0 | throw new ConfigurationException( |
| 296 | "The requested encoding is not supported, try the default encoding.", e); |
|
| 297 | 0 | } |
| 298 | } |
|
| 299 | ||
| 300 | 6482 | if (reader == null) |
| 301 | 81 | { |
| 302 | 6554 | reader = new InputStreamReader(in); |
| 303 | 72 | } |
| 304 | ||
| 305 | 6482 | load(reader); |
| 306 | 6482 | } |
| 307 | ||
| 308 | /** |
|
| 309 | * Save the configuration. |
|
| 310 | * |
|
| 311 | * @throws ConfigurationException |
|
| 312 | */ |
|
| 313 | public void save() throws ConfigurationException |
|
| 314 | { |
|
| 315 | 126 | save(fileName); |
| 316 | 112 | strategy.init(); |
| 317 | 238 | } |
| 318 | 117 | |
| 319 | /** |
|
| 320 | 9 | * Save the configuration to the specified file. This doesn't change the |
| 321 | * source of the configuration, use setFileName() if you need it. |
|
| 322 | 108 | * |
| 323 | * @param fileName |
|
| 324 | 9 | * |
| 325 | * @throws ConfigurationException |
|
| 326 | 9 | */ |
| 327 | public void save(String fileName) throws ConfigurationException |
|
| 328 | 9 | { |
| 329 | try |
|
| 330 | 9 | { |
| 331 | 304 | File file = ConfigurationUtils.getFile(basePath, fileName); |
| 332 | 290 | if (file == null) |
| 333 | { |
|
| 334 | 14 | throw new ConfigurationException("Invalid file name for save: " + fileName); |
| 335 | } |
|
| 336 | 168 | save(file); |
| 337 | } |
|
| 338 | 14 | catch (ConfigurationException e) |
| 339 | { |
|
| 340 | 14 | throw e; |
| 341 | } |
|
| 342 | 14 | catch (Exception e) |
| 343 | { |
|
| 344 | 14 | throw new ConfigurationException(e.getMessage(), e); |
| 345 | 177 | } |
| 346 | 177 | } |
| 347 | ||
| 348 | /** |
|
| 349 | * Save the configuration to the specified URL if it's a file URL. |
|
| 350 | * This doesn't change the source of the configuration, use setURL() |
|
| 351 | * if you need it. |
|
| 352 | 9 | * |
| 353 | * @param url |
|
| 354 | * |
|
| 355 | * @throws ConfigurationException |
|
| 356 | */ |
|
| 357 | public void save(URL url) throws ConfigurationException |
|
| 358 | { |
|
| 359 | 14 | File file = ConfigurationUtils.fileFromURL(url); |
| 360 | 14 | if (file != null) |
| 361 | { |
|
| 362 | 0 | save(file); |
| 363 | } |
|
| 364 | else |
|
| 365 | { |
|
| 366 | 14 | throw new ConfigurationException("Could not save to URL " + url); |
| 367 | 135 | } |
| 368 | 0 | } |
| 369 | ||
| 370 | /** |
|
| 371 | * Save the configuration to the specified file. The file is created |
|
| 372 | 135 | * automatically if it doesn't exist. This doesn't change the source |
| 373 | 135 | * of the configuration, use {@link #setFile} if you need it. |
| 374 | 135 | * |
| 375 | 135 | * @param file |
| 376 | * |
|
| 377 | * @throws ConfigurationException |
|
| 378 | */ |
|
| 379 | public void save(File file) throws ConfigurationException |
|
| 380 | { |
|
| 381 | 224 | OutputStream out = null; |
| 382 | ||
| 383 | try |
|
| 384 | { |
|
| 385 | 135 | // create the file if necessary |
| 386 | 224 | createPath(file); |
| 387 | 359 | out = new FileOutputStream(file); |
| 388 | 224 | save(out); |
| 389 | 224 | } |
| 390 | 0 | catch (IOException e) |
| 391 | { |
|
| 392 | 0 | throw new ConfigurationException(e.getMessage(), e); |
| 393 | 270 | } |
| 394 | 135 | finally |
| 395 | 135 | { |
| 396 | // close the output stream |
|
| 397 | 0 | try |
| 398 | { |
|
| 399 | 224 | if (out != null) |
| 400 | { |
|
| 401 | 224 | out.close(); |
| 402 | } |
|
| 403 | } |
|
| 404 | 0 | catch (IOException e) |
| 405 | { |
|
| 406 | 0 | e.printStackTrace(); |
| 407 | 583 | } |
| 408 | 359 | } |
| 409 | 224 | } |
| 410 | ||
| 411 | /** |
|
| 412 | * Save the configuration to the specified stream, using the encoding |
|
| 413 | * returned by {@link #getEncoding()}. |
|
| 414 | * |
|
| 415 | * @param out |
|
| 416 | * |
|
| 417 | * @throws ConfigurationException |
|
| 418 | */ |
|
| 419 | public void save(OutputStream out) throws ConfigurationException |
|
| 420 | 135 | { |
| 421 | 224 | save(out, getEncoding()); |
| 422 | 359 | } |
| 423 | ||
| 424 | /** |
|
| 425 | * Save the configuration to the specified stream, using the specified |
|
| 426 | 9 | * encoding. If the encoding is null the default encoding is used. |
| 427 | * |
|
| 428 | * @param out |
|
| 429 | * @param encoding |
|
| 430 | * @throws ConfigurationException |
|
| 431 | */ |
|
| 432 | 9 | public void save(OutputStream out, String encoding) throws ConfigurationException |
| 433 | { |
|
| 434 | 224 | Writer writer = null; |
| 435 | 135 | |
| 436 | 224 | if (encoding != null) |
| 437 | 126 | { |
| 438 | try |
|
| 439 | { |
|
| 440 | 149 | writer = new OutputStreamWriter(out, encoding); |
| 441 | 135 | } |
| 442 | 0 | catch (UnsupportedEncodingException e) |
| 443 | { |
|
| 444 | 0 | throw new ConfigurationException( |
| 445 | "The requested encoding is not supported, try the default encoding.", e); |
|
| 446 | 14 | } |
| 447 | } |
|
| 448 | 3735 | |
| 449 | 224 | if (writer == null) |
| 450 | { |
|
| 451 | 210 | writer = new OutputStreamWriter(out); |
| 452 | } |
|
| 453 | ||
| 454 | 224 | save(writer); |
| 455 | 224 | } |
| 456 | ||
| 457 | /** |
|
| 458 | * Return the name of the file. |
|
| 459 | */ |
|
| 460 | 3420 | public String getFileName() |
| 461 | 3420 | { |
| 462 | 5950 | return fileName; |
| 463 | } |
|
| 464 | ||
| 465 | /** |
|
| 466 | * Set the name of the file. The passed in file name should not contain a |
|
| 467 | * path. Use <code>{@link AbstractFileConfiguration#setPath(String) |
|
| 468 | 1314 | * setPath()}</code> to set a full qualified file name. |
| 469 | * |
|
| 470 | * @param fileName the name of the file |
|
| 471 | */ |
|
| 472 | public void setFileName(String fileName) |
|
| 473 | { |
|
| 474 | 5418 | this.fileName = fileName; |
| 475 | 5418 | } |
| 476 | ||
| 477 | /** |
|
| 478 | * Return the base path. |
|
| 479 | 2889 | */ |
| 480 | 2889 | public String getBasePath() |
| 481 | { |
|
| 482 | 2170 | return basePath; |
| 483 | } |
|
| 484 | ||
| 485 | /** |
|
| 486 | * Set the base path. Relative configurations are loaded from this path. |
|
| 487 | * The base path can be either a path to a directory or a URL. |
|
| 488 | * |
|
| 489 | * @param basePath the base path. |
|
| 490 | */ |
|
| 491 | 90 | public void setBasePath(String basePath) |
| 492 | { |
|
| 493 | 4564 | this.basePath = basePath; |
| 494 | 4564 | } |
| 495 | ||
| 496 | /** |
|
| 497 | * Return the file where the configuration is stored. If the base path is |
|
| 498 | * a URL with a protocol different than "file", the return value |
|
| 499 | * will not point to a valid file object. |
|
| 500 | * |
|
| 501 | * @return the file where the configuration is stored |
|
| 502 | */ |
|
| 503 | 2340 | public File getFile() |
| 504 | 2340 | { |
| 505 | 2578 | return ConfigurationUtils.getFile(getBasePath(), getFileName()); |
| 506 | } |
|
| 507 | ||
| 508 | /** |
|
| 509 | * Set the file where the configuration is stored. The passed in file is |
|
| 510 | * made absolute if it is not yet. Then the file's path component becomes |
|
| 511 | * the base path and its name component becomes the file name. |
|
| 512 | * |
|
| 513 | * @param file the file where the configuration is stored |
|
| 514 | */ |
|
| 515 | public void setFile(File file) |
|
| 516 | 18 | { |
| 517 | 3696 | setFileName(file.getName()); |
| 518 | 3696 | setBasePath((file.getParentFile() != null) ? file.getParentFile().getAbsolutePath() : class="keyword">null); |
| 519 | 3696 | } |
| 520 | ||
| 521 | /** |
|
| 522 | * Returns the full path to the file this configuration is based on. The |
|
| 523 | * return value is valid only if this configuration is based on a file on |
|
| 524 | * the local disk. |
|
| 525 | * |
|
| 526 | * @return the full path to the configuration file |
|
| 527 | 1638 | */ |
| 528 | 1638 | public String getPath() |
| 529 | { |
|
| 530 | 28 | return getFile().getAbsolutePath(); |
| 531 | } |
|
| 532 | ||
| 533 | /** |
|
| 534 | * Sets the location of this configuration as a full path name. The passed |
|
| 535 | * in path should represent a valid file name. |
|
| 536 | * |
|
| 537 | 9 | * @param path the full path name of the configuration file |
| 538 | */ |
|
| 539 | public void setPath(String path) |
|
| 540 | { |
|
| 541 | 2562 | setFile(new File(path)); |
| 542 | 2562 | } |
| 543 | ||
| 544 | /** |
|
| 545 | * Return the URL where the configuration is stored. |
|
| 546 | * |
|
| 547 | * @return the configuration's location as URL |
|
| 548 | */ |
|
| 549 | public URL getURL() |
|
| 550 | 18 | { |
| 551 | 32 | return ConfigurationUtils.locate(getBasePath(), getFileName()); |
| 552 | 18 | } |
| 553 | ||
| 554 | /** |
|
| 555 | * Set the location of this configuration as a URL. For loading this can be |
|
| 556 | 9 | * an arbitrary URL with a supported protocol. If the configuration is to |
| 557 | 9 | * be saved, too, a URL with the "file" protocol should be |
| 558 | * provided. |
|
| 559 | * |
|
| 560 | * @param url the location of this configuration as URL |
|
| 561 | */ |
|
| 562 | public void setURL(URL url) |
|
| 563 | { |
|
| 564 | 28 | setBasePath(ConfigurationUtils.getBasePath(url)); |
| 565 | 28 | setFileName(ConfigurationUtils.getFileName(url)); |
| 566 | 28 | } |
| 567 | ||
| 568 | public void setAutoSave(boolean autoSave) |
|
| 569 | { |
|
| 570 | 62348 | this.autoSave = autoSave; |
| 571 | 14 | } |
| 572 | ||
| 573 | public boolean isAutoSave() |
|
| 574 | 27 | { |
| 575 | 0 | return autoSave; |
| 576 | } |
|
| 577 | ||
| 578 | /** |
|
| 579 | 27 | * Save the configuration if the automatic persistence is enabled |
| 580 | * and if a file is specified. |
|
| 581 | 62334 | */ |
| 582 | protected void possiblySave() |
|
| 583 | { |
|
| 584 | 98238 | if (autoSave && fileName != null) |
| 585 | 61542 | { |
| 586 | 61542 | try |
| 587 | 61542 | { |
| 588 | 42 | save(); |
| 589 | } |
|
| 590 | 0 | catch (ConfigurationException e) |
| 591 | 225 | { |
| 592 | 225 | throw new ConfigurationRuntimeException("Failed to auto-save", e); |
| 593 | 267 | } |
| 594 | } |
|
| 595 | 98238 | } |
| 596 | ||
| 597 | protected void addPropertyDirect(String key, Object obj) |
|
| 598 | { |
|
| 599 | 97006 | super.addPropertyDirect(key, obj); |
| 600 | 97006 | possiblySave(); |
| 601 | 97006 | } |
| 602 | 3042 | |
| 603 | 3042 | public void clearProperty(String key) |
| 604 | 3042 | { |
| 605 | 3392 | super.clearProperty(key); |
| 606 | 350 | possiblySave(); |
| 607 | 350 | } |
| 608 | ||
| 609 | 67914 | public ReloadingStrategy getReloadingStrategy() |
| 610 | { |
|
| 611 | 67914 | return strategy; |
| 612 | } |
|
| 613 | ||
| 614 | public void setReloadingStrategy(ReloadingStrategy strategy) |
|
| 615 | 18 | { |
| 616 | 4848 | this.strategy = strategy; |
| 617 | 4830 | strategy.setConfiguration(this); |
| 618 | 4830 | strategy.init(); |
| 619 | 4848 | } |
| 620 | ||
| 621 | public void reload() |
|
| 622 | { |
|
| 623 | 107002 | synchronized (reloadLock) |
| 624 | { |
|
| 625 | 107020 | if (strategy.reloadingRequired()) |
| 626 | { |
|
| 627 | 67914 | try |
| 628 | 67914 | { |
| 629 | 28 | clear(); |
| 630 | 28 | load(); |
| 631 | ||
| 632 | 64710 | // notify the strategy |
| 633 | 64738 | strategy.reloadingPerformed(); |
| 634 | } |
|
| 635 | 0 | catch (Exception e) |
| 636 | { |
|
| 637 | 0 | e.printStackTrace(); |
| 638 | 63 | // todo rollback the changes if the file can't be reloaded |
| 639 | 91 | } |
| 640 | } |
|
| 641 | 107002 | } |
| 642 | 107002 | } |
| 643 | ||
| 644 | 2682 | public Object getProperty(String key) |
| 645 | 2682 | { |
| 646 | 102004 | reload(); |
| 647 | 102004 | return super.getProperty(key); |
| 648 | } |
|
| 649 | ||
| 650 | 459 | public boolean isEmpty() |
| 651 | 459 | { |
| 652 | 98 | reload(); |
| 653 | 98 | return super.isEmpty(); |
| 654 | } |
|
| 655 | ||
| 656 | public boolean containsKey(String key) |
|
| 657 | { |
|
| 658 | 4186 | reload(); |
| 659 | 4321 | return super.containsKey(key); |
| 660 | } |
|
| 661 | ||
| 662 | 135 | public Iterator getKeys() |
| 663 | { |
|
| 664 | 804 | reload(); |
| 665 | 804 | return super.getKeys(); |
| 666 | } |
|
| 667 | 27 | |
| 668 | /** |
|
| 669 | * Create the path to the specified file. |
|
| 670 | */ |
|
| 671 | 135 | private void createPath(File file) |
| 672 | { |
|
| 673 | 224 | if (file != null) |
| 674 | { |
|
| 675 | 4239 | // create the path to the file if the file doesn't exist |
| 676 | 224 | if (!file.exists()) |
| 677 | { |
|
| 678 | 154 | File parent = file.getParentFile(); |
| 679 | 154 | if (parent != null && !parent.exists()) |
| 680 | 27 | { |
| 681 | 69 | parent.mkdirs(); |
| 682 | } |
|
| 683 | } |
|
| 684 | } |
|
| 685 | 224 | } |
| 686 | ||
| 687 | public String getEncoding() |
|
| 688 | { |
|
| 689 | 6734 | return encoding; |
| 690 | } |
|
| 691 | ||
| 692 | public void setEncoding(String encoding) |
|
| 693 | { |
|
| 694 | 42 | this.encoding = encoding; |
| 695 | 42 | } |
| 696 | } |
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |