Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/beans/beancontext/BeanContextChildSupport.java
38918 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.beans.beancontext;2627import java.beans.PropertyChangeEvent;28import java.beans.PropertyChangeListener;29import java.beans.PropertyChangeSupport;3031import java.beans.VetoableChangeListener;32import java.beans.VetoableChangeSupport;3334import java.beans.PropertyVetoException;3536import java.io.IOException;37import java.io.ObjectInputStream;38import java.io.ObjectOutputStream;39import java.io.Serializable;4041/**42* <p>43* This is a general support class to provide support for implementing the44* BeanContextChild protocol.45*46* This class may either be directly subclassed, or encapsulated and delegated47* to in order to implement this interface for a given component.48* </p>49*50* @author Laurence P. G. Cable51* @since 1.252*53* @see java.beans.beancontext.BeanContext54* @see java.beans.beancontext.BeanContextServices55* @see java.beans.beancontext.BeanContextChild56*/5758public class BeanContextChildSupport implements BeanContextChild, BeanContextServicesListener, Serializable {5960static final long serialVersionUID = 6328947014421475877L;6162/**63* construct a BeanContextChildSupport where this class has been64* subclassed in order to implement the JavaBean component itself.65*/6667public BeanContextChildSupport() {68super();6970beanContextChildPeer = this;7172pcSupport = new PropertyChangeSupport(beanContextChildPeer);73vcSupport = new VetoableChangeSupport(beanContextChildPeer);74}7576/**77* construct a BeanContextChildSupport where the JavaBean component78* itself implements BeanContextChild, and encapsulates this, delegating79* that interface to this implementation80* @param bcc the underlying bean context child81*/8283public BeanContextChildSupport(BeanContextChild bcc) {84super();8586beanContextChildPeer = (bcc != null) ? bcc : this;8788pcSupport = new PropertyChangeSupport(beanContextChildPeer);89vcSupport = new VetoableChangeSupport(beanContextChildPeer);90}9192/**93* Sets the <code>BeanContext</code> for94* this <code>BeanContextChildSupport</code>.95* @param bc the new value to be assigned to the <code>BeanContext</code>96* property97* @throws PropertyVetoException if the change is rejected98*/99public synchronized void setBeanContext(BeanContext bc) throws PropertyVetoException {100if (bc == beanContext) return;101102BeanContext oldValue = beanContext;103BeanContext newValue = bc;104105if (!rejectedSetBCOnce) {106if (rejectedSetBCOnce = !validatePendingSetBeanContext(bc)) {107throw new PropertyVetoException(108"setBeanContext() change rejected:",109new PropertyChangeEvent(beanContextChildPeer, "beanContext", oldValue, newValue)110);111}112113try {114fireVetoableChange("beanContext",115oldValue,116newValue117);118} catch (PropertyVetoException pve) {119rejectedSetBCOnce = true;120121throw pve; // re-throw122}123}124125if (beanContext != null) releaseBeanContextResources();126127beanContext = newValue;128rejectedSetBCOnce = false;129130firePropertyChange("beanContext",131oldValue,132newValue133);134135if (beanContext != null) initializeBeanContextResources();136}137138/**139* Gets the nesting <code>BeanContext</code>140* for this <code>BeanContextChildSupport</code>.141* @return the nesting <code>BeanContext</code> for142* this <code>BeanContextChildSupport</code>.143*/144public synchronized BeanContext getBeanContext() { return beanContext; }145146/**147* Add a PropertyChangeListener for a specific property.148* The same listener object may be added more than once. For each149* property, the listener will be invoked the number of times it was added150* for that property.151* If <code>name</code> or <code>pcl</code> is null, no exception is thrown152* and no action is taken.153*154* @param name The name of the property to listen on155* @param pcl The <code>PropertyChangeListener</code> to be added156*/157public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {158pcSupport.addPropertyChangeListener(name, pcl);159}160161/**162* Remove a PropertyChangeListener for a specific property.163* If <code>pcl</code> was added more than once to the same event164* source for the specified property, it will be notified one less time165* after being removed.166* If <code>name</code> is null, no exception is thrown167* and no action is taken.168* If <code>pcl</code> is null, or was never added for the specified169* property, no exception is thrown and no action is taken.170*171* @param name The name of the property that was listened on172* @param pcl The PropertyChangeListener to be removed173*/174public void removePropertyChangeListener(String name, PropertyChangeListener pcl) {175pcSupport.removePropertyChangeListener(name, pcl);176}177178/**179* Add a VetoableChangeListener for a specific property.180* The same listener object may be added more than once. For each181* property, the listener will be invoked the number of times it was added182* for that property.183* If <code>name</code> or <code>vcl</code> is null, no exception is thrown184* and no action is taken.185*186* @param name The name of the property to listen on187* @param vcl The <code>VetoableChangeListener</code> to be added188*/189public void addVetoableChangeListener(String name, VetoableChangeListener vcl) {190vcSupport.addVetoableChangeListener(name, vcl);191}192193/**194* Removes a <code>VetoableChangeListener</code>.195* If <code>pcl</code> was added more than once to the same event196* source for the specified property, it will be notified one less time197* after being removed.198* If <code>name</code> is null, no exception is thrown199* and no action is taken.200* If <code>vcl</code> is null, or was never added for the specified201* property, no exception is thrown and no action is taken.202*203* @param name The name of the property that was listened on204* @param vcl The <code>VetoableChangeListener</code> to be removed205*/206public void removeVetoableChangeListener(String name, VetoableChangeListener vcl) {207vcSupport.removeVetoableChangeListener(name, vcl);208}209210/**211* A service provided by the nesting BeanContext has been revoked.212*213* Subclasses may override this method in order to implement their own214* behaviors.215* @param bcsre The <code>BeanContextServiceRevokedEvent</code> fired as a216* result of a service being revoked217*/218public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) { }219220/**221* A new service is available from the nesting BeanContext.222*223* Subclasses may override this method in order to implement their own224* behaviors225* @param bcsae The BeanContextServiceAvailableEvent fired as a226* result of a service becoming available227*228*/229public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) { }230231/**232* Gets the <tt>BeanContextChild</tt> associated with this233* <tt>BeanContextChildSupport</tt>.234*235* @return the <tt>BeanContextChild</tt> peer of this class236*/237public BeanContextChild getBeanContextChildPeer() { return beanContextChildPeer; }238239/**240* Reports whether or not this class is a delegate of another.241*242* @return true if this class is a delegate of another243*/244public boolean isDelegated() { return !this.equals(beanContextChildPeer); }245246/**247* Report a bound property update to any registered listeners. No event is248* fired if old and new are equal and non-null.249* @param name The programmatic name of the property that was changed250* @param oldValue The old value of the property251* @param newValue The new value of the property252*/253public void firePropertyChange(String name, Object oldValue, Object newValue) {254pcSupport.firePropertyChange(name, oldValue, newValue);255}256257/**258* Report a vetoable property update to any registered listeners.259* If anyone vetos the change, then fire a new event260* reverting everyone to the old value and then rethrow261* the PropertyVetoException. <P>262*263* No event is fired if old and new are equal and non-null.264* <P>265* @param name The programmatic name of the property that is about to266* change267*268* @param oldValue The old value of the property269* @param newValue - The new value of the property270*271* @throws PropertyVetoException if the recipient wishes the property272* change to be rolled back.273*/274public void fireVetoableChange(String name, Object oldValue, Object newValue) throws PropertyVetoException {275vcSupport.fireVetoableChange(name, oldValue, newValue);276}277278/**279* Called from setBeanContext to validate (or otherwise) the280* pending change in the nesting BeanContext property value.281* Returning false will cause setBeanContext to throw282* PropertyVetoException.283* @param newValue the new value that has been requested for284* the BeanContext property285* @return <code>true</code> if the change operation is to be vetoed286*/287public boolean validatePendingSetBeanContext(BeanContext newValue) {288return true;289}290291/**292* This method may be overridden by subclasses to provide their own293* release behaviors. When invoked any resources held by this instance294* obtained from its current BeanContext property should be released295* since the object is no longer nested within that BeanContext.296*/297298protected void releaseBeanContextResources() {299// do nothing300}301302/**303* This method may be overridden by subclasses to provide their own304* initialization behaviors. When invoked any resources required by the305* BeanContextChild should be obtained from the current BeanContext.306*/307308protected void initializeBeanContextResources() {309// do nothing310}311312/**313* Write the persistence state of the object.314*/315316private void writeObject(ObjectOutputStream oos) throws IOException {317318/*319* don't serialize if we are delegated and the delegator is not also320* serializable.321*/322323if (!equals(beanContextChildPeer) && !(beanContextChildPeer instanceof Serializable))324throw new IOException("BeanContextChildSupport beanContextChildPeer not Serializable");325326else327oos.defaultWriteObject();328329}330331332/**333* Restore a persistent object, must wait for subsequent setBeanContext()334* to fully restore any resources obtained from the new nesting335* BeanContext336*/337338private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {339ois.defaultReadObject();340}341342/*343* fields344*/345346/**347* The <code>BeanContext</code> in which348* this <code>BeanContextChild</code> is nested.349*/350public BeanContextChild beanContextChildPeer;351352/**353* The <tt>PropertyChangeSupport</tt> associated with this354* <tt>BeanContextChildSupport</tt>.355*/356protected PropertyChangeSupport pcSupport;357358/**359* The <tt>VetoableChangeSupport</tt> associated with this360* <tt>BeanContextChildSupport</tt>.361*/362protected VetoableChangeSupport vcSupport;363364/**365* The bean context.366*/367protected transient BeanContext beanContext;368369/**370* A flag indicating that there has been371* at least one <code>PropertyChangeVetoException</code>372* thrown for the attempted setBeanContext operation.373*/374protected transient boolean rejectedSetBCOnce;375376}377378379