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