/* VetoableChangeSupport.java -- support to manage vetoable change listeners
   Copyright (C) 1998, 1999, 2000, 2002 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;

/**
 * VetoableChangeSupport makes it easy to fire vetoable 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 VetoableChangeSupport implements Serializable
{
  /**
   * Compatible with JDK 1.1+.
   */
  private static final long serialVersionUID = -5090210921595982017L;

  /**
   * Maps property names (String) to named listeners (VetoableChangeSupport).
   * 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 final int vetoableChangeSupportSerializedDataVersion = 2;

  /**
   * The list of all registered vetoable 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 VetoableChangeSupport to work with a specific source bean.
   *
   * @param source the source bean to use
   * @throws NullPointerException if source is null
   */
  public VetoableChangeSupport(Object source)
  {
    this.source = source;
    if (source == null)
      throw new NullPointerException();
  }

  /**
   * Adds a VetoableChangeListener to the list of global listeners. All
   * vetoable 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
   * vetoable change. Adding a null listener may cause a NullPointerException
   * down the road. This method will unwrap a VetoableChangeListenerProxy,
   * registering the underlying delegate to the named property list.
   *
   * @param l the listener to add
   */
  public synchronized void addVetoableChangeListener(VetoableChangeListener l)
  {
    if (l instanceof VetoableChangeListenerProxy)
      {
        VetoableChangeListenerProxy p = (VetoableChangeListenerProxy) l;
        addVetoableChangeListener(p.propertyName,
                                  (VetoableChangeListener) p.getListener());
      }
    else
      {
        if (listeners == null)
          listeners = new Vector();
        listeners.add(l);
      }
  }

  /**
   * Removes a VetoableChangeListener 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
   * VetoableChangeListenerProxy, removing the underlying delegate from the
   * named property list.
   *
   * @param l the listener to remove
   */
  public synchronized void
    removeVetoableChangeListener(VetoableChangeListener l)
  {
    if (l instanceof VetoableChangeListenerProxy)
      {
        VetoableChangeListenerProxy p = (VetoableChangeListenerProxy) l;
        removeVetoableChangeListener(p.propertyName,
                                     (VetoableChangeListener) p.getListener());
      }
    else if (listeners != null)
      {
        listeners.remove(l);
        if (listeners.isEmpty())
          listeners = null;
      }
  }

  /**
   * Returns an array of all registered vetoable change listeners. Those that
   * were registered under a name will be wrapped in a
   * <code>VetoableChangeListenerProxy</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 VetoableChangeListenerProxy
   * @since 1.4
   */
  public synchronized VetoableChangeListener[] getVetoableChangeListeners()
  {
    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 = ((VetoableChangeSupport) e.getValue()).listeners;
            int j = v.size();
            while (--j >= 0)
              list.add(new VetoableChangeListenerProxy
                (name, (VetoableChangeListener) v.get(j)));
          }
      }
    return (VetoableChangeListener[])
      list.toArray(new VetoableChangeListener[list.size()]);
  }

  /**
   * Adds a VetoableChangeListener 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 vetoable 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 VetoableChangeListenerProxy, 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 addVetoableChangeListener(String propertyName,
                                                     VetoableChangeListener l)
  {
    while (l instanceof VetoableChangeListenerProxy)
      {
        VetoableChangeListenerProxy p = (VetoableChangeListenerProxy) l;
        if (propertyName == null ? p.propertyName != null
            : ! propertyName.equals(p.propertyName))
          return;
        l = (VetoableChangeListener) p.getListener();
      }
    VetoableChangeSupport s = null;
    if (children == null)
      children = new Hashtable();
    else
      s = (VetoableChangeSupport) children.get(propertyName);
    if (s == null)
      {
        s = new VetoableChangeSupport(source);
        s.listeners = new Vector();
        children.put(propertyName, s);
      }
    s.listeners.add(l);
  }

  /**
   * Removes a VetoableChangeListener 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
   * VetoableChangeListenerProxy, 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
    removeVetoableChangeListener(String propertyName, VetoableChangeListener l)
  {
    if (children == null)
      return;
    VetoableChangeSupport s
      = (VetoableChangeSupport) children.get(propertyName);
    if (s == null)
      return;
    while (l instanceof VetoableChangeListenerProxy)
      {
        VetoableChangeListenerProxy p = (VetoableChangeListenerProxy) l;
        if (propertyName == null ? p.propertyName != null
            : ! propertyName.equals(p.propertyName))
          return;
        l = (VetoableChangeListener) p.getListener();
      }
    s.listeners.remove(l);
    if (s.listeners.isEmpty())
      {
        children.remove(propertyName);
        if (children.isEmpty())
          children = null;
      }
  }

  /**
   * Returns an array of all vetoable 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 VetoableChangeListener[]
    getVetoableChangeListeners(String propertyName)
  {
    if (children == null)
      return new VetoableChangeListener[0];
    VetoableChangeSupport s
      = (VetoableChangeSupport) children.get(propertyName);
    if (s == null)
      return new VetoableChangeListener[0];
    return (VetoableChangeListener[])
      s.listeners.toArray(new VetoableChangeListener[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. If the change is vetoed, a new event is fired to notify
   * listeners about the rollback before the exception is thrown.
   *
   * @param propertyName the name of the property that changed
   * @param oldVal the old value
   * @param newVal the new value
   * @throws PropertyVetoException if the change is vetoed by a listener
   */
  public void fireVetoableChange(String propertyName,
                                 Object oldVal, Object newVal)
    throws PropertyVetoException
  {
    fireVetoableChange(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.
   * If the change is vetoed, a new event is fired to notify listeners about
   * the rollback before the exception is thrown.
   *
   * @param propertyName the name of the property that changed
   * @param oldVal the old value
   * @param newVal the new value
   * @throws PropertyVetoException if the change is vetoed by a listener
   */
  public void fireVetoableChange(String propertyName, int oldVal, int newVal)
    throws PropertyVetoException
  {
    if (oldVal != newVal)
      fireVetoableChange(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.
   * If the change is vetoed, a new event is fired to notify listeners about
   * the rollback before the exception is thrown.
   *
   * @param propertyName the name of the property that changed
   * @param oldVal the old value
   * @param newVal the new value
   * @throws PropertyVetoException if the change is vetoed by a listener
   */
  public void fireVetoableChange(String propertyName,
                                 boolean oldVal, boolean newVal)
    throws PropertyVetoException
  {
    if (oldVal != newVal)
      fireVetoableChange(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. If the change is vetoed, a new event
   * is fired to notify listeners about the rollback before the exception is
   * thrown.
   *
   * @param event the event to fire
   * @throws NullPointerException if event is null
   * @throws PropertyVetoException if the change is vetoed by a listener
   */
  public void fireVetoableChange(PropertyChangeEvent event)
    throws PropertyVetoException
  {
    if (event.oldValue != null && event.oldValue.equals(event.newValue))
      return;
    Vector v = listeners; // Be thread-safe.
    if (v != null)
      {
        int i = v.size();
        try
          {
            while (--i >= 0)
              ((VetoableChangeListener) v.get(i)).vetoableChange(event);
          }
        catch (PropertyVetoException e)
          {
            event = event.rollback();
            int limit = i;
            i = v.size();
            while (--i >= limit)
              ((VetoableChangeListener) v.get(i)).vetoableChange(event);
            throw e;
          }
      }
    Hashtable h = children; // Be thread-safe.
    if (h != null && event.propertyName != null)
      {
        VetoableChangeSupport s
          = (VetoableChangeSupport) h.get(event.propertyName);
        if (s != null)
          {
            Vector v1 = s.listeners; // Be thread-safe.
            int i = v1 == null ? 0 : v1.size();
            try
              {
                while (--i >= 0)
                  ((VetoableChangeListener) v1.get(i)).vetoableChange(event);
              }
            catch (PropertyVetoException e)
              {
                event = event.rollback();
                int limit = i;
                i = v.size();
                while (--i >= 0)
                  ((VetoableChangeListener) v.get(i)).vetoableChange(event);
                i = v1.size();
                while (--i >= limit)
                  ((VetoableChangeListener) v1.get(i)).vetoableChange(event);
                throw e;
              }
          }
      }
  }

  /**
   * 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 vetoable 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 vetoableChangeSupportSerializedDataVersion 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 vetoable 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();
    VetoableChangeListener l = (VetoableChangeListener) s.readObject();
    while (l != null)
      {
        addVetoableChangeListener(l);
        l = (VetoableChangeListener) 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();
            VetoableChangeSupport vcs = (VetoableChangeSupport) e.getValue();
            if (vcs.listeners == null)
              vcs.listeners = new Vector();
            if (vcs.children != null)
              vcs.listeners.addAll
                (Arrays.asList(vcs.getVetoableChangeListeners(name)));
            if (vcs.listeners.size() == 0)
              iter.remove();
            else
              vcs.children = null;
          }
        if (children.size() == 0)
          children = null;
      }
  }
} // class VetoableChangeSupport
