Skip to content

Commit ddeaffc

Browse files
committed
light refactoring of EventEngine and CallbacksFactory
1 parent 9442f4d commit ddeaffc

File tree

2 files changed

+130
-123
lines changed

2 files changed

+130
-123
lines changed

hibernate-core/src/main/java/org/hibernate/event/spi/EventEngine.java

Lines changed: 86 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,26 @@
55
package org.hibernate.event.spi;
66

77
import java.util.Collection;
8-
import java.util.Collections;
98
import java.util.HashMap;
109
import java.util.Map;
1110
import java.util.function.Consumer;
1211

1312
import org.hibernate.HibernateException;
1413
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
1514
import org.hibernate.boot.spi.MetadataImplementor;
15+
import org.hibernate.boot.spi.SessionFactoryOptions;
1616
import org.hibernate.engine.spi.SessionFactoryImplementor;
1717
import org.hibernate.event.service.internal.EventListenerRegistryImpl;
1818
import org.hibernate.event.service.spi.EventListenerGroup;
1919
import org.hibernate.event.service.spi.EventListenerRegistry;
20-
import org.hibernate.internal.util.collections.CollectionHelper;
21-
import org.hibernate.jpa.event.internal.CallbacksFactory;
2220
import org.hibernate.jpa.event.spi.CallbackRegistry;
21+
import org.hibernate.service.spi.ServiceRegistryImplementor;
2322
import org.hibernate.service.spi.Stoppable;
2423

24+
import static java.util.Collections.unmodifiableMap;
25+
import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty;
26+
import static org.hibernate.jpa.event.internal.CallbacksFactory.buildCallbackRegistry;
27+
2528
/**
2629
* Composite for the things related to Hibernate's event system.
2730
*
@@ -36,102 +39,39 @@ public class EventEngine {
3639

3740
public EventEngine(MetadataImplementor mappings, SessionFactoryImplementor sessionFactory) {
3841

42+
final SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions();
43+
final ServiceRegistryImplementor serviceRegistry = sessionFactory.getServiceRegistry();
44+
3945
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4046
// resolve (JPA) callback handlers
4147

42-
callbackRegistry = CallbacksFactory.buildCallbackRegistry( sessionFactory.getSessionFactoryOptions(),
43-
sessionFactory.getServiceRegistry(), mappings.getEntityBindings() );
44-
48+
callbackRegistry = buildCallbackRegistry( sessionFactoryOptions, serviceRegistry, mappings.getEntityBindings() );
4549

4650
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4751
// resolve event types and listeners
4852

49-
final EventListenerRegistryImpl.Builder listenerRegistryBuilder = new EventListenerRegistryImpl.Builder(
50-
callbackRegistry,
51-
sessionFactory.getSessionFactoryOptions().isJpaBootstrap()
52-
);
53+
final EventListenerRegistryImpl.Builder listenerRegistryBuilder =
54+
new EventListenerRegistryImpl.Builder( callbackRegistry, sessionFactoryOptions.isJpaBootstrap() );
5355

5456
final Map<String,EventType<?>> eventTypes = new HashMap<>();
5557
EventType.registerStandardTypes( eventTypes );
5658

57-
final EventEngineContributions contributionManager = new EventEngineContributions() {
58-
@Override
59-
public <T> EventType<T> findEventType(String name) {
60-
//noinspection unchecked
61-
return (EventType<T>) eventTypes.get( name );
62-
}
63-
64-
@Override
65-
public <T> EventType<T> contributeEventType(String name, Class<T> listenerRole) {
66-
final EventType<T> eventType = registerEventType( name, listenerRole );
67-
68-
listenerRegistryBuilder.prepareListeners( eventType );
69-
70-
return eventType;
71-
}
72-
73-
private <T> EventType<T> registerEventType(String name, Class<T> listenerRole) {
74-
if ( name == null ) {
75-
throw new HibernateException( "Custom event-type name must be non-null." );
76-
}
77-
78-
if ( listenerRole == null ) {
79-
throw new HibernateException( "Custom event-type listener role must be non-null." );
80-
}
81-
82-
// make sure it does not match an existing name...
83-
if ( eventTypes.containsKey( name ) ) {
84-
final EventType<?> existing = eventTypes.get( name );
85-
throw new HibernateException(
86-
"Custom event-type already registered: " + name + " => " + existing
87-
);
88-
}
89-
90-
final EventType<T> eventType = EventType.create(
91-
name,
92-
listenerRole,
93-
eventTypes.size()
94-
);
95-
96-
eventTypes.put( name, eventType );
97-
return eventType;
98-
}
99-
100-
@Override @SafeVarargs
101-
public final <T> EventType<T> contributeEventType(String name, Class<T> listenerRole, T... defaultListeners) {
102-
final EventType<T> eventType = contributeEventType( name, listenerRole );
103-
104-
if ( defaultListeners != null ) {
105-
listenerRegistryBuilder.getListenerGroup( eventType ).appendListeners( defaultListeners );
106-
}
107-
108-
return eventType;
109-
}
110-
111-
@Override
112-
public <T> void configureListeners(
113-
EventType<T> eventType,
114-
Consumer<EventListenerGroup<T>> action) {
115-
if ( ! eventTypes.containsValue( eventType ) ) {
116-
throw new HibernateException( "EventType [" + eventType + "] not registered" );
117-
}
59+
callContributors( serviceRegistry, new ContributionManager( eventTypes, listenerRegistryBuilder ) );
11860

119-
action.accept( listenerRegistryBuilder.getListenerGroup( eventType ) );
120-
}
121-
};
61+
registeredEventTypes = unmodifiableMap( eventTypes );
62+
listenerRegistry = listenerRegistryBuilder.buildRegistry( registeredEventTypes );
63+
}
12264

65+
private static void callContributors(
66+
ServiceRegistryImplementor serviceRegistry, EventEngineContributions contributionManager) {
12367
final Collection<EventEngineContributor> discoveredContributors =
124-
sessionFactory.getServiceRegistry()
125-
.requireService( ClassLoaderService.class )
68+
serviceRegistry.requireService( ClassLoaderService.class )
12669
.loadJavaServices( EventEngineContributor.class );
127-
if ( CollectionHelper.isNotEmpty( discoveredContributors ) ) {
70+
if ( isNotEmpty( discoveredContributors ) ) {
12871
for ( EventEngineContributor contributor : discoveredContributors ) {
12972
contributor.contribute( contributionManager );
13073
}
13174
}
132-
133-
this.registeredEventTypes = Collections.unmodifiableMap( eventTypes );
134-
this.listenerRegistry = listenerRegistryBuilder.buildRegistry( registeredEventTypes );
13575
}
13676

13777
public Collection<EventType<?>> getRegisteredEventTypes() {
@@ -152,10 +92,73 @@ public CallbackRegistry getCallbackRegistry() {
15292
}
15393

15494
public void stop() {
155-
if ( listenerRegistry instanceof Stoppable ) {
156-
( (Stoppable) listenerRegistry ).stop();
95+
if ( listenerRegistry instanceof Stoppable stoppable ) {
96+
stoppable.stop();
15797
}
158-
15998
callbackRegistry.release();
16099
}
100+
101+
private static class ContributionManager implements EventEngineContributions {
102+
private final Map<String, EventType<?>> eventTypes;
103+
private final EventListenerRegistryImpl.Builder listenerRegistryBuilder;
104+
105+
public ContributionManager(
106+
Map<String, EventType<?>> eventTypes,
107+
EventListenerRegistryImpl.Builder listenerRegistryBuilder) {
108+
this.eventTypes = eventTypes;
109+
this.listenerRegistryBuilder = listenerRegistryBuilder;
110+
}
111+
112+
@Override
113+
public <T> EventType<T> findEventType(String name) {
114+
//noinspection unchecked
115+
return (EventType<T>) eventTypes.get( name );
116+
}
117+
118+
@Override
119+
public <T> EventType<T> contributeEventType(String name, Class<T> listenerRole) {
120+
final EventType<T> eventType = registerEventType( name, listenerRole );
121+
listenerRegistryBuilder.prepareListeners( eventType );
122+
return eventType;
123+
}
124+
125+
private <T> EventType<T> registerEventType(String name, Class<T> listenerRole) {
126+
if ( name == null ) {
127+
throw new HibernateException( "Custom event-type name must be non-null." );
128+
}
129+
else if ( listenerRole == null ) {
130+
throw new HibernateException( "Custom event-type listener role must be non-null." );
131+
}
132+
// make sure it does not match an existing name...
133+
else if ( eventTypes.containsKey( name ) ) {
134+
final EventType<?> existing = eventTypes.get( name );
135+
throw new HibernateException(
136+
"Custom event-type already registered: " + name + " => " + existing
137+
);
138+
}
139+
else {
140+
final EventType<T> eventType = EventType.create( name, listenerRole, eventTypes.size() );
141+
eventTypes.put( name, eventType );
142+
return eventType;
143+
}
144+
}
145+
146+
@Override
147+
@SafeVarargs
148+
public final <T> EventType<T> contributeEventType(String name, Class<T> listenerRole, T... defaultListeners) {
149+
final EventType<T> eventType = contributeEventType( name, listenerRole );
150+
if ( defaultListeners != null ) {
151+
listenerRegistryBuilder.getListenerGroup( eventType ).appendListeners( defaultListeners );
152+
}
153+
return eventType;
154+
}
155+
156+
@Override
157+
public <T> void configureListeners(EventType<T> eventType, Consumer<EventListenerGroup<T>> action) {
158+
if ( !eventTypes.containsValue( eventType ) ) {
159+
throw new HibernateException( "EventType [" + eventType + "] not registered" );
160+
}
161+
action.accept( listenerRegistryBuilder.getListenerGroup( eventType ) );
162+
}
163+
}
161164
}

hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbacksFactory.java

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -29,63 +29,67 @@
2929
public final class CallbacksFactory {
3030
private static final Logger log = Logger.getLogger( CallbacksFactory.class );
3131

32-
public static CallbackRegistry buildCallbackRegistry(SessionFactoryOptions options, ServiceRegistry serviceRegistry, Collection<PersistentClass> entityBindings) {
33-
if ( !jpaCallBacksEnabled( options ) ) {
32+
public static CallbackRegistry buildCallbackRegistry(
33+
SessionFactoryOptions options, ServiceRegistry serviceRegistry, Collection<PersistentClass> entityBindings) {
34+
if ( !options.areJPACallbacksEnabled() ) {
3435
return new EmptyCallbackRegistryImpl();
3536
}
36-
ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
37-
CallbackRegistryImpl.Builder registryBuilder = new CallbackRegistryImpl.Builder();
38-
Set<Class<?>> entityClasses = new HashSet<>();
37+
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
38+
final CallbackRegistryImpl.Builder registryBuilder = new CallbackRegistryImpl.Builder();
39+
final Set<Class<?>> entityClasses = new HashSet<>();
3940

4041
for ( PersistentClass persistentClass : entityBindings ) {
41-
if ( persistentClass.getClassName() == null ) {
42-
// we can have dynamic (non-java class) mapping
43-
continue;
44-
}
45-
46-
Class<?> entityClass = persistentClass.getMappedClass();
47-
48-
if ( !entityClasses.add( entityClass ) ) {
49-
// this most likely means we have a class mapped multiple times using the hbm.xml
50-
// "entity name" feature
51-
if ( log.isDebugEnabled() ) {
52-
log.debugf(
53-
"Class [%s] already has callbacks registered; " +
54-
"assuming this means the class was mapped twice " +
55-
"(using hbm.xml entity-name support) - skipping subsequent registrations" +
56-
"to avoid duplicates",
57-
entityClass.getName()
58-
);
42+
if ( persistentClass.getClassName() != null ) {
43+
final Class<?> entityClass = persistentClass.getMappedClass();
44+
if ( !entityClasses.add( entityClass ) ) {
45+
// this most likely means we have a class mapped multiple
46+
// times using the hbm.xml "entity name" feature
47+
if ( log.isDebugEnabled() ) {
48+
log.debugf(
49+
"Class [%s] already has callbacks registered; " +
50+
"assuming this means the class was mapped twice " +
51+
"(using hbm.xml entity-name support) - skipping subsequent registrations" +
52+
"to avoid duplicates",
53+
entityClass.getName()
54+
);
55+
}
56+
}
57+
else {
58+
registerAllCallbacks( persistentClass, registryBuilder, entityClass, beanRegistry );
5959
}
60-
continue;
61-
}
62-
63-
registryBuilder.registerCallbacks( persistentClass.getMappedClass(),
64-
buildCallbacks( persistentClass.getCallbackDefinitions(), beanRegistry ) );
65-
66-
for ( Property property : persistentClass.getDeclaredProperties() ) {
67-
registryBuilder.registerCallbacks( persistentClass.getMappedClass(),
68-
buildCallbacks( property.getCallbackDefinitions(), beanRegistry ) );
6960
}
61+
// else we can have dynamic (non-java class) mapping
7062
}
7163

7264
return registryBuilder.build();
7365
}
7466

67+
private static void registerAllCallbacks(
68+
PersistentClass persistentClass,
69+
CallbackRegistryImpl.Builder registryBuilder,
70+
Class<?> entityClass,
71+
ManagedBeanRegistry beanRegistry) {
72+
registryBuilder.registerCallbacks( entityClass,
73+
buildCallbacks( persistentClass.getCallbackDefinitions(), beanRegistry ) );
74+
75+
for ( Property property : persistentClass.getDeclaredProperties() ) {
76+
registryBuilder.registerCallbacks( entityClass,
77+
buildCallbacks( property.getCallbackDefinitions(), beanRegistry ) );
78+
}
79+
}
80+
7581
private static Callback[] buildCallbacks(List<CallbackDefinition> callbackDefinitions,
7682
ManagedBeanRegistry beanRegistry) {
7783
if ( callbackDefinitions == null || callbackDefinitions.isEmpty() ) {
7884
return null;
7985
}
80-
List<Callback> callbacks = new ArrayList<>();
81-
for ( CallbackDefinition definition : callbackDefinitions ) {
82-
callbacks.add( definition.createCallback( beanRegistry ) );
86+
else {
87+
final List<Callback> callbacks = new ArrayList<>();
88+
for ( CallbackDefinition definition : callbackDefinitions ) {
89+
callbacks.add( definition.createCallback( beanRegistry ) );
90+
}
91+
return callbacks.toArray( new Callback[0] );
8392
}
84-
return callbacks.toArray( new Callback[0] );
85-
}
86-
87-
private static boolean jpaCallBacksEnabled(SessionFactoryOptions options) {
88-
return options.areJPACallbacksEnabled();
8993
}
9094

9195
}

0 commit comments

Comments
 (0)