FileDocCategorySizeDatePackage
GenericBroadcaster.javaAPI DocExample7785Thu May 23 09:32:50 BST 2002 sample.notification

GenericBroadcaster.java

package  sample.notification;

import  javax.management.*;
import  java.util.*;


/**
 * Naive implementation of NotificationBroadcaster.
 */
public class GenericBroadcaster implements NotificationBroadcaster {
    
    private static final boolean traceOn = true;
    /**
     * This is the list of listeners, which contains one triplet
     * object for each interested listener.
     */
    private ArrayList _listeners = new ArrayList();
    /**
     * Hashtable containing the notification types and the number of
     * times each one was sent.
     */
    private Hashtable _notifications = new Hashtable();

    /**
     * Default constructor. Delegates to alternate constructor.
     */
    public GenericBroadcaster () {
        this(null);
    }

    /**
     * Alternate constructor. Allows the agent to specify a String array
     * that contains the possible notification types that can be sent by
     * this broadcaster. This information is used for getNotificationInfo()
     */
    public GenericBroadcaster (String[] notificationTypes) {
        if (notificationTypes != null) {
            for (int aa = 0; aa < notificationTypes.length; aa++) {
                String notifType = notificationTypes[aa];
                trace("GenericBroadcaster(): INFO: Attempting to add notification type \'"
                        + notifType + "\'.");
                if (notifType != null && !notifType.equals("")) {
                    // We don't care if something else was there, the counters
                    /// all get set to zero anyway...
                    _notifications.put(notifType, new Integer(0));
                    trace("GenericBroadcaster(): INFO: Notification type \'"
                            + notifType + "\' successfully added.");
                }
            }
        }
    }

    /**
     * Adds the specified listener (if not null) to the list of listeners.
     * A triplet object is created and added to the backing store.
     */
    public void addNotificationListener (NotificationListener listener, NotificationFilter filter, 
            Object handback) {
        if (listener != null) {
            trace("GenericBroadcaster.addNotificationListener(): INFO: " + 
                    "Adding listener/filter/handback triplet: " + listener + 
                    "/" + filter + "/" + handback + ".");
            _listeners.add(new ListenerFilterHandbackTriplet(listener, filter, 
                    handback));
        }
    }

    /**
     * Removes all triplets associated with the specified listener.
     */
    public void removeNotificationListener (NotificationListener listener) {
        trace("GenericBroadcaster.removeNotificationListener(): INFO: " + "Removing all triplets for listener: "
                + listener);
        removeNotificationListener(listener, null);
    }

    /**
     * Removes the specified listener/filter/handback triplet from the
     * list. If the handback object is null, all triplets for the specified
     * listener are removed. The handback reference must be to the same
     * object instance (not a clone).
     */
    public void removeNotificationListener (NotificationListener listener, 
            Object handback) {
        trace("GenericBroadcaster.removeNotificationListener(): INFO: Removing listener/handback: "
                + listener + "/" + handback);
        if (listener != null) {
            Iterator iter = _listeners.iterator();
            while (iter.hasNext()) {
                ListenerFilterHandbackTriplet triplet = (ListenerFilterHandbackTriplet)iter.next();
                trace("GenericBroadcaster.removeNotificationListener(): INFO: Examining triplet: "
                        + triplet);
                if (listener == triplet.getListener() && (handback == null || 
                        handback == triplet.getHandback())) {
                    trace("GenericBroadcaster.removeNotificationListener(): INFO: Removing triplet: "
                            + triplet);
                    iter.remove();
                    if (handback != null)
                        break;
                }
            }
        }
    }

    /**
     * Constructs an array of MBeanNotificationInfo objects and returns
     * it to the caller.
     */
    public MBeanNotificationInfo[] getNotificationInfo () {
        MBeanNotificationInfo[] notifications = new MBeanNotificationInfo[1];
        String[] notificationTypes = new String[_notifications.size()];
        Iterator iter = _notifications.keySet().iterator();
        int aa = 0;
        while (iter.hasNext()) {
            notificationTypes[aa] = (String)iter.next();
            aa++;
        }
        notifications[0] = new MBeanNotificationInfo(notificationTypes, "NotificationTypes", 
                "Types of notifications emitted by this broadcaster.");
        return  notifications;
    }

    /**
     * Sends the specified notification. The hashtable of notifications
     * is checked to see if this notification has been sent. If not, a
     * new entry is created, otherwise the counter for this notification
     * type is incremented.
     */
    public void sendNotification (Notification notification) {
        if (notification != null) {
            String notifType = notification.getType();
            if (_notifications.containsKey(notifType)) {
                Integer count = (Integer)_notifications.get(notifType);
                _notifications.put(notifType, new Integer(count.intValue() + 
                        1));
            } 
            else {
                _notifications.put(notifType, new Integer(1));
            }
            // Now send the notification to all interested listeners
            for (int aa = 0; aa < _listeners.size(); aa++) {
                ListenerFilterHandbackTriplet triplet = (ListenerFilterHandbackTriplet)_listeners.get(aa);
                trace("GenericBroadcaster.sendNotification(): INFO: Looking at triplet: "
                        + triplet);
                NotificationListener listener = triplet.getListener();
                NotificationFilter filter = triplet.getFilter();
                Object handback = triplet.getHandback();
                if (filter == null || filter.isNotificationEnabled(notification)) {
                    trace("GenericBroadcaster.sendNotification(): INFO: Sending notification to listener: "
                            + listener + ", sending handback: " + handback);
                    listener.handleNotification(notification, handback);
                }
            }
        }
    }

    /**
     * This class is used to encapsulate a listener/filter/handback triplet.
     */
    private class ListenerFilterHandbackTriplet {
        private NotificationListener _listener;

        NotificationListener getListener () {
            return  _listener;
        }
        private NotificationFilter _filter;

        NotificationFilter getFilter () {
            return  _filter;
        }
        private Object _handback;

        Object getHandback () {
            return  _handback;
        }

        ListenerFilterHandbackTriplet (NotificationListener listener, NotificationFilter filter, 
                Object handback) {
            _listener = listener;
            _filter = filter;
            _handback = handback;
        }

        public String toString () {
            return  _listener + "/" + _filter + "/" + _handback;
        }
    }

    private void trace (String message) {
        if (traceOn)
            System.out.println(message);
    }
}