com.coroptis.coidi.core.services.impl.ConfigurationServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.coroptis.coidi.core.services.impl.ConfigurationServiceImpl.java

Source

/**
 * Copyright 2012 coroptis.com
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package com.coroptis.coidi.core.services.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.digester.Digester;
import org.apache.log4j.Logger;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.ClasspathResource;
import org.xml.sax.SAXException;

import com.coroptis.coidi.core.services.ConfigurationException;
import com.coroptis.coidi.core.services.ConfigurationService;
import com.coroptis.coidi.core.util.Conf;
import com.coroptis.coidi.core.util.FsResource;
import com.google.common.base.Preconditions;

/**
 * Loads {@link Properties} from configuration file. Configuration files are
 * located in folder specified in system property "sso.conf.dir". If such a
 * property is not found then configuration files are searched for in
 * <code>src/main/resources/META-INF/</code> folder.
 * <p>
 * Files are named like this: <code>configuration-${server.role}.xml</code>
 * where ${server.role} is replaced by value of system property "server.role".
 * </p>
 * 
 * @author jan
 */
public class ConfigurationServiceImpl implements ConfigurationService {

    private final static Logger logger = Logger.getLogger(ConfigurationServiceImpl.class);

    private final String systemPropertyConfigurationDirectory;

    public ConfigurationServiceImpl() {
        /**
         * This value can't be get through SymbolProvider, because there will be
         * recursion. Configuration service depends on symbol provide which
         * indirectly depends on this class.
         */
        this.systemPropertyConfigurationDirectory = System.getProperty(CONF_KEY_CONFIGURATION_DIRECTORY);
        if (systemPropertyConfigurationDirectory == null) {
            throw new ConfigurationException("system propety '" + CONF_KEY_CONFIGURATION_DIRECTORY + "' is null. "
                    + "Application don't know where to find" + " directory with configuration.");
        }
    }

    private Resource getConfigurationFileResource(final String configurationUrl) {
        Resource configurationResource = null;
        if (configurationUrl.startsWith(".")) {
            /**
             * Relative path
             */
            configurationResource = new ClasspathResource(configurationUrl);
        } else {
            /**
             * Absolute path
             */
            configurationResource = new FsResource(configurationUrl);
        }
        if (!configurationResource.exists()) {
            throw new ConfigurationException("Configuration file '" + configurationUrl + "' didn't exists.");
        }
        return configurationResource;
    }

    /**
     * Creates {@link Properties} instance. Properties are read from the
     * specified XML file and XML elements.
     * 
     * @param configurationSection
     *            pattern that matches an element in configuration
     * @param resourceUrl
     *            specifies where configuration file is located
     * @return Map loaded from XML configuration file
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private HashMap<String, String> createProperties(String configurationSection, Resource configurationResource) {
        Digester digester = new Digester();
        digester.addObjectCreate("configuration/" + configurationSection, HashMap.class);
        // TODO refactor it, add test
        // call the put method on the top object on the digester stack
        // passing the key attribute as the 0th parameterw
        // and the element body text as the 1th parameter..
        digester.addCallMethod("configuration/" + configurationSection + "/property", "put", 2);
        digester.addCallParam("configuration/" + configurationSection + "/property", 0, "name");
        digester.addCallParam("configuration/" + configurationSection + "/property", 1);

        InputStream inputStream = null;
        HashMap properties = null;
        try {
            inputStream = configurationResource.openStream();
            properties = (HashMap) digester.parse(inputStream);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        } catch (SAXException e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                logger.warn("Unable to close input stream after reading configuration file.");
            }
        }
        return properties;
    }

    /**
     * @return path on classpath where the configuration file is located.
     */
    private String getDefaultConfigurationFile() {
        return getConfigurationDirectory() + "configuration-" + getServerRole() + ".xml";
    }

    /**
     * @return Value of server.role property or it's default value if not
     *         defined.
     */
    @Override
    public String getServerRole() {
        String value = System.getProperty(SYSTEM_PROPERTY_SERVER_ROLE);
        if (value != null) {
            return value;
        }
        return DEFAULT_SERVER_ROLE;
    }

    @Override
    public String getConfigurationDirectory() {
        return Conf.getConfigurationDirectory(systemPropertyConfigurationDirectory);
    }

    @Override
    public Resource getDefaultConfiguration() {
        return getConfigurationFileResource(getDefaultConfigurationFile());
    }

    @Override
    public Resource getConfiguration(final String configurationName) {
        return getConfiguration(configurationName, "xml");
    }

    @Override
    public Resource getConfiguration(final String configurationName, final String fileExtension) {
        Preconditions.checkNotNull(configurationName, "configurationName is null");
        Preconditions.checkNotNull(fileExtension, "fileExtension is null");
        String fileName = getConfigurationDirectory() + configurationName + "-" + getServerRole() + "."
                + fileExtension;
        return getConfigurationFileResource(fileName);
    }

    @Override
    public Map<String, String> loadDefaultConfiguration(String configurationSection) {
        Resource configurationResource = getDefaultConfiguration();
        return createProperties(configurationSection, configurationResource);
    }

    @Override
    public String getProperty(String symbolName) {
        int pos = symbolName.indexOf(".");
        if (pos < 0) {
            return null;
        }
        String section = symbolName.substring(0, pos);
        String key = symbolName.substring(pos + 1);
        Map<String, String> prop = loadDefaultConfiguration(section);
        if (prop == null) {
            return null;
        }
        return prop.get(key);
    }

    @Override
    public Integer getPropertyInt(String symbolName) {
        String val = getProperty(symbolName);
        return val == null ? null : Integer.parseInt(val);
    }

}