1 /* java.beans.beancontext.BeanContextChildSupport
2 Copyright (C) 1999 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 As a special exception, if you link this library with other files to
22 produce an executable, this library does not by itself cause the
23 resulting executable to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why the
25 executable file might be covered by the GNU General Public License. */
28 package java.beans.beancontext;
30 import java.beans.PropertyChangeListener;
31 import java.beans.VetoableChangeListener;
32 import java.beans.PropertyVetoException;
33 import java.beans.PropertyChangeEvent;
34 import java.beans.PropertyChangeSupport;
35 import java.beans.VetoableChangeSupport;
36 import java.io.Serializable;
39 * Support for creating a <code>BeanContextChild</code>.
40 * This class contains the most common implementations of the methods in
41 * the <code>BeanContextChild</code>
43 * @specnote This class is not very well specified. I had to "fill in the
44 * blanks" in most places with what I thought was reasonable
45 * behavior. If there are problems, let me know.
49 * @see java.beans.beancontext.BeanContextChild
52 public class BeanContextChildSupport implements BeanContextChild, BeanContextServicesListener, Serializable {
54 * The peer on which to perform <code>set</code> actions.
55 * This is here so that this class can be used as a peer.
58 * When extending this class, this variable will be set to
61 public BeanContextChild beanContextChildPeer;
64 * The parent <code>BeanContext</code>.
66 protected transient BeanContext beanContext;
69 * If <code>setBeanContext()</code> was vetoed once before, this
70 * is set to <code>true</code> so that the next time, vetoes will
73 protected transient boolean rejectedSetBCOnce;
76 * Listeners are registered here and events are fired through here.
78 protected PropertyChangeSupport pcSupport;
81 * Listeners are registered here and events are fired through here.
83 protected VetoableChangeSupport vcSupport;
87 * Create a new <code>BeanContextChildSupport</code> with itself as the peer.
88 * This is meant to be used when you subclass
89 * <code>BeanContextChildSupport</code> to create your child.
91 public BeanContextChildSupport() {
96 * Create a new <code>BeanContextChildSupport</code> with the specified peer.
97 * @param peer the peer to use, or <code>null</code> to specify
100 public BeanContextChildSupport(BeanContextChild peer) {
105 beanContextChildPeer = peer;
106 pcSupport = new PropertyChangeSupport(peer);
107 vcSupport = new VetoableChangeSupport(peer);
111 * Set the parent <code>BeanContext</code>.
114 * When this Object is being added to a new BeanContext or moved
115 * from an old one, a non-null value will be passed in.
118 * When this Object is being removed from the current
119 * <code>BeanContext</code>, <code>setBeanContext()</code> will
120 * receive the parameter <code>null</code>.
126 * If the new <code>BeanContext</code> is the same as the old
127 * one, nothing happens.
130 * If the change has not been rejected or vetoed before, call
131 * <code>validatePendingSetBeanContext()</code>. If this call
132 * returns <code>false</code>, the change is rejected and a
133 * <code>PropertyVetoException</code> is thrown.
136 * If the change has not been rejected or vetoed before,
137 * <code>VetoableChangeEvent</code>s are fired with the name
138 * <code>"beanContext"</code>, using the
139 * <code>fireVetoableChange()</code> method. If a veto
140 * occurs, reversion events are fired using the same method,
141 * the change is rejected, and the veto is rethrown.
144 * <code>releaseBeanContextResources()</code> is called.
147 * The change is made.
150 * <code>PropertyChangeEvent</code>s are fired using the
151 * <code>firePropertyChange()</code> method.
154 * <code>initializeBeanContextResources()</code> is called.
159 * @param newBeanContext the new parent for the
160 * <code>BeanContextChild</code>, or <code>null</code> to
161 * signify removal from a tree.
162 * @exception PropertyVetoException if the
163 * <code>BeanContextChild</code> implementor does not
164 * wish to have its parent changed.
166 public void setBeanContext(BeanContext newBeanContext)
167 throws PropertyVetoException {
168 synchronized(beanContextChildPeer) {
169 if(newBeanContext == beanContext)
172 if(!rejectedSetBCOnce) {
173 if(!validatePendingSetBeanContext(newBeanContext)) {
174 rejectedSetBCOnce = true;
175 throw new PropertyVetoException("validatePendingSetBeanContext() rejected change",
176 new PropertyChangeEvent(beanContextChildPeer, "beanContext", beanContext, newBeanContext));
179 fireVetoableChange("beanContext", beanContext, newBeanContext);
180 } catch(PropertyVetoException e) {
181 rejectedSetBCOnce = true;
186 releaseBeanContextResources();
188 beanContext = newBeanContext;
189 rejectedSetBCOnce = false;
191 firePropertyChange("beanContext", beanContext, newBeanContext);
193 initializeBeanContextResources();
198 * Get the parent <code>BeanContext</code>.
199 * @return the parent <code>BeanContext</code>.
201 public BeanContext getBeanContext() {
206 * Get the peer (or <code>this</code> if there is no peer).
207 * @return the peer, or <code>this</code> if there is no peer.
209 public BeanContextChild getBeanContextChildPeer() {
210 return beanContextChildPeer;
214 * Determine whether there is a peer.
215 * This is true iff <code>getBeanContextChildPeer() == this</code>.
216 * @return whether there is a peer.
218 public boolean isDelegated() {
219 return beanContextChildPeer == this;
223 * Add a listener that will be notified when a specific property changes.
224 * @param propertyName the name of the property to listen on.
225 * @param listener the listener to listen on the property.
227 public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
228 pcSupport.addPropertyChangeListener(propertyName, listener);
232 * Remove a listener to a certain property.
234 * @param propertyName the name of the property being listened on.
235 * @param listener the listener listening on the property.
237 public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
238 pcSupport.removePropertyChangeListener(propertyName, listener);
242 * Add a listener that will be notified when a specific property
243 * change is requested (a PropertyVetoException may be thrown) as
244 * well as after the change is successfully made.
246 * @param propertyName the name of the property to listen on.
247 * @param listener the listener to listen on the property.
249 public void addVetoableChangeListener(String propertyName, VetoableChangeListener listener) {
250 vcSupport.addVetoableChangeListener(propertyName, listener);
254 * Remove a listener to a certain property.
256 * @param propertyName the name of the property being listened on
257 * @param listener the listener listening on the property.
259 public void removeVetoableChangeListener(String propertyName, VetoableChangeListener listener) {
260 vcSupport.removeVetoableChangeListener(propertyName, listener);
264 * Fire a property change.
266 * @param propertyName the name of the property that changed
267 * @param oldVal the old value of the property
268 * @param newVal the new value of the property
270 public void firePropertyChange(String propertyName, Object oldVal, Object newVal) {
271 pcSupport.firePropertyChange(propertyName, oldVal, newVal);
275 * Fire a vetoable property change.
277 * @param propertyName the name of the property that changed
278 * @param oldVal the old value of the property
279 * @param newVal the new value of the property
280 * @exception PropertyVetoException if the change is vetoed.
282 public void fireVetoableChange(String propertyName, Object oldVal, Object newVal)
283 throws PropertyVetoException {
284 vcSupport.fireVetoableChange(propertyName, oldVal, newVal);
288 * Called by <code>BeanContextServices.revokeService()</code> to indicate that a service has been revoked.
289 * If you have a reference to such a service, it should be
290 * discarded and may no longer function properly.
291 * <code>getService()</code> will no longer work on the specified
292 * service class after this event has been fired.
295 * <EM>This method is meant to be overriden.</EM>
296 * <code>BeanContextChildSupport</code>'s implementation does
299 * @param event the service revoked event.
300 * @see java.beans.beancontext.BeanContextServices#revokeService(java.lang.Class,java.beans.beancontext.BeanContextServiceProvider,boolean)
302 public void serviceRevoked(BeanContextServiceRevokedEvent event) {
306 * Called by <code>BeanContextServices</code> whenever a service is made available.
309 * <EM>This method is meant to be overriden.</EM>
310 * <code>BeanContextChildSupport</code>'s implementation does
313 * @param event the service revoked event, with useful information
314 * about the new service.
316 public void serviceAvailable(BeanContextServiceAvailableEvent event) {
320 * Called by <code>setBeanContext()</code> to determine whether the set should be rejected.
323 * <EM>This method is meant to be overriden.</EM>
324 * <code>BeanContextChildSupport</code>'s implementation simply
325 * returns <code>true</code>.
327 * @param newBeanContext the new parent.
328 * @return whether to allow the parent to be changed to the new
331 public boolean validatePendingSetBeanContext(BeanContext newBeanContext) {
336 * Called by <code>setBeanContext()</code> to release resources of a what will soon no longer be the parent.
339 * <EM>This method is meant to be overriden.</EM>
340 * <code>BeanContextChildSupport</code>'s implementation does
343 protected void releaseBeanContextResources() {
347 * Called by <code>setBeanContext()</code> to grab resources when the parent has been set.
350 * <EM>This method is meant to be overriden.</EM>
351 * <code>BeanContextChildSupport</code>'s implementation does
354 protected void initializeBeanContextResources() {