All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opensaml.xml.Configuration Maven / Gradle / Ivy

/*
 * Licensed to the University Corporation for Advanced Internet Development, 
 * Inc. (UCAID) under one or more contributor license agreements.  See the 
 * NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The UCAID licenses this file to You 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 org.opensaml.xml;

import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;

import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.io.MarshallerFactory;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.io.UnmarshallerFactory;
import org.opensaml.xml.parse.ParserPool;
import org.opensaml.xml.security.SecurityConfiguration;
import org.opensaml.xml.util.XMLConstants;
import org.opensaml.xml.validation.ValidatorSuite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;

/** Class for loading library configuration files and retrieving the configured components. */
public class Configuration {

    /** Default object provider. */
    private static QName defaultProvider = new QName(XMLConstants.XMLTOOLING_CONFIG_NS,
            XMLConstants.XMLTOOLING_DEFAULT_OBJECT_PROVIDER);

    /** Object provider configuration elements indexed by QName. */
    private static Map configuredObjectProviders = new ConcurrentHashMap(0);

    /** Validator suite configuration elements indexed by suite IDs. */
    private static Map validatorSuiteConfigurations = new ConcurrentHashMap(0);

    /** Configured XMLObject builder factory. */
    private static XMLObjectBuilderFactory builderFactory = new XMLObjectBuilderFactory();

    /** Configured XMLObject marshaller factory. */
    private static MarshallerFactory marshallerFactory = new MarshallerFactory();

    /** Configured XMLObject unmarshaller factory. */
    private static UnmarshallerFactory unmarshallerFactory = new UnmarshallerFactory();

    /** Configured ValidatorSuites. */
    private static Map validatorSuites = new ConcurrentHashMap(5);

    /** Configured set of attribute QNames which have been globally registered as having an ID type. */
    private static Set idAttributeNames = new CopyOnWriteArraySet();

    /** Configured global security configuration information. */
    private static SecurityConfiguration globalSecurityConfig;

    /** Configured parser pool. */
    private static ParserPool parserPool;

    /** Constructor. */
    protected Configuration() {

    }
    
    /**
     * Get the currently configured ParserPool instance.
     * 
     * @return the currently ParserPool
     */
    public static ParserPool getParserPool() {
        return parserPool;
    }

    /**
     * Set the currently configured ParserPool instance.
     * 
     * @param newParserPool the new ParserPool instance to configure
     */
    public static void setParserPool(ParserPool newParserPool) {
        parserPool = newParserPool;
    }
    
    /**
     * Gets the QName for the object provider that will be used for XMLObjects that do not have a registered object
     * provider.
     * 
     * @return the QName for the default object provider
     */
    public static QName getDefaultProviderQName() {
        return defaultProvider;
    }

    /**
     * Adds an object provider to this configuration.
     * 
     * @param providerName the name of the object provider, corresponding to the element name or type name that the
     *            builder, marshaller, and unmarshaller operate on
     * @param builder the builder for that given provider
     * @param marshaller the marshaller for the provider
     * @param unmarshaller the unmarshaller for the provider
     */
    public static void registerObjectProvider(QName providerName, XMLObjectBuilder builder, Marshaller marshaller,
            Unmarshaller unmarshaller) {
        Logger log = getLogger();
        log.debug("Registering new builder, marshaller, and unmarshaller for {}", providerName);
        builderFactory.registerBuilder(providerName, builder);
        marshallerFactory.registerMarshaller(providerName, marshaller);
        unmarshallerFactory.registerUnmarshaller(providerName, unmarshaller);
    }

    /**
     * Removes the builder, marshaller, and unmarshaller registered to the given key.
     * 
     * @param key the key of the builder, marshaller, and unmarshaller to be removed
     */
    public static void deregisterObjectProvider(QName key) {
        Logger log = getLogger();
        log.debug("Unregistering builder, marshaller, and unmarshaller for {}", key);
        configuredObjectProviders.remove(key);
        builderFactory.deregisterBuilder(key);
        marshallerFactory.deregisterMarshaller(key);
        unmarshallerFactory.deregisterUnmarshaller(key);
    }

    /**
     * Gets the XMLObject builder factory that has been configured with information from loaded configuration files.
     * 
     * @return the XMLObject builder factory
     */
    public static XMLObjectBuilderFactory getBuilderFactory() {
        return builderFactory;
    }

    /**
     * Gets the XMLObject marshaller factory that has been configured with information from loaded configuration files.
     * 
     * @return the XMLObject marshaller factory
     */
    public static MarshallerFactory getMarshallerFactory() {
        return marshallerFactory;
    }

    /**
     * Gets the XMLObject unmarshaller factory that has been configured with information from loaded configuration
     * files.
     * 
     * @return the XMLObject unmarshaller factory
     */
    public static UnmarshallerFactory getUnmarshallerFactory() {
        return unmarshallerFactory;
    }

    /**
     * Registers a configured validator suite.
     * 
     * @param suiteId the ID of the suite
     * @param suite the configured suite
     */
    public static void registerValidatorSuite(String suiteId, ValidatorSuite suite) {
        validatorSuites.put(suiteId, suite);
    }

    /**
     * Removes a registered validator suite.
     * 
     * @param suiteId the ID of the suite
     */
    public static void deregisterValidatorSuite(String suiteId) {
        validatorSuiteConfigurations.remove(suiteId);
        validatorSuites.remove(suiteId);
    }

    /**
     * Gets a configured ValidatorSuite by its ID.
     * 
     * @param suiteId the suite's ID
     * 
     * @return the ValidatorSuite or null if no suite was registered under that ID
     */
    public static ValidatorSuite getValidatorSuite(String suiteId) {
        return validatorSuites.get(suiteId);
    }

    /**
     * Register an attribute as having a type of ID.
     * 
     * @param attributeName the QName of the ID attribute to be registered
     */
    public static void registerIDAttribute(QName attributeName) {
        if (!idAttributeNames.contains(attributeName)) {
            idAttributeNames.add(attributeName);
        }
    }

    /**
     * Deregister an attribute as having a type of ID.
     * 
     * @param attributeName the QName of the ID attribute to be de-registered
     */
    public static void deregisterIDAttribute(QName attributeName) {
        if (idAttributeNames.contains(attributeName)) {
            idAttributeNames.remove(attributeName);
        }
    }

    /**
     * Determine whether a given attribute is registered as having an ID type.
     * 
     * @param attributeName the QName of the attribute to be checked for ID type.
     * @return true if attribute is registered as having an ID type.
     */
    public static boolean isIDAttribute(QName attributeName) {
        return idAttributeNames.contains(attributeName);
    }

    /**
     * Get the global security configuration.
     * 
     * @return the global security configuration instance
     */
    public static SecurityConfiguration getGlobalSecurityConfiguration() {
        return globalSecurityConfig;
    }

    /**
     * Set the global security configuration.
     * 
     * @param config the new global security configuration instance
     */
    public static void setGlobalSecurityConfiguration(SecurityConfiguration config) {
        globalSecurityConfig = config;
    }

    /**
     * Validates that the system is not using the horribly buggy Sun JAXP implementation.
     */
    public static void validateNonSunJAXP() {
        Logger log = getLogger();
        String builderFactoryClass = DocumentBuilderFactory.newInstance().getClass().getName();
        log.debug("VM using JAXP parser {}", builderFactoryClass);

        if (builderFactoryClass.startsWith("com.sun")) {
            String errorMsg = "\n\n\nOpenSAML requires an xml parser that supports JAXP 1.3 and DOM3.\n"
                    + "The JVM is currently configured to use the Sun XML parser, which is known\n"
                    + "to be buggy and can not be used with OpenSAML.  Please endorse a functional\n"
                    + "JAXP library(ies) such as Xerces and Xalan.  For instructions on how to endorse\n"
                    + "a new parser see http://java.sun.com/j2se/1.5.0/docs/guide/standards/index.html\n\n\n";

            log.error(errorMsg);
            throw new Error(errorMsg);
        }
    }

    /**
     * Validates that the set of security providers configured in the JVM supports required cryptographic capabilities,
     * for example for the XML Encryption and XML Signature specifications.
     * 
     * Depending on the requirements of the calling code, failure to fully support encryption and signature requirements
     * may or may not be significant, so return a status flag to let the caller make that determination.
     * 
     * @return false if one or more capablities are not present, otherwise true
     */
    public static boolean validateJCEProviders() {
        Logger log = getLogger();
        boolean ret = true;

        // XML Encryption spec requires AES support (128 and 256).
        // Some JRE's are known to ship with no JCE's that support
        // the ISO10126Padding padding scheme.

        String errorMsgAESPadding = "The JCE providers currently configured in the JVM do not support\n"
                + "required capabilities for XML Encryption, either the 'AES' cipher algorithm\n"
                + "or the 'ISO10126Padding' padding scheme\n";

        try {
            Cipher.getInstance("AES/CBC/ISO10126Padding");
        } catch (NoSuchAlgorithmException e) {
            // IBM JCE returns this as the top-level exception even for the unsupported padding case. :-(
            // Otherwise would be nice to make the error msg more specific.
            log.warn(errorMsgAESPadding);
            ret = false;
        } catch (NoSuchPaddingException e) {
            log.warn(errorMsgAESPadding);
            ret = false;
        }

        // Could do more tests here as needed.

        return ret;
    }

    /**
     * Adds an object provider to this configuration.
     * 
     * @param providerName the name of the object provider, corresponding to the element name or type name that the
     *            builder, marshaller, and unmarshaller operate on
     * @param builder the builder for that given provider
     * @param marshaller the marshaller for the provider
     * @param unmarshaller the unmarshaller for the provider
     * @param configuration optional XML configuration snippet
     * 
     * @deprecated this method is deprecated with no replacement
     */
    public static void registerObjectProvider(QName providerName, XMLObjectBuilder builder, Marshaller marshaller,
            Unmarshaller unmarshaller, Element configuration) {
        Logger log = getLogger();
        log.debug("Registering new builder, marshaller, and unmarshaller for {}", providerName);
        if (configuration != null) {
            configuredObjectProviders.put(providerName, configuration);
        }
        builderFactory.registerBuilder(providerName, builder);
        marshallerFactory.registerMarshaller(providerName, marshaller);
        unmarshallerFactory.registerUnmarshaller(providerName, unmarshaller);
    }

    /**
     * Gets a clone of the configuration element for a qualified element. Note that this configuration reflects the
     * state of things as they were when the configuration was loaded, applications may have programmatically removed
     * builder, marshallers, and unmarshallers during runtime.
     * 
     * @param qualifedName the namespace qualifed element name of the schema type of the object provider
     * 
     * @return the object provider configuration element or null if no object provider is configured with that name
     * 
     * @deprecated this method is deprecated with no replacement
     */
    public static Element getObjectProviderConfiguration(QName qualifedName) {
        Element configElement = configuredObjectProviders.get(qualifedName);
        if (configElement != null) {
            return (Element) configElement.cloneNode(true);
        }
        return null;
    }

    /**
     * Registers a configured validator suite.
     * 
     * @param suiteId the ID of the suite
     * @param suite the configured suite
     * @param configuration optional XML configuration information
     * 
     * @deprecated this method is deprecated with no replacement
     */
    public static void registerValidatorSuite(String suiteId, ValidatorSuite suite, Element configuration) {
        if (configuration != null) {
            validatorSuiteConfigurations.put(suiteId, configuration);
        }
        validatorSuites.put(suiteId, suite);
    }

    /**
     * Gets a clone of the ValidatorSuite configuration element for the ID. Note that this configuration reflects the
     * state of things as they were when the configuration was loaded, applications may have programmatically removed
     * altered the suite during runtime.
     * 
     * @param suiteId the ID of the ValidatorSuite whose configuration is to be retrieved
     * 
     * @return the validator suite configuration element or null if no suite is configured with that ID
     * 
     * @deprecated this method is deprecated with no replacement
     */
    public static Element getValidatorSuiteConfiguration(String suiteId) {
        Element configElement = validatorSuiteConfigurations.get(suiteId);
        if (configElement != null) {
            return (Element) configElement.cloneNode(true);
        }

        return null;
    }
    
    /**
     * Get an SLF4J Logger.
     * 
     * @return a Logger instance
     */
    private static Logger getLogger() {
        return LoggerFactory.getLogger(Configuration.class);
    }

    static {
        validateJCEProviders();

        // Default to registering the xml:id attribute as an ID type for all configurations
        registerIDAttribute(new QName(javax.xml.XMLConstants.XML_NS_URI, "id"));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy