001/* *********************************************************************** *
002 * project: org.matsim.*
003 * ControlerListenerManager
004 *                                                                         *
005 * *********************************************************************** *
006 *                                                                         *
007 * copyright       : (C) 2009 by the members listed in the COPYING,        *
008 *                   LICENSE and WARRANTY file.                            *
009 * email           : info at matsim dot org                                *
010 *                                                                         *
011 * *********************************************************************** *
012 *                                                                         *
013 *   This program is free software; you can redistribute it and/or modify  *
014 *   it under the terms of the GNU General Public License as published by  *
015 *   the Free Software Foundation; either version 2 of the License, or     *
016 *   (at your option) any later version.                                   *
017 *   See also COPYING, LICENSE and WARRANTY file                           *
018 *                                                                         *
019 * *********************************************************************** */
020
021package org.matsim.core.controler;
022
023import org.apache.log4j.Logger;
024import org.matsim.core.controler.events.*;
025import org.matsim.core.controler.listener.*;
026import org.matsim.core.utils.misc.ClassUtils;
027
028import javax.swing.event.EventListenerList;
029
030/**
031 * Class encapsulating all behavior concerning the ControlerEvents/Listeners
032 *
033 * @author dgrether
034 */
035public final class ControlerListenerManagerImpl implements ControlerListenerManager {
036
037        private final static Logger log = Logger.getLogger(ControlerListenerManagerImpl.class);
038
039    private MatsimServices controler = null;
040
041        void setControler(MatsimServices controler) {
042        this.controler = controler;
043    }
044
045        /** The swing event listener list to manage ControlerListeners efficiently. First list manages core listeners
046         * which are called first when a ControlerEvent is thrown. I.e. this list contains the listeners that are
047         * always running in a predefined order to ensure correctness.
048         * The second list manages the other listeners, which can be added by calling addControlerListener(...).
049         * A normal ControlerListener is not allowed to depend on the execution of other ControlerListeners.
050         */
051        private final EventListenerList coreListenerList = new EventListenerList();
052        private final EventListenerList listenerList = new EventListenerList();
053
054        
055        /**
056         * Add a core ControlerListener to the Controler instance
057         *
058         */
059        @SuppressWarnings("unchecked")
060        protected void addCoreControlerListener(final ControlerListener l) {
061                for (Class type : ClassUtils.getAllTypes(l.getClass())) {
062                        if (type.isInterface() && ControlerListener.class.isAssignableFrom(type)) {
063                                this.coreListenerList.add(type, l);
064                        }
065                }
066        }
067
068        /**
069         * Add a ControlerListener to the Controler instance
070         *
071         */
072        @SuppressWarnings("unchecked")
073        public void addControlerListener(final ControlerListener l) {
074                for (Class type : ClassUtils.getAllTypes(l.getClass())) {
075                        if (ControlerListener.class.isAssignableFrom(type)) {
076                                this.listenerList.add(type, l);
077                        }
078                }
079        }
080
081        /**
082         * Removes a ControlerListener from the Controler instance
083         *
084         */
085        @SuppressWarnings("unchecked")
086        public void removeControlerListener(final ControlerListener l) {
087                Class[] interfaces = l.getClass().getInterfaces();
088        for (Class anInterface : interfaces) {
089            if (ControlerListener.class.isAssignableFrom(anInterface)) {
090                this.listenerList.remove(anInterface, l);
091            }
092        }
093        }
094
095        /**
096         * Notifies all ControlerListeners
097         */
098        public void fireControlerStartupEvent() {
099                StartupEvent event = new StartupEvent(this.controler);
100                StartupListener[] listener = this.coreListenerList.getListeners(StartupListener.class);
101        for (StartupListener aListener : listener) {
102            log.info("calling notifyStartup on " + aListener.getClass().getName());
103            aListener.notifyStartup(event);
104        }
105                listener = this.listenerList.getListeners(StartupListener.class);
106        for (StartupListener aListener : listener) {
107            log.info("calling notifyStartup on " + aListener.getClass().getName());
108            aListener.notifyStartup(event);
109        }
110                log.info("all ControlerStartupListeners called." );
111        }
112
113        /**
114         * Notifies all ControlerListeners
115         * @param unexpected Whether the shutdown is unexpected or not.
116         */
117        public void fireControlerShutdownEvent(final boolean unexpected) {
118                ShutdownEvent event = new ShutdownEvent(this.controler, unexpected);
119        ShutdownListener[] listener = this.coreListenerList.getListeners(ShutdownListener.class);
120        for (ShutdownListener aListener : listener) {
121            log.info("calling notifyShutdown on " + aListener.getClass().getName());
122            aListener.notifyShutdown(event);
123        }
124        listener = this.listenerList.getListeners(ShutdownListener.class);
125        for (ShutdownListener aListener : listener) {
126            log.info("calling notifyShutdown on " + aListener.getClass().getName());
127            aListener.notifyShutdown(event);
128        }
129        log.info("all ControlerShutdownListeners called.");
130        }
131
132        /**
133         * Notifies all ControlerSetupIterationStartsListeners
134     *
135         */
136        public void fireControlerIterationStartsEvent(final int iteration) {
137                IterationStartsEvent event = new IterationStartsEvent(this.controler, iteration);
138                IterationStartsListener[] listener = this.coreListenerList.getListeners(IterationStartsListener.class);
139        for (IterationStartsListener aListener : listener) {
140            log.info("calling notifyIterationStarts on " + aListener.getClass().getName());
141            aListener.notifyIterationStarts(event);
142        }
143                listener = this.listenerList.getListeners(IterationStartsListener.class);
144        for (IterationStartsListener aListener : listener) {
145            log.info("calling notifyIterationStarts on " + aListener.getClass().getName());
146            aListener.notifyIterationStarts(event);
147        }
148                log.info("[it." + iteration + "] all ControlerIterationStartsListeners called.");
149        }
150
151        /**
152         * Notifies all ControlerIterationEndsListeners
153         *
154         */
155        public void fireControlerIterationEndsEvent(final int iteration) {
156                IterationEndsEvent event = new IterationEndsEvent(this.controler, iteration);
157                {
158                        IterationEndsListener[] listener = this.coreListenerList.getListeners(IterationEndsListener.class);
159            for (IterationEndsListener aListener : listener) {
160                log.info("calling notifyIterationEnds on " + aListener.getClass().getName());
161                aListener.notifyIterationEnds(event);
162            }
163                }
164                {
165                        IterationEndsListener[] listener = this.listenerList.getListeners(IterationEndsListener.class);
166            for (IterationEndsListener aListener : listener) {
167                log.info("calling notifyIterationEnds on " + aListener.getClass().getName());
168                aListener.notifyIterationEnds(event);
169            }
170                }
171                log.info("[it." + iteration + "] all ControlerIterationEndsListeners called.");
172        }
173
174        /**
175         * Notifies all ControlerScoringListeners
176         *
177         */
178        public void fireControlerScoringEvent(final int iteration) {
179                ScoringEvent event = new ScoringEvent(this.controler, iteration);
180                {
181                        ScoringListener[] listener = this.coreListenerList.getListeners(ScoringListener.class);
182            for (ScoringListener aListener : listener) {
183                log.info("calling notifyScoring on " + aListener.getClass().getName());
184                aListener.notifyScoring(event);
185            }
186                }
187                {
188                        ScoringListener[] listener = this.listenerList.getListeners(ScoringListener.class);
189            for (ScoringListener aListener : listener) {
190                log.info("calling notifyScoring on " + aListener.getClass().getName());
191                aListener.notifyScoring(event);
192            }
193                }
194                log.info("[it." + iteration + "] all ControlerScoringListeners called.");
195        }
196
197        /**
198         * Notifies all ControlerReplanningListeners
199         *
200         */
201        public void fireControlerReplanningEvent(final int iteration) {
202                ReplanningEvent event = new ReplanningEvent(this.controler, iteration);
203                ReplanningListener[] listener = this.coreListenerList.getListeners(ReplanningListener.class);
204        for (ReplanningListener aListener : listener) {
205            log.info("calling notifyReplanning on " + aListener.getClass().getName());
206            aListener.notifyReplanning(event);
207        }
208                listener = this.listenerList.getListeners(ReplanningListener.class);
209        for (ReplanningListener aListener : listener) {
210            log.info("calling notifyReplanning on " + aListener.getClass().getName());
211            aListener.notifyReplanning(event);
212        }
213                log.info("[it." + iteration + "] all ControlerReplanningListeners called.");
214        }
215
216        /**
217         * Notifies all ControlerBeforeMobsimListeners
218         *
219         */
220        public void fireControlerBeforeMobsimEvent(final int iteration) {
221                BeforeMobsimEvent event = new BeforeMobsimEvent(this.controler, iteration);
222                BeforeMobsimListener[] listener = this.coreListenerList.getListeners(BeforeMobsimListener.class);
223        for (BeforeMobsimListener aListener : listener) {
224            log.info("calling notifyBeforeMobsim on " + aListener.getClass().getName());
225            aListener.notifyBeforeMobsim(event);
226        }
227                listener = this.listenerList.getListeners(BeforeMobsimListener.class);
228        for (BeforeMobsimListener aListener : listener) {
229            log.info("calling notifyBeforeMobsim on " + aListener.getClass().getName());
230            aListener.notifyBeforeMobsim(event);
231        }
232                log.info("[it." + iteration + "] all ControlerBeforeMobsimListeners called.");
233        }
234
235        /**
236         * Notifies all ControlerAfterMobsimListeners
237         *
238         */
239        public void fireControlerAfterMobsimEvent(final int iteration) {
240                AfterMobsimEvent event = new AfterMobsimEvent(this.controler, iteration);
241                AfterMobsimListener[] listener = this.coreListenerList.getListeners(AfterMobsimListener.class);
242        for (AfterMobsimListener aListener : listener) {
243            log.info("calling notifyAfterMobsim on " + aListener.getClass().getName());
244            aListener.notifyAfterMobsim(event);
245        }
246                listener = this.listenerList.getListeners(AfterMobsimListener.class);
247        for (AfterMobsimListener aListener : listener) {
248            log.info("calling notifyAfterMobsim on " + aListener.getClass().getName());
249            aListener.notifyAfterMobsim(event);
250        }
251                log.info("[it." + iteration + "] all ControlerAfterMobsimListeners called.");
252        }
253
254}