/* java.beans.beancontext.BeanContextChildSupport
   Copyright (C) 1999 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.beancontext;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;
import java.io.Serializable;

/**
 * Support for creating a <code>BeanContextChild</code>.
 * This class contains the most common implementations of the methods in
 * the <code>BeanContextChild</code>
 *
 * @specnote This class is not very well specified.  I had to "fill in the
 *           blanks" in most places with what I thought was reasonable
 *           behavior.  If there are problems, let me know.
 *
 * @author John Keiser
 * @since 1.2
 * @see java.beans.beancontext.BeanContextChild
 */
public class BeanContextChildSupport
  implements BeanContextChild, BeanContextServicesListener, Serializable
{
  static final long serialVersionUID = 6328947014421475877L;

        /**
         * The peer on which to perform <code>set</code> actions.
         * This is here so that this class can be used as a peer.
         * <P>
         *
         * When extending this class, this variable will be set to
         * <code>this</code>.
         */
        public BeanContextChild beanContextChildPeer;

        /**
         * The parent <code>BeanContext</code>.
         */
        protected transient BeanContext beanContext;

        /**
         * If <code>setBeanContext()</code> was vetoed once before, this
         * is set to <code>true</code> so that the next time, vetoes will
         * be ignored.
         */
        protected transient boolean rejectedSetBCOnce;

        /**
         * Listeners are registered here and events are fired through here.
         */
        protected PropertyChangeSupport pcSupport;

        /**
         * Listeners are registered here and events are fired through here.
         */
        protected VetoableChangeSupport vcSupport;

        /**
         * Create a new <code>BeanContextChildSupport</code> with itself as the peer.
         * This is meant to be used when you subclass
         * <code>BeanContextChildSupport</code> to create your child.
         */
        public BeanContextChildSupport()
  {
                this (null);
        }

        /**
         * Create a new <code>BeanContextChildSupport</code> with the specified peer.
         * @param peer the peer to use, or <code>null</code> to specify
         *        <code>this</code>.
         */
        public BeanContextChildSupport (BeanContextChild peer)
  {
                if (peer == null)
      {
        peer = this;
      }

                beanContextChildPeer = peer;
                pcSupport = new PropertyChangeSupport (peer);
                vcSupport = new VetoableChangeSupport (peer);
        }

        /**
         * Set the parent <code>BeanContext</code>.
         * <P>
         *
         * When this Object is being added to a new BeanContext or moved
         * from an old one, a non-null value will be passed in.
         * <P>
         *
         * When this Object is being removed from the current
         * <code>BeanContext</code>, <code>setBeanContext()</code> will
         * receive the parameter <code>null</code>.
         * <P>
         *
         * Order of events:
         * <OL>
         *   <LI>
         *     If the new <code>BeanContext</code> is the same as the old
         *     one, nothing happens.
         *   </LI>
         *   <LI>
         *     If the change has not been rejected or vetoed before, call
         *     <code>validatePendingSetBeanContext()</code>.  If this call
         *     returns <code>false</code>, the change is rejected and a
         *     <code>PropertyVetoException</code> is thrown.
         *   </LI>
         *   <LI>
         *     If the change has not been rejected or vetoed before,
         *     <code>VetoableChangeEvent</code>s are fired with the name
         *     <code>"beanContext"</code>, using the
         *     <code>fireVetoableChange()</code> method.  If a veto
         *     occurs, reversion events are fired using the same method,
         *     the change is rejected, and the veto is rethrown.
         *   </LI>
         *   <LI>
         *     <code>releaseBeanContextResources()</code> is called.
         *   </LI>
         *   <LI>
         *     The change is made.
         *   </LI>
         *   <LI>
         *     <code>PropertyChangeEvent</code>s are fired using the
         *     <code>firePropertyChange()</code> method.
         *   </LI>
         *   <LI>
         *     <code>initializeBeanContextResources()</code> is called.
         *   </LI>
         * </OL>
         * <P>
         *
         * @param newBeanContext the new parent for the
         *        <code>BeanContextChild</code>, or <code>null</code> to
         *        signify removal from a tree.
         * @exception PropertyVetoException if the
         *            <code>BeanContextChild</code> implementor does not
         *            wish to have its parent changed.
         */
  public void setBeanContext(BeanContext newBeanContext)
    throws PropertyVetoException
  {
    synchronized (beanContextChildPeer)
      {
        if (newBeanContext == beanContext)
          return;

        if (!rejectedSetBCOnce)
          {
            if (!validatePendingSetBeanContext (newBeanContext))
              {
                rejectedSetBCOnce = true;
                throw new PropertyVetoException ("validatePendingSetBeanContext() rejected change",
                                                 new PropertyChangeEvent(beanContextChildPeer, "beanContext", beanContext, newBeanContext));
              }

            try
              {
                fireVetoableChange ("beanContext", beanContext, newBeanContext);
              }
            catch (PropertyVetoException e)
              {
                rejectedSetBCOnce = true;
                throw e;
              }
          }

                        releaseBeanContextResources ();

                        beanContext = newBeanContext;
                        rejectedSetBCOnce = false;

                        firePropertyChange ("beanContext", beanContext, newBeanContext);

                        initializeBeanContextResources ();
                }
        }

        /**
         * Get the parent <code>BeanContext</code>.
         * @return the parent <code>BeanContext</code>.
         */
        public BeanContext getBeanContext()
  {
                return beanContext;
        }

        /**
         * Get the peer (or <code>this</code> if there is no peer).
         * @return the peer, or <code>this</code> if there is no peer.
         */
        public BeanContextChild getBeanContextChildPeer() {
                return beanContextChildPeer;
        }

        /**
         * Determine whether there is a peer.
         * This is true iff <code>getBeanContextChildPeer() == this</code>.
         * @return whether there is a peer.
         */
        public boolean isDelegated() {
                return beanContextChildPeer == this;
        }

        /**
         * Add a listener that will be notified when a specific property changes.
         * @param propertyName the name of the property to listen on.
         * @param listener the listener to listen on the property.
         */
        public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
                pcSupport.addPropertyChangeListener(propertyName, listener);
        }

        /**
         * Remove a listener to a certain property.
         *
         * @param propertyName the name of the property being listened on.
         * @param listener the listener listening on the property.
         */
        public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
                pcSupport.removePropertyChangeListener(propertyName, listener);
        }

        /**
         * Add a listener that will be notified when a specific property
         * change is requested (a PropertyVetoException may be thrown) as
         * well as after the change is successfully made.
         *
         * @param propertyName the name of the property to listen on.
         * @param listener the listener to listen on the property.
         */
        public void addVetoableChangeListener(String propertyName, VetoableChangeListener listener) {
                vcSupport.addVetoableChangeListener(propertyName, listener);
        }

        /**
         * Remove a listener to a certain property.
         *
         * @param propertyName the name of the property being listened on
         * @param listener the listener listening on the property.
         */
        public void removeVetoableChangeListener(String propertyName, VetoableChangeListener listener) {
                vcSupport.removeVetoableChangeListener(propertyName, listener);
        }

        /**
         * Fire a property change.
         *
         * @param propertyName the name of the property that changed
         * @param oldVal the old value of the property
         * @param newVal the new value of the property
         */
        public void firePropertyChange(String propertyName, Object oldVal, Object newVal) {
                pcSupport.firePropertyChange(propertyName, oldVal, newVal);
        }

        /**
         * Fire a vetoable property change.
         *
         * @param propertyName the name of the property that changed
         * @param oldVal the old value of the property
         * @param newVal the new value of the property
         * @exception PropertyVetoException if the change is vetoed.
         */
        public void fireVetoableChange(String propertyName, Object oldVal, Object newVal)
                        throws PropertyVetoException {
                vcSupport.fireVetoableChange(propertyName, oldVal, newVal);
        }

        /**
         * Called by <code>BeanContextServices.revokeService()</code> to indicate that a service has been revoked.
         * If you have a reference to such a service, it should be
         * discarded and may no longer function properly.
         * <code>getService()</code> will no longer work on the specified
         * service class after this event has been fired.
         * <P>
         *
         * <EM>This method is meant to be overriden.</EM>
         * <code>BeanContextChildSupport</code>'s implementation does
         * nothing.
         *
         * @param event the service revoked event.
         * @see java.beans.beancontext.BeanContextServices#revokeService(java.lang.Class,java.beans.beancontext.BeanContextServiceProvider,boolean)
         */
        public void serviceRevoked(BeanContextServiceRevokedEvent event) {
        }

        /**
         * Called by <code>BeanContextServices</code> whenever a service is made available.
         * <P>
         *
         * <EM>This method is meant to be overriden.</EM>
         * <code>BeanContextChildSupport</code>'s implementation does
         * nothing.
         *
         * @param event the service revoked event, with useful information
         *        about the new service.
         */
        public void serviceAvailable(BeanContextServiceAvailableEvent event) {
        }

        /**
         * Called by <code>setBeanContext()</code> to determine whether the set should be rejected.
         * <P>
         *
         * <EM>This method is meant to be overriden.</EM>
         * <code>BeanContextChildSupport</code>'s implementation simply
         * returns <code>true</code>.
         *
         * @param newBeanContext the new parent.
         * @return whether to allow the parent to be changed to the new
         *         value.
         */
        public boolean validatePendingSetBeanContext(BeanContext newBeanContext) {
                return true;
        }

        /**
         * Called by <code>setBeanContext()</code> to release resources of a what will soon no longer be the parent.
         * <P>
         *
         * <EM>This method is meant to be overriden.</EM>
         * <code>BeanContextChildSupport</code>'s implementation does
         * nothing.
         */
        protected void releaseBeanContextResources() {
        }

        /**
         * Called by <code>setBeanContext()</code> to grab resources when the parent has been set.
         * <P>
         *
         * <EM>This method is meant to be overriden.</EM>
         * <code>BeanContextChildSupport</code>'s implementation does
         * nothing.
         */
        protected void initializeBeanContextResources() {
        }
}
