/* vim: set ts=2 et sw=2 cindent fo=qroca: */ package com.globant.katari.core.web; import org.apache.commons.lang.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; /** * Class that's responsible for initializing the modules. * @author pablo.saavedra */ public class ModuleInitializer implements ApplicationListener<ApplicationEvent>, ApplicationContextAware { /** * The logger, featuring slf4j. */ private static Logger log = LoggerFactory.getLogger(ModuleInitializer.class); /** * The module registry, where the modules to initialize will be located. */ private ModuleContextRegistrar contextRegistrar; /** The application context this bean runs in. * * This avoid reacting to events originated by other (children) application * contexts and initializing twice. This cannot be null once initialized. */ private ApplicationContext context; /** Creates a module initializer with the given module context registrar. * * @param registry The module registry, cannot be null. */ public ModuleInitializer(final ModuleContextRegistrar registry) { Validate.notNull(registry, "The registry cannot be null"); contextRegistrar = registry; } /** Method executed when an application event is raised. * * If the event is a {@link ContextRefreshedEvent}, this bean will perform * module initialization. This also initializes the session factory if it was * defined in the application context. * * @param event The event, may be null (in which case the event is ignored). */ public void onApplicationEvent(final ApplicationEvent event) { log.trace("Entering onApplicationEvent"); Validate.notNull(context, "The application context has not been set"); if (!(event instanceof ContextRefreshedEvent)) { log.trace("Leaving onApplicationEvent"); return; } ContextRefreshedEvent refreshEvent = (ContextRefreshedEvent) event; if (refreshEvent.getApplicationContext() != context) { log.debug("Received a context refreshed event from another application" + " context, ignoring it", refreshEvent.getApplicationContext()); log.trace("Leaving onApplicationEvent"); return; } if (contextRegistrar.isInitialized()) { log.trace("Leaving onApplicationEvent"); return; } log.debug("Starting module initialization"); // Gets all the modules and calls init on them. for (String beanName : contextRegistrar.getModuleBeanNames()) { Object moduleBean = context.getBean(beanName); if (!(moduleBean instanceof Module)) { throw new IllegalArgumentException("The module " + beanName + " does not implement Module"); } Module module = (Module) moduleBean; log.debug("Initializing module {}", beanName); String name = ModuleUtils.getModuleNameFromBeanName(beanName); ModuleContext moduleContext = contextRegistrar.getNewModuleContext(name); module.init(moduleContext); } contextRegistrar.setInitialized(); log.trace("Leaving onApplicationEvent"); } /** Sets the application context this bean runs in. * * @param appContext The application context, cannot be null. */ public void setApplicationContext(final ApplicationContext appContext) { Validate.notNull(appContext, "The application context cannot be null"); context = appContext; } }