/*
* This file is part of LibrePlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.libreplan.web.bootstrap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.libreplan.business.BootstrapOrder;
import org.libreplan.business.IDataBootstrap;
import org.libreplan.business.hibernate.notification.PredefinedDatabaseSnapshots;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class BootstrapListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
WebApplicationContext webApplicationContext =
WebApplicationContextUtils.getWebApplicationContext(servletContextEvent.getServletContext());
doBootstrap(webApplicationContext);
// Some snapshots could depend on the bootstrap being done, so they are launched after
launchSnapshots(webApplicationContext);
}
private void doBootstrap(WebApplicationContext webApplicationContext) {
List<IDataBootstrap> bootstrapsFound = findBootstraps(webApplicationContext);
Collections.sort(bootstrapsFound, byBootstrapOrder());
for (IDataBootstrap each : bootstrapsFound) {
each.loadRequiredData();
}
}
private List<IDataBootstrap> findBootstraps(WebApplicationContext webApplicationContext) {
String[] beanNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(webApplicationContext, IDataBootstrap.class);
List<IDataBootstrap> result = new ArrayList<>();
for (String name : beanNames) {
IDataBootstrap bootstrap = (IDataBootstrap) webApplicationContext.getBean(name);
result.add(bootstrap);
}
return result;
}
private Comparator<IDataBootstrap> byBootstrapOrder() {
return new Comparator<IDataBootstrap>() {
@Override
public int compare(IDataBootstrap o1, IDataBootstrap o2) {
return getOrderingValue(o1) - getOrderingValue(o2);
}
private int getOrderingValue(IDataBootstrap dataBootstrap) {
BootstrapOrder annotation = searchAnnotationFor(dataBootstrap);
return annotation == null ? 0 : annotation.value();
}
private BootstrapOrder searchAnnotationFor(IDataBootstrap dataBootstrap) {
Class<? extends IDataBootstrap> klass = dataBootstrap.getClass();
BootstrapOrder result = klass.getAnnotation(BootstrapOrder.class);
if ( result == null && dataBootstrap instanceof Advised ) {
return searchInProxiedClass((Advised) dataBootstrap);
}
return result;
}
private BootstrapOrder searchInProxiedClass(Advised advised) {
Class<?> proxiedClass = advised.getTargetSource().getTargetClass();
return proxiedClass.getAnnotation(BootstrapOrder.class);
}
};
}
private void launchSnapshots(WebApplicationContext webApplicationContext) {
PredefinedDatabaseSnapshots snapshots = getPredefinedDatabaseSnapshots(webApplicationContext);
snapshots.registerSnapshots();
}
private PredefinedDatabaseSnapshots getPredefinedDatabaseSnapshots(WebApplicationContext webApplicationContext) {
return (PredefinedDatabaseSnapshots)
webApplicationContext.getBean(lowercaseFirst(PredefinedDatabaseSnapshots.class.getSimpleName()));
}
private String lowercaseFirst(String simpleName) {
return simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
}
}