/* VetoableChangeSupport.java -- support to manage vetoable 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;

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