/* Observable.java -- an object to be observed
   Copyright (C) 1999, 2000, 2001, 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., 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.util;

/**
 * This class represents an object which is observable.  Other objects may
 * register their intent to be notified when this object changes; and when
 * this object does change, it will trigger the <code>update</code> method
 * of each observer.
 *
 * Note that the <code>notifyObservers()</code> method of this class is
 * unrelated to the <code>notify()</code> of Object.
 *
 * @author Warren Levy (warrenl@cygnus.com)
 * @author Eric Blake (ebb9@email.byu.edu)
 * @see Observer
 * @status updated to 1.4
 */
public class Observable
{
  /** Tracks whether this object has changed. */
  private boolean changed;

  /* List of the Observers registered as interested in this Observable. */
  private LinkedHashSet observers;

  /**
   * Constructs an Observable with zero Observers.
   */
  public Observable()
  {
    observers = new LinkedHashSet();
  }

  /**
   * Adds an Observer. If the observer was already added this method does
   * nothing.
   *
   * @param observer Observer to add
   * @throws NullPointerException if observer is null
   */
  public synchronized void addObserver(Observer observer)
  {
    if (observer == null)
      throw new NullPointerException("can't add null observer");
    observers.add(observer);
  }

  /**
   * Reset this Observable's state to unchanged. This is called automatically
   * by <code>notifyObservers</code> once all observers have been notified.
   *
   * @see #notifyObservers()
   */
  protected synchronized void clearChanged()
  {
    changed = false;
  }

  /**
   * Returns the number of observers for this object.
   *
   * @return number of Observers for this
   */
  public synchronized int countObservers()
  {
    return observers.size();
  }

  /**
   * Deletes an Observer of this Observable.
   *
   * @param victim Observer to delete
   */
  public synchronized void deleteObserver(Observer victim)
  {
    observers.remove(victim);
  }

  /**
   * Deletes all Observers of this Observable.
   */
  public synchronized void deleteObservers()
  {
    observers.clear();
  }

  /**
   * True if <code>setChanged</code> has been called more recently than
   * <code>clearChanged</code>.
   *
   * @return whether or not this Observable has changed
   */
  public synchronized boolean hasChanged()
  {
    return changed;
  }

  /**
   * If the Observable has actually changed then tell all Observers about it,
   * then reset state to unchanged.
   *
   * @see #notifyObservers(Object)
   * @see Observer#update(Observable, Object)
   */
  public void notifyObservers()
  {
    notifyObservers(null);
  }

  /**
   * If the Observable has actually changed then tell all Observers about it,
   * then reset state to unchanged. Note that though the order of
   * notification is unspecified in subclasses, in Observable it is in the
   * order of registration.
   *
   * @param obj argument to Observer's update method
   * @see Observer#update(Observable, Object)
   */
  public void notifyObservers(Object obj)
  {
    if (! hasChanged())
      return;
    // Create clone inside monitor, as that is relatively fast and still
    // important to keep threadsafe, but update observers outside of the
    // lock since update() can call arbitrary code.
    Set s;
    synchronized (this)
      {
        s = (Set) observers.clone();
      }
    int i = s.size();
    Iterator iter = s.iterator();
    while (--i >= 0)
      ((Observer) iter.next()).update(this, obj);
    clearChanged();
  }

  /**
   * Marks this Observable as having changed.
   */
  protected synchronized void setChanged()
  {
    changed = true;
  }
}
