0N/A/*
2362N/A * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage java.beans.beancontext;
0N/A
0N/Aimport java.beans.PropertyChangeEvent;
0N/Aimport java.beans.PropertyChangeListener;
0N/Aimport java.beans.PropertyChangeSupport;
0N/A
0N/Aimport java.beans.VetoableChangeListener;
0N/Aimport java.beans.VetoableChangeSupport;
0N/A
0N/Aimport java.beans.PropertyVetoException;
0N/A
0N/Aimport java.io.IOException;
0N/Aimport java.io.ObjectInputStream;
0N/Aimport java.io.ObjectOutputStream;
0N/Aimport java.io.Serializable;
0N/A
0N/A/**
0N/A * <p>
0N/A * This is a general support class to provide support for implementing the
0N/A * BeanContextChild protocol.
0N/A *
0N/A * This class may either be directly subclassed, or encapsulated and delegated
0N/A * to in order to implement this interface for a given component.
0N/A * </p>
0N/A *
0N/A * @author Laurence P. G. Cable
0N/A * @since 1.2
0N/A *
0N/A * @see java.beans.beancontext.BeanContext
0N/A * @see java.beans.beancontext.BeanContextServices
0N/A * @see java.beans.beancontext.BeanContextChild
0N/A */
0N/A
0N/Apublic class BeanContextChildSupport implements BeanContextChild, BeanContextServicesListener, Serializable {
0N/A
0N/A static final long serialVersionUID = 6328947014421475877L;
0N/A
0N/A /**
0N/A * construct a BeanContextChildSupport where this class has been
0N/A * subclassed in order to implement the JavaBean component itself.
0N/A */
0N/A
0N/A public BeanContextChildSupport() {
0N/A super();
0N/A
0N/A beanContextChildPeer = this;
0N/A
0N/A pcSupport = new PropertyChangeSupport(beanContextChildPeer);
0N/A vcSupport = new VetoableChangeSupport(beanContextChildPeer);
0N/A }
0N/A
0N/A /**
0N/A * construct a BeanContextChildSupport where the JavaBean component
0N/A * itself implements BeanContextChild, and encapsulates this, delegating
0N/A * that interface to this implementation
0N/A */
0N/A
0N/A public BeanContextChildSupport(BeanContextChild bcc) {
0N/A super();
0N/A
0N/A beanContextChildPeer = (bcc != null) ? bcc : this;
0N/A
0N/A pcSupport = new PropertyChangeSupport(beanContextChildPeer);
0N/A vcSupport = new VetoableChangeSupport(beanContextChildPeer);
0N/A }
0N/A
0N/A /**
0N/A * Sets the <code>BeanContext</code> for
0N/A * this <code>BeanContextChildSupport</code>.
0N/A * @param bc the new value to be assigned to the <code>BeanContext</code>
0N/A * property
0N/A * @throws <code>PropertyVetoException</code> if the change is rejected
0N/A */
0N/A public synchronized void setBeanContext(BeanContext bc) throws PropertyVetoException {
0N/A if (bc == beanContext) return;
0N/A
0N/A BeanContext oldValue = beanContext;
0N/A BeanContext newValue = bc;
0N/A
0N/A if (!rejectedSetBCOnce) {
0N/A if (rejectedSetBCOnce = !validatePendingSetBeanContext(bc)) {
0N/A throw new PropertyVetoException(
0N/A "setBeanContext() change rejected:",
0N/A new PropertyChangeEvent(beanContextChildPeer, "beanContext", oldValue, newValue)
0N/A );
0N/A }
0N/A
0N/A try {
0N/A fireVetoableChange("beanContext",
0N/A oldValue,
0N/A newValue
0N/A );
0N/A } catch (PropertyVetoException pve) {
0N/A rejectedSetBCOnce = true;
0N/A
0N/A throw pve; // re-throw
0N/A }
0N/A }
0N/A
0N/A if (beanContext != null) releaseBeanContextResources();
0N/A
0N/A beanContext = newValue;
0N/A rejectedSetBCOnce = false;
0N/A
0N/A firePropertyChange("beanContext",
0N/A oldValue,
0N/A newValue
0N/A );
0N/A
0N/A if (beanContext != null) initializeBeanContextResources();
0N/A }
0N/A
0N/A /**
0N/A * Gets the nesting <code>BeanContext</code>
0N/A * for this <code>BeanContextChildSupport</code>.
0N/A * @return the nesting <code>BeanContext</code> for
0N/A * this <code>BeanContextChildSupport</code>.
0N/A */
0N/A public synchronized BeanContext getBeanContext() { return beanContext; }
0N/A
0N/A /**
0N/A * Add a PropertyChangeListener for a specific property.
0N/A * The same listener object may be added more than once. For each
0N/A * property, the listener will be invoked the number of times it was added
0N/A * for that property.
0N/A * If <code>name</code> or <code>pcl</code> is null, no exception is thrown
0N/A * and no action is taken.
0N/A *
0N/A * @param name The name of the property to listen on
0N/A * @param pcl The <code>PropertyChangeListener</code> to be added
0N/A */
0N/A public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
0N/A pcSupport.addPropertyChangeListener(name, pcl);
0N/A }
0N/A
0N/A /**
0N/A * Remove a PropertyChangeListener for a specific property.
0N/A * If <code>pcl</code> was added more than once to the same event
0N/A * source for the specified property, it will be notified one less time
0N/A * after being removed.
0N/A * If <code>name</code> is null, no exception is thrown
0N/A * and no action is taken.
0N/A * If <code>pcl</code> is null, or was never added for the specified
0N/A * property, no exception is thrown and no action is taken.
0N/A *
0N/A * @param name The name of the property that was listened on
0N/A * @param pcl The PropertyChangeListener to be removed
0N/A */
0N/A public void removePropertyChangeListener(String name, PropertyChangeListener pcl) {
0N/A pcSupport.removePropertyChangeListener(name, pcl);
0N/A }
0N/A
0N/A /**
0N/A * Add a VetoableChangeListener for a specific property.
0N/A * The same listener object may be added more than once. For each
0N/A * property, the listener will be invoked the number of times it was added
0N/A * for that property.
0N/A * If <code>name</code> or <code>vcl</code> is null, no exception is thrown
0N/A * and no action is taken.
0N/A *
0N/A * @param name The name of the property to listen on
0N/A * @param vcl The <code>VetoableChangeListener</code> to be added
0N/A */
0N/A public void addVetoableChangeListener(String name, VetoableChangeListener vcl) {
0N/A vcSupport.addVetoableChangeListener(name, vcl);
0N/A }
0N/A
0N/A /**
0N/A * Removes a <code>VetoableChangeListener</code>.
0N/A * If <code>pcl</code> was added more than once to the same event
0N/A * source for the specified property, it will be notified one less time
0N/A * after being removed.
0N/A * If <code>name</code> is null, no exception is thrown
0N/A * and no action is taken.
0N/A * If <code>vcl</code> is null, or was never added for the specified
0N/A * property, no exception is thrown and no action is taken.
0N/A *
0N/A * @param name The name of the property that was listened on
0N/A * @param vcl The <code>VetoableChangeListener</code> to be removed
0N/A */
0N/A public void removeVetoableChangeListener(String name, VetoableChangeListener vcl) {
0N/A vcSupport.removeVetoableChangeListener(name, vcl);
0N/A }
0N/A
0N/A /**
0N/A * A service provided by the nesting BeanContext has been revoked.
0N/A *
0N/A * Subclasses may override this method in order to implement their own
0N/A * behaviors.
0N/A * @param bcsre The <code>BeanContextServiceRevokedEvent</code> fired as a
0N/A * result of a service being revoked
0N/A */
0N/A public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) { }
0N/A
0N/A /**
0N/A * A new service is available from the nesting BeanContext.
0N/A *
0N/A * Subclasses may override this method in order to implement their own
0N/A * behaviors
0N/A * @param bcsae The BeanContextServiceAvailableEvent fired as a
0N/A * result of a service becoming available
0N/A *
0N/A */
0N/A public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) { }
0N/A
0N/A /**
0N/A * Gets the <tt>BeanContextChild</tt> associated with this
0N/A * <tt>BeanContextChildSupport</tt>.
0N/A *
0N/A * @return the <tt>BeanContextChild</tt> peer of this class
0N/A */
0N/A public BeanContextChild getBeanContextChildPeer() { return beanContextChildPeer; }
0N/A
0N/A /**
0N/A * Reports whether or not this class is a delegate of another.
0N/A *
0N/A * @return true if this class is a delegate of another
0N/A */
0N/A public boolean isDelegated() { return !this.equals(beanContextChildPeer); }
0N/A
0N/A /**
0N/A * Report a bound property update to any registered listeners. No event is
0N/A * fired if old and new are equal and non-null.
0N/A * @param name The programmatic name of the property that was changed
0N/A * @param oldValue The old value of the property
0N/A * @param newValue The new value of the property
0N/A */
0N/A public void firePropertyChange(String name, Object oldValue, Object newValue) {
0N/A pcSupport.firePropertyChange(name, oldValue, newValue);
0N/A }
0N/A
0N/A /**
0N/A * Report a vetoable property update to any registered listeners.
0N/A * If anyone vetos the change, then fire a new event
0N/A * reverting everyone to the old value and then rethrow
0N/A * the PropertyVetoException. <P>
0N/A *
0N/A * No event is fired if old and new are equal and non-null.
0N/A * <P>
0N/A * @param name The programmatic name of the property that is about to
0N/A * change
0N/A *
0N/A * @param oldValue The old value of the property
0N/A * @param newValue - The new value of the property
0N/A *
0N/A * @throws PropertyVetoException if the recipient wishes the property
0N/A * change to be rolled back.
0N/A */
0N/A public void fireVetoableChange(String name, Object oldValue, Object newValue) throws PropertyVetoException {
0N/A vcSupport.fireVetoableChange(name, oldValue, newValue);
0N/A }
0N/A
0N/A /**
0N/A * Called from setBeanContext to validate (or otherwise) the
0N/A * pending change in the nesting BeanContext property value.
0N/A * Returning false will cause setBeanContext to throw
0N/A * PropertyVetoException.
0N/A * @param newValue the new value that has been requested for
0N/A * the BeanContext property
0N/A * @return <code>true</code> if the change operation is to be vetoed
0N/A */
0N/A public boolean validatePendingSetBeanContext(BeanContext newValue) {
0N/A return true;
0N/A }
0N/A
0N/A /**
0N/A * This method may be overridden by subclasses to provide their own
0N/A * release behaviors. When invoked any resources held by this instance
0N/A * obtained from its current BeanContext property should be released
0N/A * since the object is no longer nested within that BeanContext.
0N/A */
0N/A
0N/A protected void releaseBeanContextResources() {
0N/A // do nothing
0N/A }
0N/A
0N/A /**
0N/A * This method may be overridden by subclasses to provide their own
0N/A * initialization behaviors. When invoked any resources requried by the
0N/A * BeanContextChild should be obtained from the current BeanContext.
0N/A */
0N/A
0N/A protected void initializeBeanContextResources() {
0N/A // do nothing
0N/A }
0N/A
0N/A /**
0N/A * Write the persistence state of the object.
0N/A */
0N/A
0N/A private void writeObject(ObjectOutputStream oos) throws IOException {
0N/A
0N/A /*
0N/A * dont serialize if we are delegated and the delegator isnt also
0N/A * serializable.
0N/A */
0N/A
0N/A if (!equals(beanContextChildPeer) && !(beanContextChildPeer instanceof Serializable))
0N/A throw new IOException("BeanContextChildSupport beanContextChildPeer not Serializable");
0N/A
0N/A else
0N/A oos.defaultWriteObject();
0N/A
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Restore a persistent object, must wait for subsequent setBeanContext()
0N/A * to fully restore any resources obtained from the new nesting
0N/A * BeanContext
0N/A */
0N/A
0N/A private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
0N/A ois.defaultReadObject();
0N/A }
0N/A
0N/A /*
0N/A * fields
0N/A */
0N/A
0N/A /**
0N/A * The <code>BeanContext</code> in which
0N/A * this <code>BeanContextChild</code> is nested.
0N/A */
0N/A public BeanContextChild beanContextChildPeer;
0N/A
0N/A /**
0N/A * The <tt>PropertyChangeSupport</tt> associated with this
0N/A * <tt>BeanContextChildSupport</tt>.
0N/A */
0N/A protected PropertyChangeSupport pcSupport;
0N/A
0N/A /**
0N/A * The <tt>VetoableChangeSupport</tt> associated with this
0N/A * <tt>BeanContextChildSupport</tt>.
0N/A */
0N/A protected VetoableChangeSupport vcSupport;
0N/A
0N/A protected transient BeanContext beanContext;
0N/A
0N/A /**
0N/A * A flag indicating that there has been
0N/A * at least one <code>PropertyChangeVetoException</code>
0N/A * thrown for the attempted setBeanContext operation.
0N/A */
0N/A protected transient boolean rejectedSetBCOnce;
0N/A
0N/A}