/* PropertyChangeSupport.java -- support to manage property change listeners
   Copyright (C) 1998, 1999, 2000, 2002, 2005, 2006
   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 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 is silently ignored.
   * 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 == null)
      return;

    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 is silently ignored. 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)
  {
    if (l == 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();
      }
    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, or
   * propertyName is null, this returns an empty array.
   *
   * @return the array of registered listeners
   * @since 1.4
   */
  public synchronized PropertyChangeListener[]
    getPropertyChangeListeners(String propertyName)
  {
    if (children == null || propertyName == 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,
                                                 Integer.valueOf(oldVal),
                                                 Integer.valueOf(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);
          }
      }
  }

  /**
   * Fire an indexed property change event.  This will only fire
   * an event if the old and new values are not equal and not null. 
   * @param name the name of the property which changed
   * @param index the index of the property which changed
   * @param oldValue the old value of the property
   * @param newValue the new value of the property
   * @since 1.5
   */
  public void fireIndexedPropertyChange(String name, int index,
                                        Object oldValue, Object newValue)
  {
    // Argument checking is done in firePropertyChange(PropertyChangeEvent) .
    firePropertyChange(new IndexedPropertyChangeEvent(source, name,
                                                      oldValue, newValue,
                                                      index));
  }

  /**
   * Fire an indexed property change event.  This will only fire
   * an event if the old and new values are not equal.
   * @param name the name of the property which changed
   * @param index the index of the property which changed
   * @param oldValue the old value of the property
   * @param newValue the new value of the property
   * @since 1.5
   */
  public void fireIndexedPropertyChange(String name, int index,
                                        int oldValue, int newValue)
  {
    if (oldValue != newValue)
      fireIndexedPropertyChange(name, index, Integer.valueOf(oldValue),
                                Integer.valueOf(newValue));
  }

  /**
   * Fire an indexed property change event.  This will only fire
   * an event if the old and new values are not equal.
   * @param name the name of the property which changed
   * @param index the index of the property which changed
   * @param oldValue the old value of the property
   * @param newValue the new value of the property
   * @since 1.5
   */
  public void fireIndexedPropertyChange(String name, int index,
                                        boolean oldValue, boolean newValue)
  {
    if (oldValue != newValue)
      fireIndexedPropertyChange(name, index, Boolean.valueOf(oldValue),
                                Boolean.valueOf(newValue));
  }

  /**
   * 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
   */
  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
