Coverage report

  %line %branch
org.apache.commons.configuration.AbstractConfiguration
97% 
96% 

 1  
 /*
 2  
  * Copyright 2001-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.math.BigDecimal;
 20  
 import java.math.BigInteger;
 21  
 import java.util.ArrayList;
 22  
 import java.util.Iterator;
 23  
 import java.util.List;
 24  
 import java.util.NoSuchElementException;
 25  
 import java.util.Properties;
 26  
 
 27  
 import org.apache.commons.collections.Predicate;
 28  
 import org.apache.commons.collections.iterators.FilterIterator;
 29  
 import org.apache.commons.lang.BooleanUtils;
 30  
 
 31  
 /**
 32  
  * Abstract configuration class. Provide basic functionality but does not store
 33  
  * any data. If you want to write your own Configuration class then you should
 34  
  * implement only abstract methods from this class.
 35  
  *
 36  
  * @author <a href="mailto:ksh@scand.com">Konstantin Shaposhnikov </a>
 37  
  * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger </a>
 38  
  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen </a>
 39  
  * @version $Id: AbstractConfiguration.java,v 1.29 2004/12/02 22:05:52 ebourg
 40  
  * Exp $
 41  
  */
 42  4564
 public abstract class AbstractConfiguration implements Configuration
 43  
 {
 44  
     /** start token */
 45  
     protected static final String START_TOKEN = "${";
 46  
 
 47  
     /** end token */
 48  
     protected static final String END_TOKEN = "}";
 49  
 
 50  
     /** The property delimiter used while parsing (a comma). */
 51  123
     private static char delimiter = ',';
 52  
 
 53  
     /**
 54  
      * Whether the configuration should throw NoSuchElementExceptions or simply
 55  
      * return null when a property does not exist. Defaults to return null.
 56  
      */
 57  
     private boolean throwExceptionOnMissing;
 58  
 
 59  
     /**
 60  
      * For configurations extending AbstractConfiguration, allow them to change
 61  
      * the delimiter from the default comma (",").
 62  
      *
 63  
      * @param delimiter The new delimiter
 64  
      */
 65  
     public static void setDelimiter(char delimiter)
 66  
     {
 67  9
         AbstractConfiguration.delimiter = delimiter;
 68  9
     }
 69  
 
 70  
     /**
 71  
      * Retrieve the current delimiter. By default this is a comma (",").
 72  
      *
 73  
      * @return The delimiter in use
 74  
      */
 75  
     public static char getDelimiter()
 76  
     {
 77  94760
         return AbstractConfiguration.delimiter;
 78  
     }
 79  
 
 80  
     /**
 81  
      * Allows to set the <code>throwExceptionOnMissing</code> flag. This
 82  
      * flag controls the behavior of property getter methods that return
 83  
      * objects if the requested property is missing. If the flag is set to
 84  
      * <b>false</b> (which is the default value), these methods will return
 85  
      * <b>null</b>. If set to <b>true</b>, they will throw a
 86  
      * <code>NoSuchElementException</code> exception. Note that getter methods
 87  
      * for primitive data types are not affected by this flag.
 88  
      *
 89  
      * @param throwExceptionOnMissing The new value for the property
 90  
      */
 91  
     public void setThrowExceptionOnMissing(boolean throwExceptionOnMissing)
 92  
     {
 93  1092
         this.throwExceptionOnMissing = throwExceptionOnMissing;
 94  1092
     }
 95  
 
 96  
     /**
 97  
      * Returns true if missing values throw Exceptions.
 98  
      *
 99  
      * @return true if missing values throw Exceptions
 100  
      */
 101  
     public boolean isThrowExceptionOnMissing()
 102  
     {
 103  828
         return throwExceptionOnMissing;
 104  
     }
 105  
 
 106  
     /**
 107  
      * {@inheritDoc}
 108  
      */
 109  
     public void addProperty(String key, Object value)
 110  
     {
 111  75099
         Iterator it = PropertyConverter.toIterator(value, getDelimiter());
 112  233844
         while (it.hasNext())
 113  
         {
 114  83649
             addPropertyDirect(key, it.next());
 115  
         }
 116  75096
     }
 117  
 
 118  
     /**
 119  
      * Adds a key/value pair to the Configuration. Override this method to
 120  
      * provide write acces to underlying Configuration store.
 121  
      *
 122  
      * @param key key to use for mapping
 123  
      * @param value object to store
 124  
      */
 125  
     protected abstract void addPropertyDirect(String key, Object value);
 126  
 
 127  
     /**
 128  
      * interpolate key names to handle ${key} stuff
 129  
      *
 130  
      * @param base string to interpolate
 131  
      *
 132  
      * @return returns the key name with the ${key} substituted
 133  
      */
 134  
     protected String interpolate(String base)
 135  
     {
 136  3060
         return interpolateHelper(base, null);
 137  
     }
 138  
 
 139  
     /**
 140  
      * Returns the interpolated value. Non String values are returned without change.
 141  
      *
 142  
      * @param value the value to interpolate
 143  
      *
 144  
      * @return returns the value with variables substituted
 145  
      */
 146  
     protected Object interpolate(Object value)
 147  
     {
 148  3030
         if (value instanceof String)
 149  
         {
 150  1941
             return interpolate((String) value);
 151  
         }
 152  
         else
 153  
         {
 154  1089
             return value;
 155  
         }
 156  
     }
 157  
 
 158  
     /**
 159  
      * Recursive handler for multple levels of interpolation.
 160  
      *
 161  
      * When called the first time, priorVariables should be null.
 162  
      *
 163  
      * @param base string with the ${key} variables
 164  
      * @param priorVariables serves two purposes: to allow checking for loops,
 165  
      * and creating a meaningful exception message should a loop occur. It's
 166  
      * 0'th element will be set to the value of base from the first call. All
 167  
      * subsequent interpolated variables are added afterward.
 168  
      *
 169  
      * @return the string with the interpolation taken care of
 170  
      */
 171  
     protected String interpolateHelper(String base, List priorVariables)
 172  
     {
 173  3306
         if (base == null)
 174  
         {
 175  48
             return null;
 176  
         }
 177  
 
 178  
         // on the first call initialize priorVariables
 179  
         // and add base as the first element
 180  3258
         if (priorVariables == null)
 181  
         {
 182  3012
             priorVariables = new ArrayList();
 183  3012
             priorVariables.add(base);
 184  
         }
 185  
 
 186  3258
         int begin = -1;
 187  3258
         int end = -1;
 188  3258
         int prec = 0 - END_TOKEN.length();
 189  3258
         StringBuffer result = new StringBuffer();
 190  
 
 191  
         // FIXME: we should probably allow the escaping of the start token
 192  3258
         while (((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length())) > -1)
 193  3498
                 && ((end = base.indexOf(END_TOKEN, begin)) > -1))
 194  
         {
 195  258
             result.append(base.substring(prec + END_TOKEN.length(), begin));
 196  258
             String variable = base.substring(begin + START_TOKEN.length(), end);
 197  
 
 198  
             // if we've got a loop, create a useful exception message and throw
 199  258
             if (priorVariables.contains(variable))
 200  
             {
 201  6
                 String initialBase = priorVariables.remove(0).toString();
 202  6
                 priorVariables.add(variable);
 203  6
                 StringBuffer priorVariableSb = new StringBuffer();
 204  
 
 205  
                 // create a nice trace of interpolated variables like so:
 206  
                 // var1->var2->var3
 207  30
                 for (Iterator it = priorVariables.iterator(); it.hasNext();)
 208  
                 {
 209  18
                     priorVariableSb.append(it.next());
 210  18
                     if (it.hasNext())
 211  
                     {
 212  12
                         priorVariableSb.append("->");
 213  
                     }
 214  
                 }
 215  
 
 216  6
                 throw new IllegalStateException("infinite loop in property interpolation of " + initialBase + ": "
 217  
                         + priorVariableSb.toString());
 218  
             }
 219  
             // otherwise, add this variable to the interpolation list.
 220  
             else
 221  
             {
 222  252
                 priorVariables.add(variable);
 223  
             }
 224  
 
 225  252
             Object value = resolveContainerStore(variable);
 226  252
             if (value != null)
 227  
             {
 228  246
                 result.append(interpolateHelper(value.toString(), priorVariables));
 229  
 
 230  
                 // pop the interpolated variable off the stack
 231  
                 // this maintains priorVariables correctness for
 232  
                 // properties with multiple interpolations, e.g.
 233  
                 // prop.name=${some.other.prop1}/blahblah/${some.other.prop2}
 234  234
                 priorVariables.remove(priorVariables.size() - 1);
 235  
             }
 236  
             else
 237  
             {
 238  
                 //variable not defined - so put it back in the value
 239  6
                 result.append(START_TOKEN).append(variable).append(END_TOKEN);
 240  
             }
 241  
 
 242  240
             prec = end;
 243  
         }
 244  3240
         result.append(base.substring(prec + END_TOKEN.length(), base.length()));
 245  3240
         return result.toString();
 246  
     }
 247  
 
 248  
     /**
 249  
      * {@inheritDoc}
 250  
      */
 251  
     public Configuration subset(String prefix)
 252  
     {
 253  120
         return new SubsetConfiguration(this, prefix, ".");
 254  
     }
 255  
 
 256  
     /**
 257  
      * {@inheritDoc}
 258  
      */
 259  
     public abstract boolean isEmpty();
 260  
 
 261  
     /**
 262  
      * {@inheritDoc}
 263  
      */
 264  
     public abstract boolean containsKey(String key);
 265  
 
 266  
     /**
 267  
      * {@inheritDoc}
 268  
      */
 269  
     public void setProperty(String key, Object value)
 270  
     {
 271  2316
         clearProperty(key);
 272  2316
         addProperty(key, value);
 273  2316
     }
 274  
 
 275  
     /**
 276  
      * {@inheritDoc}
 277  
      */
 278  
     public abstract void clearProperty(String key);
 279  
 
 280  
     /**
 281  
      * {@inheritDoc}
 282  
      */
 283  
     public void clear()
 284  
     {
 285  15
         Iterator it = getKeys();
 286  291
         while (it.hasNext())
 287  
         {
 288  261
             String key = (String) it.next();
 289  261
             it.remove();
 290  
 
 291  261
             if (containsKey(key))
 292  
             {
 293  
                 // workaround for Iterators that do not remove the property on calling remove()
 294  258
                 clearProperty(key);
 295  
             }
 296  
         }
 297  15
     }
 298  
 
 299  
     /**
 300  
      * {@inheritDoc}
 301  
      */
 302  
     public abstract Iterator getKeys();
 303  
 
 304  
     /**
 305  
      * {@inheritDoc}
 306  
      */
 307  
     public Iterator getKeys(final String prefix)
 308  
     {
 309  111
         return new FilterIterator(getKeys(), class="keyword">new Predicate()
 310  
         {
 311  
             public boolean evaluate(Object obj)
 312  
             {
 313  
                 String key = (String) obj;
 314  
                 return key.startsWith(prefix + ".") || key.equals(prefix);
 315  
             }
 316  
         });
 317  
     }
 318  
 
 319  
     /**
 320  
      * {@inheritDoc}
 321  
      */
 322  
     public Properties getProperties(String key)
 323  
     {
 324  12
         return getProperties(key, null);
 325  
     }
 326  
 
 327  
     /**
 328  
      * Get a list of properties associated with the given configuration key.
 329  
      *
 330  
      * @param key The configuration key.
 331  
      * @param defaults Any default values for the returned
 332  
      * <code>Properties</code> object. Ignored if <code>null</code>.
 333  
      *
 334  
      * @return The associated properties if key is found.
 335  
      *
 336  
      * @throws ConversionException is thrown if the key maps to an object that
 337  
      * is not a String/List of Strings.
 338  
      *
 339  
      * @throws IllegalArgumentException if one of the tokens is malformed (does
 340  
      * not contain an equals sign).
 341  
      */
 342  
     public Properties getProperties(String key, Properties defaults)
 343  
     {
 344  
         /*
 345  
          * Grab an array of the tokens for this key.
 346  
          */
 347  12
         String[] tokens = getStringArray(key);
 348  
 
 349  
         /*
 350  
          * Each token is of the form 'key=value'.
 351  
          */
 352  12
         Properties props = defaults == null ? new Properties() : class="keyword">new Properties(defaults);
 353  30
         for (int i = 0; i < tokens.length; i++)
 354  
         {
 355  24
             String token = tokens[i];
 356  24
             int equalSign = token.indexOf('=');
 357  24
             if (equalSign > 0)
 358  
             {
 359  18
                 String pkey = token.substring(0, equalSign).trim();
 360  18
                 String pvalue = token.substring(equalSign + 1).trim();
 361  18
                 props.put(pkey, pvalue);
 362  
             }
 363  6
             else if (tokens.length == 1 && "".equals(token))
 364  
             {
 365  
                 // Semantically equivalent to an empty Properties
 366  
                 // object.
 367  6
                 break;
 368  
             }
 369  
             else
 370  
             {
 371  0
                 throw new IllegalArgumentException('\'' + token + "' does not contain an equals sign");
 372  
             }
 373  
         }
 374  12
         return props;
 375  
     }
 376  
 
 377  
     /**
 378  
      * {@inheritDoc}
 379  
      */
 380  
     public boolean getBoolean(String key)
 381  
     {
 382  123
         Boolean b = getBoolean(key, null);
 383  117
         if (b != null)
 384  
         {
 385  111
             return b.booleanValue();
 386  
         }
 387  
         else
 388  
         {
 389  6
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 390  
         }
 391  
     }
 392  
 
 393  
     /**
 394  
      * {@inheritDoc}
 395  
      */
 396  
     public boolean getBoolean(String key, class="keyword">boolean defaultValue)
 397  
     {
 398  33
         return getBoolean(key, BooleanUtils.toBooleanObject(defaultValue)).booleanValue();
 399  
     }
 400  
 
 401  
     /**
 402  
      * {@inheritDoc}
 403  
      */
 404  
     public Boolean getBoolean(String key, Boolean defaultValue)
 405  
     {
 406  174
         Object value = resolveContainerStore(key);
 407  
 
 408  174
         if (value == null)
 409  
         {
 410  42
             return defaultValue;
 411  
         }
 412  
         else
 413  
         {
 414  
             try
 415  
             {
 416  132
                 return PropertyConverter.toBoolean(interpolate(value));
 417  
             }
 418  
             catch (ConversionException e)
 419  
             {
 420  6
                 throw new ConversionException('\'' + key + "' doesn't map to a Boolean object", e);
 421  
             }
 422  
         }
 423  
     }
 424  
 
 425  
     /**
 426  
      * {@inheritDoc}
 427  
      */
 428  
     public byte getByte(String key)
 429  
     {
 430  42
         Byte b = getByte(key, null);
 431  36
         if (b != null)
 432  
         {
 433  30
             return b.byteValue();
 434  
         }
 435  
         else
 436  
         {
 437  6
             throw new NoSuchElementException('\'' + key + " doesn't map to an existing object");
 438  
         }
 439  
     }
 440  
 
 441  
     /**
 442  
      * {@inheritDoc}
 443  
      */
 444  
     public byte getByte(String key, byte defaultValue)
 445  
     {
 446  12
         return getByte(key, new Byte(defaultValue)).byteValue();
 447  
     }
 448  
 
 449  
     /**
 450  
      * {@inheritDoc}
 451  
      */
 452  
     public Byte getByte(String key, Byte defaultValue)
 453  
     {
 454  63
         Object value = resolveContainerStore(key);
 455  
 
 456  63
         if (value == null)
 457  
         {
 458  12
             return defaultValue;
 459  
         }
 460  
         else
 461  
         {
 462  
             try
 463  
             {
 464  51
                 return PropertyConverter.toByte(interpolate(value));
 465  
             }
 466  
             catch (ConversionException e)
 467  
             {
 468  6
                 throw new ConversionException('\'' + key + "' doesn't map to a Byte object", e);
 469  
             }
 470  
         }
 471  
     }
 472  
 
 473  
     /**
 474  
      * {@inheritDoc}
 475  
      */
 476  
     public double getDouble(String key)
 477  
     {
 478  42
         Double d = getDouble(key, null);
 479  36
         if (d != null)
 480  
         {
 481  30
             return d.doubleValue();
 482  
         }
 483  
         else
 484  
         {
 485  6
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 486  
         }
 487  
     }
 488  
 
 489  
     /**
 490  
      * {@inheritDoc}
 491  
      */
 492  
     public double getDouble(String key, class="keyword">double defaultValue)
 493  
     {
 494  33
         return getDouble(key, new Double(defaultValue)).doubleValue();
 495  
     }
 496  
 
 497  
     /**
 498  
      * {@inheritDoc}
 499  
      */
 500  
     public Double getDouble(String key, Double defaultValue)
 501  
     {
 502  84
         Object value = resolveContainerStore(key);
 503  
 
 504  84
         if (value == null)
 505  
         {
 506  33
             return defaultValue;
 507  
         }
 508  
         else
 509  
         {
 510  
             try
 511  
             {
 512  51
                 return PropertyConverter.toDouble(interpolate(value));
 513  
             }
 514  
             catch (ConversionException e)
 515  
             {
 516  6
                 throw new ConversionException('\'' + key + "' doesn't map to a Double object", e);
 517  
             }
 518  
         }
 519  
     }
 520  
 
 521  
     /**
 522  
      * {@inheritDoc}
 523  
      */
 524  
     public float getFloat(String key)
 525  
     {
 526  39
         Float f = getFloat(key, null);
 527  33
         if (f != null)
 528  
         {
 529  27
             return f.floatValue();
 530  
         }
 531  
         else
 532  
         {
 533  6
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 534  
         }
 535  
     }
 536  
 
 537  
     /**
 538  
      * {@inheritDoc}
 539  
      */
 540  
     public float getFloat(String key, class="keyword">float defaultValue)
 541  
     {
 542  21
         return getFloat(key, new Float(defaultValue)).floatValue();
 543  
     }
 544  
 
 545  
     /**
 546  
      * {@inheritDoc}
 547  
      */
 548  
     public Float getFloat(String key, Float defaultValue)
 549  
     {
 550  69
         Object value = resolveContainerStore(key);
 551  
 
 552  69
         if (value == null)
 553  
         {
 554  21
             return defaultValue;
 555  
         }
 556  
         else
 557  
         {
 558  
             try
 559  
             {
 560  48
                 return PropertyConverter.toFloat(interpolate(value));
 561  
             }
 562  
             catch (ConversionException e)
 563  
             {
 564  6
                 throw new ConversionException('\'' + key + "' doesn't map to a Float object", e);
 565  
             }
 566  
         }
 567  
     }
 568  
 
 569  
     /**
 570  
      * {@inheritDoc}
 571  
      */
 572  
     public int getInt(String key)
 573  
     {
 574  75
         Integer i = getInteger(key, null);
 575  75
         if (i != null)
 576  
         {
 577  75
             return i.intValue();
 578  
         }
 579  
         else
 580  
         {
 581  0
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 582  
         }
 583  
     }
 584  
 
 585  
     /**
 586  
      * {@inheritDoc}
 587  
      */
 588  
     public int getInt(String key, class="keyword">int defaultValue)
 589  
     {
 590  9
         Integer i = getInteger(key, null);
 591  
 
 592  9
         if (i == null)
 593  
         {
 594  9
             return defaultValue;
 595  
         }
 596  
 
 597  0
         return i.intValue();
 598  
     }
 599  
 
 600  
     /**
 601  
      * {@inheritDoc}
 602  
      */
 603  
     public Integer getInteger(String key, Integer defaultValue)
 604  
     {
 605  87
         Object value = resolveContainerStore(key);
 606  
 
 607  87
         if (value == null)
 608  
         {
 609  9
             return defaultValue;
 610  
         }
 611  
         else
 612  
         {
 613  
             try
 614  
             {
 615  78
                 return PropertyConverter.toInteger(interpolate(value));
 616  
             }
 617  
             catch (ConversionException e)
 618  
             {
 619  0
                 throw new ConversionException('\'' + key + "' doesn't map to an Integer object", e);
 620  
             }
 621  
         }
 622  
     }
 623  
 
 624  
     /**
 625  
      * {@inheritDoc}
 626  
      */
 627  
     public long getLong(String key)
 628  
     {
 629  42
         Long l = getLong(key, null);
 630  36
         if (l != null)
 631  
         {
 632  30
             return l.longValue();
 633  
         }
 634  
         else
 635  
         {
 636  6
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 637  
         }
 638  
     }
 639  
 
 640  
     /**
 641  
      * {@inheritDoc}
 642  
      */
 643  
     public long getLong(String key, class="keyword">long defaultValue)
 644  
     {
 645  21
         return getLong(key, new Long(defaultValue)).longValue();
 646  
     }
 647  
 
 648  
     /**
 649  
      * {@inheritDoc}
 650  
      */
 651  
     public Long getLong(String key, Long defaultValue)
 652  
     {
 653  72
         Object value = resolveContainerStore(key);
 654  
 
 655  72
         if (value == null)
 656  
         {
 657  21
             return defaultValue;
 658  
         }
 659  
         else
 660  
         {
 661  
             try
 662  
             {
 663  51
                 return PropertyConverter.toLong(interpolate(value));
 664  
             }
 665  
             catch (ConversionException e)
 666  
             {
 667  6
                 throw new ConversionException('\'' + key + "' doesn't map to a Long object", e);
 668  
             }
 669  
         }
 670  
     }
 671  
 
 672  
     /**
 673  
      * {@inheritDoc}
 674  
      */
 675  
     public short getShort(String key)
 676  
     {
 677  51
         Short s = getShort(key, null);
 678  45
         if (s != null)
 679  
         {
 680  39
             return s.shortValue();
 681  
         }
 682  
         else
 683  
         {
 684  6
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 685  
         }
 686  
     }
 687  
 
 688  
     /**
 689  
      * {@inheritDoc}
 690  
      */
 691  
     public short getShort(String key, class="keyword">short defaultValue)
 692  
     {
 693  21
         return getShort(key, new Short(defaultValue)).shortValue();
 694  
     }
 695  
 
 696  
     /**
 697  
      * {@inheritDoc}
 698  
      */
 699  
     public Short getShort(String key, Short defaultValue)
 700  
     {
 701  93
         Object value = resolveContainerStore(key);
 702  
 
 703  93
         if (value == null)
 704  
         {
 705  27
             return defaultValue;
 706  
         }
 707  
         else
 708  
         {
 709  
             try
 710  
             {
 711  66
                 return PropertyConverter.toShort(interpolate(value));
 712  
             }
 713  
             catch (ConversionException e)
 714  
             {
 715  6
                 throw new ConversionException('\'' + key + "' doesn't map to a Short object", e);
 716  
             }
 717  
         }
 718  
     }
 719  
 
 720  
     /**
 721  
      * {@inheritDoc}
 722  
      */
 723  
     public BigDecimal getBigDecimal(String key)
 724  
     {
 725  18
         BigDecimal number = getBigDecimal(key, null);
 726  12
         if (number != null)
 727  
         {
 728  6
             return number;
 729  
         }
 730  6
         else if (isThrowExceptionOnMissing())
 731  
         {
 732  3
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 733  
         }
 734  
         else
 735  
         {
 736  3
             return null;
 737  
         }
 738  
     }
 739  
 
 740  
     /**
 741  
      * {@inheritDoc}
 742  
      */
 743  
     public BigDecimal getBigDecimal(String key, BigDecimal defaultValue)
 744  
     {
 745  33
         Object value = resolveContainerStore(key);
 746  
 
 747  33
         if (value == null)
 748  
         {
 749  12
             return defaultValue;
 750  
         }
 751  
         else
 752  
         {
 753  
             try
 754  
             {
 755  21
                 return PropertyConverter.toBigDecimal(interpolate(value));
 756  
             }
 757  
             catch (ConversionException e)
 758  
             {
 759  6
                 throw new ConversionException('\'' + key + "' doesn't map to a BigDecimal object", e);
 760  
             }
 761  
         }
 762  
     }
 763  
 
 764  
     /**
 765  
      * {@inheritDoc}
 766  
      */
 767  
     public BigInteger getBigInteger(String key)
 768  
     {
 769  21
         BigInteger number = getBigInteger(key, null);
 770  15
         if (number != null)
 771  
         {
 772  9
             return number;
 773  
         }
 774  6
         else if (isThrowExceptionOnMissing())
 775  
         {
 776  3
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 777  
         }
 778  
         else
 779  
         {
 780  3
             return null;
 781  
         }
 782  
     }
 783  
 
 784  
     /**
 785  
      * {@inheritDoc}
 786  
      */
 787  
     public BigInteger getBigInteger(String key, BigInteger defaultValue)
 788  
     {
 789  36
         Object value = resolveContainerStore(key);
 790  
 
 791  36
         if (value == null)
 792  
         {
 793  12
             return defaultValue;
 794  
         }
 795  
         else
 796  
         {
 797  
             try
 798  
             {
 799  24
                 return PropertyConverter.toBigInteger(interpolate(value));
 800  
             }
 801  
             catch (ConversionException e)
 802  
             {
 803  6
                 throw new ConversionException('\'' + key + "' doesn't map to a BigDecimal object", e);
 804  
             }
 805  
         }
 806  
     }
 807  
 
 808  
     /**
 809  
      * {@inheritDoc}
 810  
      */
 811  
     public String getString(String key)
 812  
     {
 813  567
         String s = getString(key, null);
 814  561
         if (s != null)
 815  
         {
 816  513
             return s;
 817  
         }
 818  48
         else if (isThrowExceptionOnMissing())
 819  
         {
 820  18
             throw new NoSuchElementException('\'' + key + "' doesn't map to an existing object");
 821  
         }
 822  
         else
 823  
         {
 824  30
             return null;
 825  
         }
 826  
     }
 827  
 
 828  
     /**
 829  
      * {@inheritDoc}
 830  
      */
 831  
     public String getString(String key, String defaultValue)
 832  
     {
 833  834
         Object value = resolveContainerStore(key);
 834  
 
 835  834
         if (value instanceof String)
 836  
         {
 837  762
             return interpolate((String) value);
 838  
         }
 839  72
         else if (value == null)
 840  
         {
 841  72
             return interpolate(defaultValue);
 842  
         }
 843  
         else
 844  
         {
 845  0
             throw new ConversionException('\'' + key + "' doesn't map to a String object");
 846  
         }
 847  
     }
 848  
 
 849  
     /**
 850  
      * {@inheritDoc}
 851  
      */
 852  
     public String[] getStringArray(String key)
 853  
     {
 854  54
         Object value = getProperty(key);
 855  
 
 856  
         String[] array;
 857  
 
 858  54
         if (value instanceof String)
 859  
         {
 860  30
             array = new String[1];
 861  
 
 862  30
             array[0] = interpolate((String) value);
 863  
         }
 864  24
         else if (value instanceof List)
 865  
         {
 866  18
             List list = (List) value;
 867  18
             array = new String[list.size()];
 868  
 
 869  66
             for (int i = 0; i < array.length; i++)
 870  
             {
 871  48
                 array[i] = interpolate((String) list.get(i));
 872  
             }
 873  
         }
 874  6
         else if (value == null)
 875  
         {
 876  6
             array = new String[0];
 877  
         }
 878  
         else
 879  
         {
 880  0
             throw new ConversionException('\'' + key + "' doesn't map to a String/List object");
 881  
         }
 882  54
         return array;
 883  
     }
 884  
 
 885  
     /**
 886  
      * {@inheritDoc}
 887  
      */
 888  
     public List getList(String key)
 889  
     {
 890  645
         return getList(key, new ArrayList());
 891  
     }
 892  
 
 893  
     /**
 894  
      * {@inheritDoc}
 895  
      */
 896  
     public List getList(String key, List defaultValue)
 897  
     {
 898  525
         Object value = getProperty(key);
 899  
         List list;
 900  
 
 901  525
         if (value instanceof String)
 902  
         {
 903  147
             list = new ArrayList(1);
 904  147
             list.add(interpolate((String) value));
 905  
         }
 906  378
         else if (value instanceof List)
 907  
         {
 908  282
             list = new ArrayList();
 909  282
             List l = (List) value;
 910  
 
 911  
             // add the interpolated elements in the new list
 912  282
             Iterator it = l.iterator();
 913  1551
             while (it.hasNext())
 914  
             {
 915  987
                 list.add(interpolate(it.next()));
 916  
             }
 917  
 
 918  
         }
 919  96
         else if (value == null)
 920  
         {
 921  93
             list = defaultValue;
 922  
         }
 923  
         else
 924  
         {
 925  3
             throw new ConversionException('\'' + key + "' doesn't map to a List object: " + value + ", a "
 926  
                     + value.getClass().getName());
 927  
         }
 928  522
         return list;
 929  
     }
 930  
 
 931  
     /**
 932  
      * Returns an object from the store described by the key. If the value is a
 933  
      * List object, replace it with the first object in the list.
 934  
      *
 935  
      * @param key The property key.
 936  
      *
 937  
      * @return value Value, transparently resolving a possible List dependency.
 938  
      */
 939  
     protected Object resolveContainerStore(String key)
 940  
     {
 941  1884
         Object value = getProperty(key);
 942  1884
         if (value != null)
 943  
         {
 944  1605
             if (value instanceof List)
 945  
             {
 946  27
                 List list = (List) value;
 947  27
                 value = list.isEmpty() ? null : list.get(0);
 948  
             }
 949  1578
             else if (value instanceof Object[])
 950  
             {
 951  3
                 Object[] array = (Object[]) value;
 952  3
                 value = array.length == 0 ? null : array[0];
 953  
             }
 954  1575
             else if (value instanceof boolean[])
 955  
             {
 956  3
                 boolean[] array = (class="keyword">boolean[]) value;
 957  3
                 value = array.length == 0 ? null : new Boolean(array[0]);
 958  
             }
 959  1572
             else if (value instanceof byte[])
 960  
             {
 961  3
                 byte[] array = (byte[]) value;
 962  3
                 value = array.length == 0 ? null : new Byte(array[0]);
 963  
             }
 964  1569
             else if (value instanceof short[])
 965  
             {
 966  3
                 short[] array = (class="keyword">short[]) value;
 967  3
                 value = array.length == 0 ? null : new Short(array[0]);
 968  
             }
 969  1566
             else if (value instanceof int[])
 970  
             {
 971  3
                 int[] array = (class="keyword">int[]) value;
 972  3
                 value = array.length == 0 ? null : new Integer(array[0]);
 973  
             }
 974  1563
             else if (value instanceof long[])
 975  
             {
 976  3
                 long[] array = (class="keyword">long[]) value;
 977  3
                 value = array.length == 0 ? null : new Long(array[0]);
 978  
             }
 979  1560
             else if (value instanceof float[])
 980  
             {
 981  3
                 float[] array = (class="keyword">float[]) value;
 982  3
                 value = array.length == 0 ? null : new Float(array[0]);
 983  
             }
 984  1557
             else if (value instanceof double[])
 985  
             {
 986  3
                 double[] array = (class="keyword">double[]) value;
 987  3
                 value = array.length == 0 ? null : new Double(array[0]);
 988  
             }
 989  
         }
 990  
 
 991  1884
         return value;
 992  
     }
 993  
 
 994  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.