1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.scxml;
18
19 import java.io.Serializable;
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 implements Serializable {
40
41 /***
42 * Serial version UID.
43 */
44 private static final long serialVersionUID = 1L;
45
46 /***
47 * The Map of all listeners keyed by Observable.
48 */
49 private Map regs = new HashMap();
50
51 /***
52 * Constructor.
53 */
54 public NotificationRegistry() {
55 super();
56 }
57
58 /***
59 * Register this SCXMLListener for this Observable.
60 *
61 * @param source The observable this listener wants to listen to
62 * @param lst The listener
63 */
64 synchronized void addListener(final Object source,
65 final SCXMLListener lst) {
66 Set entries = (Set) regs.get(source);
67 if (entries == null) {
68 entries = new HashSet();
69 regs.put(source, entries);
70 }
71 entries.add(lst);
72 }
73
74 /***
75 * Deregister this SCXMLListener for this Observable.
76 *
77 * @param source The observable this listener wants to stop listening to
78 * @param lst The listener
79 */
80 synchronized void removeListener(final Object source,
81 final SCXMLListener lst) {
82 Set entries = (Set) regs.get(source);
83 if (entries != null) {
84 entries.remove(lst);
85 if (entries.size() == 0) {
86 regs.remove(source);
87 }
88 }
89 }
90
91 /***
92 * Inform all relevant listeners that a TransitionTarget has been
93 * entered.
94 *
95 * @param observable The Observable
96 * @param state The TransitionTarget that was entered
97 */
98 public void fireOnEntry(final TransitionTarget observable,
99 final TransitionTarget state) {
100 Object source = observable;
101 fireOnEntry(source, state);
102 }
103
104 /***
105 * Inform all relevant listeners that a TransitionTarget has been
106 * entered.
107 *
108 * @param observable The Observable
109 * @param state The TransitionTarget that was entered
110 */
111 public void fireOnEntry(final SCXML observable,
112 final TransitionTarget state) {
113 Object source = observable;
114 fireOnEntry(source, state);
115 }
116
117 /***
118 * Inform all relevant listeners that a TransitionTarget has been
119 * entered.
120 *
121 * @param source The Observable
122 * @param state The TransitionTarget that was entered
123 */
124 private synchronized void fireOnEntry(final Object source,
125 final TransitionTarget state) {
126 Set entries = (Set) regs.get(source);
127 if (entries != null) {
128 for (Iterator iter = entries.iterator(); iter.hasNext();) {
129 SCXMLListener lst = (SCXMLListener) iter.next();
130 lst.onEntry(state);
131 }
132 }
133 }
134
135 /***
136 * Inform all relevant listeners that a TransitionTarget has been
137 * exited.
138 *
139 * @param observable The Observable
140 * @param state The TransitionTarget that was exited
141 */
142 public void fireOnExit(final TransitionTarget observable,
143 final TransitionTarget state) {
144 Object source = observable;
145 fireOnExit(source, state);
146 }
147
148 /***
149 * Inform all relevant listeners that a TransitionTarget has been
150 * exited.
151 *
152 * @param observable The Observable
153 * @param state The TransitionTarget that was exited
154 */
155 public void fireOnExit(final SCXML observable,
156 final TransitionTarget state) {
157 Object source = observable;
158 fireOnExit(source, state);
159 }
160
161 /***
162 * Inform all relevant listeners that a TransitionTarget has been
163 * exited.
164 *
165 * @param source The Observable
166 * @param state The TransitionTarget that was exited
167 */
168 private synchronized void fireOnExit(final Object source,
169 final TransitionTarget state) {
170 Set entries = (Set) regs.get(source);
171 if (entries != null) {
172 for (Iterator iter = entries.iterator(); iter.hasNext();) {
173 SCXMLListener lst = (SCXMLListener) iter.next();
174 lst.onExit(state);
175 }
176 }
177 }
178
179 /***
180 * Inform all relevant listeners of a transition that has occured.
181 *
182 * @param observable The Observable
183 * @param from The source TransitionTarget
184 * @param to The destination TransitionTarget
185 * @param transition The Transition that was taken
186 */
187 public void fireOnTransition(final Transition observable,
188 final TransitionTarget from, final TransitionTarget to,
189 final Transition transition) {
190 Object source = observable;
191 fireOnTransition(source, from, to, transition);
192 }
193
194 /***
195 * Inform all relevant listeners of a transition that has occured.
196 *
197 * @param observable The Observable
198 * @param from The source TransitionTarget
199 * @param to The destination TransitionTarget
200 * @param transition The Transition that was taken
201 */
202 public void fireOnTransition(final SCXML observable,
203 final TransitionTarget from, final TransitionTarget to,
204 final Transition transition) {
205 Object source = observable;
206 fireOnTransition(source, from, to, transition);
207 }
208
209 /***
210 * Inform all relevant listeners of a transition that has occured.
211 *
212 * @param source The Observable
213 * @param from The source TransitionTarget
214 * @param to The destination TransitionTarget
215 * @param transition The Transition that was taken
216 */
217 private synchronized void fireOnTransition(final Object source,
218 final TransitionTarget from, final TransitionTarget to,
219 final Transition transition) {
220 Set entries = (Set) regs.get(source);
221 if (entries != null) {
222 for (Iterator iter = entries.iterator(); iter.hasNext();) {
223 SCXMLListener lst = (SCXMLListener) iter.next();
224 lst.onTransition(from, to, transition);
225 }
226 }
227 }
228
229 }
230