HHH-5562 - Improve how event listeners are handled and introduce a service pattern for integrators to leverage

This commit is contained in:
Steve Ebersole 2011-03-27 10:39:38 -05:00
parent 47abaf12fa
commit 7cba21dcd9
2 changed files with 100 additions and 4 deletions

View File

@ -0,0 +1,44 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.impl;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
/**
* Contract for stuff that integrates with Hibernate.
*
* @todo : obviously, come up with a better name :)
*
* @author Steve Ebersole
* @since 4.0
* @jira HHH-5562
*/
public interface Integrator {
public void integrate(
Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry);
}

View File

@ -27,11 +27,13 @@ import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.net.URL;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
@ -39,6 +41,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@ -117,9 +120,11 @@ import org.hibernate.persister.spi.PersisterFactory;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistryFactory;
import org.hibernate.stat.Statistics;
import org.hibernate.stat.internal.ConcurrentStatisticsImpl;
@ -209,6 +214,7 @@ public final class SessionFactoryImpl
SessionFactoryObserver observer) throws HibernateException {
LOG.buildingSessionFactory();
// todo : move stats building to SF service reg building
this.statistics = buildStatistics( settings, serviceRegistry );
this.properties = new Properties();
@ -239,6 +245,12 @@ public final class SessionFactoryImpl
settings.getRegionFactory().start( settings, properties );
this.queryPlanCache = new QueryPlanCache( this );
// todo : everything above here consider implementing as standard SF service. specifically: stats, caches, types, function-reg
for ( Integrator integrator : locateIntegrators( this.serviceRegistry ) ) {
integrator.integrate( cfg, this, (SessionFactoryServiceRegistry) this.serviceRegistry );
}
//Generators:
identifierGenerators = new HashMap();
@ -477,6 +489,46 @@ public final class SessionFactoryImpl
this.observer.sessionFactoryCreated( this );
}
private Iterable<Integrator> locateIntegrators(ServiceRegistryImplementor serviceRegistry) {
List<Integrator> integrators = new ArrayList<Integrator>();
// todo : add "known" integrators -> BV, hibernate validation, search, envers
final Properties properties = new Properties();
ClassLoaderService classLoader = serviceRegistry.getService( ClassLoaderService.class );
List<URL> urls = classLoader.locateResources( "META-INF/hibernate/org.hibernate.impl.Integrator" );
for ( URL url : urls ) {
try {
final InputStream propertyStream = url.openStream();
try {
properties.clear();
properties.load( propertyStream );
// for now we only understand 'implClass' as key
final String implClass = properties.getProperty( "implClass" );
Class integratorClass = classLoader.classForName( implClass );
try {
integrators.add( (Integrator) integratorClass.newInstance() );
}
catch (Exception e) {
throw new HibernateException( "Unable to instantiate specified Integrator class [" + implClass + "]", e );
}
}
finally {
try {
propertyStream.close();
}
catch (IOException ignore) {
}
}
}
catch ( IOException ioe ) {
LOG.debugf( ioe, "Unable to process Integrator service file [%s], skipping" , url.toExternalForm() );
}
}
return integrators;
}
@Override
public void addObserver(SessionFactoryObserver observer) {
this.observer.addObserver( observer );