Package ucar.nc2.util

Source Code of ucar.nc2.util.ListenerManager

/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation.  Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.nc2.util;

import net.jcip.annotations.ThreadSafe;
import org.slf4j.Logger;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;

/**
* Helper class for managing event listeners.
* It is thread safe, but better not to be adding/deleting listeners while sending events.
*
* Example:
* <pre>
*
  private void createListenerManager() {
    lm = new ListenerManager(
            "ucar.nc2.util.DatasetCollectionManager$EventListener",
            "ucar.nc2.util.DatasetCollectionManager$Event",
            "setMessage");
  }

  public void addEventListener(EventListener l) {
    lm.addListener(l);
  }

  public void removeEventListener(EventListener l) {
    lm.removeListener(l);
  }

  public class Event extends java.util.EventObject {
    private String message;

    Event(String message) {
      super(DatasetCollectionManager.this);
      this.message = message;
    }

    public String getMessage() {
      return message;
    }
  }

  public static interface EventListener {
    public void setMessage(DatasetCollectionManager.Event event);
  }

lm.sendEvent(event);
</pre>

*
* @author John Caron
*/
@ThreadSafe
public class ListenerManager {
  static private final Logger logger = org.slf4j.LoggerFactory.getLogger(ListenerManager.class);

  private final List<Object> listeners = new CopyOnWriteArrayList<Object>(); // cf http://www.ibm.com/developerworks/java/library/j-jtp07265/index.html
  private final java.lang.reflect.Method method;
  private boolean hasListeners = false;
  private boolean enabled = true;

  /**
   * Constructor.
   *
   * @param listener_class the name of the EventListener class, eg "ucar.unidata.ui.UIChangeListener"
   * @param event_class    the name of the Event class, eg "ucar.unidata.ui.UIChangeEvent"
   * @param method_name    the name of the EventListener method, eg "processChange". <pre>
   *                          This method must have the signature     public void method_name( event_class e) </pre>
   */
  public ListenerManager(String listener_class, String event_class, String method_name) {

    try {
      Class lc = Class.forName(listener_class);
      Class ec = Class.forName(event_class);
      Class[] params = new Class[1];
      params[0] = ec;
      this.method = lc.getMethod(method_name, params);

    } catch (Exception ee) {
      logger.error("ListenerManager failed on " + listener_class + "." + method_name + "( " + event_class + " )", ee);
      throw new RuntimeException(ee);
    }

  }

  public void setEnabled(boolean enabled) {
    this.enabled = enabled;
  }

  public boolean getEnabled() {
    return enabled;
  }

  /**
   * Add a listener.
   *
   * @param l listener must be of type "listener_class"
   */
  public synchronized void addListener(Object l) {
    if (!listeners.contains(l)) {
      listeners.add(l);
      hasListeners = true;
    } else
      logger.warn("ListenerManager.addListener already has Listener " + l);
  }

  /**
   * Remove a listener.
   * @param l listener must be of type "listener_class"
   */
  public synchronized void removeListener(Object l) {
    if (listeners.contains(l)) {
      listeners.remove(l);
      hasListeners = (listeners.size() > 0);
    } else
      logger.warn("ListenerManager.removeListener couldnt find Listener " + l);
  }

  public boolean hasListeners() {
    return hasListeners;
  }

  /**
   * Send an event to all registered listeners. If an exception is thrown, remove
   * the Listener from the list
   *
   * @param event the event to be sent: public void method_name( event_class event)
   */
  public void sendEvent(java.util.EventObject event) {
    if (!hasListeners || !enabled)
      return;

    Object[] args = new Object[1];
    args[0] = event;

    // send event to all listeners
    ListIterator iter = listeners.listIterator();
    while (iter.hasNext()) {
      Object client = iter.next();
      try {
        method.invoke(client, args);
      } catch (IllegalAccessException e) {
        logger.error("ListenerManager IllegalAccessException", e);
        iter.remove();
      } catch (IllegalArgumentException e) {
        logger.error("ListenerManager IllegalArgumentException", e);
        iter.remove();
      } catch (InvocationTargetException e) {
        logger.error("ListenerManager InvocationTargetException on " + method+ " threw exception " + e.getTargetException(), e);
        //iter.remove();
        //e.printStackTrace();
      }
    }
  }

  /**
   * Send an event to all registered listeners, except the named one.
   *
   * @param event the event to be sent: public void method_name( event_class event)
   */
  public void sendEventExcludeSource(java.util.EventObject event) {
    if (!hasListeners || !enabled)
      return;

    Object source = event.getSource();
    Object[] args = new Object[1];
    args[0] = event;

    // send event to all listeners except the source
    ListIterator iter = listeners.listIterator();
    while (iter.hasNext()) {
      Object client = iter.next();
      if (client == source)
        continue;

      try {
        method.invoke(client, args);
      } catch (IllegalAccessException e) {
        iter.remove();
        logger.error("ListenerManager IllegalAccessException", e);
      } catch (IllegalArgumentException e) {
        iter.remove();
        logger.error("ListenerManager IllegalArgumentException", e);
      } catch (InvocationTargetException e) {
        iter.remove();
        logger.error("ListenerManager InvocationTargetException on " + method+ " threw exception " + e.getTargetException(), e);
      }
    }
  }

}
TOP

Related Classes of ucar.nc2.util.ListenerManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.