View Javadoc

1   /*
2    * $Id: Configuration.java 20746 2010-12-15 14:20:27Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.context.notification;
12  
13  import org.mule.api.context.notification.ServerNotification;
14  import org.mule.api.context.notification.ServerNotificationListener;
15  import org.mule.config.i18n.CoreMessages;
16  
17  import java.util.Collection;
18  import java.util.Collections;
19  import java.util.HashMap;
20  import java.util.HashSet;
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.Set;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  import static org.mule.context.notification.ServerNotificationManager.toClass;
29  
30  /**
31   * This acts as a synchronized collection. No call blocks and all are synchronized.
32   */
33  class Configuration
34  {
35  
36      protected static Log logger = LogFactory.getLog(Configuration.class);
37      private Map<Class<? extends ServerNotificationListener>, Set<Class<? extends ServerNotification>>> interfaceToTypes =
38              new HashMap<Class<? extends ServerNotificationListener>, Set<Class<? extends ServerNotification>>>(); // map from interface to collection of events
39      private Set<ListenerSubscriptionPair> listenerSubscriptionPairs = new HashSet<ListenerSubscriptionPair>();
40      private Set<Class<? extends ServerNotificationListener>> disabledInterfaces = new HashSet<Class<? extends ServerNotificationListener>>();
41      private Set<Class<? extends ServerNotification>> disabledNotificationTypes = new HashSet<Class<? extends ServerNotification>>();
42      private volatile boolean dirty = true;
43      private Policy policy;
44  
45      synchronized void addInterfaceToType(Class<? extends ServerNotificationListener> iface, Class<? extends ServerNotification> type)
46      {
47          dirty = true;
48          if (!ServerNotification.class.isAssignableFrom(type))
49          {
50              throw new IllegalArgumentException(
51                      CoreMessages.propertyIsNotSupportedType("type",
52                              ServerNotification.class, type).getMessage());
53          }
54          if (!interfaceToTypes.containsKey(iface))
55          {
56              interfaceToTypes.put(iface, new HashSet<Class<? extends ServerNotification>>());
57          }
58          Set<Class<? extends ServerNotification>> events = interfaceToTypes.get(iface);
59          events.add(type);
60          if (logger.isDebugEnabled())
61          {
62              logger.debug("Registered event type: " + type);
63              logger.debug("Binding listener type '" + iface + "' to event type '" + type + "'");
64          }
65      }
66  
67      /**
68       * @param interfaceToTypes map from interace to a particular event
69       * @throws ClassNotFoundException if the interface is a key, but the corresponding class cannot be loaded
70       */
71      synchronized void addAllInterfaceToTypes(Map<Class<? extends ServerNotificationListener>, Set<Class<? extends ServerNotification>>> interfaceToTypes) throws ClassNotFoundException
72      {
73          dirty = true;
74  
75          for (Iterator ifaces = interfaceToTypes.keySet().iterator(); ifaces.hasNext();)
76          {
77              Object iface = ifaces.next();
78              addInterfaceToType(toClass(iface), toClass(interfaceToTypes.get(iface)));
79          }
80      }
81  
82      synchronized void addListenerSubscriptionPair(ListenerSubscriptionPair pair)
83      {
84          dirty = true;
85          if (!listenerSubscriptionPairs.add(pair))
86          {
87              logger.warn(CoreMessages.notificationListenerSubscriptionAlreadyRegistered(pair));
88          }
89      }
90  
91      synchronized void addAllListenerSubscriptionPairs(Collection pairs)
92      {
93          dirty = true;
94          for (Iterator listener = pairs.iterator(); listener.hasNext();)
95          {
96              addListenerSubscriptionPair((ListenerSubscriptionPair) listener.next());
97          }
98      }
99  
100     synchronized void removeListener(ServerNotificationListener listener)
101     {
102         dirty = true;
103         Set<ListenerSubscriptionPair> toRemove = new HashSet<ListenerSubscriptionPair>();
104         for (Iterator listeners = listenerSubscriptionPairs.iterator(); listeners.hasNext();)
105         {
106             ListenerSubscriptionPair pair = (ListenerSubscriptionPair) listeners.next();
107             if (pair.getListener().equals(listener))
108             {
109                 toRemove.add(pair);
110             }
111         }
112         listenerSubscriptionPairs.removeAll(toRemove);
113     }
114 
115     synchronized void removeAllListeners(Collection listeners)
116     {
117         dirty = true;
118         for (Iterator listener = listeners.iterator(); listener.hasNext();)
119         {
120             removeListener((ServerNotificationListener) listener.next());
121         }
122     }
123 
124     synchronized void disableInterface(Class<? extends ServerNotificationListener> iface)
125     {
126         dirty = true;
127         disabledInterfaces.add(iface);
128     }
129 
130     synchronized void disabledAllInterfaces(Collection<Class<? extends ServerNotificationListener>> interfaces) throws ClassNotFoundException
131     {
132         dirty = true;
133         for (Iterator iface = interfaces.iterator(); iface.hasNext();)
134         {
135             disableInterface(toClass(iface.next()));
136         }
137     }
138 
139     synchronized void disableType(Class<? extends ServerNotification> type)
140     {
141         dirty = true;
142         disabledNotificationTypes.add(type);
143     }
144 
145     synchronized void disableAllTypes(Collection types) throws ClassNotFoundException
146     {
147         dirty = true;
148         for (Iterator event = types.iterator(); event.hasNext();)
149         {
150             disableType(toClass(event.next()));
151         }
152     }
153 
154     protected Policy getPolicy()
155     {
156         if (dirty)
157         {
158             synchronized (this)
159             {
160                 if (dirty)
161                 {
162                     policy = new Policy(interfaceToTypes, listenerSubscriptionPairs, disabledInterfaces, disabledNotificationTypes);
163                     dirty = false;
164                 }
165             }
166         }
167         return policy;
168     }
169 
170     // for tests -------------------------------
171 
172     Map<Class<? extends ServerNotificationListener>, Set<Class<? extends ServerNotification>>> getInterfaceToTypes()
173     {
174         return Collections.unmodifiableMap(interfaceToTypes);
175     }
176 
177     Set<ListenerSubscriptionPair> getListeners()
178     {
179         return Collections.unmodifiableSet(listenerSubscriptionPairs);
180     }
181 
182 }