Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arc - basic asynchronous observer methods support #43

Merged
merged 1 commit into from
Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ private List<BeanInfo> findBeans(List<DotName> beanDefiningAnnotations, List<Obs
Set<MethodInfo> producerMethods = new HashSet<>();
Set<MethodInfo> disposerMethods = new HashSet<>();
Set<FieldInfo> producerFields = new HashSet<>();
Set<MethodInfo> observerMethods = new HashSet<>();
Set<MethodInfo> syncObserverMethods = new HashSet<>();
Set<MethodInfo> asyncObserverMethods = new HashSet<>();

for (DotName beanDefiningAnnotation : beanDefiningAnnotations) {
for (AnnotationInstance annotation : index.getAnnotations(beanDefiningAnnotation)) {
Expand Down Expand Up @@ -222,7 +223,10 @@ private List<BeanInfo> findBeans(List<DotName> beanDefiningAnnotations, List<Obs
disposerMethods.add(method);
} else if (method.hasAnnotation(DotNames.OBSERVES)) {
// TODO observers are inherited
observerMethods.add(method);
syncObserverMethods.add(method);
} else if (method.hasAnnotation(DotNames.OBSERVES_ASYNC)) {
// TODO observers are inherited
asyncObserverMethods.add(method);
}
}
for (FieldInfo field : beanClass.fields()) {
Expand Down Expand Up @@ -266,10 +270,16 @@ private List<BeanInfo> findBeans(List<DotName> beanDefiningAnnotations, List<Obs
}
}

for (MethodInfo observerMethod : observerMethods) {
for (MethodInfo observerMethod : syncObserverMethods) {
BeanInfo declaringBean = beanClassToBean.get(observerMethod.declaringClass());
if (declaringBean != null) {
observers.add(new ObserverInfo(declaringBean, observerMethod, Injection.forObserver(observerMethod, this), false));
}
}
for (MethodInfo observerMethod : asyncObserverMethods) {
BeanInfo declaringBean = beanClassToBean.get(observerMethod.declaringClass());
if (declaringBean != null) {
observers.add(new ObserverInfo(declaringBean, observerMethod, Injection.forObserver(observerMethod, this)));
observers.add(new ObserverInfo(declaringBean, observerMethod, Injection.forObserver(observerMethod, this), true));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import javax.annotation.Priority;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.enterprise.event.ObservesAsync;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Default;
Expand All @@ -31,6 +32,7 @@ final class DotNames {

static final DotName OBJECT = DotName.createSimple(Object.class.getName());
static final DotName OBSERVES = DotName.createSimple(Observes.class.getName());
static final DotName OBSERVES_ASYNC = DotName.createSimple(ObservesAsync.class.getName());
static final DotName PRODUCES = DotName.createSimple(Produces.class.getName());
static final DotName DISPOSES = DotName.createSimple(Disposes.class.getName());
static final DotName QUALIFIER = DotName.createSimple(Qualifier.class.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static Injection forDisposer(MethodInfo disposerMethod, BeanDeployment beanDeplo

static Injection forObserver(MethodInfo observerMethod, BeanDeployment beanDeployment) {
return new Injection(observerMethod, InjectionPointInfo.fromMethod(observerMethod, beanDeployment,
annotations -> annotations.stream().anyMatch(a -> a.name().equals(DotNames.OBSERVES))));
annotations -> annotations.stream().anyMatch(a -> a.name().equals(DotNames.OBSERVES) || a.name().equals(DotNames.OBSERVES_ASYNC))));
}

final AnnotationTarget target;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static List<InjectionPointInfo> fromMethod(MethodInfo method, BeanDeployment bea
return fromMethod(method, beanDeployment, null);
}

static List<InjectionPointInfo> fromMethod(MethodInfo method, BeanDeployment beanDeployment, Predicate<Set<AnnotationInstance>> skiPredicate) {
static List<InjectionPointInfo> fromMethod(MethodInfo method, BeanDeployment beanDeployment, Predicate<Set<AnnotationInstance>> skipPredicate) {
List<InjectionPointInfo> injectionPoints = new ArrayList<>();
for (ListIterator<Type> iterator = method.parameters().listIterator(); iterator.hasNext();) {
Type paramType = iterator.next();
Expand All @@ -43,7 +43,7 @@ static List<InjectionPointInfo> fromMethod(MethodInfo method, BeanDeployment bea
paramAnnotations.add(annotation);
}
}
if (skiPredicate != null && skiPredicate.test(paramAnnotations)) {
if (skipPredicate != null && skipPredicate.test(paramAnnotations)) {
// Skip parameter, e.g. @Disposes
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,19 @@ Collection<Resource> generate(ObserverInfo observer, ReflectionRegistration refl
initMaps(observer, injectionPointToProviderField);

createProviderFields(observerCreator, observer, injectionPointToProviderField);

createConstructor(classOutput, observerCreator, observer, baseName, injectionPointToProviderField, annotationLiterals);
createGetObservedType(observerCreator, observedType.getFieldDescriptor());

implementGetObservedType(observerCreator, observedType.getFieldDescriptor());
if (observedQualifiers != null) {
createGetObservedQualifiers(observerCreator, observedQualifiers.getFieldDescriptor());
implementGetObservedQualifiers(observerCreator, observedQualifiers.getFieldDescriptor());
}
createGetBeanClass(observerCreator, observer.getDeclaringBean().getTarget().asClass().name());
createNotify(observer, observerCreator, injectionPointToProviderField, reflectionRegistration);
implementGetBeanClass(observerCreator, observer.getDeclaringBean().getTarget().asClass().name());
implementNotify(observer, observerCreator, injectionPointToProviderField, reflectionRegistration);
if (observer.getPriority() != ObserverMethod.DEFAULT_PRIORITY) {
createGetPriority(observerCreator, observer);
implementGetPriority(observerCreator, observer);
}
if (observer.isAsync()) {
implementIsAsync(observerCreator);
}

observerCreator.close();
Expand All @@ -120,27 +123,32 @@ protected void initMaps(ObserverInfo observer, Map<InjectionPointInfo, String> i
}
}

protected void createGetObservedType(ClassCreator observerCreator, FieldDescriptor observedTypeField) {
protected void implementGetObservedType(ClassCreator observerCreator, FieldDescriptor observedTypeField) {
MethodCreator getObservedType = observerCreator.getMethodCreator("getObservedType", Type.class).setModifiers(ACC_PUBLIC);
getObservedType.returnValue(getObservedType.readInstanceField(observedTypeField, getObservedType.getThis()));
}

protected void createGetObservedQualifiers(ClassCreator observerCreator, FieldDescriptor observedQualifiersField) {
protected void implementGetObservedQualifiers(ClassCreator observerCreator, FieldDescriptor observedQualifiersField) {
MethodCreator getObservedQualifiers = observerCreator.getMethodCreator("getObservedQualifiers", Set.class).setModifiers(ACC_PUBLIC);
getObservedQualifiers.returnValue(getObservedQualifiers.readInstanceField(observedQualifiersField, getObservedQualifiers.getThis()));
}

protected void createGetBeanClass(ClassCreator observerCreator, DotName beanClass) {
protected void implementGetBeanClass(ClassCreator observerCreator, DotName beanClass) {
MethodCreator getBeanClass = observerCreator.getMethodCreator("getBeanClass", Class.class).setModifiers(ACC_PUBLIC);
getBeanClass.returnValue(getBeanClass.loadClass(beanClass.toString()));
}

protected void createGetPriority(ClassCreator observerCreator, ObserverInfo observer) {
protected void implementGetPriority(ClassCreator observerCreator, ObserverInfo observer) {
MethodCreator getPriority = observerCreator.getMethodCreator("getPriority", int.class).setModifiers(ACC_PUBLIC);
getPriority.returnValue(getPriority.load(observer.getPriority()));
}

protected void createNotify(ObserverInfo observer, ClassCreator observerCreator, Map<InjectionPointInfo, String> injectionPointToProviderField,
protected void implementIsAsync(ClassCreator observerCreator) {
MethodCreator isAsync = observerCreator.getMethodCreator("isAsync", boolean.class).setModifiers(ACC_PUBLIC);
isAsync.returnValue(isAsync.load(true));
}

protected void implementNotify(ObserverInfo observer, ClassCreator observerCreator, Map<InjectionPointInfo, String> injectionPointToProviderField,
ReflectionRegistration reflectionRegistration) {
MethodCreator notify = observerCreator.getMethodCreator("notify", void.class, EventContext.class).setModifiers(ACC_PUBLIC);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
import org.jboss.jandex.MethodParameterInfo;
import org.jboss.jandex.Type;

/**
* Represents an observer method.
*
* @author Martin Kouba
*/
public class ObserverInfo {

private final BeanInfo declaringBean;
Expand All @@ -29,7 +34,9 @@ public class ObserverInfo {

private final int priority;

ObserverInfo(BeanInfo declaringBean, MethodInfo observerMethod, Injection injection) {
private final boolean isAsync;

ObserverInfo(BeanInfo declaringBean, MethodInfo observerMethod, Injection injection, boolean isAsync) {
this.declaringBean = declaringBean;
this.observerMethod = observerMethod;
this.injection = injection;
Expand All @@ -41,6 +48,7 @@ public class ObserverInfo {
} else {
this.priority = ObserverMethod.DEFAULT_PRIORITY;
}
this.isAsync = isAsync;
}

BeanInfo getDeclaringBean() {
Expand All @@ -63,6 +71,10 @@ Injection getInjection() {
return injection;
}

boolean isAsync() {
return isAsync;
}

void init() {
for (InjectionPointInfo injectionPoint : injection.injectionPoints) {
Beans.resolveInjectionPoint(declaringBean.getDeployment(), null, injectionPoint);
Expand Down Expand Up @@ -90,7 +102,8 @@ int getPriority() {
MethodParameterInfo initEventParam(MethodInfo observerMethod) {
List<MethodParameterInfo> eventParams = new ArrayList<>();
for (AnnotationInstance annotation : observerMethod.annotations()) {
if (Kind.METHOD_PARAMETER == annotation.target().kind() && annotation.name().equals(DotNames.OBSERVES)) {
if (Kind.METHOD_PARAMETER == annotation.target().kind()
&& (annotation.name().equals(DotNames.OBSERVES) || annotation.name().equals(DotNames.OBSERVES_ASYNC))) {
eventParams.add(annotation.target().asMethodParameter());
}
}
Expand Down
Loading