001    /**
002     * ProgressController.java
003     * jCOLIBRI2 framework. 
004     * @author Juan A. Recio-García.
005     * GAIA - Group for Artificial Intelligence Applications
006     * http://gaia.fdi.ucm.es
007     * 11/01/2007
008     */
009    package jcolibri.util;
010    
011    import java.util.*;
012    /**
013     * This class allows methods to indicate their progress in a long task.
014     * This is a modification of the Observer pattern where the notifier of the tasks keeps a list of observers and notifies them its progress.
015     * Here we centralize the managing of the observers in this class simplifing the code of the notifiers.
016     * <br>
017     * If a method wants to notify its progress it only has to call to:
018     * <ul>
019     * <li>init(myclass, some info, estimated steps)
020     * <li>step(myclass)
021     * <li>...
022     * <li>step(myclass)
023     * <li>finish(myclass)
024     * </ul>
025     * On the other side observers must implement the ProgressListener interface and register to recieve the events from a concrete class or all the classes.
026     * @author Juan A. Recio-Garcia
027     * @version 1.0
028     * @see jcolibri.util.ProgressController
029     */
030    public class ProgressController {
031            
032            /** Defines unknown number of steps for a progress */
033            public static final int UNKNOWN_STEPS = -1;
034            
035            static Hashtable<Class, Collection<ProgressListener>> listeners = new Hashtable<Class, Collection<ProgressListener>>();
036            static Collection<ProgressListener> listenersEverything = new ArrayList<ProgressListener>();
037            
038            /**
039             * Removes all listeners
040             */
041            public static void clear()
042            {
043                listeners.clear();
044                listenersEverything.clear();
045            }
046            
047            /**
048             * Registers a listener to recieve the progress of a concrete class.
049             */
050            public static void register(ProgressListener pl, Class c)
051            {
052                    Collection<ProgressListener> l = listeners.get(c);
053                    if(l==null)
054                    {
055                            l = new ArrayList<ProgressListener>();
056                            listeners.put(c, l);
057                    }
058                    l.add(pl);
059            }
060            
061            /**
062             * Registers a listener to recieve the progress of all classes.
063             */
064            public static void register(ProgressListener pl)
065            {
066                    listenersEverything.add(pl);
067            }
068            
069            /**
070             * Deregisters a listener to recieve the progress of a concrete class.
071             */
072            public static void deregister(ProgressListener pl, Class c)
073            {
074                    Collection<ProgressListener> l = listeners.get(c);
075                    if(l!=null)
076                            l.remove(pl);
077            }
078            
079            /**
080             * Deregisters a listener to recieve the progress of all classes.
081             */
082            public static void deregister(ProgressListener pl)
083            {
084                    listenersEverything.remove(pl);
085            }
086            
087            /**
088             * Notifies to all the listeners of a class that the progress is begining.
089             * @param c Class that notifies the progress.
090             * @param info Some info about the progress.
091             * @param numberOfSteps Number of steps of the task. If unknown it must be -1.
092             */
093            public static void init(Class c, String info, int numberOfSteps)
094            {
095                    Collection<ProgressListener> ls = listeners.get(c);
096                    if(ls!=null)
097                            for(ProgressListener pl: ls)
098                                    pl.init(info, numberOfSteps);
099                    for(ProgressListener pl: listenersEverything)
100                            pl.init(info, numberOfSteps);
101            }
102            
103            /**
104             * Notifies a new step in the task for a concrete class.
105             */
106            public static void step(Class c)
107            {
108                    Collection<ProgressListener> ls = listeners.get(c);
109                    if(ls!=null)
110                            for(ProgressListener pl:ls)
111                                    pl.step();
112                    for(ProgressListener pl: listenersEverything)
113                            pl.step();
114                    
115            }
116            
117            /**
118             * Finishes the progress of a task.
119             */
120            public static void finish(Class c)
121            {
122                    Collection<ProgressListener> ls = listeners.get(c);
123                    if(ls!=null)
124                            for(ProgressListener pl:ls)
125                                    pl.finish();
126                    for(ProgressListener pl: listenersEverything)
127                            pl.finish();
128    
129            }
130            
131    }