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