Skip to content

Commit

Permalink
WELD-1787 Cache ResolvedObservers and EventMetadata within EventImpl
Browse files Browse the repository at this point in the history
  • Loading branch information
jharting committed Dec 7, 2014
1 parent 125eefa commit 68a6afc
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.jboss.weld.event;

import javax.enterprise.inject.spi.EventMetadata;
import javax.enterprise.inject.spi.ObserverMethod;

import org.jboss.weld.Container;
Expand All @@ -34,33 +35,36 @@ public class DeferredEventNotification<T> implements Runnable {
// The observer
protected final ObserverMethod<? super T> observer;
// The event object
protected final EventPacket<T> eventPacket;
private final T event;
protected final EventMetadata metadata;
private final CurrentEventMetadata currentEventMetadata;
private final String contextId;

/**
* Creates a new deferred event notifier.
*
* @param observer The observer to be notified
* @param eventPacket The event being fired
* @param metadata The event being fired
*/
public DeferredEventNotification(String contextId, EventPacket<T> eventPacket, ObserverMethod<? super T> observer, CurrentEventMetadata currentEventMetadata) {
public DeferredEventNotification(String contextId, T event, EventMetadata metadata, ObserverMethod<? super T> observer,
CurrentEventMetadata currentEventMetadata) {
this.contextId = contextId;
this.observer = observer;
this.eventPacket = eventPacket;
this.event = event;
this.metadata = metadata;
this.currentEventMetadata = currentEventMetadata;
}

public void run() {
try {
EventLogger.LOG.asyncFire(eventPacket, observer);
EventLogger.LOG.asyncFire(metadata, observer);
new RunInRequest(contextId) {

@Override
protected void execute() {
currentEventMetadata.push(eventPacket);
currentEventMetadata.push(metadata);
try {
observer.notify(eventPacket.getPayload());
observer.notify(event);
} finally {
currentEventMetadata.pop();
}
Expand All @@ -69,14 +73,14 @@ protected void execute() {
}.run();

} catch (Exception e) {
EventLogger.LOG.asyncObserverFailure(eventPacket);
EventLogger.LOG.asyncObserverFailure(metadata);
EventLogger.LOG.catchingDebug(e);
}
}

@Override
public String toString() {
return "Deferred event [" + eventPacket.getPayload() + "] for [" + observer + "]";
return "Deferred event [" + event + "] for [" + observer + "]";
}

private abstract static class RunInRequest {
Expand Down
32 changes: 15 additions & 17 deletions impl/src/main/java/org/jboss/weld/event/EventImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;

import javax.enterprise.event.Event;
import javax.enterprise.inject.spi.EventMetadata;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.ObserverMethod;
import javax.enterprise.util.TypeLiteral;

import org.jboss.weld.bean.builtin.AbstractFacade;
Expand Down Expand Up @@ -80,22 +79,21 @@ public void fire(T event) {
Preconditions.checkArgumentNotNull(event, "event");
CachedObservers observers = getObservers(event);

EventPacket<T> packet = EventPacket.of(event, observers.type, getQualifiers(), getInjectionPoint());
getBeanManager().getGlobalStrictObserverNotifier().notify(observers.methods, event, packet);
// we can do lenient here as the event type is checked within #getObservers()
getBeanManager().getGlobalLenientObserverNotifier().notify(observers.observers, event, observers.metadata);
}

private CachedObservers getObservers(T event) {
CachedObservers cachedObservers = this.cachedObservers;
if (cachedObservers != null) {
if (cachedObservers.rawType.equals(event.getClass())) {
return cachedObservers;
}
if (cachedObservers != null && cachedObservers.rawType.equals(event.getClass())) {
return cachedObservers;
}
final Type eventType = getEventType(event);
final Set<ObserverMethod<? super T>> observers = getBeanManager().getGlobalStrictObserverNotifier().resolveObserverMethods(eventType, getQualifiers());
cachedObservers = new CachedObservers(event.getClass(), eventType, observers);
this.cachedObservers = cachedObservers;
return cachedObservers;
// this performs type check
final ResolvedObservers<T> observers = getBeanManager().getGlobalStrictObserverNotifier().resolveObservers(eventType, getQualifiers());
final EventMetadata metadata = new EventMetadataImpl(eventType, getInjectionPoint(), getQualifiers());
cachedObservers = new CachedObservers(event.getClass(), observers, metadata);
return this.cachedObservers = cachedObservers;
}

@Override
Expand Down Expand Up @@ -169,13 +167,13 @@ private Object readResolve() throws ObjectStreamException {

private class CachedObservers {
private final Class<?> rawType;
private final Type type;
private final Set<ObserverMethod<? super T>> methods;
private final ResolvedObservers<T> observers;
private final EventMetadata metadata;

public CachedObservers(Class<?> rawType, Type type, Set<ObserverMethod<? super T>> methods) {
private CachedObservers(Class<?> rawType, ResolvedObservers<T> observers, EventMetadata metadata) {
this.rawType = rawType;
this.type = type;
this.methods = methods;
this.observers = observers;
this.metadata = metadata;
}
}
}
67 changes: 67 additions & 0 deletions impl/src/main/java/org/jboss/weld/event/EventMetadataImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2014, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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.jboss.weld.event;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;

import javax.enterprise.inject.spi.EventMetadata;
import javax.enterprise.inject.spi.InjectionPoint;

import org.jboss.weld.literal.AnyLiteral;

import com.google.common.collect.ImmutableSet;

/**
* Simple {@link EventMetadata} implementation.
*
* @author Jozef Hartinger
*
*/
public class EventMetadataImpl implements EventMetadata {

private final Type type;
private final InjectionPoint injectionPoint;
private final Set<Annotation> qualifiers;

EventMetadataImpl(Type type, InjectionPoint injectionPoint, Set<Annotation> qualifiers) {
this.type = type;
this.injectionPoint = injectionPoint;
this.qualifiers = ImmutableSet.<Annotation> builder().addAll(qualifiers).add(AnyLiteral.INSTANCE).build();
}

@Override
public Set<Annotation> getQualifiers() {
return qualifiers;
}

@Override
public InjectionPoint getInjectionPoint() {
return injectionPoint;
}

@Override
public Type getType() {
return type;
}

@Override
public String toString() {
return "EventMetadataImpl [type=" + type + ", qualifiers=" + qualifiers + ", injectionPoint=" + injectionPoint + "]";
}
}
14 changes: 10 additions & 4 deletions impl/src/main/java/org/jboss/weld/event/ObserverNotifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.lang.reflect.Type;
import java.util.Set;

import javax.enterprise.inject.spi.EventMetadata;
import javax.enterprise.inject.spi.ObserverMethod;

import org.jboss.weld.bootstrap.api.ServiceRegistry;
Expand Down Expand Up @@ -97,6 +98,11 @@ public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(Type eventType,
return this.<T>resolveObserverMethods(buildEventResolvable(eventType, qualifiers));
}

public <T> ResolvedObservers<T> resolveObservers(Type eventType, Set<Annotation> qualifiers) {
checkEventObjectType(eventType);
return ResolvedObservers.of(this.<T>resolveObserverMethods(buildEventResolvable(eventType, qualifiers)));
}

public void fireEvent(Object event, Annotation... qualifiers) {
fireEvent(event.getClass(), event, qualifiers);
}
Expand Down Expand Up @@ -189,17 +195,17 @@ public RuntimeException load(Type eventType) {
}
}

public <T> void notify(Set<ObserverMethod<? super T>> observers, T event, EventPacket<T> metadata) {
public <T> void notify(Set<ObserverMethod<? super T>> observers, T event, EventMetadata metadata) {
notify(ResolvedObservers.of(observers), event, metadata);
}

public <T> void notify(ResolvedObservers<T> observers, T event, EventPacket<T> metadata) {
public <T> void notify(ResolvedObservers<T> observers, T event, EventMetadata metadata) {
// TODO we obviously need to move filtering to the resolution time
notifySyncObservers(observers.getImmediateObservers(), event, metadata);
notifyTransactionObservers(observers.getTransactionObservers(), event, metadata);
}

protected <T> void notifySyncObservers(Set<ObserverMethod<? super T>> observers, T event, EventPacket<T> metadata) {
protected <T> void notifySyncObservers(Set<ObserverMethod<? super T>> observers, T event, EventMetadata metadata) {
if (observers.isEmpty()) {
return;
}
Expand All @@ -217,7 +223,7 @@ protected <T> void notifySyncObservers(Set<ObserverMethod<? super T>> observers,
}
}

protected <T> void notifyTransactionObservers(Set<ObserverMethod<? super T>> observers, T event, EventPacket<T> metadata) {
protected <T> void notifyTransactionObservers(Set<ObserverMethod<? super T>> observers, T event, EventMetadata metadata) {
notifySyncObservers(observers, event, metadata); // no transaction support
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Set;

import javax.enterprise.event.TransactionPhase;
import javax.enterprise.inject.spi.EventMetadata;
import javax.enterprise.inject.spi.ObserverMethod;

import org.jboss.weld.bootstrap.api.ServiceRegistry;
Expand Down Expand Up @@ -46,10 +47,10 @@ protected TransactionalObserverNotifier(String contextId, TypeSafeObserverResolv
* Defers an event for processing in a later phase of the current
* transaction.
*
* @param eventPacket The event object
* @param metadata The event object
*/
private <T> void deferNotification(final EventPacket<T> packet, final ObserverMethod<? super T> observer) {
DeferredEventNotification<T> deferredEvent = new DeferredEventNotification<T>(contextId, packet, observer, currentEventMetadata);
private <T> void deferNotification(T event, final EventMetadata metadata, final ObserverMethod<? super T> observer) {
DeferredEventNotification<T> deferredEvent = new DeferredEventNotification<T>(contextId, event, metadata, observer, currentEventMetadata);
TransactionPhase transactionPhase = observer.getTransactionPhase();

if (transactionPhase.equals(TransactionPhase.BEFORE_COMPLETION)) {
Expand All @@ -64,7 +65,7 @@ private <T> void deferNotification(final EventPacket<T> packet, final ObserverMe
}

@Override
protected <T> void notifyTransactionObservers(Set<ObserverMethod<? super T>> observers, T event, EventPacket<T> metadata) {
protected <T> void notifyTransactionObservers(Set<ObserverMethod<? super T>> observers, T event, EventMetadata metadata) {
if (observers.isEmpty()) {
return;
}
Expand All @@ -73,7 +74,7 @@ protected <T> void notifyTransactionObservers(Set<ObserverMethod<? super T>> obs
notifySyncObservers(observers, event, metadata);
} else {
for (ObserverMethod<? super T> observer : observers) {
deferNotification(metadata, observer);
deferNotification(event, metadata, observer);
}
}
}
Expand Down

0 comments on commit 68a6afc

Please sign in to comment.