View Javadoc

1   /*
2    *
3    *   Copyright 2005-2006 The Apache Software Foundation.
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  package org.apache.commons.scxml;
19  
20  import java.util.HashMap;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import org.apache.commons.scxml.model.SCXML;
27  import org.apache.commons.scxml.model.Transition;
28  import org.apache.commons.scxml.model.TransitionTarget;
29  
30  /***
31   * The registry where SCXML listeners are recorded for nodes of
32   * interest such as the <code>SCXML</code> root,
33   * <code>TransitionTarget</code>s and <code>Transition</code>s.
34   * The notification registry keeps track of all
35   * <code>SCXMLListener</code>s attached and notifies relevant
36   * listeners of the events that interest them.
37   *
38   */
39  public final class NotificationRegistry {
40  
41      /***
42       * The Map of all listeners keyed by Observable.
43       */
44      private Map regs = new HashMap();
45  
46      /***
47       * Constructor.
48       */
49      public NotificationRegistry() {
50          super();
51      }
52  
53      /***
54       * Register this SCXMLListener for this Observable.
55       *
56       * @param source The observable this listener wants to listen to
57       * @param lst The listener
58       */
59      void addListener(final Object source,
60              final SCXMLListener lst) {
61          Set entries = (Set) regs.get(source);
62          if (entries == null) {
63              entries = new HashSet();
64              regs.put(source, entries);
65          }
66          entries.add(lst);
67      }
68  
69      /***
70       * Deregister this SCXMLListener for this Observable.
71       *
72       * @param source The observable this listener wants to stop listening to
73       * @param lst The listener
74       */
75      void removeListener(final Object source,
76              final SCXMLListener lst) {
77          Set entries = (Set) regs.get(source);
78          if (entries != null) {
79              entries.remove(lst);
80              if (entries.size() == 0) {
81                  regs.remove(source);
82              }
83          }
84      }
85  
86      /***
87       * Inform all relevant listeners that a TransitionTarget has been
88       * entered.
89       *
90       * @param observable The Observable
91       * @param state The TransitionTarget that was entered
92       */
93      public void fireOnEntry(final TransitionTarget observable,
94              final TransitionTarget state) {
95          Object source = observable;
96          fireOnEntry(source, state);
97      }
98  
99      /***
100      * Inform all relevant listeners that a TransitionTarget has been
101      * entered.
102      *
103      * @param observable The Observable
104      * @param state The TransitionTarget that was entered
105      */
106     public void fireOnEntry(final SCXML observable,
107             final TransitionTarget state) {
108         Object source = observable;
109         fireOnEntry(source, state);
110     }
111 
112     /***
113      * Inform all relevant listeners that a TransitionTarget has been
114      * entered.
115      *
116      * @param source The Observable
117      * @param state The TransitionTarget that was entered
118      */
119     private void fireOnEntry(final Object source,
120             final TransitionTarget state) {
121         Set entries = (Set) regs.get(source);
122         if (entries != null) {
123             for (Iterator iter = entries.iterator(); iter.hasNext();) {
124                 SCXMLListener lst = (SCXMLListener) iter.next();
125                 lst.onEntry(state);
126             }
127         }
128     }
129 
130     /***
131      * Inform all relevant listeners that a TransitionTarget has been
132      * exited.
133      *
134      * @param observable The Observable
135      * @param state The TransitionTarget that was exited
136      */
137     public void fireOnExit(final TransitionTarget observable,
138             final TransitionTarget state) {
139         Object source = observable;
140         fireOnExit(source, state);
141     }
142 
143     /***
144      * Inform all relevant listeners that a TransitionTarget has been
145      * exited.
146      *
147      * @param observable The Observable
148      * @param state The TransitionTarget that was exited
149      */
150     public void fireOnExit(final SCXML observable,
151             final TransitionTarget state) {
152         Object source = observable;
153         fireOnExit(source, state);
154     }
155 
156     /***
157      * Inform all relevant listeners that a TransitionTarget has been
158      * exited.
159      *
160      * @param source The Observable
161      * @param state The TransitionTarget that was exited
162      */
163     private void fireOnExit(final Object source,
164             final TransitionTarget state) {
165         Set entries = (Set) regs.get(source);
166         if (entries != null) {
167             for (Iterator iter = entries.iterator(); iter.hasNext();) {
168                 SCXMLListener lst = (SCXMLListener) iter.next();
169                 lst.onExit(state);
170             }
171         }
172     }
173 
174     /***
175      * Inform all relevant listeners of a transition that has occured.
176      *
177      * @param observable The Observable
178      * @param from The source TransitionTarget
179      * @param to The destination TransitionTarget
180      * @param transition The Transition that was taken
181      */
182     public void fireOnTransition(final Transition observable,
183             final TransitionTarget from, final TransitionTarget to,
184             final Transition transition) {
185         Object source = observable;
186         fireOnTransition(source, from, to, transition);
187     }
188 
189     /***
190      * Inform all relevant listeners of a transition that has occured.
191      *
192      * @param observable The Observable
193      * @param from The source TransitionTarget
194      * @param to The destination TransitionTarget
195      * @param transition The Transition that was taken
196      */
197     public void fireOnTransition(final SCXML observable,
198             final TransitionTarget from, final TransitionTarget to,
199             final Transition transition) {
200         Object source = observable;
201         fireOnTransition(source, from, to, transition);
202     }
203 
204     /***
205      * Inform all relevant listeners of a transition that has occured.
206      *
207      * @param source The Observable
208      * @param from The source TransitionTarget
209      * @param to The destination TransitionTarget
210      * @param transition The Transition that was taken
211      */
212     private void fireOnTransition(final Object source,
213             final TransitionTarget from, final TransitionTarget to,
214             final Transition transition) {
215         Set entries = (Set) regs.get(source);
216         if (entries != null) {
217             for (Iterator iter = entries.iterator(); iter.hasNext();) {
218                 SCXMLListener lst = (SCXMLListener) iter.next();
219                 lst.onTransition(from, to, transition);
220             }
221         }
222     }
223 
224 }
225