Skip to content
ConfigurationHandler.java 46.1 KiB
Newer Older
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 *
 * The Original Code is Java RASP toolkit.
 *
 * The Initial Developer of the Original Code is Lenio. Portions
 * created by Lenio are Copyright (C) 2007 Danish National IT and
 * Telecom Agency (http://www.itst.dk). All Rights Reserved.
 */

package dk.gov.oiosi.configuration;

Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
import dk.gov.oiosi.common.RaspLibraryException;
dlk-truelink's avatar
dlk-truelink committed
import dk.gov.oiosi.common.startup.IStartupTask;
import dk.gov.oiosi.common.startup.StartupTaskConfiguration;
import dk.gov.oiosi.communication.RMPolicy;
import dk.gov.oiosi.communication.SendPolicy;
import dk.gov.oiosi.communication.configuration.*;
dlk-truelink's avatar
dlk-truelink committed
import dk.gov.oiosi.exception.MainException;
import dk.gov.oiosi.security.RootCertificateConfig;
import dk.gov.oiosi.security.ldap.LdapLookupFactoryConfig;
import dk.gov.oiosi.security.ldap.LdapSettings;
import dk.gov.oiosi.security.oces.InvalidOcesCertificateSubjectKeyException;
import dk.gov.oiosi.security.oces.OcesCertificateSubjectKey;
import dk.gov.oiosi.security.oces.OcesX509CertificateConfig;
import dk.gov.oiosi.security.revocation.RevocationLookupFactoryConfig;
import dk.gov.oiosi.security.revocation.ocsp.OcspConfig;
import dk.gov.oiosi.xml.schematron.SchematronValidationConfig;
import dk.gov.oiosi.xml.xpath.PrefixedNamespace;
import dk.gov.oiosi.xml.xpath.discriminator.XPathDiscriminatorConfig;
import dk.gov.oiosi.xml.xpath.discriminator.XPathDiscriminatorConfigCollection;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.SubnodeConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
import javax.crypto.Cipher;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
import java.net.URISyntaxException;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
import java.security.NoSuchAlgorithmException;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
import java.security.Security;
import java.util.*;
/**
 * ReadOnly version of RaspConfigurationHandler.
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
 * <p/>
dsoegaard's avatar
dsoegaard committed
 * Reads RaspConfiguration.xml - and initializes configuration classes.
public class ConfigurationHandler {
    private static final Log log = LogFactory.getLog(ConfigurationHandler.class);
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
    /**
cpedersen's avatar
cpedersen committed
     * The default file name of the configuration file.
    private static final String RASPCONFIGURATION_XML_DEFAULT = "RaspConfiguration.xml";
    private static String versionNumber;
    private static String raspConfigurationFileName = RASPCONFIGURATION_XML_DEFAULT;
    private static ConfigurationHandler static_configurationHandler = null;
    private XMLConfiguration raspConfigurationFile = null;
    private LdapSettings ldapSettings = null;
    private OcspConfig ocspConfig = null;
    private CacheConfig cacheConfig = null;
    private UddiConfig uddiConfig = null;
    private LdapLookupFactoryConfig ldapFactory = null;
    private RevocationLookupFactoryConfig revocationFactory = null;
    private UddiLookupClientFactoryConfig uddiClientFactory = null;
    private RegistryLookupClientFactoryConfig registryClientFactory = null;
rfadel's avatar
 
rfadel committed
    private ProfileMappingCollectionConfig profileMappingCollectionConfig;
    private DocumentTypeCollectionConfig raspDocumentTypeCollectionConfig;
dsoegaard's avatar
dsoegaard committed
    private SendPolicy sendPolicy = null;
dlk-truelink's avatar
dlk-truelink committed
    private List<IStartupTask> startupTaskList = null;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * Enforces the singleton pattern.
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
    private ConfigurationHandler() {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
    }
    /**
     * Returns the static instance of the configuration handler.
     *
     * @return ConfigurationHandler The static instance of the configuration handler
     */
    public synchronized static ConfigurationHandler getInstance() {
        return getInstance(false);
    }

    /**
     * Returns the static instance of the configuration handler.
     *
     * @return ConfigurationHandler The static instance of the configuration handler
     */
    public synchronized static ConfigurationHandler getInstance(final boolean forceReload) {
        if (static_configurationHandler == null || forceReload) {
            static_configurationHandler = new ConfigurationHandler();
            static_configurationHandler.loadXMLConfiguration();
        }
        return static_configurationHandler;
    }

    /**
     * Sets the file name of the configuration file.
     *
     */
    public static void setConfigurationFile(String file) {
        raspConfigurationFileName = file;
    }

    /**
     * Actual building start task list configurations
     */
    @SuppressWarnings("unchecked")
    static List<IStartupTask> parseStartTaskList(XMLConfiguration xmlConfig) {
        List<IStartupTask> taskList = new ArrayList<>();
        String startupConfigKey = "//ConfigurationSection[@*=\"StartupConfig\"]/StartupTasks/StartupTask";
        List<HierarchicalConfiguration> startupTaskConfigList = xmlConfig.configurationsAt(startupConfigKey);
        if (startupTaskConfigList != null) {
            for (HierarchicalConfiguration taskConfig : startupTaskConfigList) {
                String className = taskConfig.getString("ImplementationNamespaceClass");
                if (className != null) {
                    className = className.trim();
                } else {
                    log.warn("ConfigurationHandler: in RaspConfiguration a section StartupTask is found without subtag ImplementationNamespaceClass, section is ignored");
                    continue;
                }
                List<StartupTaskConfiguration> configList = new ArrayList<>();
                List<HierarchicalConfiguration> configs = taskConfig.configurationsAt("ConfigurationList/Configuration");
                if (configs != null) {
                    for (HierarchicalConfiguration config : configs) {
                        String name = config.getString("Name");
                        String value = config.getString("Value");
                        if (name != null) {
                            name = name.trim();
                        }
                        if (value != null) {
                            value = value.trim();
                        }
                        if (name != null && value != null) {
                            configList.add(new StartupTaskConfiguration(name, value));
                        } else {
                            log.warn("ConfigurationHandler: in RaspConfiguration.xml a section StartupTask for class " + className + " is found with tag ConfigurationList/Configuration but empty Name or Value subtags, configuration is ignored.");
                        }
                    }
                }
                if (className.length() > 0) {
                    Class<?> taskImpl;
                    try {
                        taskImpl = Class.forName(className);
                    } catch (Exception e) {
                        log.warn("ConfigurationHandler: can not find class " + className + ", defined as Startup task implementation in RaspConfiguration.xml", e);
                        continue;
                    }
                    Object taskInstance;
                    try {
                        taskInstance = taskImpl.newInstance();
                    } catch (Exception e) {
                        log.warn("ConfigurationHandler: cannot create new instance with empty constructor for " + className + ", defined as Startup task implementation in RaspConfiguration.xml", e);
                        continue;
                    }
                    if (taskInstance instanceof IStartupTask) {
                        IStartupTask startupTask = (IStartupTask) taskInstance;
                        try {
                            startupTask.init(configList);
                        } catch (Exception e) {
                            log.warn("ConfigurationHandler: failed to initialize instance of class " + className + " with config values " + configList + ", startup task is skipped", e);
                            continue;
                        }
                        taskList.add(startupTask);
                    } else {
                        log.warn("ConfigurationHandler: class " + className + ", defined as Startup task implementation in RaspConfiguration.xml, does not implement interface " + IStartupTask.class.getName() + ", skipped.");
                    }
                }
            }
        }
        return taskList;
    }

    /**
     * Clear loaded configuration.
     * <p/>
     * Marked as protected to be clearable from unit tests only.
     */
    protected static void clear() {
        ConfigurationHandler.static_configurationHandler = null;
    }

    static String getVersionNumber() {
        return versionNumber;
    }

Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * Environment check and initializes related libraries
     * @since OIORASP 1.3.0
    private void initEnvironment() {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        try {
            if (Cipher.getMaxAllowedKeyLength("AES") < 1024) {
                log.fatal("Java JCE is not installed - see https://en.wikipedia.org/wiki/Java_Cryptography_Extension");
                throw new RaspLibraryException("Java JCE is not installed - see https://en.wikipedia.org/wiki/Java_Cryptography_Extension");
            }
        } catch (NoSuchAlgorithmException e) {
            log.fatal("Java JCE might not be installed - see https://en.wikipedia.org/wiki/Java_Cryptography_Extension", e);
            throw new RaspLibraryException("Java JCE is not installed - see https://en.wikipedia.org/wiki/Java_Cryptography_Extension", e);
        }

Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        // http://stackoverflow.com/questions/16651005/workaround-for-xmlschema-not-supporting-maxoccurs-larger-than-5000
        System.setProperty("jdk.xml.maxOccurLimit", "10000");
        // Support XSLT 2 for PEPPOL schematron files - se http://stackoverflow.com/questions/16455276/saxon-9-xslt-transformer-vs-xalan-2-7
        // Force default Transformation to be XSLT 1.0: org.apache.xalan.processor.TransformerFactoryImpl
        // Explicit choice of Saxon as Transformer is done in XsltUtility.getTransformerFactory().
        System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");
cpedersen's avatar
cpedersen committed
     * Loads the configuration from the file specified with setConfigurationFile(String file).
    synchronized public void loadXMLConfiguration() {
        // Empty local cache:
        uddiConfig = null;

Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        raspConfigurationFile = ConfigurationLoaderUtil.loadXMLConfiguration(raspConfigurationFileName, log);
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        log.debug("Loading RaspConfiguration from file=" + raspConfigurationFileName);
        versionNumber = loadVersionNumber();
        Version.initNumbering();
        log.info("This RASP is: " + Version.getVersion());
dsoegaard's avatar
dsoegaard committed
     * Get the LDAP Settings.
dsoegaard's avatar
dsoegaard committed
     * @return LDAP settings
    public LdapSettings getLdapSettings() {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        // The XPath for our configuration section
        String xpathBase = "//ConfigurationSection[@*=\"LdapSettings\"]/";
dlk-truelink's avatar
dlk-truelink committed
        if (log.isDebugEnabled()) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            log.debug("Loading LDAP settings from RaspConfiguration file...");
dlk-truelink's avatar
dlk-truelink committed
        }
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        synchronized (RASPCONFIGURATION_XML_DEFAULT) {
            if (ldapSettings == null) {
                ldapSettings = new LdapSettings();

                ldapSettings.setHost(raspConfigurationFile.getString(xpathBase + "Host"));
                ldapSettings.setMaxResults(raspConfigurationFile.getInt(xpathBase + "MaxResults"));
                ldapSettings.setPort(raspConfigurationFile.getInt(xpathBase + "Port"));
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                ldapSettings.setSearchServerTimeoutMsec(raspConfigurationFile.getInt(xpathBase + "SearchServerTimeoutMsec"));
                ldapSettings.setSearchClientTimeoutMsec(raspConfigurationFile.getInt(xpathBase + "ConnectionTimeoutMsec"));
dsoegaard's avatar
dsoegaard committed
     * Get the OCSP settings.
dsoegaard's avatar
dsoegaard committed
     * @return OCSP settings
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @throws URISyntaxException On error...
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
    public OcspConfig getOcspConfig() throws URISyntaxException {
        log.debug("RaspConfigurationHandler.getOcspConfig");
        if (ocspConfig == null) {
            // The XPath for our configuration section
            String xpathBase = "//ConfigurationSection[@*=\"OcspConfig\"]/";
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
                ocspConfig = new OcspConfig();
                ocspConfig.setDefaultTimeoutMsec(raspConfigurationFile.getInt(xpathBase + "DefaultTimeoutMsec"));
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                String serverUrl = raspConfigurationFile.getString(xpathBase + "ServerUrl");
                if (serverUrl != null) {
                    ocspConfig.setServerUrl(serverUrl);
                }
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
    /**
     * Get the OCSP settings.
     *
     * @return OCSP settings
     */
    public CacheConfig getCacheConfig() {
        log.debug("RaspConfigurationHandler.getCacheConfig");
        if (cacheConfig == null) {
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                cacheConfig = new CacheConfig();
                cacheConfig.setOcspLookupCache(parseCacheConfigElement(CacheConfigKey.OcspLookupCache));
                cacheConfig.setCrlLookupCache(parseCacheConfigElement(CacheConfigKey.CrlLookupCache));
                cacheConfig.setUddiServiceCache(parseCacheConfigElement(CacheConfigKey.UddiServiceCache));
                cacheConfig.setUddiTModelCache(parseCacheConfigElement(CacheConfigKey.UddiTModelCache));
                cacheConfig.setCertificateCache(parseCacheConfigElement(CacheConfigKey.CertificateCache));
                cacheConfig.setSchematronCache(parseCacheConfigElement(CacheConfigKey.SchematronCache));
            }
        }

        return cacheConfig;
    }

    @SuppressWarnings("unchecked")
    private CacheConfigElement parseCacheConfigElement(CacheConfigKey cacheConfigKey) {
        String cacheElementName = cacheConfigKey.name();
        String xpathCacheBase = "//ConfigurationSection[@*=\"CacheConfig\"]//" + cacheElementName;
        String implementationNamespaceClass = raspConfigurationFile.getString(xpathCacheBase + "/ImplementationNamespaceClass");
        String implementationAssembly = raspConfigurationFile.getString(xpathCacheBase + "/ImplementationAssembly");
        List<SubnodeConfiguration> list = raspConfigurationFile.configurationsAt(xpathCacheBase + "/CacheConfigurationCollection");
        Map<String, String> configuration = null;
        if (!list.isEmpty()) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            /*
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
             * Each ConfigurationSection can contain only one
             * CacheConfigurationCollection, but method configurationAt
             * IllegalArgumentException throws exception, if it cannot find
             * given key, so we replace it with configurationsAt() to support
             * old versions of RaspConfiguration.xml
             */
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            SubnodeConfiguration subnodeConfiguration = list.get(0);
            configuration = this.cacheConfiguration(subnodeConfiguration);
        }
        return new CacheConfigElement(cacheElementName, implementationNamespaceClass, implementationAssembly, configuration);
    }

    @SuppressWarnings("unchecked")
    private Map<String, String> cacheConfiguration(SubnodeConfiguration subnodeConfiguration) {
        Map<String, String> configurationMap = new HashMap<>();
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed

        List<HierarchicalConfiguration> configurationCollection = subnodeConfiguration.configurationsAt("Configuration");
        for (HierarchicalConfiguration cacheConfiguration : configurationCollection) {
            String key = cacheConfiguration.getString("Key");
            String value = cacheConfiguration.getString("Value");
            configurationMap.put(key, value);
        }

        return configurationMap;
    }

    /**
     * Get the Root certificate settings. In case of old version of RaspConfiguration.xml, returns collection with only one value from
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * getRootCertificateConfig()
     * <p/>
     * The reason for such method to be used - from some point OIORASP will support multiple root certificates from different issuers or
     * with different roots.
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     *
     * @return Root certificate settings
     * @since OIORASP 1.3.0
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     */
    public List<RootCertificateConfig> getRootCertificateLocationCollection() {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        // The XPath for our configuration section.
        String xpathBase = "//ConfigurationSection[@*=\"RootCertificateCollectionConfig\"]/";
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        List<RootCertificateConfig> collection = new ArrayList<>();
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        RootCertificateConfig rootCertificateConfig;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        List<SubnodeConfiguration> subnodeConfigurationList = raspConfigurationFile.configurationsAt(xpathBase + "RootCertificateLocationCollection");
        if (subnodeConfigurationList.isEmpty()) {
            // Get the Root certificate settings for old versions of RaspConfiguration.xml
            String xpathBaseOld = "//ConfigurationSection[@*=\"RootCertificateConfig\"]/";
            rootCertificateConfig = new RootCertificateConfig();
            rootCertificateConfig.setKeyStoreLocation(raspConfigurationFile.getString(xpathBaseOld + "KeyStoreLocation"));
            rootCertificateConfig.setKeyStorePassword(raspConfigurationFile.getString(xpathBaseOld + "KeyStorePassword"));
            rootCertificateConfig.setKeyLabel(raspConfigurationFile.getString(xpathBaseOld + "KeyLabel"));

Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            collection.add(rootCertificateConfig);
        } else {
            // New version of RaspConfiguration.xml - contains tag RootCertificateLocationCollection
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            SubnodeConfiguration subnodeConfiguration = subnodeConfigurationList.get(0);
            List<HierarchicalConfiguration> rootCertificateLocationList = subnodeConfiguration.configurationsAt("RootCertificateLocation");
            log.debug("RootCertificateLocationCollection: Elements found, count=" + rootCertificateLocationList.size());
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            for (HierarchicalConfiguration rootCertificateLocation : rootCertificateLocationList) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                rootCertificateConfig = new RootCertificateConfig();
                rootCertificateConfig.setKeyStoreLocation(rootCertificateLocation.getString("KeyStoreLocation"));
                rootCertificateConfig.setKeyStorePassword(rootCertificateLocation.getString("KeyStorePassword"));
                rootCertificateConfig.setKeyLabel(rootCertificateLocation.getString("KeyLabel"));

                // add the rootCert
                collection.add(rootCertificateConfig);
            }
        }
        log.debug("Root certificates loaded from RootCertificateLocationCollection, count=" + collection.size());
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * Get the OcesX509 certificate settings.
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @return OcesX509 certificate settings.
     */
    public OcesX509CertificateConfig getOcesX509CertificateConfig() throws InvalidOcesCertificateSubjectKeyException {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        // The XPath for our configuration section
        String xpathBase = "//ConfigurationSection[@*=\"OcesX509CertificateConfig\"]/";
        OcesX509CertificateConfig ocesX509CertConfig = new OcesX509CertificateConfig();
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        log.debug("getOcesX509CertificateConfig called...");
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        synchronized (RASPCONFIGURATION_XML_DEFAULT) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            ocesX509CertConfig.set_personalCertificateSubjectKey(new OcesCertificateSubjectKey(raspConfigurationFile.getString(xpathBase + "/PersonalCertificateSubjectKey/SubjectKeyString")));
            ocesX509CertConfig.set_organizationCertificateSubjectKey(new OcesCertificateSubjectKey(raspConfigurationFile.getString(xpathBase + "/OrganizationCertificateSubjectKey/SubjectKeyString")));
            ocesX509CertConfig.set_employeeCertificateSubjectKey(new OcesCertificateSubjectKey(raspConfigurationFile.getString(xpathBase + "/EmployeeCertificateSubjectKey/SubjectKeyString")));
            ocesX509CertConfig.set_functionCertificateSubjectKey(new OcesCertificateSubjectKey(raspConfigurationFile.getString(xpathBase + "/FunctionCertificateSubjectKey/SubjectKeyString")));
        }
        return ocesX509CertConfig;
    }
     * Get the settings used for NHR/UDDI lookup.
dsoegaard's avatar
dsoegaard committed
     * @return UDDI settings
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @throws URISyntaxException On error...
cpedersen's avatar
cpedersen committed
    public UddiConfig getUddiConfig() throws URISyntaxException {
        return getUddiConfig(false);
    }
    /**
     * Get the settings used for NHR/UDDI lookup. Loaded uddiConfig can be bypassed.
     *
     * @return UDDI settings
     * @throws URISyntaxException On error...
     */
    public UddiConfig getUddiConfig(final boolean forceReload) throws URISyntaxException {
        log.debug("RaspConfigurationHandler.getUddiConfig");
        if (uddiConfig == null || forceReload) {
            // The XPath for our configuration section
            String xpathBase = "//ConfigurationSection[@*=\"UddiConfig\"]/";

            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
                uddiConfig = new UddiConfig();
                uddiConfig.setFallbackTimeoutMinutes(raspConfigurationFile.getInt(xpathBase + "FallbackTimeoutMinutes"));
                SubnodeConfiguration lookupRegistryFallbackSubNodes = raspConfigurationFile.configurationAt(xpathBase + "LookupRegistryFallbackConfig");
                LookupRegistryFallbackConfig lookupRegistryFallbackConfig = getLookupRegistryFallbackConfig(lookupRegistryFallbackSubNodes);
                uddiConfig.setLookupRegistryFallbackConfig(lookupRegistryFallbackConfig);
            }
        }
        return uddiConfig;
    private LookupRegistryFallbackConfig getLookupRegistryFallbackConfig(SubnodeConfiguration lookupRegistryFallbackSubNodes) throws URISyntaxException {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        LookupRegistryFallbackConfig config = new LookupRegistryFallbackConfig();
        ArrayList<Registry> registries = new ArrayList<>();
        List<?> registrySubNodes = lookupRegistryFallbackSubNodes.configurationsAt("PrioritizedRegistryList/Registry");
        for (Object registrySubNodeObject : registrySubNodes) {
            SubnodeConfiguration registrySubNode = (SubnodeConfiguration) registrySubNodeObject;
            Registry registry = loadRegistry(registrySubNode);
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            registries.add(registry);
        }
        config.setRegistries(registries);
        return config;
    private Registry loadRegistry(SubnodeConfiguration registrySubNode) throws URISyntaxException {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        String xpath = "/EndpointCollection/Endpoint";
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        String[] endpoints = registrySubNode.getStringArray(xpath);
        int uddiLookupTimeoutSeconds = registrySubNode.getInt("/UddiLookupTimeoutSeconds", 120);
        return new Registry(endpoints, uddiLookupTimeoutSeconds);
cpedersen's avatar
cpedersen committed
     * Gets the document type configurations.
cpedersen's avatar
cpedersen committed
     * @return Document type configurations
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @throws ConfigurationException On error...
    public DocumentTypeCollectionConfig getRaspDocumentTypeCollectionConfig() throws ConfigurationException {
        return getRaspDocumentTypeCollectionConfig(false);
    }

    /**
     * Gets the document type configurations.
     *
     * @return Document type configurations
     * @throws ConfigurationException On error...
     */
    public DocumentTypeCollectionConfig getRaspDocumentTypeCollectionConfig(final boolean forceReload) throws ConfigurationException {
        log.debug("RaspConfigurationHandler.getRaspDocumentTypeCollectionConfig");
        if (raspDocumentTypeCollectionConfig == null || forceReload) {
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
                    raspDocumentTypeCollectionConfig = new DocumentTypeCollectionConfig();

Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    String[] docs = raspConfigurationFile.getStringArray("//DocumentTypes/DocumentTypeConfig/RootName");
                    for (int i = 0; i < docs.length; i++) {
                        DocumentTypeConfig typeConfig = initDocumentTypeConfig(i);
                        raspDocumentTypeCollectionConfig.addDocumentType(typeConfig);
                } catch (Exception e) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    log.error("Could not init DocumentTypeConfig " + e.getMessage(), e);
pjohansson's avatar
pjohansson committed
                    ConfigurationException ex = new ConfigurationException("Could not init DocumentTypeConfig " + e);
                    ex.setStackTrace(e.getStackTrace());
        return raspDocumentTypeCollectionConfig;
dsoegaard's avatar
dsoegaard committed
     * Gets the send policy.
cpedersen's avatar
cpedersen committed
     * @return The send policy
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @throws ConfigurationException On error...
    public SendPolicy getSendPolicy() throws ConfigurationException {
        if (sendPolicy == null) {
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
                log.debug("RaspConfigurationHandler.getSendPolicy");
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed

                // The XPath for our configuration section
                String xpathBase = "//ConfigurationSection[@*=\"Axis2JavaRasp\"]/";

                sendPolicy = new SendPolicy();
                String wssPolicy = raspConfigurationFile.getString(xpathBase + "WSSPolicyFile");
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                if (log.isInfoEnabled()) {
                    log.info("Config: wss policy file: " + wssPolicy);
dlk-truelink's avatar
dlk-truelink committed
                }
                sendPolicy.setWSSPolicyFileName(wssPolicy);
                String axisConf = raspConfigurationFile.getString(xpathBase + "AxisConfigurationFile");
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                if (log.isInfoEnabled()) {
                    log.info("Config: axis configuration: " + axisConf);
dlk-truelink's avatar
dlk-truelink committed
                }
                sendPolicy.setAxisConfigurationFile(axisConf);
                String repoDir = raspConfigurationFile.getString(xpathBase + "AxisRepositoryDir");
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                if (log.isInfoEnabled()) {
                    log.info("Config: axis repository dir: " + repoDir);
dlk-truelink's avatar
dlk-truelink committed
                }
                sendPolicy.setAxisRepositoryDir(repoDir);
                String httpPrefix = xpathBase + "RMPolicy/HTTPTransport/RMAssertion/Policy/";
                RMPolicy httpPolicy = initRMPolicy(httpPrefix);
                sendPolicy.setHttpRMPolicy(httpPolicy);
        return sendPolicy;
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
    /**
dsoegaard's avatar
dsoegaard committed
     * Gets the UDDI factory configuration.
dsoegaard's avatar
dsoegaard committed
     * @return UDDI factory configuration
     */
    public UddiLookupClientFactoryConfig getUddiLookupClientFactoryConfig() {
        log.debug("RaspConfigurationHandler.getUddiLookupClientFactoryConfig");
        if (uddiClientFactory == null) {
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
dsoegaard's avatar
dsoegaard committed
                initFactories();
            }
        }
        return uddiClientFactory;
    }

cpedersen's avatar
cpedersen committed
     * Gets the Registry lookup factory configuration.
     * @return Registry factory configuration
     */
    public RegistryLookupClientFactoryConfig getRegistryLookupClientFactoryConfig() {
        log.debug("RaspConfigurationHandler.getUddiLookupClientFactoryConfig");
        if (registryClientFactory == null) {
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
                initFactories();
            }
        }
        return registryClientFactory;
    }

dsoegaard's avatar
dsoegaard committed
    /**
     * Gets the LDAP factory configuration
dsoegaard's avatar
dsoegaard committed
     * @return LDAP factory configuration
     */
    public LdapLookupFactoryConfig getLdapLookupFactoryConfig() {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        log.debug("getLdapLookupFactoryConfig called...");
        if (ldapFactory == null) {
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
dsoegaard's avatar
dsoegaard committed
                initFactories();
            }
        }
        return ldapFactory;
    }

    /**
cpedersen's avatar
cpedersen committed
     * Gets the revocation lookup client factory
cpedersen's avatar
cpedersen committed
     * @return Revocation lookup client factory
dsoegaard's avatar
dsoegaard committed
     */
    public RevocationLookupFactoryConfig getRevocationLookupFactoryConfig() {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        log.debug("getRevocationLookupFactoryConfig called...");
        if (revocationFactory == null) {
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
dsoegaard's avatar
dsoegaard committed
                initFactories();
            }
        }
        return revocationFactory;
dsoegaard's avatar
dsoegaard committed
    }
cpedersen's avatar
cpedersen committed
     * Gets the ProfileMapping configuration.
     * @return ProfileMappingCollectionConfig object.
     * @throws ConfigurationException On error...
rfadel's avatar
 
rfadel committed
    public ProfileMappingCollectionConfig getProfileMappingCollectionConfig() throws ConfigurationException {
        if (profileMappingCollectionConfig == null) {
            synchronized (RASPCONFIGURATION_XML_DEFAULT) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    profileMappingCollectionConfig = new ProfileMappingCollectionConfig();

                    String[] names = raspConfigurationFile.getStringArray("//ProfileMappingCollection/ProfileMapping/Name");
                    String[] tModelIds = raspConfigurationFile.getStringArray("//ProfileMappingCollection/ProfileMapping/TModelGuid");
                    if (names == null || tModelIds == null) {
                        throw new ConfigurationException("ProfileMappingCollectionConfig: Names or tModelGuids are null");
                    } else if (names.length != tModelIds.length) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                        throw new ConfigurationException("ProfileMappingCollectionConfig: Different number of names and tModelGuids");
                    for (int i = 0; i < names.length; i++) {
                        ProfileMapping profileMapping = new ProfileMapping(names[i], tModelIds[i]);
rfadel's avatar
 
rfadel committed
                        profileMappingCollectionConfig.AddProfileMapping(profileMapping);
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                } catch (Exception e) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    ConfigurationException ex = new ConfigurationException("Could not init ProfileMappingCollectionConfig: " + e);
                    ex.setStackTrace(e.getStackTrace());
                    throw ex;
                }
            }
        }
rfadel's avatar
 
rfadel committed
        return profileMappingCollectionConfig;
dsoegaard's avatar
dsoegaard committed
    /**
     * Initiate the reliable messaging configuration.
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @param xpath where to find the configuration in the XML-document
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @return RMPolicy
     * @throws ConfigurationException On error...
    private RMPolicy initRMPolicy(String xpath) throws ConfigurationException {
            boolean eb = raspConfigurationFile.getBoolean(xpath + "ExponentialBackoff");
            long retr = raspConfigurationFile.getLong(xpath + "RetransmissionInterval");
            int max = raspConfigurationFile.getInt(xpath + "MaximumRetransmissionCount");
            return new RMPolicy(max, retr, eb);
        } catch (Exception e) {
            ConfigurationException ex = new ConfigurationException("Could not init SendPolicy " + e);
            ex.setStackTrace(e.getStackTrace());
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @param docIndex ix in configuration file
     * @return configuration for document
     */
    private DocumentTypeConfig initDocumentTypeConfig(int docIndex) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        // The XPath for our configuration section
        String xpathBase = "//ConfigurationSection[@*=\"DocumentTypeCollectionConfig\"]/";
        DocumentTypeConfig documentTypeConfig = new DocumentTypeConfig();
        String documentSelect = xpathBase + "DocumentTypes/DocumentTypeConfig[" + (docIndex + 1) + "]";
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        if (log.isDebugEnabled()) {
            log.debug("Retrieving basic data for " + documentSelect);
        }
        documentTypeConfig.setRootName(raspConfigurationFile.getString(documentSelect + "/RootName"));
        documentTypeConfig.setFriendlyName(raspConfigurationFile.getString(documentSelect + "/FriendlyName"));
        documentTypeConfig.setRootNamespace(raspConfigurationFile.getString(documentSelect + "/RootNamespace"));
        documentTypeConfig.setSchemaPath(raspConfigurationFile.getString(documentSelect + "/SchemaPath"));
        documentTypeConfig.setServiceContractTModel(raspConfigurationFile.getString(documentSelect + "/ServiceContractTModel"));
        documentTypeConfig.setStylesheetPath(raspConfigurationFile.getString(documentSelect + "/StylesheetPath"));
        String tmp = raspConfigurationFile.getString(documentSelect + "/XsltTransformStylesheetPath");
        if (tmp != null && tmp.length() > 0) {
            documentTypeConfig.setXsltTransformStylesheetPath(tmp);
        int noOfSchematronValidationConfigs = raspConfigurationFile.getList(documentSelect + "/SchematronValidationConfigs/SchematronValidationConfig/SchematronDocumentPath").size();
        documentTypeConfig.getSchematronValidationConfigList().clear();
        for (int x = 0; x < noOfSchematronValidationConfigs; x++) {
            SchematronValidationConfig svc = new SchematronValidationConfig(raspConfigurationFile.getString(documentSelect + "/SchematronValidationConfigs/SchematronValidationConfig[" + (x + 1) + "]/SchematronDocumentPath"),
                    raspConfigurationFile.getString(documentSelect + "/SchematronValidationConfigs/SchematronValidationConfig[" + (x + 1) + "]/ErrorXPath"),
                    raspConfigurationFile.getString(documentSelect + "/SchematronValidationConfigs/SchematronValidationConfig[" + (x + 1) + "]/ErrorMessageXPath"));
            documentTypeConfig.getSchematronValidationConfigList().add(svc);
        }

        //
        DocumentEndpointInformation rdept = new DocumentEndpointInformation();
        rdept.setEndpointFriendlyName(new ServiceEndpointFriendlyName(raspConfigurationFile.getString(documentSelect
                + "/EndpointType/EndpointFriendlyName/XPath")));
        rdept.setSenderFriendlyName(new ServiceEndpointFriendlyName(raspConfigurationFile.getString(documentSelect
                + "/EndpointType/SenderFriendlyName/XPath")));
        rdept.setReplyAction(raspConfigurationFile.getString(documentSelect + "/EndpointType/ReplyAction"));
        rdept.setRequestAction(raspConfigurationFile.getString(documentSelect + "/EndpointType/RequestAction"));

        // Receiver Key
        ServiceEndpointKey recipientRdk = new ServiceEndpointKey();
        recipientRdk.setXPath(raspConfigurationFile.getString(documentSelect + "/EndpointType/Key/Xpath"));
        KeyTypeMappingExpression recipientKeyTypeMapping = getKeyTypeMappingExpression(documentSelect + "/EndpointType/Key");
        recipientRdk.addMappingExpression(recipientKeyTypeMapping);

        // Sender Key
        ServiceEndpointKey senderRdk = new ServiceEndpointKey();
        senderRdk.setXPath(raspConfigurationFile.getString(documentSelect + "/EndpointType/SenderKey/Xpath"));
        KeyTypeMappingExpression senderKeyTypeMapping = getKeyTypeMappingExpression(documentSelect + "/EndpointType/SenderKey");
        senderRdk.addMappingExpression(senderKeyTypeMapping);

        rdept.setSenderKey(senderRdk);
        documentTypeConfig.setEndpointType(rdept);
rfadel's avatar
 
rfadel committed
        // Set ProfileId XPath
        String profileIdXPath = raspConfigurationFile.getString(documentSelect + "/ProfileIdXPath/XPath");
        documentTypeConfig.setProfileIdXPath(profileIdXPath);
rfadel's avatar
rfadel committed
        // End Set ProfileId XPath
        int noOfEndNameSpaces = raspConfigurationFile.getList(documentSelect + "/Namespaces/PrefixedNamespace/Namespace").size();
        documentTypeConfig.getNamespacesList().clear();
        for (int x = 0; x < noOfEndNameSpaces; x++) {
            PrefixedNamespace namespace = new PrefixedNamespace();
            namespace.setPrefix(raspConfigurationFile.getString(documentSelect + "/Namespaces/PrefixedNamespace[" + (x + 1) + "]/Prefix"));
            namespace.setNamespace(raspConfigurationFile.getString(documentSelect + "/Namespaces/PrefixedNamespace[" + (x + 1) + "]/Namespace"));
            documentTypeConfig.getNamespacesList().add(namespace);
        String csXpath = documentSelect + "/CustomHeaderConfiguration/XPaths";

        CustomHeaderConfiguration chc = new CustomHeaderConfiguration();
        List<CustomHeaderXPathConfiguration> headerList = new ArrayList<>();
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        for (Iterator<?> it = raspConfigurationFile.getKeys(csXpath); it.hasNext(); ) {
            String key = it.next().toString();
            String xpath = raspConfigurationFile.getString(key);
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            if (xpath.length() > 0) {
                String elementName = key.substring(csXpath.length() + 1);
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                CustomHeaderXPathConfiguration chxc = new CustomHeaderXPathConfiguration();
                chxc.setName(elementName);
                chxc.setXPath(xpath);

                headerList.add(chxc);
            }
        }
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        if (headerList.size() > 0) {
            chc.setXPaths(headerList.toArray(new CustomHeaderXPathConfiguration[0]));
            documentTypeConfig.setCustomHeaderConfiguration(chc);
        // xpath discriminator collection
        String[] identifierList = raspConfigurationFile.getStringArray(documentSelect + "/IdentifierDiscriminators/XPathDiscriminatorConfig/XPathExpression");
        if (identifierList.length > 0) {
            XPathDiscriminatorConfigCollection xpathIdentifiers = new XPathDiscriminatorConfigCollection();
            for (int i = 0; i < identifierList.length; i++) {
                XPathDiscriminatorConfig identifier = new XPathDiscriminatorConfig();

                String expression = raspConfigurationFile.getString(documentSelect
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                        + "/IdentifierDiscriminators/XPathDiscriminatorConfig[" + (i + 1) + "]/XPathExpression");
                String expectedResult = raspConfigurationFile.getString(documentSelect
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                        + "/IdentifierDiscriminators/XPathDiscriminatorConfig[" + (i + 1) + "]/XPathExpectedResult");
                identifier.setXPathExpression(expression);
                identifier.setXPathExpectedResult(expectedResult);

                xpathIdentifiers.add(identifier);
            }
            documentTypeConfig.setIdentifierDiscriminators(xpathIdentifiers);
        log.debug("Finished loading documentType");
        return documentTypeConfig;
dsoegaard's avatar
dsoegaard committed
     * Utility to initiate key type for sender/receiver key (CVR, EAN...).
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * @param path path in document
    private KeyTypeMappingExpression getKeyTypeMappingExpression(String path) {
        KeyTypeMappingExpression keyTypeMapping = new KeyTypeMappingExpression();
dsoegaard's avatar
dsoegaard committed
        String keyTypeMappingXPath = path + "/MappingExpressions/KeyTypeMappingExpressions/Name";
dsoegaard's avatar
dsoegaard committed
        String[] mappings = raspConfigurationFile.getStringArray(keyTypeMappingXPath);
        for (int i = 0; i < mappings.length; i++) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            String mapExprKey = path + "/MappingExpressions/KeyTypeMappingExpressions[" + (i + 1) + "]";
            String mapName = raspConfigurationFile.getString(mapExprKey + "/Name");
            String mapXPath = raspConfigurationFile.getString(mapExprKey + "/XPathExpression");
            keyTypeMapping.setName(mapName);
            keyTypeMapping.setXPathExpression(mapXPath);
            String[] mapList = raspConfigurationFile.getStringArray(mapExprKey + "/Mappings/Mapping/Value");
            for (int j = 0; j < mapList.length; j++) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                String mapListKey = mapExprKey + "/Mappings/Mapping[" + (j + 1) + "]";
                String value = raspConfigurationFile.getString(mapListKey + "/Value");
                String mapsTo = raspConfigurationFile.getString(mapListKey + "/MapsTo");

                KeyTypeMapping map = new KeyTypeMapping();
                map.setValue(value);
                map.setMapsTo(mapsTo);

                keyTypeMapping.addMapping(map);
            }
        }
        return keyTypeMapping;
    }
    private void initFactories() {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        registryClientFactory = new RegistryLookupClientFactoryConfig();
        registryClientFactory.setImplementationNamespaceClass(raspConfigurationFile.getString("//ConfigurationSection[@*=\"RegistryLookupClientFactoryConfig\"]/ImplementationNamespaceClass"));
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        uddiClientFactory = new UddiLookupClientFactoryConfig();
        uddiClientFactory.setImplementationNamespaceClass(raspConfigurationFile.getString("//ConfigurationSection[@*=\"UddiLookupClientFactoryConfig\"]/ImplementationNamespaceClass"));
        ldapFactory = new LdapLookupFactoryConfig();
        ldapFactory.setImplementationNamespaceClass(raspConfigurationFile.getString("//ConfigurationSection[@*=\"LdapLookupFactoryConfig\"]/ImplementationNamespaceClass"));
        revocationFactory = new RevocationLookupFactoryConfig();
        revocationFactory.setImplementationNamespaceClass(raspConfigurationFile.getString("//ConfigurationSection[@*=\"RevocationLookupFactoryConfig\"]/ImplementationNamespaceClass"));
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed

    public void executeStartupTasks() throws MainException {
        List<IStartupTask> taskList = this.getStartupTaskList();
        if (taskList != null && !taskList.isEmpty()) {
            int failedExecutionCount = 0;
            Exception firstException = null;
            long start = System.currentTimeMillis();
            for (IStartupTask task : taskList) {
                try {
                    task.doTask();
                } catch (Exception e) {
                    log.error("Failure during startup execution of task " + task + ": " + e.getMessage(), e);
                    if (firstException == null) {
                        firstException = e;
                    }
                }
            }
            if (firstException == null) {
                if (log.isInfoEnabled()) {
                    log.info("ConfigurationHandler successfully executed " + taskList.size() + " startup tasks in " + (System.currentTimeMillis() - start) + " ms");
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                }
            } else {
                throw new MainException("ConfigurationHandler failed to execute " + failedExecutionCount + " startup tasks, see first exception in stack trace", firstException);
            }
        } else {
            log.warn("ConfigurationHandler: executeStartupTasks method was called but no startup tasks are configured. Please check RaspConfiguration.xml file to be updated with StartupConfig ConfigurationSection");
        }
    }

    /**
     * Returns list of startup tasks. This list can be modified before call of executeStartupTasks().
     * @since OIORASP 1.3.0
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     */
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
    List<IStartupTask> getStartupTaskList() {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
        if (this.startupTaskList == null) {
            try {
                /*
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                 * In case if several threads try to initialize tasks, we should
                 * not restrict it, as it is not critical to have several
                 * instances of them - only last instance of List will be kept in memory
                 */
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                long start = System.currentTimeMillis();
                List<IStartupTask> taskList;
                synchronized (RASPCONFIGURATION_XML_DEFAULT) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    taskList = parseStartTaskList(this.raspConfigurationFile);
                    this.startupTaskList = taskList;
                }
                if (log.isInfoEnabled()) {
                    // Skip showing success message if no task is correctly configured
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    if (taskList.size() > 0) {
                        log.info("ConfigurationHandler: startup tasks are initialized in " + (System.currentTimeMillis() - start) + " ms, found " + taskList.size() + " tasks.");
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                    }
                }
            } catch (Exception e) {
                /*
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
                 * Additionally protect start task initialization from
                 * unexpected exceptions, they should not prevent the system to
                 * start, as they are not necessary should be executed.
                 */
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            }
        }
        return startupTaskList;
    }

    /**
     * Overwrites configured startup task list
     *
     * @param startupTaskList List of IStartupTasks.
     */
    public void setStartupTaskList(List<IStartupTask> startupTaskList) {
        this.startupTaskList = startupTaskList;
    }

    /**
     * Load version number from file "version-number.txt".
     * <p/>
     * 1st priority is to load it from root of JAR file, 2nd priority is loading it from source root (for unit tests).
     *
     * @return Text with version number.
     */
    private String loadVersionNumber() {
            InputStream is = getClass().getResourceAsStream("/version-number.txt");
            if (is == null) {
                return loadVersionNumberFromLocalFile();
            }
            byte[] b = new byte[20];
            //noinspection ResultOfMethodCallIgnored
            is.read(b);
            if (b.length > 0) {
                return new String(b).trim();
                // Non-JAR/Unit test scenario
                return loadVersionNumberFromLocalFile();
            }
        } catch (IOException e) {
            log.fatal("Problem loading version file: " + e.getMessage(), e);
        }
        log.fatal("Problem loading version file... but no exception thrown");
        return null;
    }

Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
     * Load version number from local file "version-number.txt" as part of unit test.
     *
     * @return Text with version number.
     */
    private String loadVersionNumberFromLocalFile() {
        File versionFile = new File("target/version-number.txt");
        try {
            // Unit test scenario, where the
            return FileUtils.readFileToString(versionFile);
        } catch (IOException e) {
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
            log.warn("Problem loading version file from " + versionFile.getAbsolutePath() + ": " + e.getMessage());
            return null;
        }
    }
Peter Sone Koldkjær's avatar
Peter Sone Koldkjær committed
}