View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *  http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.any23.configuration;
    19
    20  import org.slf4j.Logger;
    21  import org.slf4j.LoggerFactory;
    22
    23  import java.io.IOException;
    24  import java.util.Properties;
    25
    26  /**
    27   * Default implementation of {@link Configuration}. The default property values are read from the
    28   * <i>/default-configuration.properties</i> properties file in classpath.
    29   *
    30   * @author Michele Mostarda (michele.mostarda@gmail.com)
    31   */
    32  public class DefaultConfiguration implements Configuration {
    33
    34      /**
    35       * Default configuration file.
    36       */
    37      public static final String DEFAULT_CONFIG_FILE = "/default-configuration.properties";
    38
    39      public static final String FLAG_PROPERTY_ON = "on";
    40
    41      public static final String FLAG_PROPERTY_OFF = "off";
    42
    43      protected static final Logger logger = LoggerFactory.getLogger(DefaultConfiguration.class);
    44
    45      protected static final DefaultConfiguration singleton = new DefaultConfiguration();
    46
    47      protected final Properties properties;
    48
    49      protected DefaultConfiguration(Properties properties) {
    50          this.properties = properties;
    51      }
    52
    53      private DefaultConfiguration() {
    54          this(loadDefaultProperties());
    55      }
    56
    57      /**
    58       * @return the singleton configuration instance. Such instance is unmodifiable.
    59       */
    60      public static synchronized DefaultConfiguration singleton() {
    61          return singleton;
    62      }
    63
    64      /**
    65       * @return a copy of the singleton instance. such instance is modifiable.
    66       */
    67      public static synchronized ModifiableConfiguration copy() {
    68          final Properties propertiesCopy = (Properties) singleton.properties.clone();
    69          return new DefaultModifiableConfiguration(propertiesCopy);
    70      }
    71
    72      private static Properties loadDefaultProperties() {
    73          final Properties properties = new Properties();
    74          try {
    75              properties.load(DefaultConfiguration.class.getResourceAsStream(DEFAULT_CONFIG_FILE));
    76          } catch (IOException ioe) {
    77              throw new IllegalStateException("Error while loading default configuration.", ioe);
    78          }
    79          return properties;
    80      }
    81
    82      @Override
    83      public synchronized String[] getProperties() {
    84          return properties.keySet().toArray(new String[properties.size()]);
    85      }
    86
    87      @Override
    88      public synchronized boolean defineProperty(String propertyName) {
    89          return properties.containsKey(propertyName);
    90      }
    91
    92      @Override
    93      public synchronized String getProperty(String propertyName, String defaultValue) {
    94          final String value = getPropertyValue(propertyName);
    95          if (value == null) {
    96              return defaultValue;
    97          }
    98          return value;
    99      }
    100
    101     @Override
    102     public synchronized String getPropertyOrFail(String propertyName) {
    103         final String propertyValue = getPropertyValue(propertyName);
    104         if (propertyValue == null) {
    105             throw new IllegalArgumentException("The property '" + propertyName + "' is expected to be declared.");
    106         }
    107         if (propertyValue.trim().length() == 0) {
    108             throw new IllegalArgumentException(
    109                     "Invalid value '" + propertyValue + "' for property '" + propertyName + "'");
    110         }
    111         return propertyValue;
    112     }
    113
    114     @Override
    115     public synchronized int getPropertyIntOrFail(String propertyName) {
    116         final String value = getPropertyOrFail(propertyName);
    117         final String trimValue = value.trim();
    118         try {
    119             return Integer.parseInt(trimValue);
    120         } catch (NumberFormatException nfe) {
    121             throw new NumberFormatException("The retrieved property is not a valid Integer: '" + trimValue + "'");
    122         }
    123     }
    124
    125     @Override
    126     public synchronized boolean getFlagProperty(final String propertyName) {
    127         final String value = getPropertyOrFail(propertyName);
    128         if (value == null) {
    129             return false;
    130         }
    131         if (FLAG_PROPERTY_ON.equals(value)) {
    132             return true;
    133         }
    134         if (FLAG_PROPERTY_OFF.equals(value)) {
    135             return false;
    136         }
    137         throw new IllegalArgumentException(String.format(java.util.Locale.ROOT,
    138                 "Invalid value [%s] for flag property [%s]. Supported values are %s|%s", value, propertyName,
    139                 FLAG_PROPERTY_ON, FLAG_PROPERTY_OFF));
    140     }
    141
    142     @Override
    143     public synchronized String getConfigurationDump() {
    144         final String[] defaultProperties = getProperties();
    145         final StringBuilder sb = new StringBuilder();
    146         sb.append("\n======================= Configuration Properties =======================\n");
    147         for (String defaultProperty : defaultProperties) {
    148             sb.append(defaultProperty).append('=').append(getPropertyValue(defaultProperty)).append('\n');
    149         }
    150         sb.append("========================================================================\n");
    151         return sb.toString();
    152     }
    153
    154     private String getPropertyValue(String propertyName) {
    155         if (!defineProperty(propertyName)) {
    156             if (logger.isDebugEnabled()) {
    157                 logger.debug(String.format(java.util.Locale.ROOT,
    158                         "Property '%s' is not declared in default configuration file [%s]", propertyName,
    159                         DEFAULT_CONFIG_FILE));
    160             }
    161             return null;
    162         }
    163         final String systemValue = System.getProperties().getProperty(propertyName);
    164         if (systemValue == null) {
    165             return properties.getProperty(propertyName);
    166         }
    167         return systemValue;
    168     }
    169
    170 }