package org.jboss.resteasy.plugins.guice; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.Stage; import org.jboss.resteasy.plugins.guice.i18n.LogMessages; import org.jboss.resteasy.plugins.guice.i18n.Messages; import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap; import org.jboss.resteasy.spi.Registry; import org.jboss.resteasy.spi.ResteasyDeployment; import org.jboss.resteasy.spi.ResteasyProviderFactory; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class GuiceResteasyBootstrapServletContextListener extends ResteasyBootstrap implements ServletContextListener { private List<? extends Module> modules; @Inject private Injector parentInjector = null; @Override public void contextInitialized(final ServletContextEvent event) { super.contextInitialized(event); final ServletContext context = event.getServletContext(); final ResteasyDeployment deployment = (ResteasyDeployment) context.getAttribute(ResteasyDeployment.class.getName()); final Registry registry = deployment.getRegistry(); final ResteasyProviderFactory providerFactory = deployment.getProviderFactory(); final ModuleProcessor processor = new ModuleProcessor(registry, providerFactory); final List<? extends Module> modules = getModules(context); final Stage stage = getStage(context); Injector injector; if (parentInjector != null) { injector = parentInjector.createChildInjector(modules); } else { if (stage == null) { injector = Guice.createInjector(modules); } else { injector = Guice.createInjector(stage, modules); } } withInjector(injector); processor.processInjector(injector); //load parent injectors while (injector.getParent() != null) { injector = injector.getParent(); processor.processInjector(injector); } this.modules = modules; triggerAnnotatedMethods(PostConstruct.class); } /** * Override this method to interact with the {@link Injector} after it has been created. The default is no-op. * * @param injector */ protected void withInjector(Injector injector) { } /** * Override this method to set the Stage. By default it is taken from resteasy.guice.stage context param. * * @param context * @return Guice Stage */ protected Stage getStage(ServletContext context) { final String stageAsString = context.getInitParameter("resteasy.guice.stage"); if (stageAsString == null) { return null; } try { return Stage.valueOf(stageAsString.trim()); } catch (IllegalArgumentException e) { throw new RuntimeException(Messages.MESSAGES.injectorStageNotProperlyDefined(stageAsString)); } } /** * Override this method to instantiate your {@link Module}s yourself. * * @param context * @return */ protected List<? extends Module> getModules(final ServletContext context) { final List<Module> result = new ArrayList<Module>(); final String modulesString = context.getInitParameter("resteasy.guice.modules"); if (modulesString != null) { final String[] moduleStrings = modulesString.trim().split(","); for (final String moduleString : moduleStrings) { try { LogMessages.LOGGER.info(Messages.MESSAGES.foundModule(moduleString)); final Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(moduleString.trim()); final Module module = (Module) clazz.newInstance(); result.add(module); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } } } return result; } @Override public void contextDestroyed(final ServletContextEvent event) { triggerAnnotatedMethods(PreDestroy.class); } private void triggerAnnotatedMethods(final Class<? extends Annotation> annotationClass) { for (Module module : this.modules) { final Method[] methods = module.getClass().getMethods(); for (Method method : methods) { if (method.isAnnotationPresent(annotationClass)) { if(method.getParameterTypes().length > 0) { LogMessages.LOGGER.warn(Messages.MESSAGES.cannotExecute(module.getClass().getSimpleName(), annotationClass.getSimpleName(), method.getName())); continue; } try { method.invoke(module); } catch (InvocationTargetException ex) { LogMessages.LOGGER.warn(Messages.MESSAGES.problemRunningAnnotationMethod(annotationClass.getSimpleName()), ex); } catch (IllegalAccessException ex) { LogMessages.LOGGER.warn(Messages.MESSAGES.problemRunningAnnotationMethod(annotationClass.getSimpleName()), ex); } } } } } }