Skip to content
ConfigurationLoaderUtil.java 5.82 KiB
Newer Older
import dk.gov.oiosi.common.RaspLibraryException;
import org.apache.commons.configuration.ConfigurationUtils;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
import org.apache.commons.logging.Log;
import java.io.File;
import java.net.URL;

 * Loads OIORASP configuration file, provides as clear as possible error messages in case of problems
 *
 * @since OIORASP 1.3.0
     * At first we search by directly given path, than also in conf subfolder
     * (like it was in OIORASP 1.2.3.HotFix1, for backward compatibility), than
     * - in parent folder.
     *
     * TODO DLK: Why do we search in parent folder? What if file with the same
     * name is located in more than 2 places?
     */
    protected static final String[] CONFIG_PATH_PREFIX_LIST = new String[]{"", "conf/", "../"};
    public static XMLConfiguration loadXMLConfiguration(String configPath, Log log) {
            throw new IllegalArgumentException("ConfigurationLoaderUtil.loadXMLConfiguration: log object is null but must be present");
        XMLConfiguration config = null;
        try {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                log.debug("Looking for configuration file: " + configPath);
            Throwable firstError = null;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            for (String configPrefix : CONFIG_PATH_PREFIX_LIST) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    config = new XMLConfiguration(configPrefix + configPath);
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    if (log.isInfoEnabled()) {
                        log.debug("Ready to load configuration file: " + configPrefix + configPath);
                    }
                    /*
                     * If 2 files exist, then the first should be used
                     */
                    break;
                } catch (Throwable e) {
                    if (firstError == null) {
                        firstError = e;
                    }
                }
            }
             * Try to give a hint at which location OIORASP configuration was
             * found or at least where we looked for it
             */
            if (config == null) {
                URL configPathUrl = null;
                try {
                    /*
                     * It is highly important to use the same way of location as XMLConfiguration uses.
                     *
                     * It is not enough just to check that File(configPath)
                     * exists, at server environment OIORASP configuration xml
                     * is placed into classpath.
                     */
                    configPathUrl = ConfigurationUtils.locate(configPath);
                } catch (Exception e2) {
                    // Hide locate exception, it has no detailed information, we will build our own message below
                }
                if (configPathUrl == null) {
                    // OIORASP configuration xml was not found at all, try to describe, where we looked for it.
                    throw new RuntimeException(buildLoadingErrorDescription(CONFIG_PATH_PREFIX_LIST, configPath));
                }
                throw new RuntimeException("Failed to parse OIORASP configuration file loaded by url '" + configPathUrl + "' with path " + configPath, firstError);
            }
            try {
                config = new XMLConfiguration(configPath);
            } catch (Throwable e) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                log.error("Unable to find configuration at [" + configPath + "]: " + e.getMessage(), e);
                try {
                    config = new XMLConfiguration("../" + configPath);
                } catch (Throwable e1) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    log.error("Unable to find configuration at [" + "../" + configPath + "]: " + e1.getMessage(), e1);
             * TODO: What is the reason to have this reloading strategy? Do we really support RaspConfiguration.xml dynamic modification?
             */
//            config.setReloadingStrategy(new FileChangedReloadingStrategy());
            config.setExpressionEngine(new XPathExpressionEngine());
        } catch (Exception e) {
            /*
             * Log error also into System.err in case if logger is not configured at all at this environment
             *
             * This is a critical situation which is expected to be fixed asap, so it should be very visible
             */
            log.fatal("OIORASP cannot load configuration xml [" + configPath + "]: " + e.getMessage(), e);
            throw new RaspLibraryException("OIORASP cannot load configuration xml [" + configPath + "]", e);
        log.info("Configuration file [" + configPath + "] loaded!");
        return config;
    }

    protected static String buildLoadingErrorDescription(String[] configPathPrefixList, String configPath) {
        StringBuilder sb = new StringBuilder();
        sb.append("Failed to locate OIORASP configuration file '");
        sb.append(configPath);
        sb.append("', tried to check next locations: ");
        sb.append("classpath");
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        for (String configPathPrefix : configPathPrefixList) {
            String canonicalPath = canonicalPath(new File(configPathPrefix + configPath));
            sb.append(", '");
            sb.append(canonicalPath);
            sb.append("'");
        }
        return sb.toString();
    }

    private static String canonicalPath(File file) {
        try {
            return file.getCanonicalPath();
        } catch (Exception e) {
            return file.getAbsolutePath();
        }
    }