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 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java
.beans
.beancontext
;
41 import java
.beans
.PropertyChangeListener
;
42 import java
.beans
.VetoableChangeListener
;
43 import java
.beans
.PropertyVetoException
;
44 import java
.beans
.PropertyChangeEvent
;
45 import java
.beans
.PropertyChangeSupport
;
46 import java
.beans
.VetoableChangeSupport
;
47 import java
.io
.Serializable
;
50 * Support for creating a <code>BeanContextChild</code>.
51 * This class contains the most common implementations of the methods in
52 * the <code>BeanContextChild</code>
54 * @specnote This class is not very well specified. I had to "fill in the
55 * blanks" in most places with what I thought was reasonable
56 * behavior. If there are problems, let me know.
60 * @see java.beans.beancontext.BeanContextChild
63 public class BeanContextChildSupport
64 implements BeanContextChild
, BeanContextServicesListener
, Serializable
66 static final long serialVersionUID
= 6328947014421475877L;
69 * The peer on which to perform <code>set</code> actions.
70 * This is here so that this class can be used as a peer.
73 * When extending this class, this variable will be set to
76 public BeanContextChild beanContextChildPeer
;
79 * The parent <code>BeanContext</code>.
81 protected transient BeanContext beanContext
;
84 * If <code>setBeanContext()</code> was vetoed once before, this
85 * is set to <code>true</code> so that the next time, vetoes will
88 protected transient boolean rejectedSetBCOnce
;
91 * Listeners are registered here and events are fired through here.
93 protected PropertyChangeSupport pcSupport
;
96 * Listeners are registered here and events are fired through here.
98 protected VetoableChangeSupport vcSupport
;
102 * Create a new <code>BeanContextChildSupport</code> with itself as the peer.
103 * This is meant to be used when you subclass
104 * <code>BeanContextChildSupport</code> to create your child.
106 public BeanContextChildSupport() {
111 * Create a new <code>BeanContextChildSupport</code> with the specified peer.
112 * @param peer the peer to use, or <code>null</code> to specify
115 public BeanContextChildSupport(BeanContextChild peer
) {
120 beanContextChildPeer
= peer
;
121 pcSupport
= new PropertyChangeSupport(peer
);
122 vcSupport
= new VetoableChangeSupport(peer
);
126 * Set the parent <code>BeanContext</code>.
129 * When this Object is being added to a new BeanContext or moved
130 * from an old one, a non-null value will be passed in.
133 * When this Object is being removed from the current
134 * <code>BeanContext</code>, <code>setBeanContext()</code> will
135 * receive the parameter <code>null</code>.
141 * If the new <code>BeanContext</code> is the same as the old
142 * one, nothing happens.
145 * If the change has not been rejected or vetoed before, call
146 * <code>validatePendingSetBeanContext()</code>. If this call
147 * returns <code>false</code>, the change is rejected and a
148 * <code>PropertyVetoException</code> is thrown.
151 * If the change has not been rejected or vetoed before,
152 * <code>VetoableChangeEvent</code>s are fired with the name
153 * <code>"beanContext"</code>, using the
154 * <code>fireVetoableChange()</code> method. If a veto
155 * occurs, reversion events are fired using the same method,
156 * the change is rejected, and the veto is rethrown.
159 * <code>releaseBeanContextResources()</code> is called.
162 * The change is made.
165 * <code>PropertyChangeEvent</code>s are fired using the
166 * <code>firePropertyChange()</code> method.
169 * <code>initializeBeanContextResources()</code> is called.
174 * @param newBeanContext the new parent for the
175 * <code>BeanContextChild</code>, or <code>null</code> to
176 * signify removal from a tree.
177 * @exception PropertyVetoException if the
178 * <code>BeanContextChild</code> implementor does not
179 * wish to have its parent changed.
181 public void setBeanContext(BeanContext newBeanContext
)
182 throws PropertyVetoException
{
183 synchronized(beanContextChildPeer
) {
184 if(newBeanContext
== beanContext
)
187 if(!rejectedSetBCOnce
) {
188 if(!validatePendingSetBeanContext(newBeanContext
)) {
189 rejectedSetBCOnce
= true;
190 throw new PropertyVetoException("validatePendingSetBeanContext() rejected change",
191 new PropertyChangeEvent(beanContextChildPeer
, "beanContext", beanContext
, newBeanContext
));
194 fireVetoableChange("beanContext", beanContext
, newBeanContext
);
195 } catch(PropertyVetoException e
) {
196 rejectedSetBCOnce
= true;
201 releaseBeanContextResources();
203 beanContext
= newBeanContext
;
204 rejectedSetBCOnce
= false;
206 firePropertyChange("beanContext", beanContext
, newBeanContext
);
208 initializeBeanContextResources();
213 * Get the parent <code>BeanContext</code>.
214 * @return the parent <code>BeanContext</code>.
216 public BeanContext
getBeanContext() {
221 * Get the peer (or <code>this</code> if there is no peer).
222 * @return the peer, or <code>this</code> if there is no peer.
224 public BeanContextChild
getBeanContextChildPeer() {
225 return beanContextChildPeer
;
229 * Determine whether there is a peer.
230 * This is true iff <code>getBeanContextChildPeer() == this</code>.
231 * @return whether there is a peer.
233 public boolean isDelegated() {
234 return beanContextChildPeer
== this;
238 * Add a listener that will be notified when a specific property changes.
239 * @param propertyName the name of the property to listen on.
240 * @param listener the listener to listen on the property.
242 public void addPropertyChangeListener(String propertyName
, PropertyChangeListener listener
) {
243 pcSupport
.addPropertyChangeListener(propertyName
, listener
);
247 * Remove a listener to a certain property.
249 * @param propertyName the name of the property being listened on.
250 * @param listener the listener listening on the property.
252 public void removePropertyChangeListener(String propertyName
, PropertyChangeListener listener
) {
253 pcSupport
.removePropertyChangeListener(propertyName
, listener
);
257 * Add a listener that will be notified when a specific property
258 * change is requested (a PropertyVetoException may be thrown) as
259 * well as after the change is successfully made.
261 * @param propertyName the name of the property to listen on.
262 * @param listener the listener to listen on the property.
264 public void addVetoableChangeListener(String propertyName
, VetoableChangeListener listener
) {
265 vcSupport
.addVetoableChangeListener(propertyName
, listener
);
269 * Remove a listener to a certain property.
271 * @param propertyName the name of the property being listened on
272 * @param listener the listener listening on the property.
274 public void removeVetoableChangeListener(String propertyName
, VetoableChangeListener listener
) {
275 vcSupport
.removeVetoableChangeListener(propertyName
, listener
);
279 * Fire a property change.
281 * @param propertyName the name of the property that changed
282 * @param oldVal the old value of the property
283 * @param newVal the new value of the property
285 public void firePropertyChange(String propertyName
, Object oldVal
, Object newVal
) {
286 pcSupport
.firePropertyChange(propertyName
, oldVal
, newVal
);
290 * Fire a vetoable property change.
292 * @param propertyName the name of the property that changed
293 * @param oldVal the old value of the property
294 * @param newVal the new value of the property
295 * @exception PropertyVetoException if the change is vetoed.
297 public void fireVetoableChange(String propertyName
, Object oldVal
, Object newVal
)
298 throws PropertyVetoException
{
299 vcSupport
.fireVetoableChange(propertyName
, oldVal
, newVal
);
303 * Called by <code>BeanContextServices.revokeService()</code> to indicate that a service has been revoked.
304 * If you have a reference to such a service, it should be
305 * discarded and may no longer function properly.
306 * <code>getService()</code> will no longer work on the specified
307 * service class after this event has been fired.
310 * <EM>This method is meant to be overriden.</EM>
311 * <code>BeanContextChildSupport</code>'s implementation does
314 * @param event the service revoked event.
315 * @see java.beans.beancontext.BeanContextServices#revokeService(java.lang.Class,java.beans.beancontext.BeanContextServiceProvider,boolean)
317 public void serviceRevoked(BeanContextServiceRevokedEvent event
) {
321 * Called by <code>BeanContextServices</code> whenever a service is made available.
324 * <EM>This method is meant to be overriden.</EM>
325 * <code>BeanContextChildSupport</code>'s implementation does
328 * @param event the service revoked event, with useful information
329 * about the new service.
331 public void serviceAvailable(BeanContextServiceAvailableEvent event
) {
335 * Called by <code>setBeanContext()</code> to determine whether the set should be rejected.
338 * <EM>This method is meant to be overriden.</EM>
339 * <code>BeanContextChildSupport</code>'s implementation simply
340 * returns <code>true</code>.
342 * @param newBeanContext the new parent.
343 * @return whether to allow the parent to be changed to the new
346 public boolean validatePendingSetBeanContext(BeanContext newBeanContext
) {
351 * Called by <code>setBeanContext()</code> to release resources of a what will soon no longer be the parent.
354 * <EM>This method is meant to be overriden.</EM>
355 * <code>BeanContextChildSupport</code>'s implementation does
358 protected void releaseBeanContextResources() {
362 * Called by <code>setBeanContext()</code> to grab resources when the parent has been set.
365 * <EM>This method is meant to be overriden.</EM>
366 * <code>BeanContextChildSupport</code>'s implementation does
369 protected void initializeBeanContextResources() {