package org.jboss.seam.solder.log;
import java.util.Collection;
import java.util.HashSet;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.ProcessProducerMethod;
import org.jboss.logging.MessageBundle;
import org.jboss.logging.MessageLogger;
import org.jboss.seam.solder.bean.NarrowingBeanBuilder;
/**
* Adds Producers to the deployment, and detects and installs beans for any
* typed loggers defined.
*
* @author Pete Muir
*
*/
public class LoggerExtension implements Extension
{
static
{
// Until we get tooling, set this globally
System.setProperty("jboss.i18n.generate-proxies", "true");
}
private final Collection<AnnotatedType<?>> messageLoggerTypes;
private final Collection<AnnotatedType<?>> messageBundleTypes;
private Bean<Object> loggerProducerBean;
private Bean<Object> bundleProducerBean;
LoggerExtension()
{
this.messageLoggerTypes = new HashSet<AnnotatedType<?>>();
this.messageBundleTypes = new HashSet<AnnotatedType<?>>();
}
void addProducer(@Observes BeforeBeanDiscovery event, BeanManager beanManager)
{
event.addAnnotatedType(beanManager.createAnnotatedType(Producers.class));
}
void detectInterfaces(@Observes ProcessAnnotatedType<?> event, BeanManager beanManager)
{
AnnotatedType<?> type = event.getAnnotatedType();
if (type.isAnnotationPresent(MessageLogger.class))
{
messageLoggerTypes.add(type);
}
if (type.isAnnotationPresent(MessageBundle.class))
{
messageBundleTypes.add(type);
}
}
void detectProducers(@Observes ProcessProducerMethod<Producers, Object> event)
{
if (event.getAnnotatedProducerMethod().isAnnotationPresent(TypedLogger.class))
{
this.loggerProducerBean = event.getBean();
}
if (event.getAnnotatedProducerMethod().isAnnotationPresent(TypedMessageBundle.class))
{
this.bundleProducerBean = event.getBean();
}
}
void installBeans(@Observes AfterBeanDiscovery event, BeanManager beanManager)
{
for (AnnotatedType<?> type : messageLoggerTypes)
{
event.addBean(createMessageLoggerBean(loggerProducerBean, type, beanManager));
}
for (AnnotatedType<?> type : messageBundleTypes)
{
event.addBean(createMessageBundleBean(bundleProducerBean, type, beanManager));
}
}
private static <T> Bean<T> createMessageLoggerBean(Bean<Object> delegate, AnnotatedType<T> type, BeanManager beanManager)
{
return new NarrowingBeanBuilder<T>(delegate, beanManager).readFromType(type).types(type.getBaseType(), Object.class).create();
}
private static <T> Bean<T> createMessageBundleBean(Bean<Object> delegate, AnnotatedType<T> type, BeanManager beanManager)
{
return new NarrowingBeanBuilder<T>(delegate, beanManager).readFromType(type).types(type.getBaseType(), Object.class).addQualifier(MessageBundleLiteral.INSTANCE).create();
}
void cleanup(@Observes AfterDeploymentValidation event)
{
// defensively clear the set to help with gc
this.messageLoggerTypes.clear();
this.messageBundleTypes.clear();
}
}