/* 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., 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.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)
  {
    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;
  }
}
