--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.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;
+
+/**
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @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
+ * @param bcc the underlying bean context child
+ */
+
+ public BeanContextChildSupport(BeanContextChild bcc) {
+ super();
+
+ beanContextChildPeer = (bcc != null) ? bcc : this;
+
+ pcSupport = new PropertyChangeSupport(beanContextChildPeer);
+ vcSupport = new VetoableChangeSupport(beanContextChildPeer);
+ }
+
+ /**
+ * Sets the {@code BeanContext} for
+ * this {@code BeanContextChildSupport}.
+ * @param bc the new value to be assigned to the {@code 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 {@code BeanContext}
+ * for this {@code BeanContextChildSupport}.
+ * @return the nesting {@code BeanContext} for
+ * this {@code 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 {@code name} or {@code 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 {@code PropertyChangeListener} to be added
+ */
+ public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
+ pcSupport.addPropertyChangeListener(name, pcl);
+ }
+
+ /**
+ * Remove a PropertyChangeListener for a specific property.
+ * If {@code 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 {@code name} is null, no exception is thrown
+ * and no action is taken.
+ * If {@code 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 {@code name} or {@code 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 {@code VetoableChangeListener} to be added
+ */
+ public void addVetoableChangeListener(String name, VetoableChangeListener vcl) {
+ vcSupport.addVetoableChangeListener(name, vcl);
+ }
+
+ /**
+ * Removes a {@code VetoableChangeListener}.
+ * If {@code 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 {@code name} is null, no exception is thrown
+ * and no action is taken.
+ * If {@code 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 {@code 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 {@code 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 {@code BeanContextChild} associated with this
+ * {@code BeanContextChildSupport}.
+ *
+ * @return the {@code 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. <P>
+ *
+ * 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 {@code 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 required 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 {
+
+ /*
+ * don't serialize if we are delegated and the delegator is not 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 {@code BeanContext} in which
+ * this {@code BeanContextChild} is nested.
+ */
+ public BeanContextChild beanContextChildPeer;
+
+ /**
+ * The {@code PropertyChangeSupport} associated with this
+ * {@code BeanContextChildSupport}.
+ */
+ protected PropertyChangeSupport pcSupport;
+
+ /**
+ * The {@code VetoableChangeSupport} associated with this
+ * {@code BeanContextChildSupport}.
+ */
+ protected VetoableChangeSupport vcSupport;
+
+ /**
+ * The bean context.
+ */
+ protected transient BeanContext beanContext;
+
+ /**
+ * A flag indicating that there has been
+ * at least one {@code PropertyChangeVetoException}
+ * thrown for the attempted setBeanContext operation.
+ */
+ protected transient boolean rejectedSetBCOnce;
+
+}