package com.ctp.cdi.query;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.persistence.EntityManager;
import org.jboss.solder.bean.BeanBuilder;
import org.jboss.solder.logging.Logger;
import org.jboss.solder.serviceHandler.ServiceHandlerBeanLifecycle;
import org.jboss.solder.serviceHandler.ServiceHandlerExtension;
import com.ctp.cdi.query.handler.QueryHandler;
import com.ctp.cdi.query.meta.DaoComponentsFactory;
import com.ctp.cdi.query.meta.unit.PersistenceUnits;
/**
* The main extension class for CDI queries, based on Seam Solder service handlers.
* Overrides the behavior for looking up handler classes.
*
* @author thomashug
*/
public class QueryExtension extends ServiceHandlerExtension {
private final Logger log = Logger.getLogger(QueryExtension.class);
void beforeBeanDiscovery(@Observes BeforeBeanDiscovery before) {
PersistenceUnits.instance().init();
}
@Override
protected <X> Class<?> getHandlerClass(ProcessAnnotatedType<X> event) {
if (event.getAnnotatedType().isAnnotationPresent(Dao.class) || event.getAnnotatedType().getJavaClass().isAnnotationPresent(Dao.class)) {
log.debugv("getHandlerClass: Dao annotation detected on {0}", event.getAnnotatedType());
boolean added = DaoComponentsFactory.instance().add(event.getAnnotatedType().getJavaClass());
if (!added) {
log.infov("getHandlerClass: Type {0} ignored as it's not related to an entity",
event.getAnnotatedType());
}
return added ? QueryHandler.class : null;
}
return null;
}
//FIX for https://issues.jboss.org/browse/SOLDER-327
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
protected <X> void buildBean(AnnotatedType<X> annotatedType, BeanManager beanManager, final Class<?> handlerClass) {
try {
final BeanBuilder<X> builder = new BeanBuilder<X>(beanManager);
builder.readFromType(annotatedType);
builder.types(extracted(annotatedType));
builder.beanLifecycle(new ServiceHandlerBeanLifecycle(
annotatedType.getJavaClass(), handlerClass, beanManager));
builder.toString("Generated @ServiceHandler for [" + builder.getBeanClass() + "] with qualifiers ["
+ builder.getQualifiers() + "] handled by " + handlerClass);
beans.add(builder.create());
log.debug("Adding @ServiceHandler bean for [" + builder.getBeanClass() + "] with qualifiers ["
+ builder.getQualifiers() + "] handled by " + handlerClass);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
}
private <X> Set<Type> extracted(AnnotatedType<X> annotatedType) {
Set<Type> result = new HashSet<Type>();
for (Type type : annotatedType.getTypeClosure()) {
if (!type.equals(EntityManager.class)) {
result.add(type);
}
}
return result;
}
}