/* PropertyChangeSupport.java -- support to manage property change listeners
   Copyright (C) 1998, 1999, 2000, 2002, 2005  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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 java.beans;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Vector;

/**
 * PropertyChangeSupport makes it easy to fire property change events and
 * handle listeners. It allows chaining of listeners, as well as filtering
 * by property name. In addition, it will serialize only those listeners
 * which are serializable, ignoring the others without problem. This class
 * is thread-safe.
 *
 * @author John Keiser
 * @author Eric Blake (ebb9@email.byu.edu)
 * @since 1.1
 * @status updated to 1.4
 */
public class PropertyChangeSupport implements Serializable
{
  /**
   * Compatible with JDK 1.1+.
   */
  private static final long serialVersionUID = 6401253773779951803L;

  /**
   * Maps property names (String) to named listeners (PropertyChangeSupport).
   * If this is a child instance, this field will be null.
   *
   * @serial the map of property names to named listener managers
   * @since 1.2
   */
  private Hashtable children;

  /**
   * The non-null source object for any generated events.
   *
   * @serial the event source
   */
  private final Object source;

  /**
   * A field to compare serialization versions - this class uses version 2.
   *
   * @serial the serialization format
   */
  private static final int propertyChangeSupportSerializedDataVersion = 2;

  /**
   * The list of all registered property listeners. If this instance was
   * created by user code, this only holds the global listeners (ie. not tied
   * to a name), and may be null. If it was created by this class, as a
   * helper for named properties, then this vector will be non-null, and this
   * instance appears as a value in the <code>children</code> hashtable of
   * another instance, so that the listeners are tied to the key of that
   * hashtable entry.
   */
  private transient Vector listeners;

  /**
   * Create a PropertyChangeSupport to work with a specific source bean.
   *
   * @param source the source bean to use
   * @throws NullPointerException if source is null
   */
  public PropertyChangeSupport(Object source)
  {
    this.source = source;
    if (source == null)
      throw new NullPointerException();
  }

  /**
   * Adds a PropertyChangeListener to the list of global listeners. All
   * property change events will be sent to this listener. The listener add
   * is not unique: that is, <em>n</em> adds with the same listener will
   * result in <em>n</em> events being sent to that listener for every
   * property change. Adding a null listener may cause a NullPointerException
   * down the road. This method will unwrap a PropertyChangeListenerProxy,
   * registering the underlying delegate to the named property list.
   *
   * @param l the listener to add
   */
  public synchronized void addPropertyChangeListener(PropertyChangeListener l)
  {
    if (l instanceof PropertyChangeListenerProxy)
      {
        PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l;
        addPropertyChangeListener(p.propertyName,
                                  (PropertyChangeListener) p.getListener());
      }
    else
      {
        if (listeners == null)
          listeners = new Vector();
        listeners.add(l);
      }
  }

  /**
   * Removes a PropertyChangeListener from the list of global listeners. If
   * any specific properties are being listened on, they must be deregistered
   * by themselves; this will only remove the general listener to all
   * properties. If <code>add()</code> has been called multiple times for a
   * particular listener, <code>remove()</code> will have to be called the
   * same number of times to deregister it. This method will unwrap a
   * PropertyChangeListenerProxy, removing the underlying delegate from the
   * named property list.
   *
   * @param l the listener to remove
   */
  public synchronized void
    removePropertyChangeListener(PropertyChangeListener l)
  {
    if (l instanceof PropertyChangeListenerProxy)
      {
        PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l;
        removePropertyChangeListener(p.propertyName,
                                     (PropertyChangeListener) p.getListener());
      }
    else if (listeners != null)
      {
        listeners.remove(l);
        if (listeners.isEmpty())
          listeners = null;
      }
  }

  /**
   * Returns an array of all registered property change listeners. Those that
   * were registered under a name will be wrapped in a
   * <code>PropertyChangeListenerProxy</code>, so you must check whether the
   * listener is an instance of the proxy class in order to see what name the
   * real listener is registered under. If there are no registered listeners,
   * this returns an empty array.
   *
   * @return the array of registered listeners
   * @see PropertyChangeListenerProxy
   * @since 1.4
   */
  public synchronized PropertyChangeListener[] getPropertyChangeListeners()
  {
    ArrayList list = new ArrayList();
    if (listeners != null)
      list.addAll(listeners);
    if (children != null)
      {
        int i = children.size();
        Iterator iter = children.entrySet().iterator();
        while (--i >= 0)
          {
            Entry e = (Entry) iter.next();
            String name = (String) e.getKey();
            Vector v = ((PropertyChangeSupport) e.getValue()).listeners;
            int j = v.size();
            while (--j >= 0)
              list.add(new PropertyChangeListenerProxy
                (name, (PropertyChangeListener) v.get(j)));
          }
      }
    return (PropertyChangeListener[])
      list.toArray(new PropertyChangeListener[list.size()]);
  }

  /**
   * Adds a PropertyChangeListener listening on the specified property. Events
   * will be sent to the listener only if the property name matches. The
   * listener add is not unique; that is, <em>n</em> adds on a particular
   * property for a particular listener will result in <em>n</em> events
   * being sent to that listener when that property is changed. The effect is
   * cumulative, too; if you are registered to listen to receive events on
   * all property changes, and then you register on a particular property,
   * you will receive change events for that property twice. Adding a null
   * listener may cause a NullPointerException down the road. This method
   * will unwrap a PropertyChangeListenerProxy, registering the underlying
   * delegate to the named property list if the names match, and discarding
   * it otherwise.
   *
   * @param propertyName the name of the property to listen on
   * @param l the listener to add
   * @throws NullPointerException if propertyName is null
   */
  public synchronized void addPropertyChangeListener(String propertyName,
                                                     PropertyChangeListener l)
  {
    while (l instanceof PropertyChangeListenerProxy)
      {
        PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l;
        if (propertyName == null ? p.propertyName != null
            : ! propertyName.equals(p.propertyName))
          return;
        l = (PropertyChangeListener) p.getListener();
      }
    PropertyChangeSupport s = null;
    if (children == null)
      children = new Hashtable();
    else
      s = (PropertyChangeSupport) children.get(propertyName);
    if (s == null)
      {
        s = new PropertyChangeSupport(source);
        s.listeners = new Vector();
        children.put(propertyName, s);
      }
    s.listeners.add(l);
  }

  /**
   * Removes a PropertyChangeListener from listening to a specific property.
   * If <code>add()</code> has been called multiple times for a particular
   * listener on a property, <code>remove()</code> will have to be called the
   * same number of times to deregister it. This method will unwrap a
   * PropertyChangeListenerProxy, removing the underlying delegate from the
   * named property list if the names match.
   *
   * @param propertyName the property to stop listening on
   * @param l the listener to remove
   * @throws NullPointerException if propertyName is null
   */
  public synchronized void
    removePropertyChangeListener(String propertyName, PropertyChangeListener l)
  {
    if (children == null)
      return;
    PropertyChangeSupport s
      = (PropertyChangeSupport) children.get(propertyName);
    if (s == null)
      return;
    while (l instanceof PropertyChangeListenerProxy)
      {
        PropertyChangeListenerProxy p = (PropertyChangeListenerProxy) l;
        if (propertyName == null ? p.propertyName != null
            : ! propertyName.equals(p.propertyName))
          return;
        l = (PropertyChangeListener) p.getListener();
      }
    s.listeners.remove(l);
    if (s.listeners.isEmpty())
      {
        children.remove(propertyName);
        if (children.isEmpty())
          children = null;
      }
  }

  /**
   * Returns an array of all property change listeners registered under the
   * given property name. If there are no registered listeners, this returns
   * an empty array.
   *
   * @return the array of registered listeners
   * @throws NullPointerException if propertyName is null
   * @since 1.4
   */
  public synchronized PropertyChangeListener[]
    getPropertyChangeListeners(String propertyName)
  {
    if (children == null)
      return new PropertyChangeListener[0];
    PropertyChangeSupport s
      = (PropertyChangeSupport) children.get(propertyName);
    if (s == null)
      return new PropertyChangeListener[0];
    return (PropertyChangeListener[])
      s.listeners.toArray(new PropertyChangeListener[s.listeners.size()]);
  }

  /**
   * Fire a PropertyChangeEvent containing the old and new values of the
   * property to all the global listeners, and to all the listeners for the
   * specified property name. This does nothing if old and new are non-null
   * and equal.
   *
   * @param propertyName the name of the property that changed
   * @param oldVal the old value
   * @param newVal the new value
   */
  public void firePropertyChange(String propertyName,
                                 Object oldVal, Object newVal)
  {
    firePropertyChange(new PropertyChangeEvent(source, propertyName,
                                               oldVal, newVal));
  }

  /**
   * Fire a PropertyChangeEvent containing the old and new values of the
   * property to all the global listeners, and to all the listeners for the
   * specified property name. This does nothing if old and new are equal.
   *
   * @param propertyName the name of the property that changed
   * @param oldVal the old value
   * @param newVal the new value
   */
  public void firePropertyChange(String propertyName, int oldVal, int newVal)
  {
    if (oldVal != newVal)
      firePropertyChange(new PropertyChangeEvent(source, propertyName,
                                                 new Integer(oldVal),
                                                 new Integer(newVal)));
  }

  /**
   * Fire a PropertyChangeEvent containing the old and new values of the
   * property to all the global listeners, and to all the listeners for the
   * specified property name. This does nothing if old and new are equal.
   *
   * @param propertyName the name of the property that changed
   * @param oldVal the old value
   * @param newVal the new value
   */
  public void firePropertyChange(String propertyName,
                                 boolean oldVal, boolean newVal)
  {
    if (oldVal != newVal)
      firePropertyChange(new PropertyChangeEvent(source, propertyName,
                                                 Boolean.valueOf(oldVal),
                                                 Boolean.valueOf(newVal)));
  }

  /**
   * Fire a PropertyChangeEvent to all the global listeners, and to all the
   * listeners for the specified property name. This does nothing if old and
   * new values of the event are equal.
   *
   * @param event the event to fire
   * @throws NullPointerException if event is null
   */
  public void firePropertyChange(PropertyChangeEvent event)
  {
    if (event.oldValue != null && event.oldValue.equals(event.newValue))
      return;
    Vector v = listeners; // Be thread-safe.
    if (v != null)
      {
        int i = v.size();
        while (--i >= 0)
          ((PropertyChangeListener) v.get(i)).propertyChange(event);
      }
    Hashtable h = children; // Be thread-safe.
    if (h != null && event.propertyName != null)
      {
        PropertyChangeSupport s
          = (PropertyChangeSupport) h.get(event.propertyName);
        if (s != null)
          {
            v = s.listeners; // Be thread-safe.
            int i = v == null ? 0 : v.size();
            while (--i >= 0)
              ((PropertyChangeListener) v.get(i)).propertyChange(event);
          }
      }
  }

  /**
   * Tell whether the specified property is being listened on or not. This
   * will only return <code>true</code> if there are listeners on all
   * properties or if there is a listener specifically on this property.
   *
   * @param propertyName the property that may be listened on
   * @return whether the property is being listened on
   * @throws NullPointerException if propertyName is null
   */
  public synchronized boolean hasListeners(String propertyName)
  {
    return listeners != null || (children != null
                                 && children.get(propertyName) != null);
  }

  /**
   * Saves the state of the object to the stream.
   *
   * @param s the stream to write to
   * @throws IOException if anything goes wrong
   * @serialData this writes out a null-terminated list of serializable
   *             global property change listeners (the listeners for a named
   *             property are written out as the global listeners of the
   *             children, when the children hashtable is saved)
   */
  private synchronized void writeObject(ObjectOutputStream s)
    throws IOException
  {
    s.defaultWriteObject();
    if (listeners != null)
      {
        int i = listeners.size();
        while (--i >= 0)
          if (listeners.get(i) instanceof Serializable)
            s.writeObject(listeners.get(i));
      }
    s.writeObject(null);
  }

  /**
   * Reads the object back from stream (deserialization).
   *
   * XXX Since serialization for 1.1 streams was not documented, this may
   * not work if propertyChangeSupportSerializedDataVersion is 1.
   *
   * @param s the stream to read from
   * @throws IOException if reading the stream fails
   * @throws ClassNotFoundException if deserialization fails
   * @serialData this reads in a null-terminated list of serializable
   *             global property change listeners (the listeners for a named
   *             property are written out as the global listeners of the
   *             children, when the children hashtable is saved)
   */
  private void readObject(ObjectInputStream s)
    throws IOException, ClassNotFoundException
  {
    s.defaultReadObject();
    PropertyChangeListener l = (PropertyChangeListener) s.readObject();
    while (l != null)
      {
        addPropertyChangeListener(l);
        l = (PropertyChangeListener) s.readObject();
      }
    // Sun is not as careful with children as we are, and lets some proxys
    // in that can never receive events. So, we clean up anything that got
    // serialized, to make sure our invariants hold.
    if (children != null)
      {
        int i = children.size();
        Iterator iter = children.entrySet().iterator();
        while (--i >= 0)
          {
            Entry e = (Entry) iter.next();
            String name = (String) e.getKey();
            PropertyChangeSupport pcs = (PropertyChangeSupport) e.getValue();
            if (pcs.listeners == null)
              pcs.listeners = new Vector();
            if (pcs.children != null)
              pcs.listeners.addAll
                (Arrays.asList(pcs.getPropertyChangeListeners(name)));
            if (pcs.listeners.size() == 0)
              iter.remove();
            else
              pcs.children = null;
          }
        if (children.size() == 0)
          children = null;
      }
  }
} // class PropertyChangeSupport
