org.acmsl.commons.ConfigurationManager.java Source code

Java tutorial

Introduction

Here is the source code for org.acmsl.commons.ConfigurationManager.java

Source

//;-*- mode: java -*-
/*
                    ACM-SL Commons
    
Copyright (C) 2002-today  Jose San Leandro Armendariz
                          chous@acm-sl.org
    
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or any later version.
    
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
    
You should have received a copy of the GNU General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    
Thanks to ACM S.L. for distributing this library under the GPL license.
Contact info: jose.sanleandro@acm-sl.com
    
 ******************************************************************************
 *
 * Filename: ConfigurationManager.java
 *
 * Author: Jose San Leandro Armendariz
 *
 * Description: Provides basic methods to allow specialized classes to
 *              manage the configuration of applications.
 */
package org.acmsl.commons;

/*
 * Importing project classes.
 */
import org.acmsl.commons.patterns.Manager;

/*
 * Importing JetBrains annotations..
 */
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/*
 * Importing some JDK classes.
 */
import java.io.InputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

/*
 * Importing Apache Commons Logging classes.
 */
import org.apache.commons.logging.LogFactory;

/**
 * Provides basic methods to allow specialized classes to manage th
 * configuration of applications.
 * @author <a href="mailto:chous@acm-sl.org">Jose San Leandro Armendariz</a>
 */
public abstract class ConfigurationManager implements Manager {
    /**
     * In-memory configuration settings.
     */
    @Nullable
    private Properties m__Properties = null;

    /**
     * Default protected constructor to avoid accidental instantiation.
     */
    protected ConfigurationManager() {
    }

    /**
     * Retrieves the properties file name.
     * @return such name.
     */
    @NotNull
    protected abstract String getPropertiesFileName();

    /**
     * Specifies the configuration settings.
     * @param properties the properties.
     */
    protected final void immutableSetProperties(@NotNull final Properties properties) {
        m__Properties = properties;
    }

    /**
     * Retrieves the configuration settings.
     * @return the properties.
     */
    @Nullable
    protected final Properties immutableGetProperties() {
        return m__Properties;
    }

    /**
     * Retrieves the configuration settings.
     * @return the properties.
     */
    @NotNull
    public Properties getProperties() {
        return getProperties(getPropertiesFileName());
    }

    /**
     * Retrieves the configuration settings.
     * @param propertiesFileName the properties' file name.
     * @return the properties.
     */
    @NotNull
    public synchronized final Properties getProperties(@NotNull final String propertiesFileName) {
        return getProperties(propertiesFileName, immutableGetProperties());
    }

    /**
     * Retrieves the configuration settings.
     * @param propertiesFileName the properties' file name.
     * @param properties the properties.
     * @return the properties.
     */
    @NotNull
    protected final Properties getProperties(@NotNull final String propertiesFileName,
            @Nullable final Properties properties) {
        @NotNull
        final Properties result;

        if (properties == null) {
            result = new Properties();
            immutableSetProperties(result);
        } else {
            result = properties;
        }

        if (result.size() == 0) {
            loadProperties(result, propertiesFileName);
        }

        return result;
    }

    /**
     * Retrieves the property.
     * @param key the setting name.
     * @return the configuration value associated to such setting.
     */
    @Nullable
    public String getProperty(@NotNull final String key) {
        return getProperty(key, getProperties());
    }

    /**
     * Retrieves the property.
     * @param key the setting name.
     * @param properties the property collection.
     * @return the configuration value associated to such setting.
     */
    @Nullable
    protected String getProperty(@NotNull final String key, @NotNull final Properties properties) {
        return properties.getProperty(key);
    }

    /**
     * Retrieves the array property.
     * @param name the name.
     * @return the array of values.
     */
    @NotNull
    @SuppressWarnings("unused")
    public String[] getStringArray(@NotNull final String name) {
        @NotNull
        final String[] result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getStringArrayValue(t_strValue);
        } else {
            result = new String[0];
        }

        return result;
    }

    /**
     * Retrieves the array property.
     * @param value the value.
     * @return the array of values.
     */
    @NotNull
    protected String[] getStringArrayValue(@NotNull final String value) {
        return value.split(",");
    }

    /**
     * Specifies an array property.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setStringArray(@SuppressWarnings("unused") @NotNull final String name,
            @NotNull final String[] value) {
        @NotNull
        final StringBuilder propertyValue = new StringBuilder();

        for (int index = 0; index < value.length; index++) {
            propertyValue.append(value[index]);

            if (index < value.length - 1) {
                propertyValue.append(",");
            }
        }
    }

    /**
     * Retrieves the property.
     * @param key the setting name.
     * @param value the value.
     */
    public void setProperty(@NotNull final String key, @NotNull final String value) {
        setProperty(key, value, getProperties());
    }

    /**
     * Specifies the property.
     * @param key the setting name.
     * @param value the value.
     * @param properties the property collection.
     */
    protected void setProperty(@NotNull final String key, @NotNull final String value,
            @NotNull final Properties properties) {
        properties.setProperty(key, value);
    }

    /**
     * Retrieves a concrete integer setting.
     * @param name the name.
     * @return such parameter.
     */
    @SuppressWarnings("unused")
    public int getIntProperty(@NotNull final String name) {
        final int result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getIntProperty(name, t_strValue);
        } else {
            result = -1;
        }

        return result;
    }

    /**
     * Retrieves a concrete integer setting.
     * @param name the name.
     * @param value the value.
     * @return such parameter.
     */
    protected int getIntProperty(@NotNull final String name, @NotNull final String value) {
        int result = -1;

        try {
            result = Integer.parseInt(value);
        } catch (final NumberFormatException numberFormatException) {
            LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                    .fatal("Invalid integer setting (" + name + "): " + value, numberFormatException);
        }

        return result;
    }

    /**
     * Specifies a concrete integer setting.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setIntProperty(@NotNull final String name, final int value) {
        setProperty(name, String.valueOf(value));
    }

    /**
     * Retrieves an array of integers associated to given name.
     * @param name the name.
     * @return such value.
     */
    @SuppressWarnings("unused")
    @NotNull
    public int[] getIntArray(@NotNull final String name) {
        @NotNull
        final int[] result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getIntArray(name, t_strValue);
        } else {
            result = new int[0];
        }

        return result;
    }

    /**
     * Retrieves an array of integers associated to given name.
     * @param name the name.
     * @param value the property value.
     * @return such parsed value.
     */
    @NotNull
    protected int[] getIntArray(@NotNull final String name, @NotNull final String value) {
        @NotNull
        final int[] result;

        @NotNull
        final String[] splitValue = value.split(",");

        result = new int[splitValue.length];

        try {
            for (int t_iIndex = 0; t_iIndex < splitValue.length; t_iIndex++) {
                result[t_iIndex] = Integer.parseInt(splitValue[t_iIndex]);
            }
        } catch (final NumberFormatException numberFormatException) {
            LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                    .fatal("Invalid integer array setting (" + name + "): " + value, numberFormatException);
        }

        return result;
    }

    /**
     * Specifies an integer setting.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setIntArray(@NotNull final String name, @NotNull final int[] value) {
        @NotNull
        final StringBuilder propertyValue = new StringBuilder();

        for (int index = 0; index < value.length; index++) {
            propertyValue.append(value[index]);

            if (index < value.length - 1) {
                propertyValue.append(",");
            }
        }

        setProperty(name, propertyValue.toString());
    }

    /**
     * Retrieves a concrete long setting.
     * @param name the name.
     * @return such parameter.
     */
    @SuppressWarnings("unused")
    public long getLongProperty(@NotNull final String name) {
        final long result;

        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getLongProperty(name, t_strValue);
        } else {
            result = -1;
        }

        return result;
    }

    /**
     * Retrieves a concrete long setting.
     * @param name the name.
     * @param value the value.
     * @return such parameter.
     */
    protected long getLongProperty(@NotNull final String name, @NotNull final String value) {
        long result = -1;

        try {
            result = Long.parseLong(value);
        } catch (final NumberFormatException numberFormatException) {
            LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                    .fatal("Invalid long setting (" + name + "): " + value, numberFormatException);
        }

        return result;
    }

    /**
     * Specifies a concrete long setting.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setLongProperty(@NotNull final String name, final long value) {
        setProperty(name, String.valueOf(value));
    }

    /**
     * Retrieves an array of longs associated to given name.
     * @param name the name.
     * @return such value.
     */
    @NotNull
    @SuppressWarnings("unused")
    public long[] getLongArray(@NotNull final String name) {
        @NotNull
        final long[] result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getLongArray(name, t_strValue);
        } else {
            result = new long[0];
        }

        return result;
    }

    /**
     * Retrieves an array of longs associated to given name.
     * @param name the name.
     * @param value the property value.
     * @return such parsed value.
     */
    @NotNull
    protected long[] getLongArray(@NotNull final String name, @NotNull final String value) {
        @NotNull
        final long[] result;

        @NotNull
        final String[] splitValue = value.split(",");

        result = new long[splitValue.length];

        try {
            for (int index = 0; index < result.length; index++) {
                result[index] = Long.parseLong(splitValue[index]);
            }
        } catch (final NumberFormatException numberFormatException) {
            LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                    .fatal("Invalid long array setting (" + name + "): " + value, numberFormatException);
        }

        return result;
    }

    /**
     * Specifies an long setting.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setLongArray(@NotNull final String name, @NotNull final long[] value) {
        @NotNull
        final StringBuilder propertyValue = new StringBuilder();

        for (int index = 0; index < value.length; index++) {
            propertyValue.append("" + value[index]);

            if (index < value.length - 1) {
                propertyValue.append(",");
            }
        }

        setProperty(name, propertyValue.toString());
    }

    /**
     * Retrieves a concrete double setting.
     * @param name the name.
     * @return such parameter.
     */
    @SuppressWarnings("unused")
    public double getDoubleProperty(@NotNull final String name) {
        final double result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getDoubleProperty(name, t_strValue);
        } else {
            result = -1.0d;
        }

        return result;
    }

    /**
     * Retrieves a concrete double setting.
     * @param name the name.
     * @param value the value.
     * @return such parameter.
     */
    protected double getDoubleProperty(@NotNull final String name, @NotNull final String value) {
        double result = -1.0d;

        try {
            result = Double.parseDouble(value);
        } catch (final NumberFormatException numberFormatException) {
            LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                    .fatal("Invalid double setting (" + name + "): " + value, numberFormatException);
        }

        return result;
    }

    /**
     * Specifies a concrete double setting.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setDoubleProperty(@NotNull final String name, final double value) {
        setProperty(name, String.valueOf(value));
    }

    /**
     * Retrieves an array of doubles associated to given name.
     * @param name the name.
     * @return such value.
     */
    @SuppressWarnings("unused")
    @NotNull
    public double[] getDoubleArray(@NotNull final String name) {
        @NotNull
        final double[] result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getDoubleArray(name, t_strValue);
        } else {
            result = new double[0];
        }

        return result;
    }

    /**
     * Retrieves an array of doubles associated to given name.
     * @param name the name.
     * @param value the property value.
     * @return such parsed value.
     */
    @NotNull
    protected double[] getDoubleArray(@NotNull final String name, @NotNull final String value) {
        @NotNull
        final double[] result;

        @NotNull
        final String[] splitValue = value.split(",");

        result = new double[splitValue.length];

        try {
            for (int index = 0; index < result.length; index++) {
                result[index] = Double.parseDouble(splitValue[index]);
            }
        } catch (final NumberFormatException numberFormatException) {
            LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                    .fatal("Invalid double array setting (" + name + "): " + value, numberFormatException);
        }

        return result;
    }

    /**
     * Specifies an double setting.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setDoubleArray(@NotNull final String name, @NotNull final double[] value) {
        @NotNull
        final StringBuilder propertyValue = new StringBuilder();

        for (int index = 0; index < value.length; index++) {
            propertyValue.append("" + value[index]);

            if (index < value.length - 1) {
                propertyValue.append(",");
            }
        }

        setProperty(name, propertyValue.toString());
    }

    /**
     * Retrieves a concrete boolean setting.
     * @param name the name.
     * @return such parameter.
     */
    @SuppressWarnings("unused")
    public boolean getBooleanProperty(@NotNull final String name) {
        final boolean result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getBooleanPropertyValue(t_strValue);
        } else {
            result = false;
        }

        return result;
    }

    /**
     * Retrieves a concrete boolean setting.
     * @param value the value.
     * @return such parameter.
     */
    protected boolean getBooleanPropertyValue(@NotNull final String value) {
        return Boolean.valueOf(value).booleanValue();
    }

    /**
     * Specifies a concrete boolean setting.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setBooleanProperty(@NotNull final String name, final boolean value) {
        setProperty(name, String.valueOf(value));
    }

    /**
     * Retrieves an array of boolean values associated to given name.
     * @param name the name.
     * @return such value.
     */
    @SuppressWarnings("unused")
    @NotNull
    public boolean[] getBooleanArray(@NotNull final String name) {
        @NotNull
        final boolean[] result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getBooleanArrayValue(t_strValue);
        } else {
            result = new boolean[0];
        }

        return result;
    }

    /**
     * Retrieves an array of boolean values associated to given name.
     * @param value the property value.
     * @return such parsed value.
     */
    @NotNull
    protected boolean[] getBooleanArrayValue(@NotNull final String value) {
        @NotNull
        final boolean[] result;

        @NotNull
        final String[] splitValue = value.split(",");

        result = new boolean[splitValue.length];

        for (int index = 0; index < result.length; index++) {
            result[index] = Boolean.valueOf(splitValue[index]);
        }

        return result;
    }

    /**
     * Specifies an boolean setting.
     * @param name the name.
     * @param value the value.
     */
    @SuppressWarnings("unused")
    public void setBooleanArray(@NotNull final String name, @NotNull final boolean[] value) {
        @NotNull
        final StringBuilder propertyValue = new StringBuilder();

        for (int index = 0; index < value.length; index++) {
            propertyValue.append(value[index]);

            if (index < value.length - 1) {
                propertyValue.append(",");
            }
        }

        setProperty(name, propertyValue.toString());
    }

    /**
     * Retrieves a date property.
     * @param name the name.
     * @param format the date format.
     * @return the property.
     */
    @SuppressWarnings("unused")
    @Nullable
    public Date getDateProperty(@NotNull final String name, @NotNull final String format) {
        @Nullable
        final Date result;

        @Nullable
        final String t_strValue = getProperty(name);

        if (t_strValue != null) {
            result = getDateProperty(name, format, t_strValue);
        } else {
            result = null;
        }

        return result;
    }

    /**
     * Retrieves a date property.
     * @param name the name.
     * @param format the date format.
     * @param value the value.
     * @return the property.
     */
    @Nullable
    protected Date getDateProperty(@NotNull final String name, @NotNull final String format,
            @NotNull final String value) {
        @Nullable
        Date result = null;

        try {
            result = new SimpleDateFormat(format).parse(value);
        } catch (final ParseException parseException) {
            LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                    .error("Invalid date property (" + name + "):" + value, parseException);
        }

        return result;
    }

    /**
     * Specifies a date property.
     * @param name the name.
     * @param value the value.
     * @param format the format.
     */
    @SuppressWarnings("unused")
    public void setDateProperty(@NotNull final String name, @NotNull final Date value,
            @NotNull final String format) {
        setProperty(name, new SimpleDateFormat(format).format(value));
        setProperty(name + ".format", format);
    }

    /**
     * Loads the configuration from a property file.
     * @param properties where to store the settings.
     * @param propertiesFileName the properties file.
     */
    public final void loadProperties(@NotNull final Properties properties,
            @NotNull final String propertiesFileName) {
        loadProperties(properties, propertiesFileName, true);
    }

    /**
     * Loads the configuration from a property file.
     * @param properties where to store the settings.
     * @param propertiesFileName the properties file.
     * @param retry whether to retry to load the properties appending an slash
     * at the beginning of the file name or not.
     */
    public synchronized void loadProperties(@NotNull final Properties properties,
            @NotNull final String propertiesFileName, final boolean retry) {
        @Nullable
        InputStream propertiesFile = null;

        final boolean startsWithSlash = propertiesFileName.startsWith("/");

        @NotNull
        final String alternatePropertiesFileName;

        if (startsWithSlash) {
            alternatePropertiesFileName = propertiesFileName.substring(1);
        } else {
            alternatePropertiesFileName = "/" + propertiesFileName;
        }

        // Loading properties
        try {
            propertiesFile = getClass().getResourceAsStream(propertiesFileName);

            if (propertiesFile != null) {
                properties.load(propertiesFile);
            } else if (retry) {
                LogFactory.getLog(ConfigurationManager.class + "." + getClass()).debug("Properties file: "
                        + propertiesFileName + " not found. Trying " + alternatePropertiesFileName);

                loadProperties(properties, alternatePropertiesFileName, false);
            } else {
                LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                        .warn("Could not load configuration properties from file: " + propertiesFileName);
            }
        } catch (final IOException ioException) {
            if (retry) {
                LogFactory.getLog(ConfigurationManager.class + "." + getClass()).debug("Properties file: "
                        + propertiesFileName + " not found. Trying " + alternatePropertiesFileName);

                loadProperties(properties, alternatePropertiesFileName, false);
            } else {
                LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                        .warn("Could not load configuration properties from file: " + propertiesFileName);
            }
        } finally {
            if (propertiesFile != null) {
                try {
                    propertiesFile.close();
                } catch (@NotNull final IOException cannotClose) {
                    LogFactory.getLog(ConfigurationManager.class + "." + getClass())
                            .warn("Could not close file: " + propertiesFileName);
                }
            }
        }
    }

    @Override
    @NotNull
    public String toString() {
        return "ConfigurationManager{ properties=" + m__Properties + " }";
    }
}