/* NotificationBroadcasterSupport.java -- Supporting implementation.
   Copyright (C) 2007 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package javax.management;

import gnu.javax.management.ListenerData;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import java.util.concurrent.Executor;

/**
 * <p>
 * Provides an implementation of the {@link NotificationEmitter}
 * interface, which beans may utilise by extension.  By default,
 * a synchronous dispatch system is provided, whereby the
 * {@link #handleNotification(NotificationListener, Notification,
 * Object)} is called once per listener by
 * {*@link #sendNotification(Notification)} before returning.
 * Thus, unless the listener is remote, it will have received
 * the notification before the method returns.
 * This may be changed by overriding the <code>handleNotification</code>
 * method, or by providing an {@link java.util.concurrent.Executor} to
 * use.  With the latter, the dispatch of a notification to a particular
 * listener will form one task performed by the executor.
 * </p>
 * <p>
 * Any exceptions thrown by the dispatch process will be caught, allowing
 * other listeners to still receive the notification.  However, any
 * {@link Error}s that are thrown will be propogated to the caller of
 * {@link #sendNotification(Notification)}.
 * </p>
 *
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.5
 */
public class NotificationBroadcasterSupport
  implements NotificationEmitter
{

  /**
   * The executor for dispatch, or
   * <code>null</code> if this thread should
   * handle dispatch itself.
   */
  private Executor executor;

  /**
   * An array containing information on each
   * notification, or <code>null</code> if an
   * empty array should be returned by
   * {@link #getNotificationInfo()}.
   */
  private MBeanNotificationInfo[] info;

  /**
   * The list of listeners registered with
   * this broadcaster.
   */
  private final List<ListenerData> listeners =
    new ArrayList<ListenerData>();

  /**
   * Constructs a {@link NotificationBroadcasterSupport} using
   * the default synchronous dispatch model, where a single
   * thread sends the notification to all listeners.  This
   * is equivalent to calling
   * <code>NotificationBroadcasterSupport(null, null)</code>.
   */
  public NotificationBroadcasterSupport()
  {
    this(null, (MBeanNotificationInfo[]) null);
  }

  /**
   * Constructs a {@link NotificationBroadcasterSupport} where
   * the specified (@link java.util.concurrent.Executor} is used
   * to perform each invocation of the
   * {@link #handleNotification(NotificationListener, Notification,
   * Object)} method.  Filtering is performed beforehand, by this
   * thread; only calls which have successfully passed through the
   * filter are sent to the executor.  This is equivalent to calling
   * <code>NotificationBroadcasterSupport(executor, null)</code>.
   *
   * @param executor the executor to use for each call to
   *                 <code>handleNotification()</code>.
   * @since 1.6
   */
  public NotificationBroadcasterSupport(Executor executor)
  {
    this(executor, (MBeanNotificationInfo) null);
  }

  /**
   * Constructs a {@link NotificationBroadcasterSupport} using
   * the default synchronous dispatch model, where a single
   * thread sends the notification to all listeners. The specified
   * {@link MBeanNotificationInfo} array is used to provide
   * information about the notifications on calls to
   * {@link #getNotificationInfo()}, where a clone will be
   * returned if the array is non-empty.   This is equivalent to
   * calling <code>NotificationBroadcasterSupport(null, info)</code>.
   *
   * @param info an array of {@link MBeanNotificationInfo} objects
   *             describing the notifications delivered by this
   *             broadcaster.  This may be <code>null</code>, which
   *             is taken as being equivalent to an empty array.
   */
  public NotificationBroadcasterSupport(MBeanNotificationInfo... info)
  {
    this(null, info);
  }

  /**
   * Constructs a {@link NotificationBroadcasterSupport} where
   * the specified (@link java.util.concurrent.Executor} is used
   * to perform each invocation of the
   * {@link #handleNotification(NotificationListener, Notification,
   * Object)} method.  Filtering is performed beforehand, by this
   * thread; only calls which have successfully passed through the
   * filter are sent to the executor.  The specified
   * {@link MBeanNotificationInfo} array is used to provide
   * information about the notifications on calls to
   * {@link #getNotificationInfo()}, where a clone will be
   * returned if the array is non-empty.
   *
   * @param executor the executor to use for each call to
   *                 <code>handleNotification()</code>.
   * @param info an array of {@link MBeanNotificationInfo} objects
   *             describing the notifications delivered by this
   *             broadcaster.  This may be <code>null</code>, which
   *             is taken as being equivalent to an empty array.
   * @since 1.6
   */
  public NotificationBroadcasterSupport(Executor executor,
                                        MBeanNotificationInfo... info)
  {
    this.executor = executor;
    this.info = info;
  }

  /**
   * Registers the specified listener as a new recipient of
   * notifications from this bean.  If non-null, the filter
   * argument will be used to select which notifications are
   * delivered.  The supplied object will also be passed to
   * the recipient with each notification.  This should not
   * be modified by the broadcaster, but instead should be
   * passed unmodified to the listener.
   *
   * @param listener the new listener, who will receive
   *                 notifications from this broadcasting bean.
   * @param filter a filter to determine which notifications are
   *               delivered to the listener, or <code>null</code>
   *               if no filtering is required.
   * @param passback an object to be passed to the listener with
   *                 each notification.
   * @throws IllegalArgumentException if <code>listener</code> is
   *                                  <code>null</code>.
   * @see #removeNotificationListener(NotificationListener)
   */
  public void addNotificationListener(NotificationListener listener,
                                      NotificationFilter filter,
                                      Object passback)
    throws IllegalArgumentException
  {
    if (listener == null)
      throw new IllegalArgumentException("Null listener added to bean.");
    listeners.add(new ListenerData(listener, filter, passback));
  }

  /**
   * Returns an array describing the notifications this
   * bean may send to its registered listeners.  Ideally, this
   * array should be complete, but in some cases, this may
   * not be possible.  However, be aware that some listeners
   * may expect this to be so.
   *
   * @return the array of possible notifications.
   */
  public MBeanNotificationInfo[] getNotificationInfo()
  {
    if (info == null || info.length == 0)
      return new MBeanNotificationInfo[0];
    return (MBeanNotificationInfo[]) info.clone();
  }

  /**
   * This method is called on a per-listener basis, either
   * from this thread or the supplied executor, and may be
   * overridden by subclasses which wish to change how
   * notifications are delivered.  The default
   * implementation simply calls
   * <code>listener.handleNotification(notif, passback)</code>.
   *
   * @param listener the listener to send the notification to.
   * @param notif the notification to dispatch.
   * @param passback the passback object of the listener.
   */
  protected void handleNotification(NotificationListener listener,
                                    Notification notif,
                                    Object passback)
  {
    listener.handleNotification(notif, passback);
  }

  /**
   * Removes the specified listener from the list of recipients
   * of notifications from this bean.  This includes all combinations
   * of filters and passback objects registered for this listener.
   * For more specific removal of listeners, see the subinterface
   * {@link NotificationEmitter}.
   *
   * @param listener the listener to remove.
   * @throws ListenerNotFoundException if the specified listener
   *                                   is not registered with this bean.
   * @see #addNotificationListener(NotificationListener, NotificationFilter,
   *                               java.lang.Object)
   */
  public void removeNotificationListener(NotificationListener listener)
    throws ListenerNotFoundException
  {
    Iterator<ListenerData> it = listeners.iterator();
    boolean foundOne = false;
    while (it.hasNext())
      {
        if (it.next().getListener() == listener)
          {
            it.remove();
            foundOne = true;
          }
      }
    if (!foundOne)
      throw new ListenerNotFoundException("The specified listener, " + listener +
                                          "is not registered with this bean.");
  }

  /**
   * Removes the specified listener from the list of recipients
   * of notifications from this bean.  Only the first instance with
   * the supplied filter and passback object is removed.
   * <code>null</code> is used as a valid value for these parameters,
   * rather than as a way to remove all registration instances for
   * the specified listener; for this behaviour instead, see the details
   * of the same method in {@link NotificationBroadcaster}.
   *
   * @param listener the listener to remove.
   * @param filter the filter of the listener to remove.
   * @param passback the passback object of the listener to remove.
   * @throws ListenerNotFoundException if the specified listener
   *                                   is not registered with this bean.
   * @see #addNotificationListener(NotificationListener, NotificationFilter,
   *                               java.lang.Object)
   */
  public void removeNotificationListener(NotificationListener listener,
                                         NotificationFilter filter,
                                         Object passback)
    throws ListenerNotFoundException
  {
    if (!(listeners.remove(new ListenerData(listener, filter, passback))))
      {
        throw new ListenerNotFoundException("The specified listener, " + listener +
                                            " with filter " + filter +
                                            "and passback " + passback +
                                            ", is not registered with this bean.");
      }
  }

  /**
   * <p>
   * Performs delivery of the notification.  If an executor
   * was specified on construction, this will be used to call
   * {@link #handleNotification(NotificationListener, Notification,
   * Object)}.  If the executor is <code>null</code>, however,
   * this thread calls the method itself in order to perform a
   * synchronous dispatch of the notification to all eligible
   * listeners.
   * </p>
   * <p>
   * Prior to either process taking place, the listeners are filtered.
   * Notifications are only delivered if the filter is either
   * <code>null</code> or returns true from the
   * {@link NotificationFilter#isNotificationEnabled(Notification)}
   * method.
   * </p>
   *
   * @param notif the notification to send.
   */
  public void sendNotification(Notification notif)
  {
    for (ListenerData ldata : listeners)
      {
        NotificationFilter filter = ldata.getFilter();
        if (filter == null || filter.isNotificationEnabled(notif))
          {
            if (executor == null)
              try
                {
                  handleNotification(ldata.getListener(), notif,
                                     ldata.getPassback());
                }
              catch (Exception e) { /* Ignore */ }
            else
              executor.execute(new DispatchTask(ldata, notif));
          }
      }
  }

  /**
   * The dispatch task to be performed by an executor.
   */
  private final class DispatchTask
    implements Runnable
  {

    /**
     * The data on the listener being called.
     */
    private ListenerData ldata;

    /**
     * The notification to send.
     */
    private Notification notif;

    /**
     * Construct a new {@link DispatchTask}.
     *
     * @param ldata the listener data.
     * @param notif the notification to send.
     */
    public DispatchTask(ListenerData ldata,
                        Notification notif)
    {
      this.ldata = ldata;
      this.notif = notif;
    }

    /**
     * Dispatch the notification.
     */
    public void run()
    {
      try
        {
          handleNotification(ldata.getListener(), notif,
                             ldata.getPassback());
        }
      catch (Exception e) { /* Ignore */ }
    }
  }

}
