View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  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  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