View Javadoc

1   /**
2    *  Copyright 2003-2007 Greg Luck
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.event;
18  
19  import net.sf.ehcache.Status;
20  
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.Set;
24  
25  /**
26   * Registered listeners for registering and unregistering CacheManagerEventListeners and sending notifications to registrants.
27   * <p/>
28   * There is one of these per CacheManager. It is a composite listener.
29   *
30   * @author Greg Luck
31   * @version $Id: CacheManagerEventListenerRegistry.java 512 2007-07-10 09:18:45Z gregluck $
32   * @since 1.3
33   */
34  public class CacheManagerEventListenerRegistry implements CacheManagerEventListener {
35  
36      private Status status;
37  
38      /**
39       * A Set of CacheEventListeners keyed by listener instance.
40       * CacheEventListener implementations that will be notified of this cache's events.
41       *
42       * @see CacheManagerEventListener
43       */
44      private Set listeners;
45  
46      /**
47       * Construct a new registry
48       */
49      public CacheManagerEventListenerRegistry() {
50          status = Status.STATUS_UNINITIALISED;
51          listeners = new HashSet();
52      }
53  
54      /**
55       * Adds a listener to the notification service. No guarantee is made that listeners will be
56       * notified in the order they were added.
57       *
58       * @param cacheManagerEventListener the listener to add. Can be null, in which case nothing happens
59       * @return true if the listener is being added and was not already added
60       */
61      public final boolean registerListener(CacheManagerEventListener cacheManagerEventListener) {
62          if (cacheManagerEventListener == null) {
63              return false;
64          }
65          return listeners.add(cacheManagerEventListener);
66      }
67  
68      /**
69       * Removes a listener from the notification service.
70       *
71       * @param cacheManagerEventListener the listener to remove
72       * @return true if the listener was present
73       */
74      public final boolean unregisterListener(CacheManagerEventListener cacheManagerEventListener) {
75          return listeners.remove(cacheManagerEventListener);
76      }
77  
78      /**
79       * Returns whether or not at least one cache manager event listeners has been registered.
80       *
81       * @return true if a one or more listeners have registered, otherwise false
82       */
83      public boolean hasRegisteredListeners() {
84          return listeners.size() > 0;
85      }
86  
87      /**
88       * Gets a Set of the listeners registered to this class
89       *
90       * @return a set of type <code>CacheManagerEventListener</code>
91       */
92      public Set getRegisteredListeners() {
93          return listeners;
94      }
95  
96      /**
97       * Initialises the listeners, ready to receive events.
98       */
99      public void init() {
100         Iterator iterator = listeners.iterator();
101         while (iterator.hasNext()) {
102             CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator.next();
103             cacheManagerEventListener.init();
104         }
105     }
106 
107     /**
108      * Returns the listener status.
109      *
110      * @return the status at the point in time the method is called
111      */
112     public Status getStatus() {
113         return status;
114     }
115 
116     /**
117      * Tell listeners to dispose themselves.
118      * Because this method is only ever called from a synchronized cache method, it does not itself need to be
119      * synchronized.
120      */
121     public void dispose() {
122         Iterator iterator = listeners.iterator();
123         while (iterator.hasNext()) {
124             CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator.next();
125             cacheManagerEventListener.dispose();
126         }
127         listeners.clear();
128     }
129 
130     /**
131      * Called immediately after a cache has been added and activated.
132      * <p/>
133      * Note that the CacheManager calls this method from a synchronized method. Any attempt to
134      * call a synchronized method on CacheManager from this method will cause a deadlock.
135      * <p/>
136      * Note that activation will also cause a CacheEventListener status change notification
137      * from {@link net.sf.ehcache.Status#STATUS_UNINITIALISED} to
138      * {@link net.sf.ehcache.Status#STATUS_ALIVE}. Care should be taken on processing that
139      * notification because:
140      * <ul>
141      * <li>the cache will not yet be accessible from the CacheManager.
142      * <li>the addCaches methods which cause this notification are synchronized on the
143      * CacheManager. An attempt to call {@link net.sf.ehcache.CacheManager#getEhcache(String)}
144      * will cause a deadlock.
145      * </ul>
146      * The calling method will block until this method returns.
147      * <p/>
148      *
149      * @param cacheName the name of the <code>Cache</code> the operation relates to
150      * @see CacheEventListener
151      */
152     public void notifyCacheAdded(String cacheName) {
153         Iterator iterator = listeners.iterator();
154         while (iterator.hasNext()) {
155             CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator.next();
156             cacheManagerEventListener.notifyCacheAdded(cacheName);
157         }
158     }
159 
160     /**
161      * Called immediately after a cache has been disposed and removed. The calling method will
162      * block until this method returns.
163      * <p/>
164      * Note that the CacheManager calls this method from a synchronized method. Any attempt to
165      * call a synchronized method on CacheManager from this method will cause a deadlock.
166      * <p/>
167      * Note that a {@link CacheEventListener} status changed will also be triggered. Any
168      * attempt from that notification to access CacheManager will also result in a deadlock.
169      *
170      * @param cacheName the name of the <code>Cache</code> the operation relates to
171      */
172     public void notifyCacheRemoved(String cacheName) {
173         Iterator iterator = listeners.iterator();
174         while (iterator.hasNext()) {
175             CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator.next();
176             cacheManagerEventListener.notifyCacheRemoved(cacheName);
177         }
178     }
179 
180     /**
181      * Returns a string representation of the object. In general, the
182      * <code>toString</code> method returns a string that
183      * "textually represents" this object. The result should
184      * be a concise but informative representation that is easy for a
185      * person to read.
186      *
187      * @return a string representation of the object.
188      */
189     public String toString() {
190         StringBuffer stringBuffer = new StringBuffer(" cacheManagerEventListeners: ");
191         for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
192             CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator.next();
193             stringBuffer.append(cacheManagerEventListener.getClass().getName()).append(" ");
194         }
195         return stringBuffer.toString();
196     }
197 }