1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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