001: /**
002: * Copyright 2003-2007 Luck Consulting Pty Ltd
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */package net.sf.ehcache.event;
016:
017: import net.sf.ehcache.Status;
018:
019: import java.util.HashSet;
020: import java.util.Iterator;
021: import java.util.Set;
022:
023: /**
024: * Registered listeners for registering and unregistering CacheManagerEventListeners and sending notifications to registrants.
025: * <p/>
026: * There is one of these per CacheManager. It is a composite listener.
027: *
028: * @author Greg Luck
029: * @version $Id: CacheManagerEventListenerRegistry.java 519 2007-07-27 07:11:45Z gregluck $
030: * @since 1.3
031: */
032: public class CacheManagerEventListenerRegistry implements
033: CacheManagerEventListener {
034:
035: private Status status;
036:
037: /**
038: * A Set of CacheEventListeners keyed by listener instance.
039: * CacheEventListener implementations that will be notified of this cache's events.
040: *
041: * @see CacheManagerEventListener
042: */
043: private Set listeners;
044:
045: /**
046: * Construct a new registry
047: */
048: public CacheManagerEventListenerRegistry() {
049: status = Status.STATUS_UNINITIALISED;
050: listeners = new HashSet();
051: }
052:
053: /**
054: * Adds a listener to the notification service. No guarantee is made that listeners will be
055: * notified in the order they were added.
056: *
057: * @param cacheManagerEventListener the listener to add. Can be null, in which case nothing happens
058: * @return true if the listener is being added and was not already added
059: */
060: public final boolean registerListener(
061: CacheManagerEventListener cacheManagerEventListener) {
062: if (cacheManagerEventListener == null) {
063: return false;
064: }
065: return listeners.add(cacheManagerEventListener);
066: }
067:
068: /**
069: * Removes a listener from the notification service.
070: *
071: * @param cacheManagerEventListener the listener to remove
072: * @return true if the listener was present
073: */
074: public final boolean unregisterListener(
075: CacheManagerEventListener cacheManagerEventListener) {
076: return listeners.remove(cacheManagerEventListener);
077: }
078:
079: /**
080: * Returns whether or not at least one cache manager event listeners has been registered.
081: *
082: * @return true if a one or more listeners have registered, otherwise false
083: */
084: public boolean hasRegisteredListeners() {
085: return listeners.size() > 0;
086: }
087:
088: /**
089: * Gets a Set of the listeners registered to this class
090: *
091: * @return a set of type <code>CacheManagerEventListener</code>
092: */
093: public Set getRegisteredListeners() {
094: return listeners;
095: }
096:
097: /**
098: * Initialises the listeners, ready to receive events.
099: */
100: public void init() {
101: Iterator iterator = listeners.iterator();
102: while (iterator.hasNext()) {
103: CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator
104: .next();
105: cacheManagerEventListener.init();
106: }
107: }
108:
109: /**
110: * Returns the listener status.
111: *
112: * @return the status at the point in time the method is called
113: */
114: public Status getStatus() {
115: return status;
116: }
117:
118: /**
119: * Tell listeners to dispose themselves.
120: * Because this method is only ever called from a synchronized cache method, it does not itself need to be
121: * synchronized.
122: */
123: public void dispose() {
124: Iterator iterator = listeners.iterator();
125: while (iterator.hasNext()) {
126: CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator
127: .next();
128: cacheManagerEventListener.dispose();
129: }
130: listeners.clear();
131: }
132:
133: /**
134: * Called immediately after a cache has been added and activated.
135: * <p/>
136: * Note that the CacheManager calls this method from a synchronized method. Any attempt to
137: * call a synchronized method on CacheManager from this method will cause a deadlock.
138: * <p/>
139: * Note that activation will also cause a CacheEventListener status change notification
140: * from {@link net.sf.ehcache.Status#STATUS_UNINITIALISED} to
141: * {@link net.sf.ehcache.Status#STATUS_ALIVE}. Care should be taken on processing that
142: * notification because:
143: * <ul>
144: * <li>the cache will not yet be accessible from the CacheManager.
145: * <li>the addCaches methods which cause this notification are synchronized on the
146: * CacheManager. An attempt to call {@link net.sf.ehcache.CacheManager#getEhcache(String)}
147: * will cause a deadlock.
148: * </ul>
149: * The calling method will block until this method returns.
150: * <p/>
151: *
152: * @param cacheName the name of the <code>Cache</code> the operation relates to
153: * @see CacheEventListener
154: */
155: public void notifyCacheAdded(String cacheName) {
156: Iterator iterator = listeners.iterator();
157: while (iterator.hasNext()) {
158: CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator
159: .next();
160: cacheManagerEventListener.notifyCacheAdded(cacheName);
161: }
162: }
163:
164: /**
165: * Called immediately after a cache has been disposed and removed. The calling method will
166: * block until this method returns.
167: * <p/>
168: * Note that the CacheManager calls this method from a synchronized method. Any attempt to
169: * call a synchronized method on CacheManager from this method will cause a deadlock.
170: * <p/>
171: * Note that a {@link CacheEventListener} status changed will also be triggered. Any
172: * attempt from that notification to access CacheManager will also result in a deadlock.
173: *
174: * @param cacheName the name of the <code>Cache</code> the operation relates to
175: */
176: public void notifyCacheRemoved(String cacheName) {
177: Iterator iterator = listeners.iterator();
178: while (iterator.hasNext()) {
179: CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator
180: .next();
181: cacheManagerEventListener.notifyCacheRemoved(cacheName);
182: }
183: }
184:
185: /**
186: * Returns a string representation of the object. In general, the
187: * <code>toString</code> method returns a string that
188: * "textually represents" this object. The result should
189: * be a concise but informative representation that is easy for a
190: * person to read.
191: *
192: * @return a string representation of the object.
193: */
194: public String toString() {
195: StringBuffer stringBuffer = new StringBuffer(
196: " cacheManagerEventListeners: ");
197: for (Iterator iterator = listeners.iterator(); iterator
198: .hasNext();) {
199: CacheManagerEventListener cacheManagerEventListener = (CacheManagerEventListener) iterator
200: .next();
201: stringBuffer.append(
202: cacheManagerEventListener.getClass().getName())
203: .append(" ");
204: }
205: return stringBuffer.toString();
206: }
207: }
|