001: /*
002: * $Id: Watcher.java 458804 2006-01-23 14:00:38Z jcompagner $
003: * $Revision: 458804 $ $Date: 2006-01-23 15:00:38 +0100 (Mon, 23 Jan 2006) $
004: *
005: * ==============================================================================
006: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007: * use this file except in compliance with the License. You may obtain a copy of
008: * the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.util.watch;
019:
020: import java.util.Map;
021:
022: import wicket.util.concurrent.ConcurrentHashMap;
023: import wicket.util.listener.ChangeListenerSet;
024: import wicket.util.listener.IChangeListener;
025:
026: /**
027: * Similar to ModificationWatcher but manually triggered, calling all registered
028: * ChangeListeners when a given object is triggered.
029: *
030: * @author Juergen Donnerstag
031: */
032: public final class Watcher {
033: /** Maps objects to change listener sets */
034: private final Map keyToEntry = new ConcurrentHashMap();
035:
036: // Class for holding entries to watch
037: private static final class Entry {
038: // The value associated with the key
039: Object data;
040:
041: // The set of listeners to call when triggered
042: final ChangeListenerSet listeners = new ChangeListenerSet();
043: }
044:
045: /**
046: * Constructor
047: */
048: public Watcher() {
049: }
050:
051: /**
052: * Adds a key and an IChangeListener to call when the key is triggered.
053: * <p>
054: * Note: the value is ignored if the key and an associated value already
055: * exists. Only the listeners is added (if an equals does not already
056: * exist).
057: *
058: * @param key
059: * The key to identifiy a ChangeListenerSet
060: * @param listener
061: * The listener to call if the key gets triggered
062: * @return <tt>true</tt> if the set did not already contain the specified
063: * element.
064: */
065: public final boolean add(final Object key,
066: final IChangeListener listener) {
067: // Look up entry for modifiable
068: final Entry entry = (Entry) keyToEntry.get(key);
069:
070: // Found it?
071: if (entry == null) {
072: // Construct new entry
073: final Entry newEntry = new Entry();
074: if (listener != null) {
075: newEntry.listeners.add(listener);
076: }
077:
078: // Put in map
079: keyToEntry.put(key, newEntry);
080:
081: return true;
082: } else {
083: // Add listener to existing entry
084: if (listener != null) {
085: return entry.listeners.add(listener);
086: }
087: }
088:
089: return false;
090: }
091:
092: /**
093: * Remove all entries associated with 'modifiable'
094: *
095: * @param key
096: * @return the object removed, else null
097: */
098: public Object remove(final Object key) {
099: return keyToEntry.remove(key);
100: }
101:
102: /**
103: * Remove all entries
104: */
105: public void clear() {
106: keyToEntry.clear();
107: }
108:
109: /**
110: * trigger all listeners registered with key
111: *
112: * @param key
113: * The key to identify the ChangeListenerSet
114: */
115: public void notifyListeners(final Object key) {
116: // Look up entry for modifiable
117: final Entry entry = (Entry) keyToEntry.get(key);
118: if (entry != null) {
119: entry.listeners.notifyListeners();
120: }
121: }
122: }
|