org.hibernate.boot.registry.StandardServiceRegistryBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.hibernate.boot.registry.StandardServiceRegistryBuilder.java

Source

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.boot.registry;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.boot.cfgxml.internal.ConfigLoader;
import org.hibernate.boot.cfgxml.spi.LoadedConfig;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl;
import org.hibernate.cfg.Environment;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.integrator.spi.IntegratorService;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.Service;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.StandardServiceInitiators;
import org.hibernate.service.internal.ProvidedService;
import org.hibernate.service.spi.ServiceContributor;

/**
 * Builder for standard {@link org.hibernate.service.ServiceRegistry} instances.
 *
 * @author Steve Ebersole
 * 
 * @see StandardServiceRegistryImpl
 * @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder
 */
public class StandardServiceRegistryBuilder {
    /**
     * Intended only for use from {@link org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl}.
     *
     * Creates a StandardServiceRegistryBuilder specific to the needs of JPA bootstrapping.
     * Specifically we ignore properties found in `cfg.xml` files in terms of adding them to
     * the builder immediately.  EntityManagerFactoryBuilderImpl handles collecting these
     * properties itself.
     */
    public static StandardServiceRegistryBuilder forJpa(BootstrapServiceRegistry bootstrapServiceRegistry) {
        final LoadedConfig loadedConfig = new LoadedConfig(null) {
            @Override
            protected void addConfigurationValues(Map configurationValues) {
                // here, do nothing
            }
        };
        return new StandardServiceRegistryBuilder(bootstrapServiceRegistry, new HashMap(), loadedConfig) {
            @Override
            public StandardServiceRegistryBuilder configure(LoadedConfig loadedConfig) {
                getAggregatedCfgXml().merge(loadedConfig);
                // super also collects the properties - here we skip that part
                return this;
            }
        };
    }

    /**
     * The default resource name for a hibernate configuration xml file.
     */
    public static final String DEFAULT_CFG_RESOURCE_NAME = "hibernate.cfg.xml";

    private final Map settings;
    private final List<StandardServiceInitiator> initiators = standardInitiatorList();
    private final List<ProvidedService> providedServices = new ArrayList<>();

    private boolean autoCloseRegistry = true;

    private final BootstrapServiceRegistry bootstrapServiceRegistry;
    private final ConfigLoader configLoader;
    private final LoadedConfig aggregatedCfgXml;

    /**
     * Create a default builder.
     */
    public StandardServiceRegistryBuilder() {
        this(new BootstrapServiceRegistryBuilder().enableAutoClose().build());
    }

    /**
     * Create a builder with the specified bootstrap services.
     *
     * @param bootstrapServiceRegistry Provided bootstrap registry to use.
     */
    public StandardServiceRegistryBuilder(BootstrapServiceRegistry bootstrapServiceRegistry) {
        this(bootstrapServiceRegistry, LoadedConfig.baseline());
    }

    /**
     * Intended for use exclusively from JPA boot-strapping.
     *
     * @see #forJpa
     */
    private StandardServiceRegistryBuilder(BootstrapServiceRegistry bootstrapServiceRegistry, Map settings,
            LoadedConfig loadedConfig) {
        this.bootstrapServiceRegistry = bootstrapServiceRegistry;
        this.configLoader = new ConfigLoader(bootstrapServiceRegistry);
        this.settings = settings;
        this.aggregatedCfgXml = loadedConfig;
    }

    /**
     * Create a builder with the specified bootstrap services.
     *
     * @param bootstrapServiceRegistry Provided bootstrap registry to use.
     */
    public StandardServiceRegistryBuilder(BootstrapServiceRegistry bootstrapServiceRegistry,
            LoadedConfig loadedConfigBaseline) {
        this.settings = Environment.getProperties();
        this.bootstrapServiceRegistry = bootstrapServiceRegistry;
        this.configLoader = new ConfigLoader(bootstrapServiceRegistry);
        this.aggregatedCfgXml = loadedConfigBaseline;
    }

    public ConfigLoader getConfigLoader() {
        return configLoader;
    }

    /**
     * Intended for internal testing use only!!
     */
    public LoadedConfig getAggregatedCfgXml() {
        return aggregatedCfgXml;
    }

    /**
     * Used from the {@link #initiators} variable initializer
     *
     * @return List of standard initiators
     */
    private static List<StandardServiceInitiator> standardInitiatorList() {
        final List<StandardServiceInitiator> initiators = new ArrayList<>(StandardServiceInitiators.LIST.size());
        initiators.addAll(StandardServiceInitiators.LIST);
        return initiators;
    }

    @SuppressWarnings("unused")
    public BootstrapServiceRegistry getBootstrapServiceRegistry() {
        return bootstrapServiceRegistry;
    }

    /**
     * Read settings from a {@link java.util.Properties} file by resource name.
     * <p>
     * Differs from {@link #configure()} and {@link #configure(String)} in that here we expect to read a
     * {@link java.util.Properties} file while for {@link #configure} we read the XML variant.
     *
     * @param resourceName The name by which to perform a resource look up for the properties file.
     *
     * @return this, for method chaining
     *
     * @see #configure()
     * @see #configure(String)
     */
    @SuppressWarnings({ "unchecked" })
    public StandardServiceRegistryBuilder loadProperties(String resourceName) {
        settings.putAll(configLoader.loadProperties(resourceName));
        return this;
    }

    /**
     * Read settings from a {@link java.util.Properties} file by File reference
     * <p>
     * Differs from {@link #configure()} and {@link #configure(String)} in that here we expect to read a
     * {@link java.util.Properties} file while for {@link #configure} we read the XML variant.
     *
     * @param file The properties File reference
     *
     * @return this, for method chaining
     *
     * @see #configure()
     * @see #configure(String)
     */
    @SuppressWarnings({ "unchecked" })
    public StandardServiceRegistryBuilder loadProperties(File file) {
        settings.putAll(configLoader.loadProperties(file));
        return this;
    }

    /**
     * Read setting information from an XML file using the standard resource location.
     *
     * @return this, for method chaining
     *
     * @see #DEFAULT_CFG_RESOURCE_NAME
     * @see #configure(String)
     * @see #loadProperties(String)
     */
    public StandardServiceRegistryBuilder configure() {
        return configure(DEFAULT_CFG_RESOURCE_NAME);
    }

    /**
     * Read setting information from an XML file using the named resource location.
     *
     * @param resourceName The named resource
     *
     * @return this, for method chaining
     */
    public StandardServiceRegistryBuilder configure(String resourceName) {
        return configure(configLoader.loadConfigXmlResource(resourceName));
    }

    public StandardServiceRegistryBuilder configure(File configurationFile) {
        return configure(configLoader.loadConfigXmlFile(configurationFile));
    }

    public StandardServiceRegistryBuilder configure(URL url) {
        return configure(configLoader.loadConfigXmlUrl(url));
    }

    @SuppressWarnings({ "unchecked" })
    public StandardServiceRegistryBuilder configure(LoadedConfig loadedConfig) {
        aggregatedCfgXml.merge(loadedConfig);
        settings.putAll(loadedConfig.getConfigurationValues());

        return this;
    }

    /**
     * Apply a setting value.
     *
     * @param settingName The name of the setting
     * @param value The value to use.
     *
     * @return this, for method chaining
     */
    @SuppressWarnings({ "unchecked", "UnusedDeclaration" })
    public StandardServiceRegistryBuilder applySetting(String settingName, Object value) {
        settings.put(settingName, value);
        return this;
    }

    /**
     * Apply a groups of setting values.
     *
     * @param settings The incoming settings to apply
     *
     * @return this, for method chaining
     */
    @SuppressWarnings({ "unchecked", "UnusedDeclaration" })
    public StandardServiceRegistryBuilder applySettings(Map settings) {
        this.settings.putAll(settings);
        return this;
    }

    public void clearSettings() {
        settings.clear();
    }

    /**
     * Adds a service initiator.
     *
     * @param initiator The initiator to be added
     *
     * @return this, for method chaining
     */
    @SuppressWarnings({ "UnusedDeclaration" })
    public StandardServiceRegistryBuilder addInitiator(StandardServiceInitiator initiator) {
        initiators.add(initiator);
        return this;
    }

    /**
     * Adds a user-provided service.
     *
     * @param serviceRole The role of the service being added
     * @param service The service implementation
     *
     * @return this, for method chaining
     */
    @SuppressWarnings({ "unchecked" })
    public StandardServiceRegistryBuilder addService(final Class serviceRole, final Service service) {
        providedServices.add(new ProvidedService(serviceRole, service));
        return this;
    }

    /**
     * By default, when a ServiceRegistry is no longer referenced by any other
     * registries as a parent it will be closed.
     * <p/>
     * Some applications that explicitly build "shared registries" may want to
     * circumvent that behavior.
     * <p/>
     * This method indicates that the registry being built should not be
     * automatically closed.  The caller agrees to take responsibility to
     * close it themselves.
     *
     * @return this, for method chaining
     */
    public StandardServiceRegistryBuilder disableAutoClose() {
        this.autoCloseRegistry = false;
        return this;
    }

    /**
     * See the discussion on {@link #disableAutoClose}.  This method enables
     * the auto-closing.
     *
     * @return this, for method chaining
     */
    public StandardServiceRegistryBuilder enableAutoClose() {
        this.autoCloseRegistry = true;
        return this;
    }

    /**
     * Build the StandardServiceRegistry.
     *
     * @return The StandardServiceRegistry.
     */
    @SuppressWarnings("unchecked")
    public StandardServiceRegistry build() {
        applyServiceContributingIntegrators();
        applyServiceContributors();

        final Map settingsCopy = new HashMap(settings);
        settingsCopy.put(org.hibernate.boot.cfgxml.spi.CfgXmlAccessService.LOADED_CONFIG_KEY, aggregatedCfgXml);
        ConfigurationHelper.resolvePlaceHolders(settingsCopy);

        return new StandardServiceRegistryImpl(autoCloseRegistry, bootstrapServiceRegistry, initiators,
                providedServices, settingsCopy);
    }

    @SuppressWarnings("deprecation")
    private void applyServiceContributingIntegrators() {
        for (Integrator integrator : bootstrapServiceRegistry.getService(IntegratorService.class)
                .getIntegrators()) {
            if (org.hibernate.integrator.spi.ServiceContributingIntegrator.class.isInstance(integrator)) {
                org.hibernate.integrator.spi.ServiceContributingIntegrator.class.cast(integrator)
                        .prepareServices(this);
            }
        }
    }

    private void applyServiceContributors() {
        final Iterable<ServiceContributor> serviceContributors = bootstrapServiceRegistry
                .getService(ClassLoaderService.class).loadJavaServices(ServiceContributor.class);

        for (ServiceContributor serviceContributor : serviceContributors) {
            serviceContributor.contribute(this);
        }
    }

    /**
     * Temporarily exposed since Configuration is still around and much code still uses Configuration.  This allows
     * code to configure the builder and access that to configure Configuration object (used from HEM atm).
     *
     * @return The settings map.
     *
     * @deprecated Temporarily exposed since Configuration is still around and much code still uses Configuration.
     * This allows code to configure the builder and access that to configure Configuration object.
     */
    @Deprecated
    public Map getSettings() {
        return settings;
    }

    /**
     * Destroy a service registry.  Applications should only destroy registries they have explicitly created.
     *
     * @param serviceRegistry The registry to be closed.
     */
    public static void destroy(ServiceRegistry serviceRegistry) {
        if (serviceRegistry == null) {
            return;
        }

        ((StandardServiceRegistryImpl) serviceRegistry).destroy();
    }
}