HHH-10271 - Add ordinal() method to EventType and change EventListenerRegistryImpl to take advantage of that

(cherry picked from commit 340cee232a)
This commit is contained in:
barreiro 2015-11-03 02:43:51 +00:00 committed by Steve Ebersole
parent feacc4a3b0
commit 0145736fe5
2 changed files with 69 additions and 50 deletions

View File

@ -7,7 +7,6 @@
package org.hibernate.event.service.internal;
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -80,11 +79,11 @@ import static org.hibernate.event.spi.EventType.UPDATE;
public class EventListenerRegistryImpl implements EventListenerRegistry {
private Map<Class,Object> listenerClassToInstanceMap = new HashMap<Class, Object>();
private Map<EventType,EventListenerGroupImpl> registeredEventListenersMap = prepareListenerMap();
private EventListenerGroupImpl[] registeredEventListeners = prepareListenerAssociation();
@SuppressWarnings({ "unchecked" })
public <T> EventListenerGroupImpl<T> getEventListenerGroup(EventType<T> eventType) {
EventListenerGroupImpl<T> listeners = registeredEventListenersMap.get( eventType );
EventListenerGroupImpl<T> listeners = registeredEventListeners[ eventType.ordinal() ];
if ( listeners == null ) {
throw new HibernateException( "Unable to find listeners for type [" + eventType.eventName() + "]" );
}
@ -93,8 +92,10 @@ public class EventListenerRegistryImpl implements EventListenerRegistry {
@Override
public void addDuplicationStrategy(DuplicationStrategy strategy) {
for ( EventListenerGroupImpl group : registeredEventListenersMap.values() ) {
group.addDuplicationStrategy( strategy );
for ( EventListenerGroupImpl group : registeredEventListeners ) {
if ( group != null ) {
group.addDuplicationStrategy( strategy );
}
}
}
@ -165,252 +166,252 @@ public class EventListenerRegistryImpl implements EventListenerRegistry {
getEventListenerGroup( type ).prependListeners( listeners );
}
private static Map<EventType,EventListenerGroupImpl> prepareListenerMap() {
final Map<EventType,EventListenerGroupImpl> workMap = new HashMap<EventType, EventListenerGroupImpl>();
private static EventListenerGroupImpl[] prepareListenerAssociation() {
EventListenerGroupImpl[] listenerArray = new EventListenerGroupImpl[ EventType.values().size() ];
// auto-flush listeners
prepareListeners(
AUTO_FLUSH,
new DefaultAutoFlushEventListener(),
workMap
listenerArray
);
// create listeners
prepareListeners(
PERSIST,
new DefaultPersistEventListener(),
workMap
listenerArray
);
// create-onflush listeners
prepareListeners(
PERSIST_ONFLUSH,
new DefaultPersistOnFlushEventListener(),
workMap
listenerArray
);
// delete listeners
prepareListeners(
DELETE,
new DefaultDeleteEventListener(),
workMap
listenerArray
);
// dirty-check listeners
prepareListeners(
DIRTY_CHECK,
new DefaultDirtyCheckEventListener(),
workMap
listenerArray
);
// evict listeners
prepareListeners(
EVICT,
new DefaultEvictEventListener(),
workMap
listenerArray
);
prepareListeners(
CLEAR,
workMap
listenerArray
);
// flush listeners
prepareListeners(
FLUSH,
new DefaultFlushEventListener(),
workMap
listenerArray
);
// flush-entity listeners
prepareListeners(
FLUSH_ENTITY,
new DefaultFlushEntityEventListener(),
workMap
listenerArray
);
// load listeners
prepareListeners(
LOAD,
new DefaultLoadEventListener(),
workMap
listenerArray
);
// resolve natural-id listeners
prepareListeners(
RESOLVE_NATURAL_ID,
new DefaultResolveNaturalIdEventListener(),
workMap
listenerArray
);
// load-collection listeners
prepareListeners(
INIT_COLLECTION,
new DefaultInitializeCollectionEventListener(),
workMap
listenerArray
);
// lock listeners
prepareListeners(
LOCK,
new DefaultLockEventListener(),
workMap
listenerArray
);
// merge listeners
prepareListeners(
MERGE,
new DefaultMergeEventListener(),
workMap
listenerArray
);
// pre-collection-recreate listeners
prepareListeners(
PRE_COLLECTION_RECREATE,
workMap
listenerArray
);
// pre-collection-remove listeners
prepareListeners(
PRE_COLLECTION_REMOVE,
workMap
listenerArray
);
// pre-collection-update listeners
prepareListeners(
PRE_COLLECTION_UPDATE,
workMap
listenerArray
);
// pre-delete listeners
prepareListeners(
PRE_DELETE,
workMap
listenerArray
);
// pre-insert listeners
prepareListeners(
PRE_INSERT,
workMap
listenerArray
);
// pre-load listeners
prepareListeners(
PRE_LOAD,
new DefaultPreLoadEventListener(),
workMap
listenerArray
);
// pre-update listeners
prepareListeners(
PRE_UPDATE,
workMap
listenerArray
);
// post-collection-recreate listeners
prepareListeners(
POST_COLLECTION_RECREATE,
workMap
listenerArray
);
// post-collection-remove listeners
prepareListeners(
POST_COLLECTION_REMOVE,
workMap
listenerArray
);
// post-collection-update listeners
prepareListeners(
POST_COLLECTION_UPDATE,
workMap
listenerArray
);
// post-commit-delete listeners
prepareListeners(
POST_COMMIT_DELETE,
workMap
listenerArray
);
// post-commit-insert listeners
prepareListeners(
POST_COMMIT_INSERT,
workMap
listenerArray
);
// post-commit-update listeners
prepareListeners(
POST_COMMIT_UPDATE,
workMap
listenerArray
);
// post-delete listeners
prepareListeners(
POST_DELETE,
workMap
listenerArray
);
// post-insert listeners
prepareListeners(
POST_INSERT,
workMap
listenerArray
);
// post-load listeners
prepareListeners(
POST_LOAD,
new DefaultPostLoadEventListener(),
workMap
listenerArray
);
// post-update listeners
prepareListeners(
POST_UPDATE,
workMap
listenerArray
);
// update listeners
prepareListeners(
UPDATE,
new DefaultUpdateEventListener(),
workMap
listenerArray
);
// refresh listeners
prepareListeners(
REFRESH,
new DefaultRefreshEventListener(),
workMap
listenerArray
);
// replicate listeners
prepareListeners(
REPLICATE,
new DefaultReplicateEventListener(),
workMap
listenerArray
);
// save listeners
prepareListeners(
SAVE,
new DefaultSaveEventListener(),
workMap
listenerArray
);
// save-update listeners
prepareListeners(
SAVE_UPDATE,
new DefaultSaveOrUpdateEventListener(),
workMap
listenerArray
);
return Collections.unmodifiableMap( workMap );
return listenerArray;
}
private static <T> void prepareListeners(EventType<T> type, Map<EventType,EventListenerGroupImpl> map) {
prepareListeners( type, null, map );
private static <T> void prepareListeners(EventType<T> type, EventListenerGroupImpl[] listenerArray) {
prepareListeners( type, null, listenerArray );
}
private static <T> void prepareListeners(EventType<T> type, T defaultListener, Map<EventType,EventListenerGroupImpl> map) {
private static <T> void prepareListeners(EventType<T> type, T defaultListener, EventListenerGroupImpl[] listenerArray) {
final EventListenerGroupImpl<T> listenerGroup;
if ( type == EventType.POST_COMMIT_DELETE
|| type == EventType.POST_COMMIT_INSERT
@ -424,7 +425,7 @@ public class EventListenerRegistryImpl implements EventListenerRegistry {
if ( defaultListener != null ) {
listenerGroup.appendListener( defaultListener );
}
map.put( type, listenerGroup );
listenerArray[ type.ordinal() ] = listenerGroup;
}
}

View File

@ -12,6 +12,7 @@ import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.hibernate.HibernateException;
@ -20,7 +21,10 @@ import org.hibernate.HibernateException;
*
* @author Steve Ebersole
*/
public class EventType<T> {
public final class EventType<T> {
private static AtomicInteger typeCounter = new AtomicInteger( 0 );
public static final EventType<LoadEventListener> LOAD = create( "load", LoadEventListener.class );
public static final EventType<ResolveNaturalIdEventListener> RESOLVE_NATURAL_ID = create( "resolve-natural-id", ResolveNaturalIdEventListener.class );
@ -131,13 +135,14 @@ public class EventType<T> {
return EVENT_TYPE_BY_NAME_MAP.values();
}
private final String eventName;
private final Class<? extends T> baseListenerInterface;
private final int ordinal;
private EventType(String eventName, Class<? extends T> baseListenerInterface) {
this.eventName = eventName;
this.baseListenerInterface = baseListenerInterface;
this.ordinal = typeCounter.getAndIncrement();
}
public String eventName() {
@ -152,4 +157,17 @@ public class EventType<T> {
public String toString() {
return eventName();
}
/**
* EventType is effectively an enumeration. Since there is a known, limited number of possible types, we expose an
* ordinal for each in order to be able to efficiently do associations elsewhere in the codebase (array vs. Map)
*
* For the total number of types, see {@link #values()}
*
* @return An unique ordinal for this {@link EventType}, starting at 0 and up to the number of distinct events
*/
public int ordinal() {
return ordinal;
}
}