package org.jboss.seam.rest.client;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
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.InjectionPoint;
import javax.enterprise.inject.spi.ProcessBean;
import javax.enterprise.inject.spi.ProcessManagedBean;
import org.jboss.solder.logging.Logger;
import org.jboss.seam.rest.util.Utils;
import org.jboss.solder.reflection.AnnotationInspector;
/**
* The Seam REST Client extension provides injection of
* <ul>
* <li>org.jboss.resteasy.client.ClientRequest instances</li>
* <li>REST clients - proxied JAX-RS interfaces capable of invoking client requests</li>
* </ul>
*
* @author <a href="http://community.jboss.org/people/jharting">Jozef Hartinger</a>
*/
public class RestClientExtension implements Extension {
private static final Logger log = Logger.getLogger(RestClientExtension.class);
private static final String RESTEASY_PROVIDER_FACTORY_NAME = "org.jboss.resteasy.spi.ResteasyProviderFactory";
private static final String HTTP_CLIENT_NAME = "org.apache.http.client.HttpClient";
private boolean enabled;
private Set<Type> jaxrsInterfaces = new HashSet<Type>();
private Bean<RestClientProducer> restClientProducerBean;
public void registerExtension(@Observes BeforeBeanDiscovery event, BeanManager manager) {
enabled = Utils.isClassAvailable(RESTEASY_PROVIDER_FACTORY_NAME);
enabled = enabled && Utils.isClassAvailable(HTTP_CLIENT_NAME);
}
/**
* Obtains the <code>Bean</code> instance for the <code>RestClientProducer</code> component. This instance is used later for
* registering {@link RestClientProducer#produceRestClient} as a producer method.
*
* @param event
*/
public void getRestClientProducerDelegate(@Observes ProcessManagedBean<RestClientProducer> event) {
this.restClientProducerBean = event.getBean();
}
/**
* Scans a Bean for the following injection points
* <p/>
* <code>
*
* @Inject @RestClient private T service; </code>
* <p/>
* where T is a JAX-RS annotated interface and builds a collection of these types.
*/
public <T> void scanInjectionPointsForJaxrsInterfaces(@Observes ProcessBean<T> event, BeanManager manager) {
if (!enabled) {
return;
}
for (InjectionPoint ip : event.getBean().getInjectionPoints()) {
RestClient qualifier = AnnotationInspector.getAnnotation(ip.getAnnotated(), RestClient.class, manager);
if (qualifier != null) {
if (ip.getType() instanceof Class<?>) {
Class<?> clazz = (Class<?>) ip.getType();
if (clazz.isInterface()) // we only support interfaces
{
jaxrsInterfaces.add(clazz);
}
}
}
}
}
/**
* Registers the RestClientProducer if there is an injection point that requires it
*/
public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager) {
if (enabled && !jaxrsInterfaces.isEmpty()) {
if (restClientProducerBean == null) {
log.warn("ProcessProducerMethod<RestClientProducer, Object> not fired. Client extension may not work properly.");
return;
}
// register an additional RestClientProducer that supports all the interfaces
event.addBean(new RestClientProducerBean(restClientProducerBean, jaxrsInterfaces, manager));
}
}
public boolean isClientIntegrationEnabled() {
return enabled;
}
}