EventHandlerMethod.java
package com.github.jonasrutishauser.transactional.event.core.cdi;
import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import com.github.jonasrutishauser.transactional.event.api.handler.EventHandler;
import com.github.jonasrutishauser.transactional.event.api.handler.Handler;
import com.github.jonasrutishauser.transactional.event.api.serialization.EventDeserializer;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.spi.Annotated;
import jakarta.enterprise.inject.spi.AnnotatedParameter;
import jakarta.enterprise.inject.spi.AnnotatedType;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.InjectionPoint;
import jakarta.enterprise.invoke.Invoker;
class EventHandlerMethod<T> {
private final Invoker<T, ?> invoker;
private final Class<?> eventType;
private final EventHandler eventHandlerQualifier;
private InjectionPoint injectionPoint;
public EventHandlerMethod(Invoker<T, ?> invoker, Class<?> eventType, EventHandler eventHandlerQualifier) {
this.invoker = invoker;
this.eventType = eventType;
this.eventHandlerQualifier = eventHandlerQualifier;
}
public Annotation[] getEventHandlerQualifiers() {
if (EventHandler.ABSTRACT_HANDLER_TYPE.equals(eventHandlerQualifier.eventType())) {
return new Annotation[] {eventHandlerQualifier, TypedEventHandler.Literal.of(eventType)};
}
return new Annotation[] {eventHandlerQualifier};
}
public Handler createHandler(CreationalContext<?> ctx, BeanManager beanManager) {
EventDeserializer<?> deserializer = (EventDeserializer<?>) beanManager.getInjectableReference(getEventDeserializerInjectionPoint(beanManager), ctx);
return new SyntheticHandler<>(deserializer, invoker);
}
public InjectionPoint getEventDeserializerInjectionPoint(BeanManager beanManager) {
if (injectionPoint == null) {
@SuppressWarnings("rawtypes")
AnnotatedType<SyntheticHandler> annotatedType = beanManager.createAnnotatedType(SyntheticHandler.class);
@SuppressWarnings("rawtypes")
AnnotatedParameter<SyntheticHandler> parameter = annotatedType.getConstructors().iterator().next().getParameters().get(0);
injectionPoint = new InjectionPoint() {
@Override
public boolean isTransient() {
return false;
}
@Override
public boolean isDelegate() {
return false;
}
@Override
public Type getType() {
return new ParameterizedType() {
@Override
public Type getRawType() {
return EventDeserializer.class;
}
@Override
public Type getOwnerType() {
return null;
}
@Override
public Type[] getActualTypeArguments() {
return new Type[] {eventType};
}
@Override
public int hashCode() {
return Arrays.hashCode(getActualTypeArguments()) ^ EventDeserializer.class.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj instanceof ParameterizedType) {
ParameterizedType that = (ParameterizedType) obj;
return that.getOwnerType() == null && EventDeserializer.class.equals(that.getRawType())
&& Arrays.equals(getActualTypeArguments(), that.getActualTypeArguments());
}
return false;
}
};
}
@Override
public Set<Annotation> getQualifiers() {
return Collections.singleton(Default.Literal.INSTANCE);
}
@Override
public Member getMember() {
return parameter.getDeclaringCallable().getJavaMember();
}
@Override
public Bean<?> getBean() {
return null;
}
@Override
public Annotated getAnnotated() {
return parameter;
}
@Override
public String toString() {
return parameter.toString();
}
};
}
return injectionPoint;
}
}