Coverage Report - org.apache.commons.configuration.MultiFileHierarchicalConfiguration
 
Classes in this File Line Coverage Branch Coverage Complexity
MultiFileHierarchicalConfiguration
43%
93/216
56%
27/48
1,343
MultiFileHierarchicalConfiguration$1
50%
1/2
N/A
1,343
MultiFileHierarchicalConfiguration$2
33%
1/3
N/A
1,343
 
 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  
 package org.apache.commons.configuration;
 18  
 
 19  
 import java.io.File;
 20  
 import java.io.InputStream;
 21  
 import java.io.OutputStream;
 22  
 import java.io.Reader;
 23  
 import java.io.Writer;
 24  
 import java.math.BigDecimal;
 25  
 import java.math.BigInteger;
 26  
 import java.net.URL;
 27  
 import java.util.Collection;
 28  
 import java.util.Iterator;
 29  
 import java.util.List;
 30  
 import java.util.Properties;
 31  
 import java.util.concurrent.ConcurrentHashMap;
 32  
 import java.util.concurrent.ConcurrentMap;
 33  
 
 34  
 import org.apache.commons.beanutils.BeanUtils;
 35  
 import org.apache.commons.configuration.event.ConfigurationErrorEvent;
 36  
 import org.apache.commons.configuration.event.ConfigurationErrorListener;
 37  
 import org.apache.commons.configuration.event.ConfigurationEvent;
 38  
 import org.apache.commons.configuration.event.ConfigurationListener;
 39  
 import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
 40  
 import org.apache.commons.configuration.reloading.ReloadingStrategy;
 41  
 import org.apache.commons.configuration.resolver.EntityResolverSupport;
 42  
 import org.apache.commons.configuration.tree.ConfigurationNode;
 43  
 import org.apache.commons.configuration.tree.ExpressionEngine;
 44  
 import org.apache.commons.lang.text.StrSubstitutor;
 45  
 import org.apache.commons.logging.Log;
 46  
 import org.apache.commons.logging.LogFactory;
 47  
 import org.xml.sax.EntityResolver;
 48  
 import org.xml.sax.SAXParseException;
 49  
 
 50  
 /**
 51  
  * This class provides access to multiple configuration files that reside in a location that
 52  
  * can be specified by a pattern allowing applications to be multi-tenant.  For example,
 53  
  * providing a pattern of "file:///opt/config/${product}/${client}/config.xml" will result in
 54  
  * "product" and "client" being resolved on every call. The configuration resulting from the
 55  
  * resolved pattern will be saved for future access.
 56  
  * @since 1.6
 57  
  * @author <a
 58  
  * href="http://commons.apache.org/configuration/team-list.html">Commons
 59  
  * Configuration team</a>
 60  
  * @version $Id: org.apache.commons.configuration.MultiFileHierarchicalConfiguration.html 901807 2014-03-16 10:49:30Z oheger $
 61  
  */
 62  
 public class MultiFileHierarchicalConfiguration extends AbstractHierarchicalFileConfiguration
 63  
     implements ConfigurationListener, ConfigurationErrorListener, EntityResolverSupport
 64  
 {
 65  
     /**
 66  
      * Prevent recursion while resolving unprefixed properties.
 67  
      */
 68  1
     private static ThreadLocal<Boolean> recursive = new ThreadLocal<Boolean>()
 69  1
     {
 70  
         @Override
 71  
         protected synchronized Boolean initialValue()
 72  
         {
 73  0
             return Boolean.FALSE;
 74  
         }
 75  
     };
 76  
 
 77  
     /** Map of configurations */
 78  30
     private final ConcurrentMap<String, XMLConfiguration> configurationsMap =
 79  
             new ConcurrentHashMap<String, XMLConfiguration>();
 80  
 
 81  
     /** key pattern for configurationsMap */
 82  
     private String pattern;
 83  
 
 84  
     /** True if the constructor has finished */
 85  
     private boolean init;
 86  
 
 87  
     /** Return an empty configuration if loading fails */
 88  30
     private boolean ignoreException = true;
 89  
 
 90  
     /** Capture the schema validation setting */
 91  
     private boolean schemaValidation;
 92  
 
 93  
     /** Stores a flag whether DTD or Schema validation should be performed.*/
 94  
     private boolean validating;
 95  
 
 96  
     /** A flag whether attribute splitting is disabled.*/
 97  
     private boolean attributeSplittingDisabled;
 98  
 
 99  
     /** The Logger name to use */
 100  30
     private String loggerName = MultiFileHierarchicalConfiguration.class.getName();
 101  
 
 102  
     /** The Reloading strategy to use on created configurations */
 103  
     private ReloadingStrategy fileStrategy;
 104  
 
 105  
     /** The EntityResolver */
 106  
     private EntityResolver entityResolver;
 107  
 
 108  
     /** The internally used helper object for variable substitution. */
 109  30
     private StrSubstitutor localSubst = new StrSubstitutor(new ConfigurationInterpolator());
 110  
 
 111  
     /**
 112  
      * Default Constructor.
 113  
      */
 114  
     public MultiFileHierarchicalConfiguration()
 115  
     {
 116  28
         super();
 117  28
         this.init = true;
 118  28
         setLogger(LogFactory.getLog(loggerName));
 119  28
     }
 120  
 
 121  
     /**
 122  
      * Construct the configuration with the specified pattern.
 123  
      * @param pathPattern The pattern to use to locate configuration files.
 124  
      */
 125  
     public MultiFileHierarchicalConfiguration(String pathPattern)
 126  
     {
 127  2
         super();
 128  2
         this.pattern = pathPattern;
 129  2
         this.init = true;
 130  2
         setLogger(LogFactory.getLog(loggerName));
 131  2
     }
 132  
 
 133  
     public void setLoggerName(String name)
 134  
     {
 135  0
         this.loggerName = name;
 136  0
     }
 137  
 
 138  
     /**
 139  
      * Set the File pattern
 140  
      * @param pathPattern The pattern for the path to the configuration.
 141  
      */
 142  
     public void setFilePattern(String pathPattern)
 143  
     {
 144  28
         this.pattern = pathPattern;
 145  28
     }
 146  
 
 147  
     public boolean isSchemaValidation()
 148  
     {
 149  0
         return schemaValidation;
 150  
     }
 151  
 
 152  
     public void setSchemaValidation(boolean schemaValidation)
 153  
     {
 154  27
         this.schemaValidation = schemaValidation;
 155  27
     }
 156  
 
 157  
     public boolean isValidating()
 158  
     {
 159  0
         return validating;
 160  
     }
 161  
 
 162  
     public void setValidating(boolean validating)
 163  
     {
 164  0
         this.validating = validating;
 165  0
     }
 166  
 
 167  
     public boolean isAttributeSplittingDisabled()
 168  
     {
 169  60
         return attributeSplittingDisabled;
 170  
     }
 171  
 
 172  
     public void setAttributeSplittingDisabled(boolean attributeSplittingDisabled)
 173  
     {
 174  0
         this.attributeSplittingDisabled = attributeSplittingDisabled;
 175  0
     }
 176  
 
 177  
     @Override
 178  
     public ReloadingStrategy getReloadingStrategy()
 179  
     {
 180  0
         return fileStrategy;
 181  
     }
 182  
 
 183  
     @Override
 184  
     public void setReloadingStrategy(ReloadingStrategy strategy)
 185  
     {
 186  18
         this.fileStrategy = strategy;
 187  18
     }
 188  
 
 189  
     public void setEntityResolver(EntityResolver entityResolver)
 190  
     {
 191  28
         this.entityResolver = entityResolver;
 192  28
     }
 193  
 
 194  
     public EntityResolver getEntityResolver()
 195  
     {
 196  0
         return this.entityResolver;
 197  
     }
 198  
 
 199  
     /**
 200  
      * Set to true if an empty Configuration should be returned when loading fails. If
 201  
      * false an exception will be thrown.
 202  
      * @param ignoreException The ignore value.
 203  
      */
 204  
     public void setIgnoreException(boolean ignoreException)
 205  
     {
 206  0
         this.ignoreException = ignoreException;
 207  0
     }
 208  
 
 209  
     @Override
 210  
     public void addProperty(String key, Object value)
 211  
     {
 212  0
         this.getConfiguration().addProperty(key, value);
 213  0
     }
 214  
 
 215  
     @Override
 216  
     public void clear()
 217  
     {
 218  0
         this.getConfiguration().clear();
 219  0
     }
 220  
 
 221  
     @Override
 222  
     public void clearProperty(String key)
 223  
     {
 224  0
         this.getConfiguration().clearProperty(key);
 225  0
     }
 226  
 
 227  
     @Override
 228  
     public boolean containsKey(String key)
 229  
     {
 230  0
         return this.getConfiguration().containsKey(key);
 231  
     }
 232  
 
 233  
     @Override
 234  
     public BigDecimal getBigDecimal(String key, BigDecimal defaultValue)
 235  
     {
 236  0
         return this.getConfiguration().getBigDecimal(key, defaultValue);
 237  
     }
 238  
 
 239  
     @Override
 240  
     public BigDecimal getBigDecimal(String key)
 241  
     {
 242  0
         return this.getConfiguration().getBigDecimal(key);
 243  
     }
 244  
 
 245  
     @Override
 246  
     public BigInteger getBigInteger(String key, BigInteger defaultValue)
 247  
     {
 248  0
         return this.getConfiguration().getBigInteger(key, defaultValue);
 249  
     }
 250  
 
 251  
     @Override
 252  
     public BigInteger getBigInteger(String key)
 253  
     {
 254  0
         return this.getConfiguration().getBigInteger(key);
 255  
     }
 256  
 
 257  
     @Override
 258  
     public boolean getBoolean(String key, boolean defaultValue)
 259  
     {
 260  0
         return this.getConfiguration().getBoolean(key, defaultValue);
 261  
     }
 262  
 
 263  
     @Override
 264  
     public Boolean getBoolean(String key, Boolean defaultValue)
 265  
     {
 266  0
         return this.getConfiguration().getBoolean(key, defaultValue);
 267  
     }
 268  
 
 269  
     @Override
 270  
     public boolean getBoolean(String key)
 271  
     {
 272  0
         return this.getConfiguration().getBoolean(key);
 273  
     }
 274  
 
 275  
     @Override
 276  
     public byte getByte(String key, byte defaultValue)
 277  
     {
 278  0
         return this.getConfiguration().getByte(key, defaultValue);
 279  
     }
 280  
 
 281  
     @Override
 282  
     public Byte getByte(String key, Byte defaultValue)
 283  
     {
 284  0
         return this.getConfiguration().getByte(key, defaultValue);
 285  
     }
 286  
 
 287  
     @Override
 288  
     public byte getByte(String key)
 289  
     {
 290  0
         return this.getConfiguration().getByte(key);
 291  
     }
 292  
 
 293  
     @Override
 294  
     public double getDouble(String key, double defaultValue)
 295  
     {
 296  0
         return this.getConfiguration().getDouble(key, defaultValue);
 297  
     }
 298  
 
 299  
     @Override
 300  
     public Double getDouble(String key, Double defaultValue)
 301  
     {
 302  0
         return this.getConfiguration().getDouble(key, defaultValue);
 303  
     }
 304  
 
 305  
     @Override
 306  
     public double getDouble(String key)
 307  
     {
 308  0
         return this.getConfiguration().getDouble(key);
 309  
     }
 310  
 
 311  
     @Override
 312  
     public float getFloat(String key, float defaultValue)
 313  
     {
 314  0
         return this.getConfiguration().getFloat(key, defaultValue);
 315  
     }
 316  
 
 317  
     @Override
 318  
     public Float getFloat(String key, Float defaultValue)
 319  
     {
 320  0
         return this.getConfiguration().getFloat(key, defaultValue);
 321  
     }
 322  
 
 323  
     @Override
 324  
     public float getFloat(String key)
 325  
     {
 326  0
         return this.getConfiguration().getFloat(key);
 327  
     }
 328  
 
 329  
     @Override
 330  
     public int getInt(String key, int defaultValue)
 331  
     {
 332  0
         return this.getConfiguration().getInt(key, defaultValue);
 333  
     }
 334  
 
 335  
     @Override
 336  
     public int getInt(String key)
 337  
     {
 338  3
         return this.getConfiguration().getInt(key);
 339  
     }
 340  
 
 341  
     @Override
 342  
     public Integer getInteger(String key, Integer defaultValue)
 343  
     {
 344  0
         return this.getConfiguration().getInteger(key, defaultValue);
 345  
     }
 346  
 
 347  
     @Override
 348  
     public Iterator<String> getKeys()
 349  
     {
 350  0
         return this.getConfiguration().getKeys();
 351  
     }
 352  
 
 353  
     @Override
 354  
     public Iterator<String> getKeys(String prefix)
 355  
     {
 356  0
         return this.getConfiguration().getKeys(prefix);
 357  
     }
 358  
 
 359  
     @Override
 360  
     public List<Object> getList(String key, List<?> defaultValue)
 361  
     {
 362  0
         return this.getConfiguration().getList(key, defaultValue);
 363  
     }
 364  
 
 365  
     @Override
 366  
     public List<Object> getList(String key)
 367  
     {
 368  0
         return this.getConfiguration().getList(key);
 369  
     }
 370  
 
 371  
     @Override
 372  
     public long getLong(String key, long defaultValue)
 373  
     {
 374  0
         return this.getConfiguration().getLong(key, defaultValue);
 375  
     }
 376  
 
 377  
     @Override
 378  
     public Long getLong(String key, Long defaultValue)
 379  
     {
 380  0
         return this.getConfiguration().getLong(key, defaultValue);
 381  
     }
 382  
 
 383  
     @Override
 384  
     public long getLong(String key)
 385  
     {
 386  0
         return this.getConfiguration().getLong(key);
 387  
     }
 388  
 
 389  
     @Override
 390  
     public Properties getProperties(String key)
 391  
     {
 392  0
         return this.getConfiguration().getProperties(key);
 393  
     }
 394  
 
 395  
     @Override
 396  
     public Object getProperty(String key)
 397  
     {
 398  205695
         return this.getConfiguration().getProperty(key);
 399  
     }
 400  
 
 401  
     @Override
 402  
     public short getShort(String key, short defaultValue)
 403  
     {
 404  0
         return this.getConfiguration().getShort(key, defaultValue);
 405  
     }
 406  
 
 407  
     @Override
 408  
     public Short getShort(String key, Short defaultValue)
 409  
     {
 410  0
         return this.getConfiguration().getShort(key, defaultValue);
 411  
     }
 412  
 
 413  
     @Override
 414  
     public short getShort(String key)
 415  
     {
 416  0
         return this.getConfiguration().getShort(key);
 417  
     }
 418  
 
 419  
     @Override
 420  
     public String getString(String key, String defaultValue)
 421  
     {
 422  0
         return this.getConfiguration().getString(key, defaultValue);
 423  
     }
 424  
 
 425  
     @Override
 426  
     public String getString(String key)
 427  
     {
 428  0
         return this.getConfiguration().getString(key);
 429  
     }
 430  
 
 431  
     @Override
 432  
     public String[] getStringArray(String key)
 433  
     {
 434  0
         return this.getConfiguration().getStringArray(key);
 435  
     }
 436  
 
 437  
     @Override
 438  
     public boolean isEmpty()
 439  
     {
 440  0
         return this.getConfiguration().isEmpty();
 441  
     }
 442  
 
 443  
     @Override
 444  
     public void setProperty(String key, Object value)
 445  
     {
 446  0
         if (init)
 447  
         {
 448  0
             this.getConfiguration().setProperty(key, value);
 449  
         }
 450  0
     }
 451  
 
 452  
     @Override
 453  
     public Configuration subset(String prefix)
 454  
     {
 455  0
         return this.getConfiguration().subset(prefix);
 456  
     }
 457  
 
 458  
     @Override
 459  
     public Object getReloadLock()
 460  
     {
 461  675
         return this.getConfiguration().getReloadLock();
 462  
     }
 463  
 
 464  
     @Override
 465  
     public Node getRoot()
 466  
     {
 467  0
         return this.getConfiguration().getRoot();
 468  
     }
 469  
 
 470  
     @Override
 471  
     public void setRoot(Node node)
 472  
     {
 473  0
         if (init)
 474  
         {
 475  0
             this.getConfiguration().setRoot(node);
 476  
         }
 477  
         else
 478  
         {
 479  0
             super.setRoot(node);
 480  
         }
 481  0
     }
 482  
 
 483  
     @Override
 484  
     public ConfigurationNode getRootNode()
 485  
     {
 486  673
         return this.getConfiguration().getRootNode();
 487  
     }
 488  
 
 489  
     @Override
 490  
     public void setRootNode(ConfigurationNode rootNode)
 491  
     {
 492  30
         if (init)
 493  
         {
 494  0
             this.getConfiguration().setRootNode(rootNode);
 495  
         }
 496  
         else
 497  
         {
 498  30
             super.setRootNode(rootNode);
 499  
         }
 500  30
     }
 501  
 
 502  
     @Override
 503  
     public ExpressionEngine getExpressionEngine()
 504  
     {
 505  60
         return super.getExpressionEngine();
 506  
     }
 507  
 
 508  
     @Override
 509  
     public void setExpressionEngine(ExpressionEngine expressionEngine)
 510  
     {
 511  28
         super.setExpressionEngine(expressionEngine);
 512  28
     }
 513  
 
 514  
     @Override
 515  
     public void addNodes(String key, Collection<? extends ConfigurationNode> nodes)
 516  
     {
 517  0
         this.getConfiguration().addNodes(key, nodes);
 518  0
     }
 519  
 
 520  
     @Override
 521  
     public SubnodeConfiguration configurationAt(String key, boolean supportUpdates)
 522  
     {
 523  0
         return this.getConfiguration().configurationAt(key, supportUpdates);
 524  
     }
 525  
 
 526  
     @Override
 527  
     public SubnodeConfiguration configurationAt(String key)
 528  
     {
 529  0
         return this.getConfiguration().configurationAt(key);
 530  
     }
 531  
 
 532  
     @Override
 533  
     public List<HierarchicalConfiguration> configurationsAt(String key)
 534  
     {
 535  0
         return this.getConfiguration().configurationsAt(key);
 536  
     }
 537  
 
 538  
     @Override
 539  
     public void clearTree(String key)
 540  
     {
 541  0
         this.getConfiguration().clearTree(key);
 542  0
     }
 543  
 
 544  
     @Override
 545  
     public int getMaxIndex(String key)
 546  
     {
 547  0
         return this.getConfiguration().getMaxIndex(key);
 548  
     }
 549  
 
 550  
     @Override
 551  
     public Configuration interpolatedConfiguration()
 552  
     {
 553  0
         return this.getConfiguration().interpolatedConfiguration();
 554  
     }
 555  
 
 556  
     @Override
 557  
     public void addConfigurationListener(ConfigurationListener l)
 558  
     {
 559  63
         super.addConfigurationListener(l);
 560  63
     }
 561  
 
 562  
     @Override
 563  
     public boolean removeConfigurationListener(ConfigurationListener l)
 564  
     {
 565  0
         return super.removeConfigurationListener(l);
 566  
     }
 567  
 
 568  
     @Override
 569  
     public Collection<ConfigurationListener> getConfigurationListeners()
 570  
     {
 571  1015
         return super.getConfigurationListeners();
 572  
     }
 573  
 
 574  
     @Override
 575  
     public void clearConfigurationListeners()
 576  
     {
 577  0
         super.clearConfigurationListeners();
 578  0
     }
 579  
 
 580  
     @Override
 581  
     public void addErrorListener(ConfigurationErrorListener l)
 582  
     {
 583  0
         super.addErrorListener(l);
 584  0
     }
 585  
 
 586  
     @Override
 587  
     public boolean removeErrorListener(ConfigurationErrorListener l)
 588  
     {
 589  0
         return super.removeErrorListener(l);
 590  
     }
 591  
 
 592  
     @Override
 593  
     public void clearErrorListeners()
 594  
     {
 595  0
         super.clearErrorListeners();
 596  0
     }
 597  
 
 598  
     @Override
 599  
     public Collection<ConfigurationErrorListener> getErrorListeners()
 600  
     {
 601  2
         return super.getErrorListeners();
 602  
     }
 603  
 
 604  
     public void save(Writer writer) throws ConfigurationException
 605  
     {
 606  0
         if (init)
 607  
         {
 608  0
             this.getConfiguration().save(writer);
 609  
         }
 610  0
     }
 611  
 
 612  
     public void load(Reader reader) throws ConfigurationException
 613  
     {
 614  0
         if (init)
 615  
         {
 616  0
             this.getConfiguration().load(reader);
 617  
         }
 618  0
     }
 619  
 
 620  
     @Override
 621  
     public void load() throws ConfigurationException
 622  
     {
 623  28
         this.getConfiguration();
 624  28
     }
 625  
 
 626  
     @Override
 627  
     public void load(String fileName) throws ConfigurationException
 628  
     {
 629  0
         this.getConfiguration().load(fileName);
 630  0
     }
 631  
 
 632  
     @Override
 633  
     public void load(File file) throws ConfigurationException
 634  
     {
 635  0
         this.getConfiguration().load(file);
 636  0
     }
 637  
 
 638  
     @Override
 639  
     public void load(URL url) throws ConfigurationException
 640  
     {
 641  0
         this.getConfiguration().load(url);
 642  0
     }
 643  
 
 644  
     @Override
 645  
     public void load(InputStream in) throws ConfigurationException
 646  
     {
 647  0
         this.getConfiguration().load(in);
 648  0
     }
 649  
 
 650  
     @Override
 651  
     public void load(InputStream in, String encoding) throws ConfigurationException
 652  
     {
 653  0
         this.getConfiguration().load(in, encoding);
 654  0
     }
 655  
 
 656  
     @Override
 657  
     public void save() throws ConfigurationException
 658  
     {
 659  0
         this.getConfiguration().save();
 660  0
     }
 661  
 
 662  
     @Override
 663  
     public void save(String fileName) throws ConfigurationException
 664  
     {
 665  0
         this.getConfiguration().save(fileName);
 666  0
     }
 667  
 
 668  
     @Override
 669  
     public void save(File file) throws ConfigurationException
 670  
     {
 671  0
         this.getConfiguration().save(file);
 672  0
     }
 673  
 
 674  
     @Override
 675  
     public void save(URL url) throws ConfigurationException
 676  
     {
 677  0
         this.getConfiguration().save(url);
 678  0
     }
 679  
 
 680  
     @Override
 681  
     public void save(OutputStream out) throws ConfigurationException
 682  
     {
 683  0
         this.getConfiguration().save(out);
 684  0
     }
 685  
 
 686  
     @Override
 687  
     public void save(OutputStream out, String encoding) throws ConfigurationException
 688  
     {
 689  0
         this.getConfiguration().save(out, encoding);
 690  0
     }
 691  
 
 692  
     @Override
 693  
     public void configurationChanged(ConfigurationEvent event)
 694  
     {
 695  1017
         if (event.getSource() instanceof XMLConfiguration)
 696  
         {
 697  1017
             for (ConfigurationListener listener : getConfigurationListeners())
 698  
             {
 699  2418
                 listener.configurationChanged(event);
 700  2422
             }
 701  
         }
 702  1018
     }
 703  
 
 704  
     @Override
 705  
     public void configurationError(ConfigurationErrorEvent event)
 706  
     {
 707  2
         if (event.getSource() instanceof XMLConfiguration)
 708  
         {
 709  2
             for (ConfigurationErrorListener listener : getErrorListeners())
 710  
             {
 711  0
                 listener.configurationError(event);
 712  0
             }
 713  
         }
 714  
 
 715  2
         if (event.getType() == AbstractFileConfiguration.EVENT_RELOAD)
 716  
         {
 717  2
             if (isThrowable(event.getCause()))
 718  
             {
 719  2
                 throw new ConfigurationRuntimeException(event.getCause());
 720  
             }
 721  
         }
 722  0
     }
 723  
 
 724  
     /*
 725  
      * Don't allow resolveContainerStore to be called recursively.
 726  
      * @param key The key to resolve.
 727  
      * @return The value of the key.
 728  
      */
 729  
     @Override
 730  
     protected Object resolveContainerStore(String key)
 731  
     {
 732  0
         if (recursive.get().booleanValue())
 733  
         {
 734  0
             return null;
 735  
         }
 736  0
         recursive.set(Boolean.TRUE);
 737  
         try
 738  
         {
 739  0
             return super.resolveContainerStore(key);
 740  
         }
 741  
         finally
 742  
         {
 743  0
             recursive.set(Boolean.FALSE);
 744  
         }
 745  
     }
 746  
 
 747  
     /**
 748  
      * Remove the current Configuration.
 749  
      */
 750  
     public void removeConfiguration()
 751  
     {
 752  0
         String path = getSubstitutor().replace(pattern);
 753  0
         configurationsMap.remove(path);
 754  0
     }
 755  
 
 756  
     /**
 757  
      * First checks to see if the cache exists, if it does, get the associated Configuration.
 758  
      * If not it will load a new Configuration and save it in the cache.
 759  
      *
 760  
      * @return the Configuration associated with the current value of the path pattern.
 761  
      */
 762  
     private AbstractHierarchicalFileConfiguration getConfiguration()
 763  
     {
 764  207044
         if (pattern == null)
 765  
         {
 766  0
             throw new ConfigurationRuntimeException("File pattern must be defined");
 767  
         }
 768  207116
         String path = localSubst.replace(pattern);
 769  
 
 770  207149
         if (configurationsMap.containsKey(path))
 771  
         {
 772  207034
             return configurationsMap.get(path);
 773  
         }
 774  
 
 775  81
         if (path.equals(pattern))
 776  
         {
 777  21
             XMLConfiguration configuration = new XMLConfiguration()
 778  21
             {
 779  
                 @Override
 780  
                 public void load() throws ConfigurationException
 781  
                 {
 782  0
                 }
 783  
                 @Override
 784  
                 public void save() throws ConfigurationException
 785  
                 {
 786  0
                 }
 787  
             };
 788  
 
 789  21
             configurationsMap.putIfAbsent(pattern, configuration);
 790  
 
 791  21
             return configuration;
 792  
         }
 793  
 
 794  60
         XMLConfiguration configuration = new XMLConfiguration();
 795  60
         if (loggerName != null)
 796  
         {
 797  60
             Log log = LogFactory.getLog(loggerName);
 798  60
             if (log != null)
 799  
             {
 800  60
                 configuration.setLogger(log);
 801  
             }
 802  
         }
 803  60
         configuration.setBasePath(getBasePath());
 804  60
         configuration.setFileName(path);
 805  60
         configuration.setFileSystem(getFileSystem());
 806  60
         configuration.setExpressionEngine(getExpressionEngine());
 807  60
         ReloadingStrategy strategy = createReloadingStrategy();
 808  60
         if (strategy != null)
 809  
         {
 810  21
             configuration.setReloadingStrategy(strategy);
 811  
         }
 812  60
         configuration.setDelimiterParsingDisabled(isDelimiterParsingDisabled());
 813  60
         configuration.setAttributeSplittingDisabled(isAttributeSplittingDisabled());
 814  60
         configuration.setValidating(validating);
 815  60
         configuration.setSchemaValidation(schemaValidation);
 816  60
         configuration.setEntityResolver(entityResolver);
 817  60
         configuration.setListDelimiter(getListDelimiter());
 818  60
         configuration.addConfigurationListener(this);
 819  60
         configuration.addErrorListener(this);
 820  
         try
 821  
         {
 822  60
             configuration.load();
 823  
         }
 824  12
         catch (ConfigurationException ce)
 825  
         {
 826  12
             if (isThrowable(ce))
 827  
             {
 828  1
                 throw new ConfigurationRuntimeException(ce);
 829  
             }
 830  48
         }
 831  59
         configurationsMap.putIfAbsent(path, configuration);
 832  59
         return configurationsMap.get(path);
 833  
     }
 834  
 
 835  
     private boolean isThrowable(Throwable throwable)
 836  
     {
 837  14
         if (!ignoreException)
 838  
         {
 839  0
             return true;
 840  
         }
 841  14
         Throwable cause = throwable.getCause();
 842  14
         while (cause != null && !(cause instanceof SAXParseException))
 843  
         {
 844  0
             cause = cause.getCause();
 845  
         }
 846  14
         return cause != null;
 847  
     }
 848  
 
 849  
     /**
 850  
      * Clone the FileReloadingStrategy since each file needs its own.
 851  
      * @return A new FileReloadingStrategy.
 852  
      */
 853  
     private ReloadingStrategy createReloadingStrategy()
 854  
     {
 855  60
         if (fileStrategy == null)
 856  
         {
 857  39
             return null;
 858  
         }
 859  
         try
 860  
         {
 861  21
             ReloadingStrategy strategy = (ReloadingStrategy) BeanUtils.cloneBean(fileStrategy);
 862  21
             strategy.setConfiguration(null);
 863  21
             return strategy;
 864  
         }
 865  0
         catch (Exception ex)
 866  
         {
 867  0
             return null;
 868  
         }
 869  
     }
 870  
 
 871  
 }