package ro.isdc.wro.http;
import static org.apache.commons.lang3.Validate.notNull;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.isdc.wro.config.factory.ServletContextPropertyWroConfigurationFactory;
import ro.isdc.wro.config.jmx.WroConfiguration;
import ro.isdc.wro.http.support.ServletContextAttributeHelper;
import ro.isdc.wro.manager.factory.DefaultWroManagerFactory;
import ro.isdc.wro.manager.factory.WroManagerFactory;
/**
* A listener which loads wroConfiguration and stores it in servletContext. If you want to have multiple listeners,
* extend this class and override the {@link WroServletContextListener#getListenerName()} to provide a unique non-empty
* name (defaulted to "default").
*
* @author Alex Objelean
* @created 6 May 2012
* @since 1.4.6
*/
public class WroServletContextListener
implements ServletContextListener {
private static final Logger LOG = LoggerFactory.getLogger(WroServletContextListener.class);
private WroConfiguration configuration;
private WroManagerFactory managerFactory;
private ServletContext servletContext;
private ServletContextAttributeHelper attributeHelper;
/**
* {@inheritDoc}
*/
public final void contextInitialized(final ServletContextEvent event) {
this.servletContext = event.getServletContext();
attributeHelper = new ServletContextAttributeHelper(this.servletContext, getListenerName());
initListener(event.getServletContext());
}
private void initListener(final ServletContext servletContext) {
if (attributeHelper.getWroConfiguration() != null || attributeHelper.getManagerFactory() != null) {
final String message = "Cannot initialize context because there is already a listener present - withName: "
+ getListenerName()
+ ". Check whether you have multiple listener* (of type WroServletContextListener) definitions in your web.xml!";
LOG.error(message);
throw new IllegalStateException(message);
}
// create configuration first because managerFactory require it during creation.
this.configuration = createConfiguration();
this.managerFactory = createManagerFactory();
LOG.debug("Loaded managerFactory: {}", this.managerFactory.getClass());
attributeHelper.setWroConfiguration(this.configuration);
attributeHelper.setManagerFactory(this.managerFactory);
}
/**
* @return a not null {@link WroConfiguration} object.
*/
private WroConfiguration createConfiguration() {
return this.configuration != null ? this.configuration : newConfiguration();
}
/**
* Create the ContextLoader to use. Can be overridden in subclasses.
*
* @return the new ContextLoader
*/
protected WroConfiguration newConfiguration() {
return new ServletContextPropertyWroConfigurationFactory(servletContext).create();
}
/**
* @return decorated instance of {@link WroManagerFactory}.
*/
private WroManagerFactory createManagerFactory() {
return this.managerFactory != null ? managerFactory : newManagerFactory();
}
/**
* @return default implementation of {@link WroManagerFactory}.
*/
protected WroManagerFactory newManagerFactory() {
return DefaultWroManagerFactory.create(configuration);
}
/**
* {@inheritDoc}
*/
public final void contextDestroyed(final ServletContextEvent servletContextEvent) {
attributeHelper.clear();
}
/**
* Set the manager factory to be initialized by this listener.
*
* @param managerFactory
* a not null manager instance.
*/
public final void setManagerFactory(final WroManagerFactory managerFactory) {
notNull(managerFactory);
this.managerFactory = managerFactory;
}
/**
* @return the name of the listener. Override it to provide a different name if you need to configure multiple
* listener.
*/
protected String getListenerName() {
return ServletContextAttributeHelper.DEFAULT_NAME;
}
/**
* Set the configuration to be initialized by this listener.
*
* @param configuration
* a not null configuration instance.
*/
public final void setConfiguration(final WroConfiguration configuration) {
notNull(configuration);
this.configuration = configuration;
}
/**
* @VisibleForTesting
* @return the {@link WroConfiguration} object built by this listener.
*/
final WroConfiguration getConfiguration() {
return configuration;
}
/**
* @VisibleForTesting
* @return the {@link WroManagerFactory} object built by this listener.
*/
final WroManagerFactory getManagerFactory() {
return managerFactory;
}
}