Java tutorial
/* * Copyright 2014-2015 the original author or authors. * * 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 org.codehaus.griffon.runtime.hibernate3; import griffon.core.GriffonApplication; import griffon.core.env.Metadata; import griffon.core.injection.Injector; import griffon.plugins.datasource.DataSourceFactory; import griffon.plugins.datasource.DataSourceStorage; import griffon.plugins.hibernate3.Hibernate3Bootstrap; import griffon.plugins.hibernate3.Hibernate3Factory; import griffon.plugins.monitor.MBeanManager; import griffon.util.CollectionUtils; import org.codehaus.griffon.runtime.core.storage.AbstractObjectFactory; import org.codehaus.griffon.runtime.hibernate3.internal.HibernateConfigurationHelper; import org.codehaus.griffon.runtime.jmx.SessionFactoryMonitor; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import javax.annotation.Nonnull; import javax.inject.Inject; import javax.inject.Named; import javax.sql.DataSource; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import static griffon.util.ConfigUtils.getConfigValue; import static griffon.util.ConfigUtils.getConfigValueAsBoolean; import static griffon.util.GriffonNameUtils.requireNonBlank; import static java.util.Arrays.asList; import static java.util.Objects.requireNonNull; /** * @author Andres Almiray */ public class DefaultHibernate3Factory extends AbstractObjectFactory<SessionFactory> implements Hibernate3Factory { private static final String ERROR_SESSION_FACTORY_NAME_BLANK = "Argument 'sessionFactoryName' must not be blank"; private final Set<String> sessionFactoryNames = new LinkedHashSet<>(); @Inject private DataSourceFactory dataSourceFactory; @Inject private DataSourceStorage dataSourceStorage; @Inject private Injector injector; @Inject private MBeanManager mBeanManager; @Inject private Metadata metadata; @Inject public DefaultHibernate3Factory(@Nonnull @Named("hibernate3") griffon.core.Configuration configuration, @Nonnull GriffonApplication application) { super(configuration, application); sessionFactoryNames.add(KEY_DEFAULT); if (configuration.containsKey(getPluralKey())) { Map<String, Object> sessionFactories = (Map<String, Object>) configuration.get(getPluralKey()); sessionFactoryNames.addAll(sessionFactories.keySet()); } } @Nonnull @Override public Set<String> getSessionFactoryNames() { return sessionFactoryNames; } @Nonnull @Override public Map<String, Object> getConfigurationFor(@Nonnull String sessionFactoryName) { requireNonBlank(sessionFactoryName, ERROR_SESSION_FACTORY_NAME_BLANK); return narrowConfig(sessionFactoryName); } @Nonnull @Override protected String getSingleKey() { return "sessionFactory"; } @Nonnull @Override protected String getPluralKey() { return "sessionFactories"; } @Nonnull @Override public SessionFactory create(@Nonnull String name) { Map<String, Object> config = narrowConfig(name); event("Hibernate3ConnectStart", asList(name, config)); Configuration configuration = createConfiguration(config, name); createSchema(name, config, configuration); SessionFactory sessionFactory = new RecordingSessionFactory(configuration.buildSessionFactory()); if (getConfigValueAsBoolean(config, "jmx", true)) { sessionFactory = new JMXAwareSessionFactory(sessionFactory); registerMBeans(name, (JMXAwareSessionFactory) sessionFactory); } Session session = null; try { session = openSession(name, sessionFactory); for (Object o : injector.getInstances(Hibernate3Bootstrap.class)) { ((Hibernate3Bootstrap) o).init(name, session); } } finally { if (session != null) { session.close(); } } event("Hibernate3ConnectEnd", asList(name, config, sessionFactory)); return sessionFactory; } @Override public void destroy(@Nonnull String name, @Nonnull SessionFactory instance) { requireNonNull(instance, "Argument 'instance' must not be null"); Map<String, Object> config = narrowConfig(name); event("Hibernate3DisconnectStart", asList(name, config, instance)); Session session = null; try { session = openSession(name, instance); for (Object o : injector.getInstances(Hibernate3Bootstrap.class)) { ((Hibernate3Bootstrap) o).destroy(name, session); } } finally { if (session != null) { session.close(); } } closeDataSource(name); if (getConfigValueAsBoolean(config, "jmx", true)) { ((JMXAwareSessionFactory) instance).disposeMBeans(); } event("Hibernate3DisconnectEnd", asList(name, config)); } private void registerMBeans(@Nonnull String name, @Nonnull JMXAwareSessionFactory sessionFactory) { RecordingSessionFactory recordingSessionFactory = (RecordingSessionFactory) sessionFactory.getDelegate(); SessionFactoryMonitor sessionFactoryMonitor = new SessionFactoryMonitor(metadata, recordingSessionFactory, name); sessionFactory.addObjectName(mBeanManager.registerMBean(sessionFactoryMonitor, false).getCanonicalName()); } @Nonnull @SuppressWarnings("ConstantConditions") protected Configuration createConfiguration(@Nonnull Map<String, Object> config, @Nonnull String dataSourceName) { DataSource dataSource = getDataSource(dataSourceName); HibernateConfigurationHelper configHelper = new HibernateConfigurationHelper(getApplication(), config, dataSourceName, dataSource); Configuration configuration = configHelper.buildConfiguration(); getApplication().getEventRouter().publishEvent("Hibernate3ConfigurationAvailable", asList(CollectionUtils.map().e("configuration", configuration).e("dataSourceName", dataSourceName) .e("sessionConfiguration", config))); return configuration; } protected void createSchema(@Nonnull String dataSourceName, @Nonnull Map<String, Object> config, @Nonnull Configuration configuration) { configuration.setProperty("hibernate.hbm2ddl.auto", getConfigValue(config, "schema", "create-drop")); } protected void closeDataSource(@Nonnull String dataSourceName) { DataSource dataSource = dataSourceStorage.get(dataSourceName); if (dataSource != null) { dataSourceFactory.destroy(dataSourceName, dataSource); dataSourceStorage.remove(dataSourceName); } } @Nonnull protected DataSource getDataSource(@Nonnull String dataSourceName) { DataSource dataSource = dataSourceStorage.get(dataSourceName); if (dataSource == null) { dataSource = dataSourceFactory.create(dataSourceName); dataSourceStorage.set(dataSourceName, dataSource); } return dataSource; } @Nonnull protected Session openSession(@Nonnull String sessionFactoryName, @Nonnull SessionFactory sqlSessionFactory) { return sqlSessionFactory.openSession(); } }