/* * JABM - Java Agent-Based Modeling Toolkit * Copyright (C) 2013 Steve Phelps * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 General Public License for more details. */ package net.sourceforge.jabm; import net.sourceforge.jabm.init.SpringSimulationFactory; import net.sourceforge.jabm.spring.SimulationScope; import org.apache.log4j.Logger; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.support.DefaultListableBeanFactory; /** * <p> * <code>SpringSimulationController</code> is responsible for running * one or more independent JABM simulations which are configured using the * <a href="http://www.springsource.com/developer/spring">Spring Framework</a>. * </p> * * <p> * It is responsible for running one or more Monte-carlo simulations; that is, * any object implementing the <code>Simulation</code> interface. * Typically a simulation will be run several hundred times with different * realisations of random variables. In order to ensure that each sample * is independent, the underlying simulation is initialised as a freshly * constructed bean from the Spring factory for every run. * </p> * * <p> * A simulation model is constructed using * <a href="http://martinfowler.com/articles/injection.html">dependency injection</a> * by creating a * <a href="http://unmaintainable.wordpress.com/2007/11/01/configuration-with-spring-beans/"> * Spring beans configuration file</a> which specifies which classes to use * in the simulation and the values of any attributes (parameters). * The Spring configuration file is specified using the system property * <code>jabm.config</code>. * </p> * * @author Steve Phelps * @see Simulation * */ public class SpringSimulationController extends SimulationController implements BeanFactoryAware, InitializingBean { /** * The name of the bean representing the </code>Simulation</code>. */ protected String simulationBeanName; /** * The container for beans with scope="simulation". */ protected SimulationScope simulationScope; protected BeanFactory beanFactory; protected boolean simulationInitialised = false; static Logger logger = Logger.getLogger(SpringSimulationController.class); @Override protected void tearDownSimulation() { super.tearDownSimulation(); simulationScope.startNewSimulation(); } @Override protected void constructSimulation() { logger.debug("Constructing simulation... "); // Tear down any existing simulation object so that we can run afresh. tearDownSimulation(); // First wire the reports so that they can listen to events fired // during the initialisation phase. wireReports(); // Now construct a fresh simulation. this.simulation = simulationFactory.initialise(this); logger.debug("simulation = " + simulation); // Now establish the remaining listeners wireSimulation(); // All done this.simulationInitialised = true; } public String getSimulationBeanName() { return simulationBeanName; } /** * The name of bean representing the Simulation to be run * as part of this experiment. * * @see Simulation * @param simulationBean */ @Required public void setSimulationBeanName(String simulationBean) { this.simulationBeanName = simulationBean; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = (DefaultListableBeanFactory) beanFactory; } public BeanFactory getBeanFactory() { return beanFactory; } @Override public void afterPropertiesSet() throws Exception { this.simulation = (Simulation) beanFactory.getBean(simulationBeanName); this.simulationScope = SimulationScope.getSingletonInstance(); if (this.simulationFactory == null) { this.simulationFactory = new SpringSimulationFactory(); } } }