Coverage Report - org.apache.ojb.broker.util.configuration.impl.ConfigurationAbstractImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ConfigurationAbstractImpl
N/A
N/A
3.333
 
 1  
 package org.apache.ojb.broker.util.configuration.impl;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * 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  
 import org.apache.ojb.broker.metadata.MetadataException;
 19  
 import org.apache.ojb.broker.util.configuration.Configuration;
 20  
 import org.apache.ojb.broker.util.logging.Logger;
 21  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 22  
 import org.apache.ojb.broker.util.ClassHelper;
 23  
 
 24  
 import java.io.File;
 25  
 import java.io.FileNotFoundException;
 26  
 import java.io.InputStream;
 27  
 import java.net.URL;
 28  
 import java.net.URLConnection;
 29  
 import java.util.Properties;
 30  
 import java.util.StringTokenizer;
 31  
 
 32  
 /**
 33  
  * Configuration Base Class that
 34  
  * keeps a Properties based configuration persistent in a file.
 35  
  * This class provides only basic infrastructure for loading etc.
 36  
  *
 37  
  * @author Thomas Mahler
 38  
  * @version $Id: ConfigurationAbstractImpl.java,v 1.1 2007-08-24 22:17:42 ewestfal Exp $
 39  
  */
 40  
 public abstract class ConfigurationAbstractImpl implements Configuration
 41  
 {
 42  
     /**the logger used in this class.*/
 43  
     private Logger logger = LoggerFactory.getBootLogger();
 44  
 
 45  
     /**the name of the properties file*/
 46  
     protected String filename;
 47  
 
 48  
     /**the properties object holding the configuration data*/
 49  
     protected Properties properties;
 50  
 
 51  
     /**
 52  
      * Contains all legal values for boolean configuration entries that represent
 53  
      * <code>true</code>.
 54  
      */
 55  
     private String[] trueValues = {"true", "yes", "1"};
 56  
     /**
 57  
      * Contains all legal values for boolean configuration entries that represent
 58  
      * <code>false</code>.
 59  
      */
 60  
     private String[] falseValues = {"false", "no", "0"};
 61  
 
 62  
     /**
 63  
      * The constructor loads the configuration from file
 64  
      */
 65  
     public ConfigurationAbstractImpl()
 66  
     {
 67  
         load();
 68  
     }
 69  
 
 70  
     /**
 71  
      * Returns the string value for the specified key. If no value for this key
 72  
      * is found in the configuration <code>defaultValue</code> is returned.
 73  
      *
 74  
      * @param key the key
 75  
      * @param defaultValue the default value
 76  
      * @return the value for the key, or <code>defaultValue</code>
 77  
      */
 78  
     public String getString(String key, String defaultValue)
 79  
     {
 80  
         String ret = properties.getProperty(key);
 81  
         if (ret == null)
 82  
         {
 83  
             if(defaultValue == null)
 84  
             {
 85  
                 logger.info("No value for key '" + key + "'");
 86  
             }
 87  
             else
 88  
             {
 89  
                 logger.debug("No value for key \"" + key + "\", using default \""
 90  
                         + defaultValue + "\".");
 91  
                 properties.put(key, defaultValue);
 92  
             }
 93  
 
 94  
             ret = defaultValue;
 95  
         }
 96  
 
 97  
         return ret;
 98  
     }
 99  
 
 100  
     /**
 101  
      * Gets an array of Strings from the value of the specified key, seperated
 102  
      * by any key from <code>seperators</code>. If no value for this key
 103  
      * is found the array contained in <code>defaultValue</code> is returned.
 104  
      *
 105  
      * @param key the key
 106  
      * @param defaultValue the default Value
 107  
      * @param seperators the seprators to be used
 108  
      * @return the strings for the key, or the strings contained in <code>defaultValue</code>
 109  
      *
 110  
      * @see StringTokenizer
 111  
      */
 112  
     public String[] getStrings(String key, String defaultValue, String seperators)
 113  
     {
 114  
         StringTokenizer st = new StringTokenizer(getString(key, defaultValue), seperators);
 115  
         String[] ret = new String[st.countTokens()];
 116  
         for (int i = 0; i < ret.length; i++)
 117  
         {
 118  
             ret[i] = st.nextToken();
 119  
         }
 120  
         return ret;
 121  
     }
 122  
 
 123  
     /**
 124  
      * Gets an array of Strings from the value of the specified key, seperated
 125  
      * by ";". If no value for this key
 126  
      * is found the array contained in <code>defaultValue</code> is returned.
 127  
      *
 128  
      * @param key the key
 129  
      * @param defaultValue the default Value
 130  
      * @return the strings for the key, or the strings contained in <code>defaultValue</code>
 131  
      */
 132  
     public String[] getStrings(String key, String defaultValue)
 133  
     {
 134  
         return getStrings(key, defaultValue, ";");
 135  
     }
 136  
 
 137  
     /**
 138  
      * Returns the integer value for the specified key. If no value for this key
 139  
      * is found in the configuration or the value is not an legal integer
 140  
      * <code>defaultValue</code> is returned.
 141  
      *
 142  
      * @param key the key
 143  
      * @param defaultValue the default Value
 144  
      * @return the value for the key, or <code>defaultValue</code>
 145  
      */
 146  
     public int getInteger(String key, int defaultValue)
 147  
     {
 148  
         int ret;
 149  
         try
 150  
         {
 151  
             String tmp = properties.getProperty(key);
 152  
             if (tmp == null)
 153  
             {
 154  
                 properties.put(key, String.valueOf(defaultValue));
 155  
                 logger.debug("No value for key \"" + key + "\", using default "
 156  
                         + defaultValue + ".");
 157  
                 return defaultValue;
 158  
             }
 159  
             ret = Integer.parseInt(tmp);
 160  
         }
 161  
         catch (NumberFormatException e)
 162  
         {
 163  
             Object wrongValue = properties.put(key, String.valueOf(defaultValue));
 164  
             logger.warn(
 165  
                     "Value \""
 166  
                     + wrongValue
 167  
                     + "\" is illegal for key \""
 168  
                     + key
 169  
                     + "\" (should be an integer, using default value "
 170  
                     + defaultValue
 171  
                     + ")");
 172  
             ret = defaultValue;
 173  
         }
 174  
         return ret;
 175  
     }
 176  
 
 177  
     public long getLong(String key, long defaultValue)
 178  
     {
 179  
         long ret;
 180  
         try
 181  
         {
 182  
             String tmp = properties.getProperty(key);
 183  
             if (tmp == null)
 184  
             {
 185  
                 properties.put(key, String.valueOf(defaultValue));
 186  
                 logger.debug("No value for key \"" + key + "\", using default "
 187  
                         + defaultValue + ".");
 188  
                 return defaultValue;
 189  
             }
 190  
             ret = Long.parseLong(tmp);
 191  
         }
 192  
         catch (NumberFormatException e)
 193  
         {
 194  
             Object wrongValue = properties.put(key, String.valueOf(defaultValue));
 195  
             logger.warn(
 196  
                     "Value \""
 197  
                     + wrongValue
 198  
                     + "\" is illegal for key \""
 199  
                     + key
 200  
                     + "\" (should be an integer, using default value "
 201  
                     + defaultValue
 202  
                     + ")");
 203  
             ret = defaultValue;
 204  
         }
 205  
         return ret;
 206  
     }
 207  
 
 208  
     public byte getByte(String key, byte defaultValue)
 209  
     {
 210  
         byte ret;
 211  
         try
 212  
         {
 213  
             String tmp = properties.getProperty(key);
 214  
             if (tmp == null)
 215  
             {
 216  
                 properties.put(key, String.valueOf(defaultValue));
 217  
                 logger.debug("No value for key \"" + key + "\", using default "
 218  
                         + defaultValue + ".");
 219  
                 return defaultValue;
 220  
             }
 221  
             ret = Byte.parseByte(tmp);
 222  
         }
 223  
         catch (NumberFormatException e)
 224  
         {
 225  
             Object wrongValue = properties.put(key, String.valueOf(defaultValue));
 226  
             logger.warn(
 227  
                     "Value \""
 228  
                     + wrongValue
 229  
                     + "\" is illegal for key \""
 230  
                     + key
 231  
                     + "\" (should be an integer, using default value "
 232  
                     + defaultValue
 233  
                     + ")");
 234  
             ret = defaultValue;
 235  
         }
 236  
         return ret;
 237  
     }
 238  
 
 239  
     /**
 240  
      * Returns the boolean value for the specified key. If no value for this key
 241  
      * is found in the configuration or the value is not an legal boolean
 242  
      * <code>defaultValue</code> is returned.
 243  
      *
 244  
      * @see #trueValues
 245  
      * @see #falseValues
 246  
      *
 247  
      * @param key the key
 248  
      * @param defaultValue the default Value
 249  
      * @return the value for the key, or <code>defaultValue</code>
 250  
      */
 251  
     public boolean getBoolean(String key, boolean defaultValue)
 252  
     {
 253  
         String tmp = properties.getProperty(key);
 254  
 
 255  
         if (tmp == null)
 256  
         {
 257  
             logger.debug("No value for key \"" + key + "\", using default "
 258  
                     + defaultValue + ".");
 259  
             properties.put(key, String.valueOf(defaultValue));
 260  
             return defaultValue;
 261  
         }
 262  
 
 263  
         for (int i = 0; i < trueValues.length; i++)
 264  
         {
 265  
             if (tmp.equalsIgnoreCase(trueValues[i]))
 266  
             {
 267  
                 return true;
 268  
             }
 269  
         }
 270  
 
 271  
         for (int i = 0; i < falseValues.length; i++)
 272  
         {
 273  
             if (tmp.equalsIgnoreCase(falseValues[i]))
 274  
             {
 275  
                 return false;
 276  
             }
 277  
         }
 278  
 
 279  
         logger.warn(
 280  
                 "Value \""
 281  
                 + tmp
 282  
                 + "\" is illegal for key \""
 283  
                 + key
 284  
                 + "\" (should be a boolean, using default value "
 285  
                 + defaultValue
 286  
                 + ")");
 287  
         return defaultValue;
 288  
     }
 289  
 
 290  
     /**
 291  
      * Returns the class specified by the value for the specified key. If no
 292  
      * value for this key is found in the configuration, no class of this name
 293  
      * can be found or the specified class is not assignable to each
 294  
      * class/interface in <code>assignables defaultValue</code> is returned.
 295  
      *
 296  
      * @param key the key
 297  
      * @param defaultValue the default Value
 298  
      * @param assignables classes and/or interfaces the specified class must
 299  
      *          extend/implement.
 300  
      * @return the value for the key, or <code>defaultValue</code>
 301  
      */
 302  
     public Class getClass(String key, Class defaultValue, Class[] assignables)
 303  
     {
 304  
         String className = properties.getProperty(key);
 305  
 
 306  
         if (className == null)
 307  
         {
 308  
                 if (defaultValue == null)
 309  
                 {
 310  
                         logger.info("No value for key '" + key + "'");
 311  
                 return null;
 312  
                 }
 313  
                 else
 314  
                 {
 315  
                     className = defaultValue.getName();
 316  
                     properties.put(key, className);
 317  
                     logger.debug("No value for key \"" + key + "\", using default "
 318  
                             + className + ".");
 319  
                     return defaultValue;
 320  
                 }
 321  
         }
 322  
 
 323  
         Class clazz = null;
 324  
         try
 325  
         {
 326  
             clazz = ClassHelper.getClass(className);
 327  
         }
 328  
         catch (ClassNotFoundException e)
 329  
         {
 330  
             clazz = defaultValue;
 331  
             logger.warn(
 332  
                     "Value \""
 333  
                     + className
 334  
                     + "\" is illegal for key \""
 335  
                     + key
 336  
                     + "\" (should be a class, using default value "
 337  
                     + defaultValue
 338  
                     + ")", e);
 339  
         }
 340  
 
 341  
         for (int i = 0; i < assignables.length; i++)
 342  
         {
 343  
             Class assignable = assignables[i];
 344  
             if (!assignable.isAssignableFrom(clazz))
 345  
             {
 346  
                 String extendsOrImplements;
 347  
                 if (assignable.isInterface())
 348  
                 {
 349  
                     extendsOrImplements = "implement the interface ";
 350  
                 }
 351  
                 else
 352  
                 {
 353  
                     extendsOrImplements = "extend the class ";
 354  
 
 355  
                 }
 356  
                 logger.error(
 357  
                         "The specified class \""
 358  
                         + className
 359  
                         + "\" does not "
 360  
                         + extendsOrImplements
 361  
                         + assignables[i].getName()
 362  
                         + ", which is a requirement for the key \""
 363  
                         + key
 364  
                         + "\". Using default class "
 365  
                         + defaultValue);
 366  
                 clazz = defaultValue;
 367  
             }
 368  
 
 369  
         }
 370  
 
 371  
         return clazz;
 372  
     }
 373  
 
 374  
     /**
 375  
      * Returns the class specified by the value for the specified key. If no
 376  
      * value for this key is found in the configuration, no class of this name
 377  
      * can be found or the specified class is not assignable <code>assignable
 378  
      * defaultValue</code> is returned.
 379  
      *
 380  
      * @param key the key
 381  
      * @param defaultValue the default Value
 382  
      * @param assignable a classe and/or interface the specified class must
 383  
      *          extend/implement.
 384  
      * @return the value for the key, or <code>defaultValue</code>
 385  
      */
 386  
     public Class getClass(String key, Class defaultValue, Class assignable)
 387  
     {
 388  
         return getClass(key, defaultValue, new Class[]{assignable});
 389  
     }
 390  
 
 391  
     /**
 392  
      * Returns the class specified by the value for the specified key. If no
 393  
      * value for this key is found in the configuration or no class of this name
 394  
      * can be found <code>defaultValue</code> is returned.
 395  
      *
 396  
      * @param key the key
 397  
      * @param defaultValue the default Value
 398  
      * @return the value for the key, or <code>defaultValue</code>
 399  
      */
 400  
     public Class getClass(String key, Class defaultValue)
 401  
     {
 402  
         return getClass(key, defaultValue, new Class[0]);
 403  
     }
 404  
 
 405  
     /**
 406  
      * Loads the Configuration from the properties file.
 407  
      *
 408  
      * Loads the properties file, or uses defaults on failure.
 409  
      *
 410  
      * @see org.apache.ojb.broker.util.configuration.impl.ConfigurationAbstractImpl#setFilename(java.lang.String)
 411  
      *
 412  
      */
 413  
     protected void load()
 414  
     {
 415  
         properties = new Properties();
 416  
 
 417  
         String filename = getFilename();
 418  
         
 419  
         try
 420  
         {
 421  
             URL url = ClassHelper.getResource(filename);
 422  
 
 423  
             if (url == null)
 424  
             {
 425  
                 url = (new File(filename)).toURL();
 426  
             }
 427  
 
 428  
             logger.info("Loading OJB's properties: " + url);
 429  
 
 430  
             URLConnection conn = url.openConnection();
 431  
             conn.setUseCaches(false);
 432  
             conn.connect();
 433  
             InputStream strIn = conn.getInputStream();
 434  
             properties.load(strIn);
 435  
             strIn.close();
 436  
         }
 437  
         catch (FileNotFoundException ex)
 438  
         {
 439  
             // [tomdz] If the filename is explicitly reset (null or empty string) then we'll
 440  
             //         output an info message because the user did this on purpose
 441  
             //         Otherwise, we'll output a warning
 442  
             if ((filename == null) || (filename.length() == 0))
 443  
             {
 444  
                 logger.info("Starting OJB without a properties file. OJB is using default settings instead.");
 445  
             }
 446  
             else
 447  
             {
 448  
                 logger.warn("Could not load properties file '"+filename+"'. Using default settings!", ex);
 449  
             }
 450  
             // [tomdz] There seems to be no use of this setting ?
 451  
             //properties.put("valid", "false");
 452  
         }
 453  
         catch (Exception ex)
 454  
         {
 455  
             throw new MetadataException("An error happend while loading the properties file '"+filename+"'", ex);
 456  
         }
 457  
     }
 458  
 
 459  
     private String getFilename()
 460  
     {
 461  
         if (filename == null)
 462  
         {
 463  
             filename = this.getClass().getName() + ".properties";
 464  
         }
 465  
         return filename;
 466  
     }
 467  
 
 468  
     protected void setFilename(String name)
 469  
     {
 470  
         filename = name;
 471  
     }
 472  
 
 473  
     /**
 474  
      * @see Configuration#setLogger(Logger)
 475  
      */
 476  
     public void setLogger(Logger loggerInstance)
 477  
     {
 478  
         logger = loggerInstance;
 479  
     }
 480  
 
 481  
 }