001/*
002 * Copyright (c) 2004-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2012-11-26 22:24:32 +0000 (Mon, 26 Nov 2012) $' 
007 * '$Revision: 31129 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.kepler.ssh;
031
032import java.lang.ref.WeakReference;
033import java.util.Iterator;
034import java.util.LinkedList;
035
036/**
037 * This class provides a registry to store subscriptions to SshEvents.
038 * 
039 * <p>
040 * 
041 * @author Norbert Podhorszki
042 */
043
044public class SshEventRegistry {
045
046        /* Singleton object */
047        public final static SshEventRegistry instance = new SshEventRegistry();
048
049        private SshEventRegistry() {
050        }
051
052        /**
053         * Append a listener to the current set of ssh event listeners. If the
054         * listener is already in the set, it will not be added again.
055         * 
056         * @param listener
057         *            The listener to which to send SshEvent messages.
058         * @see #removeListener(SshEventListener)
059         */
060        public void addListener(SshEventListener listener) {
061                // NOTE: This has to be synchronized to prevent
062                // concurrent modification exceptions.
063                synchronized (_listeners) {
064                        if (_listeners.contains(listener)) {
065                                return;
066                        } else {
067                                _listeners.add(new WeakReference(listener));
068                        }
069
070                        _hasListeners = true;
071                }
072        }
073
074        /**
075         * Send a SshEvent to all listeners.
076         * 
077         * @param event
078         *            The event.
079         */
080        protected final void notifyListeners(SshEvent event) {
081                if (_hasListeners) {
082                        Iterator listeners = _listeners.iterator();
083
084                        while (listeners.hasNext()) {
085                                WeakReference<SshEventListener> listenerWf = (WeakReference<SshEventListener>) listeners.next();
086//                              ((SshEventListener) listeners.next()).sshEvent(event);
087                                SshEventListener listener = (SshEventListener)listenerWf.get();
088                                if (listener != null)
089                                        listener.sshEvent(event);
090                        }
091                }
092        }
093
094        /**
095         * Unregister an event listener. If the specified listener has not been
096         * previously registered, then do nothing.
097         * 
098         * @param listener
099         *            The listener to remove from the list of listeners to which
100         *            SshEvent messages are sent.
101         * @see #addListener(SshEventListener)
102         */
103        public void removeListener(SshEventListener listener) {
104                // NOTE: This has to be synchronized to prevent
105                // concurrent modification exceptions.
106                synchronized (_listeners) {
107                        _listeners.remove(listener);
108
109                        if (_listeners.size() == 0) {
110                                _hasListeners = false;
111                        }
112                }
113        }
114
115        /* listeners will be iterated on by Ssh classes */
116//      private static LinkedList _listeners = new LinkedList();
117        private static LinkedList<WeakReference<SshEventListener>> _listeners = new LinkedList<WeakReference<SshEventListener>>();
118        private static boolean _hasListeners = false;
119
120}