package com.englishtown.vertx.guice; import com.englishtown.vertx.jersey.JerseyHandler; import com.englishtown.vertx.jersey.JerseyServerOptions; import com.englishtown.vertx.jersey.VertxContainer; import com.englishtown.vertx.jersey.impl.DefaultJerseyServer; import com.google.inject.Injector; import com.google.inject.Key; import org.glassfish.hk2.api.Context; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.api.TypeLiteral; import org.glassfish.hk2.utilities.ServiceLocatorUtilities; import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.model.ModelProcessor; import org.glassfish.jersey.server.monitoring.ApplicationEventListener; import org.glassfish.jersey.server.spi.ContainerLifecycleListener; import org.jvnet.hk2.guice.bridge.api.GuiceBridge; import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.jvnet.hk2.guice.bridge.api.GuiceScope; import org.jvnet.hk2.guice.bridge.internal.GuiceScopeContext; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.ReaderInterceptor; import javax.ws.rs.ext.WriterInterceptor; import java.lang.reflect.Type; import java.util.Set; /** * Guice extension of {@link com.englishtown.vertx.jersey.impl.DefaultJerseyServer} */ public class GuiceJerseyServer extends DefaultJerseyServer { @Inject public GuiceJerseyServer(JerseyHandler jerseyHandler, VertxContainer container, Provider<JerseyServerOptions> optionsProvider, ServiceLocator locator, Injector injector) { super(jerseyHandler, container, optionsProvider); initBridge(locator, injector); } /** * Initialize the hk2 bridge * * @param locator the HK2 locator * @param injector the Guice injector */ protected void initBridge(ServiceLocator locator, Injector injector) { // Set up bridge GuiceBridge.getGuiceBridge().initializeGuiceBridge(locator); GuiceIntoHK2Bridge guiceBridge = locator.getService(GuiceIntoHK2Bridge.class); guiceBridge.bridgeGuiceInjector(injector); injectMultibindings(locator, injector); // Bind guice scope context ServiceLocatorUtilities.bind(locator, new AbstractBinder() { @Override protected void configure() { bind(GuiceScopeContext.class).to(new TypeLiteral<Context<GuiceScope>>() { }).in(Singleton.class); } }); } /** * This is a workaround for the hk2 bridge limitations * * @param locator the HK2 locator * @param injector the Guice injector */ protected void injectMultibindings(ServiceLocator locator, Injector injector) { injectMultiBindings(locator, injector, new Key<Set<ContainerRequestFilter>>() { }, ContainerRequestFilter.class); injectMultiBindings(locator, injector, new Key<Set<ContainerResponseFilter>>() { }, ContainerResponseFilter.class); injectMultiBindings(locator, injector, new Key<Set<ReaderInterceptor>>() { }, ReaderInterceptor.class); injectMultiBindings(locator, injector, new Key<Set<WriterInterceptor>>() { }, WriterInterceptor.class); injectMultiBindings(locator, injector, new Key<Set<ModelProcessor>>() { }, ModelProcessor.class); injectMultiBindings(locator, injector, new Key<Set<ContainerLifecycleListener>>() { }, ContainerLifecycleListener.class); injectMultiBindings(locator, injector, new Key<Set<ApplicationEventListener>>() { }, ApplicationEventListener.class); injectMultiBindings(locator, injector, new Key<Set<ExceptionMapper>>() { }, ExceptionMapper.class); } protected void injectMultiBindings(ServiceLocator locator, Injector injector, Key<? extends Set<?>> key, Type type) { Set<?> set = injector.getInstance(key); if (set != null && !set.isEmpty()) { for (Object obj : set) { ServiceLocatorUtilities.addOneConstant(locator, obj, null, type); } } } }