1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/share/classes/java/beans/beancontext/BeanContextSupport.java Sat Dec 01 00:00:00 2007 +0000
1.3 @@ -0,0 +1,1393 @@
1.4 +/*
1.5 + * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Sun designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Sun in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
1.26 + * have any questions.
1.27 + */
1.28 +
1.29 +package java.beans.beancontext;
1.30 +
1.31 +import java.awt.Component;
1.32 +import java.awt.Container;
1.33 +
1.34 +import java.beans.Beans;
1.35 +import java.beans.AppletInitializer;
1.36 +
1.37 +import java.beans.DesignMode;
1.38 +
1.39 +import java.beans.PropertyChangeEvent;
1.40 +import java.beans.PropertyChangeListener;
1.41 +import java.beans.PropertyChangeSupport;
1.42 +
1.43 +import java.beans.VetoableChangeListener;
1.44 +import java.beans.VetoableChangeSupport;
1.45 +import java.beans.PropertyVetoException;
1.46 +
1.47 +import java.beans.Visibility;
1.48 +
1.49 +import java.io.IOException;
1.50 +import java.io.InputStream;
1.51 +import java.io.ObjectInputStream;
1.52 +import java.io.ObjectOutputStream;
1.53 +import java.io.Serializable;
1.54 +
1.55 +import java.net.URL;
1.56 +
1.57 +import java.util.ArrayList;
1.58 +import java.util.Collection;
1.59 +import java.util.HashMap;
1.60 +import java.util.Iterator;
1.61 +import java.util.Locale;
1.62 +import java.util.Map;
1.63 +
1.64 +
1.65 +/**
1.66 + * This helper class provides a utility implementation of the
1.67 + * java.beans.beancontext.BeanContext interface.
1.68 + * </p>
1.69 + * <p>
1.70 + * Since this class directly implements the BeanContext interface, the class
1.71 + * can, and is intended to be used either by subclassing this implementation,
1.72 + * or via ad-hoc delegation of an instance of this class from another.
1.73 + * </p>
1.74 + *
1.75 + * @author Laurence P. G. Cable
1.76 + * @since 1.2
1.77 + */
1.78 +public class BeanContextSupport extends BeanContextChildSupport
1.79 + implements BeanContext,
1.80 + Serializable,
1.81 + PropertyChangeListener,
1.82 + VetoableChangeListener {
1.83 +
1.84 + // Fix for bug 4282900 to pass JCK regression test
1.85 + static final long serialVersionUID = -4879613978649577204L;
1.86 +
1.87 + /**
1.88 + *
1.89 + * Construct a BeanContextSupport instance
1.90 + *
1.91 + *
1.92 + * @param peer The peer <tt>BeanContext</tt> we are
1.93 + * supplying an implementation for,
1.94 + * or <tt>null</tt>
1.95 + * if this object is its own peer
1.96 + * @param lcle The current Locale for this BeanContext. If
1.97 + * <tt>lcle</tt> is <tt>null</tt>, the default locale
1.98 + * is assigned to the <tt>BeanContext</tt> instance.
1.99 + * @param dTime The initial state,
1.100 + * <tt>true</tt> if in design mode,
1.101 + * <tt>false</tt> if runtime.
1.102 + * @param visible The initial visibility.
1.103 + * @see java.util.Locale#getDefault()
1.104 + * @see java.util.Locale#setDefault(java.util.Locale)
1.105 + */
1.106 + public BeanContextSupport(BeanContext peer, Locale lcle, boolean dTime, boolean visible) {
1.107 + super(peer);
1.108 +
1.109 + locale = lcle != null ? lcle : Locale.getDefault();
1.110 + designTime = dTime;
1.111 + okToUseGui = visible;
1.112 +
1.113 + initialize();
1.114 + }
1.115 +
1.116 + /**
1.117 + * Create an instance using the specified Locale and design mode.
1.118 + *
1.119 + * @param peer The peer <tt>BeanContext</tt> we
1.120 + * are supplying an implementation for,
1.121 + * or <tt>null</tt> if this object is its own peer
1.122 + * @param lcle The current Locale for this <tt>BeanContext</tt>. If
1.123 + * <tt>lcle</tt> is <tt>null</tt>, the default locale
1.124 + * is assigned to the <tt>BeanContext</tt> instance.
1.125 + * @param dtime The initial state, <tt>true</tt>
1.126 + * if in design mode,
1.127 + * <tt>false</tt> if runtime.
1.128 + * @see java.util.Locale#getDefault()
1.129 + * @see java.util.Locale#setDefault(java.util.Locale)
1.130 + */
1.131 + public BeanContextSupport(BeanContext peer, Locale lcle, boolean dtime) {
1.132 + this (peer, lcle, dtime, true);
1.133 + }
1.134 +
1.135 + /**
1.136 + * Create an instance using the specified locale
1.137 + *
1.138 + * @param peer The peer BeanContext we are
1.139 + * supplying an implementation for,
1.140 + * or <tt>null</tt> if this object
1.141 + * is its own peer
1.142 + * @param lcle The current Locale for this
1.143 + * <tt>BeanContext</tt>. If
1.144 + * <tt>lcle</tt> is <tt>null</tt>,
1.145 + * the default locale
1.146 + * is assigned to the <tt>BeanContext</tt>
1.147 + * instance.
1.148 + * @see java.util.Locale#getDefault()
1.149 + * @see java.util.Locale#setDefault(java.util.Locale)
1.150 + */
1.151 + public BeanContextSupport(BeanContext peer, Locale lcle) {
1.152 + this (peer, lcle, false, true);
1.153 + }
1.154 +
1.155 + /**
1.156 + * Create an instance using with a default locale
1.157 + *
1.158 + * @param peer The peer <tt>BeanContext</tt> we are
1.159 + * supplying an implementation for,
1.160 + * or <tt>null</tt> if this object
1.161 + * is its own peer
1.162 + */
1.163 + public BeanContextSupport(BeanContext peer) {
1.164 + this (peer, null, false, true);
1.165 + }
1.166 +
1.167 + /**
1.168 + * Create an instance that is not a delegate of another object
1.169 + */
1.170 +
1.171 + public BeanContextSupport() {
1.172 + this (null, null, false, true);
1.173 + }
1.174 +
1.175 + /**
1.176 + * Gets the instance of <tt>BeanContext</tt> that
1.177 + * this object is providing the implementation for.
1.178 + * @return the BeanContext instance
1.179 + */
1.180 + public BeanContext getBeanContextPeer() { return (BeanContext)getBeanContextChildPeer(); }
1.181 +
1.182 + /**
1.183 + * <p>
1.184 + * The instantiateChild method is a convenience hook
1.185 + * in BeanContext to simplify
1.186 + * the task of instantiating a Bean, nested,
1.187 + * into a <tt>BeanContext</tt>.
1.188 + * </p>
1.189 + * <p>
1.190 + * The semantics of the beanName parameter are defined by java.beans.Beans.instantate.
1.191 + * </p>
1.192 + *
1.193 + * @param beanName the name of the Bean to instantiate within this BeanContext
1.194 + * @throws IOException if there is an I/O error when the bean is being deserialized
1.195 + * @throws ClassNotFoundException if the class
1.196 + * identified by the beanName parameter is not found
1.197 + * @return the new object
1.198 + */
1.199 + public Object instantiateChild(String beanName)
1.200 + throws IOException, ClassNotFoundException {
1.201 + BeanContext bc = getBeanContextPeer();
1.202 +
1.203 + return Beans.instantiate(bc.getClass().getClassLoader(), beanName, bc);
1.204 + }
1.205 +
1.206 + /**
1.207 + * Gets the number of children currently nested in
1.208 + * this BeanContext.
1.209 + *
1.210 + * @return number of children
1.211 + */
1.212 + public int size() {
1.213 + synchronized(children) {
1.214 + return children.size();
1.215 + }
1.216 + }
1.217 +
1.218 + /**
1.219 + * Reports whether or not this
1.220 + * <tt>BeanContext</tt> is empty.
1.221 + * A <tt>BeanContext</tt> is considered
1.222 + * empty when it contains zero
1.223 + * nested children.
1.224 + * @return if there are not children
1.225 + */
1.226 + public boolean isEmpty() {
1.227 + synchronized(children) {
1.228 + return children.isEmpty();
1.229 + }
1.230 + }
1.231 +
1.232 + /**
1.233 + * Determines whether or not the specified object
1.234 + * is currently a child of this <tt>BeanContext</tt>.
1.235 + * @param o the Object in question
1.236 + * @return if this object is a child
1.237 + */
1.238 + public boolean contains(Object o) {
1.239 + synchronized(children) {
1.240 + return children.containsKey(o);
1.241 + }
1.242 + }
1.243 +
1.244 + /**
1.245 + * Determines whether or not the specified object
1.246 + * is currently a child of this <tt>BeanContext</tt>.
1.247 + * @param o the Object in question
1.248 + * @return if this object is a child
1.249 + */
1.250 + public boolean containsKey(Object o) {
1.251 + synchronized(children) {
1.252 + return children.containsKey(o);
1.253 + }
1.254 + }
1.255 +
1.256 + /**
1.257 + * Gets all JavaBean or <tt>BeanContext</tt> instances
1.258 + * currently nested in this <tt>BeanContext</tt>.
1.259 + * @return an <tt>Iterator</tt> of the nested children
1.260 + */
1.261 + public Iterator iterator() {
1.262 + synchronized(children) {
1.263 + return new BCSIterator(children.keySet().iterator());
1.264 + }
1.265 + }
1.266 +
1.267 + /**
1.268 + * Gets all JavaBean or <tt>BeanContext</tt>
1.269 + * instances currently nested in this BeanContext.
1.270 + */
1.271 + public Object[] toArray() {
1.272 + synchronized(children) {
1.273 + return children.keySet().toArray();
1.274 + }
1.275 + }
1.276 +
1.277 + /**
1.278 + * Gets an array containing all children of
1.279 + * this <tt>BeanContext</tt> that match
1.280 + * the types contained in arry.
1.281 + * @param arry The array of object
1.282 + * types that are of interest.
1.283 + * @return an array of children
1.284 + */
1.285 + public Object[] toArray(Object[] arry) {
1.286 + synchronized(children) {
1.287 + return children.keySet().toArray(arry);
1.288 + }
1.289 + }
1.290 +
1.291 +
1.292 + /************************************************************************/
1.293 +
1.294 + /**
1.295 + * protected final subclass that encapsulates an iterator but implements
1.296 + * a noop remove() method.
1.297 + */
1.298 +
1.299 + protected static final class BCSIterator implements Iterator {
1.300 + BCSIterator(Iterator i) { super(); src = i; }
1.301 +
1.302 + public boolean hasNext() { return src.hasNext(); }
1.303 + public Object next() { return src.next(); }
1.304 + public void remove() { /* do nothing */ }
1.305 +
1.306 + private Iterator src;
1.307 + }
1.308 +
1.309 + /************************************************************************/
1.310 +
1.311 + /*
1.312 + * protected nested class containing per child information, an instance
1.313 + * of which is associated with each child in the "children" hashtable.
1.314 + * subclasses can extend this class to include their own per-child state.
1.315 + *
1.316 + * Note that this 'value' is serialized with the corresponding child 'key'
1.317 + * when the BeanContextSupport is serialized.
1.318 + */
1.319 +
1.320 + protected class BCSChild implements Serializable {
1.321 +
1.322 + private static final long serialVersionUID = -5815286101609939109L;
1.323 +
1.324 + BCSChild(Object bcc, Object peer) {
1.325 + super();
1.326 +
1.327 + child = bcc;
1.328 + proxyPeer = peer;
1.329 + }
1.330 +
1.331 + Object getChild() { return child; }
1.332 +
1.333 + void setRemovePending(boolean v) { removePending = v; }
1.334 +
1.335 + boolean isRemovePending() { return removePending; }
1.336 +
1.337 + boolean isProxyPeer() { return proxyPeer != null; }
1.338 +
1.339 + Object getProxyPeer() { return proxyPeer; }
1.340 + /*
1.341 + * fields
1.342 + */
1.343 +
1.344 +
1.345 + private Object child;
1.346 + private Object proxyPeer;
1.347 +
1.348 + private transient boolean removePending;
1.349 + }
1.350 +
1.351 + /**
1.352 + * <p>
1.353 + * Subclasses can override this method to insert their own subclass
1.354 + * of Child without having to override add() or the other Collection
1.355 + * methods that add children to the set.
1.356 + * </p>
1.357 + *
1.358 + * @param targetChild the child to create the Child on behalf of
1.359 + * @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy
1.360 + */
1.361 +
1.362 + protected BCSChild createBCSChild(Object targetChild, Object peer) {
1.363 + return new BCSChild(targetChild, peer);
1.364 + }
1.365 +
1.366 + /************************************************************************/
1.367 +
1.368 + /**
1.369 + * Adds/nests a child within this <tt>BeanContext</tt>.
1.370 + * <p>
1.371 + * Invoked as a side effect of java.beans.Beans.instantiate().
1.372 + * If the child object is not valid for adding then this method
1.373 + * throws an IllegalStateException.
1.374 + * </p>
1.375 + *
1.376 + *
1.377 + * @param targetChild The child objects to nest
1.378 + * within this <tt>BeanContext</tt>
1.379 + * @return true if the child was added successfully.
1.380 + * @see #validatePendingAdd
1.381 + */
1.382 + public boolean add(Object targetChild) {
1.383 +
1.384 + if (targetChild == null) throw new IllegalArgumentException();
1.385 +
1.386 + // The specification requires that we do nothing if the child
1.387 + // is already nested herein.
1.388 +
1.389 + if (children.containsKey(targetChild)) return false; // test before locking
1.390 +
1.391 + synchronized(BeanContext.globalHierarchyLock) {
1.392 + if (children.containsKey(targetChild)) return false; // check again
1.393 +
1.394 + if (!validatePendingAdd(targetChild)) {
1.395 + throw new IllegalStateException();
1.396 + }
1.397 +
1.398 +
1.399 + // The specification requires that we invoke setBeanContext() on the
1.400 + // newly added child if it implements the java.beans.beancontext.BeanContextChild interface
1.401 +
1.402 + BeanContextChild cbcc = getChildBeanContextChild(targetChild);
1.403 + BeanContextChild bccp = null;
1.404 +
1.405 + synchronized(targetChild) {
1.406 +
1.407 + if (targetChild instanceof BeanContextProxy) {
1.408 + bccp = ((BeanContextProxy)targetChild).getBeanContextProxy();
1.409 +
1.410 + if (bccp == null) throw new NullPointerException("BeanContextPeer.getBeanContextProxy()");
1.411 + }
1.412 +
1.413 + BCSChild bcsc = createBCSChild(targetChild, bccp);
1.414 + BCSChild pbcsc = null;
1.415 +
1.416 + synchronized (children) {
1.417 + children.put(targetChild, bcsc);
1.418 +
1.419 + if (bccp != null) children.put(bccp, pbcsc = createBCSChild(bccp, targetChild));
1.420 + }
1.421 +
1.422 + if (cbcc != null) synchronized(cbcc) {
1.423 + try {
1.424 + cbcc.setBeanContext(getBeanContextPeer());
1.425 + } catch (PropertyVetoException pve) {
1.426 +
1.427 + synchronized (children) {
1.428 + children.remove(targetChild);
1.429 +
1.430 + if (bccp != null) children.remove(bccp);
1.431 + }
1.432 +
1.433 + throw new IllegalStateException();
1.434 + }
1.435 +
1.436 + cbcc.addPropertyChangeListener("beanContext", childPCL);
1.437 + cbcc.addVetoableChangeListener("beanContext", childVCL);
1.438 + }
1.439 +
1.440 + Visibility v = getChildVisibility(targetChild);
1.441 +
1.442 + if (v != null) {
1.443 + if (okToUseGui)
1.444 + v.okToUseGui();
1.445 + else
1.446 + v.dontUseGui();
1.447 + }
1.448 +
1.449 + if (getChildSerializable(targetChild) != null) serializable++;
1.450 +
1.451 + childJustAddedHook(targetChild, bcsc);
1.452 +
1.453 + if (bccp != null) {
1.454 + v = getChildVisibility(bccp);
1.455 +
1.456 + if (v != null) {
1.457 + if (okToUseGui)
1.458 + v.okToUseGui();
1.459 + else
1.460 + v.dontUseGui();
1.461 + }
1.462 +
1.463 + if (getChildSerializable(bccp) != null) serializable++;
1.464 +
1.465 + childJustAddedHook(bccp, pbcsc);
1.466 + }
1.467 +
1.468 +
1.469 + }
1.470 +
1.471 + // The specification requires that we fire a notification of the change
1.472 +
1.473 + fireChildrenAdded(new BeanContextMembershipEvent(getBeanContextPeer(), bccp == null ? new Object[] { targetChild } : new Object[] { targetChild, bccp } ));
1.474 +
1.475 + }
1.476 +
1.477 + return true;
1.478 + }
1.479 +
1.480 + /**
1.481 + * Removes a child from this BeanContext. If the child object is not
1.482 + * for adding then this method throws an IllegalStateException.
1.483 + * @param targetChild The child objects to remove
1.484 + * @see #validatePendingRemove
1.485 + */
1.486 + public boolean remove(Object targetChild) {
1.487 + return remove(targetChild, true);
1.488 + }
1.489 +
1.490 + /**
1.491 + * internal remove used when removal caused by
1.492 + * unexpected <tt>setBeanContext</tt> or
1.493 + * by <tt>remove()</tt> invocation.
1.494 + * @param targetChild the JavaBean, BeanContext, or Object to be removed
1.495 + * @param callChildSetBC used to indicate that
1.496 + * the child should be notified that it is no
1.497 + * longer nested in this <tt>BeanContext</tt>.
1.498 + */
1.499 + protected boolean remove(Object targetChild, boolean callChildSetBC) {
1.500 +
1.501 + if (targetChild == null) throw new IllegalArgumentException();
1.502 +
1.503 + synchronized(BeanContext.globalHierarchyLock) {
1.504 + if (!containsKey(targetChild)) return false;
1.505 +
1.506 + if (!validatePendingRemove(targetChild)) {
1.507 + throw new IllegalStateException();
1.508 + }
1.509 +
1.510 + BCSChild bcsc = (BCSChild)children.get(targetChild);
1.511 + BCSChild pbcsc = null;
1.512 + Object peer = null;
1.513 +
1.514 + // we are required to notify the child that it is no longer nested here if
1.515 + // it implements java.beans.beancontext.BeanContextChild
1.516 +
1.517 + synchronized(targetChild) {
1.518 + if (callChildSetBC) {
1.519 + BeanContextChild cbcc = getChildBeanContextChild(targetChild);
1.520 + if (cbcc != null) synchronized(cbcc) {
1.521 + cbcc.removePropertyChangeListener("beanContext", childPCL);
1.522 + cbcc.removeVetoableChangeListener("beanContext", childVCL);
1.523 +
1.524 + try {
1.525 + cbcc.setBeanContext(null);
1.526 + } catch (PropertyVetoException pve1) {
1.527 + cbcc.addPropertyChangeListener("beanContext", childPCL);
1.528 + cbcc.addVetoableChangeListener("beanContext", childVCL);
1.529 + throw new IllegalStateException();
1.530 + }
1.531 +
1.532 + }
1.533 + }
1.534 +
1.535 + synchronized (children) {
1.536 + children.remove(targetChild);
1.537 +
1.538 + if (bcsc.isProxyPeer()) {
1.539 + pbcsc = (BCSChild)children.get(peer = bcsc.getProxyPeer());
1.540 + children.remove(peer);
1.541 + }
1.542 + }
1.543 +
1.544 + if (getChildSerializable(targetChild) != null) serializable--;
1.545 +
1.546 + childJustRemovedHook(targetChild, bcsc);
1.547 +
1.548 + if (peer != null) {
1.549 + if (getChildSerializable(peer) != null) serializable--;
1.550 +
1.551 + childJustRemovedHook(peer, pbcsc);
1.552 + }
1.553 + }
1.554 +
1.555 + fireChildrenRemoved(new BeanContextMembershipEvent(getBeanContextPeer(), peer == null ? new Object[] { targetChild } : new Object[] { targetChild, peer } ));
1.556 +
1.557 + }
1.558 +
1.559 + return true;
1.560 + }
1.561 +
1.562 + /**
1.563 + * Tests to see if all objects in the
1.564 + * specified <tt>Collection</tt> are children of
1.565 + * this <tt>BeanContext</tt>.
1.566 + * @param c the specified <tt>Collection</tt>
1.567 + *
1.568 + * @return <tt>true</tt> if all objects
1.569 + * in the collection are children of
1.570 + * this <tt>BeanContext</tt>, false if not.
1.571 + */
1.572 + public boolean containsAll(Collection c) {
1.573 + synchronized(children) {
1.574 + Iterator i = c.iterator();
1.575 + while (i.hasNext())
1.576 + if(!contains(i.next()))
1.577 + return false;
1.578 +
1.579 + return true;
1.580 + }
1.581 + }
1.582 +
1.583 + /**
1.584 + * add Collection to set of Children (Unsupported)
1.585 + * implementations must synchronized on the hierarchy lock and "children" protected field
1.586 + * @throws UnsupportedOperationException
1.587 + */
1.588 + public boolean addAll(Collection c) {
1.589 + throw new UnsupportedOperationException();
1.590 + }
1.591 +
1.592 + /**
1.593 + * remove all specified children (Unsupported)
1.594 + * implementations must synchronized on the hierarchy lock and "children" protected field
1.595 + * @throws UnsupportedOperationException
1.596 + */
1.597 + public boolean removeAll(Collection c) {
1.598 + throw new UnsupportedOperationException();
1.599 + }
1.600 +
1.601 +
1.602 + /**
1.603 + * retain only specified children (Unsupported)
1.604 + * implementations must synchronized on the hierarchy lock and "children" protected field
1.605 + * @throws UnsupportedOperationException
1.606 + */
1.607 + public boolean retainAll(Collection c) {
1.608 + throw new UnsupportedOperationException();
1.609 + }
1.610 +
1.611 + /**
1.612 + * clear the children (Unsupported)
1.613 + * implementations must synchronized on the hierarchy lock and "children" protected field
1.614 + * @throws UnsupportedOperationException
1.615 + */
1.616 + public void clear() {
1.617 + throw new UnsupportedOperationException();
1.618 + }
1.619 +
1.620 + /**
1.621 + * Adds a BeanContextMembershipListener
1.622 + *
1.623 + * @param bcml the BeanContextMembershipListener to add
1.624 + * @throws NullPointerException
1.625 + */
1.626 +
1.627 + public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) {
1.628 + if (bcml == null) throw new NullPointerException("listener");
1.629 +
1.630 + synchronized(bcmListeners) {
1.631 + if (bcmListeners.contains(bcml))
1.632 + return;
1.633 + else
1.634 + bcmListeners.add(bcml);
1.635 + }
1.636 + }
1.637 +
1.638 + /**
1.639 + * Removes a BeanContextMembershipListener
1.640 + *
1.641 + * @param bcml the BeanContextMembershipListener to remove
1.642 + * @throws NullPointerException
1.643 + */
1.644 +
1.645 + public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) {
1.646 + if (bcml == null) throw new NullPointerException("listener");
1.647 +
1.648 + synchronized(bcmListeners) {
1.649 + if (!bcmListeners.contains(bcml))
1.650 + return;
1.651 + else
1.652 + bcmListeners.remove(bcml);
1.653 + }
1.654 + }
1.655 +
1.656 + /**
1.657 + * @param name the name of the resource requested.
1.658 + * @param bcc the child object making the request.
1.659 + *
1.660 + * @return the requested resource as an InputStream
1.661 + * @throws NullPointerException
1.662 + */
1.663 +
1.664 + public InputStream getResourceAsStream(String name, BeanContextChild bcc) {
1.665 + if (name == null) throw new NullPointerException("name");
1.666 + if (bcc == null) throw new NullPointerException("bcc");
1.667 +
1.668 + if (containsKey(bcc)) {
1.669 + ClassLoader cl = bcc.getClass().getClassLoader();
1.670 +
1.671 + return cl != null ? cl.getResourceAsStream(name)
1.672 + : ClassLoader.getSystemResourceAsStream(name);
1.673 + } else throw new IllegalArgumentException("Not a valid child");
1.674 + }
1.675 +
1.676 + /**
1.677 + * @param name the name of the resource requested.
1.678 + * @param bcc the child object making the request.
1.679 + *
1.680 + * @return the requested resource as an InputStream
1.681 + */
1.682 +
1.683 + public URL getResource(String name, BeanContextChild bcc) {
1.684 + if (name == null) throw new NullPointerException("name");
1.685 + if (bcc == null) throw new NullPointerException("bcc");
1.686 +
1.687 + if (containsKey(bcc)) {
1.688 + ClassLoader cl = bcc.getClass().getClassLoader();
1.689 +
1.690 + return cl != null ? cl.getResource(name)
1.691 + : ClassLoader.getSystemResource(name);
1.692 + } else throw new IllegalArgumentException("Not a valid child");
1.693 + }
1.694 +
1.695 + /**
1.696 + * Sets the new design time value for this <tt>BeanContext</tt>.
1.697 + * @param dTime the new designTime value
1.698 + */
1.699 + public synchronized void setDesignTime(boolean dTime) {
1.700 + if (designTime != dTime) {
1.701 + designTime = dTime;
1.702 +
1.703 + firePropertyChange("designMode", Boolean.valueOf(!dTime), Boolean.valueOf(dTime));
1.704 + }
1.705 + }
1.706 +
1.707 +
1.708 + /**
1.709 + * Reports whether or not this object is in
1.710 + * currently in design time mode.
1.711 + * @return <tt>true</tt> if in design time mode,
1.712 + * <tt>false</tt> if not
1.713 + */
1.714 + public synchronized boolean isDesignTime() { return designTime; }
1.715 +
1.716 + /**
1.717 + * Sets the locale of this BeanContext.
1.718 + * @param newLocale the new locale. This method call will have
1.719 + * no effect if newLocale is <CODE>null</CODE>.
1.720 + * @throws PropertyVetoException if the new value is rejected
1.721 + */
1.722 + public synchronized void setLocale(Locale newLocale) throws PropertyVetoException {
1.723 +
1.724 + if ((locale != null && !locale.equals(newLocale)) && newLocale != null) {
1.725 + Locale old = locale;
1.726 +
1.727 + fireVetoableChange("locale", old, newLocale); // throws
1.728 +
1.729 + locale = newLocale;
1.730 +
1.731 + firePropertyChange("locale", old, newLocale);
1.732 + }
1.733 + }
1.734 +
1.735 + /**
1.736 + * Gets the locale for this <tt>BeanContext</tt>.
1.737 + *
1.738 + * @return the current Locale of the <tt>BeanContext</tt>
1.739 + */
1.740 + public synchronized Locale getLocale() { return locale; }
1.741 +
1.742 + /**
1.743 + * <p>
1.744 + * This method is typically called from the environment in order to determine
1.745 + * if the implementor "needs" a GUI.
1.746 + * </p>
1.747 + * <p>
1.748 + * The algorithm used herein tests the BeanContextPeer, and its current children
1.749 + * to determine if they are either Containers, Components, or if they implement
1.750 + * Visibility and return needsGui() == true.
1.751 + * </p>
1.752 + * @return <tt>true</tt> if the implementor needs a GUI
1.753 + */
1.754 + public synchronized boolean needsGui() {
1.755 + BeanContext bc = getBeanContextPeer();
1.756 +
1.757 + if (bc != this) {
1.758 + if (bc instanceof Visibility) return ((Visibility)bc).needsGui();
1.759 +
1.760 + if (bc instanceof Container || bc instanceof Component)
1.761 + return true;
1.762 + }
1.763 +
1.764 + synchronized(children) {
1.765 + for (Iterator i = children.keySet().iterator(); i.hasNext();) {
1.766 + Object c = i.next();
1.767 +
1.768 + try {
1.769 + return ((Visibility)c).needsGui();
1.770 + } catch (ClassCastException cce) {
1.771 + // do nothing ...
1.772 + }
1.773 +
1.774 + if (c instanceof Container || c instanceof Component)
1.775 + return true;
1.776 + }
1.777 + }
1.778 +
1.779 + return false;
1.780 + }
1.781 +
1.782 + /**
1.783 + * notify this instance that it may no longer render a GUI.
1.784 + */
1.785 +
1.786 + public synchronized void dontUseGui() {
1.787 + if (okToUseGui) {
1.788 + okToUseGui = false;
1.789 +
1.790 + // lets also tell the Children that can that they may not use their GUI's
1.791 + synchronized(children) {
1.792 + for (Iterator i = children.keySet().iterator(); i.hasNext();) {
1.793 + Visibility v = getChildVisibility(i.next());
1.794 +
1.795 + if (v != null) v.dontUseGui();
1.796 + }
1.797 + }
1.798 + }
1.799 + }
1.800 +
1.801 + /**
1.802 + * Notify this instance that it may now render a GUI
1.803 + */
1.804 +
1.805 + public synchronized void okToUseGui() {
1.806 + if (!okToUseGui) {
1.807 + okToUseGui = true;
1.808 +
1.809 + // lets also tell the Children that can that they may use their GUI's
1.810 + synchronized(children) {
1.811 + for (Iterator i = children.keySet().iterator(); i.hasNext();) {
1.812 + Visibility v = getChildVisibility(i.next());
1.813 +
1.814 + if (v != null) v.okToUseGui();
1.815 + }
1.816 + }
1.817 + }
1.818 + }
1.819 +
1.820 + /**
1.821 + * Used to determine if the <tt>BeanContext</tt>
1.822 + * child is avoiding using its GUI.
1.823 + * @return is this instance avoiding using its GUI?
1.824 + * @see Visibility
1.825 + */
1.826 + public boolean avoidingGui() {
1.827 + return !okToUseGui && needsGui();
1.828 + }
1.829 +
1.830 + /**
1.831 + * Is this <tt>BeanContext</tt> in the
1.832 + * process of being serialized?
1.833 + * @return if this <tt>BeanContext</tt> is
1.834 + * currently being serialized
1.835 + */
1.836 + public boolean isSerializing() { return serializing; }
1.837 +
1.838 + /**
1.839 + * Returns an iterator of all children
1.840 + * of this <tt>BeanContext</tt>.
1.841 + * @return an iterator for all the current BCSChild values
1.842 + */
1.843 + protected Iterator bcsChildren() { synchronized(children) { return children.values().iterator(); } }
1.844 +
1.845 + /**
1.846 + * called by writeObject after defaultWriteObject() but prior to
1.847 + * serialization of currently serializable children.
1.848 + *
1.849 + * This method may be overridden by subclasses to perform custom
1.850 + * serialization of their state prior to this superclass serializing
1.851 + * the children.
1.852 + *
1.853 + * This method should not however be used by subclasses to replace their
1.854 + * own implementation (if any) of writeObject().
1.855 + */
1.856 +
1.857 + protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException {
1.858 + }
1.859 +
1.860 + /**
1.861 + * called by readObject after defaultReadObject() but prior to
1.862 + * deserialization of any children.
1.863 + *
1.864 + * This method may be overridden by subclasses to perform custom
1.865 + * deserialization of their state prior to this superclass deserializing
1.866 + * the children.
1.867 + *
1.868 + * This method should not however be used by subclasses to replace their
1.869 + * own implementation (if any) of readObject().
1.870 + */
1.871 +
1.872 + protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1.873 + }
1.874 +
1.875 + /**
1.876 + * Called by readObject with the newly deserialized child and BCSChild.
1.877 + * @param child the newly deserialized child
1.878 + * @param bcsc the newly deserialized BCSChild
1.879 + */
1.880 + protected void childDeserializedHook(Object child, BCSChild bcsc) {
1.881 + synchronized(children) {
1.882 + children.put(child, bcsc);
1.883 + }
1.884 + }
1.885 +
1.886 + /**
1.887 + * Used by writeObject to serialize a Collection.
1.888 + * @param oos the <tt>ObjectOutputStream</tt>
1.889 + * to use during serialization
1.890 + * @param coll the <tt>Collection</tt> to serialize
1.891 + * @throws IOException if serialization failed
1.892 + */
1.893 + protected final void serialize(ObjectOutputStream oos, Collection coll) throws IOException {
1.894 + int count = 0;
1.895 + Object[] objects = coll.toArray();
1.896 +
1.897 + for (int i = 0; i < objects.length; i++) {
1.898 + if (objects[i] instanceof Serializable)
1.899 + count++;
1.900 + else
1.901 + objects[i] = null;
1.902 + }
1.903 +
1.904 + oos.writeInt(count); // number of subsequent objects
1.905 +
1.906 + for (int i = 0; count > 0; i++) {
1.907 + Object o = objects[i];
1.908 +
1.909 + if (o != null) {
1.910 + oos.writeObject(o);
1.911 + count--;
1.912 + }
1.913 + }
1.914 + }
1.915 +
1.916 + /**
1.917 + * used by readObject to deserialize a collection.
1.918 + * @param ois the ObjectInputStream to use
1.919 + * @param coll the Collection
1.920 + */
1.921 + protected final void deserialize(ObjectInputStream ois, Collection coll) throws IOException, ClassNotFoundException {
1.922 + int count = 0;
1.923 +
1.924 + count = ois.readInt();
1.925 +
1.926 + while (count-- > 0) {
1.927 + coll.add(ois.readObject());
1.928 + }
1.929 + }
1.930 +
1.931 + /**
1.932 + * Used to serialize all children of
1.933 + * this <tt>BeanContext</tt>.
1.934 + * @param oos the <tt>ObjectOutputStream</tt>
1.935 + * to use during serialization
1.936 + * @throws IOException if serialization failed
1.937 + */
1.938 + public final void writeChildren(ObjectOutputStream oos) throws IOException {
1.939 + if (serializable <= 0) return;
1.940 +
1.941 + boolean prev = serializing;
1.942 +
1.943 + serializing = true;
1.944 +
1.945 + int count = 0;
1.946 +
1.947 + synchronized(children) {
1.948 + Iterator i = children.entrySet().iterator();
1.949 +
1.950 + while (i.hasNext() && count < serializable) {
1.951 + Map.Entry entry = (Map.Entry)i.next();
1.952 +
1.953 + if (entry.getKey() instanceof Serializable) {
1.954 + try {
1.955 + oos.writeObject(entry.getKey()); // child
1.956 + oos.writeObject(entry.getValue()); // BCSChild
1.957 + } catch (IOException ioe) {
1.958 + serializing = prev;
1.959 + throw ioe;
1.960 + }
1.961 + count++;
1.962 + }
1.963 + }
1.964 + }
1.965 +
1.966 + serializing = prev;
1.967 +
1.968 + if (count != serializable) {
1.969 + throw new IOException("wrote different number of children than expected");
1.970 + }
1.971 +
1.972 + }
1.973 +
1.974 + /**
1.975 + * Serialize the BeanContextSupport, if this instance has a distinct
1.976 + * peer (that is this object is acting as a delegate for another) then
1.977 + * the children of this instance are not serialized here due to a
1.978 + * 'chicken and egg' problem that occurs on deserialization of the
1.979 + * children at the same time as this instance.
1.980 + *
1.981 + * Therefore in situations where there is a distinct peer to this instance
1.982 + * it should always call writeObject() followed by writeChildren() and
1.983 + * readObject() followed by readChildren().
1.984 + *
1.985 + * @param oos the ObjectOutputStream
1.986 + */
1.987 +
1.988 + private synchronized void writeObject(ObjectOutputStream oos) throws IOException, ClassNotFoundException {
1.989 + serializing = true;
1.990 +
1.991 + synchronized (BeanContext.globalHierarchyLock) {
1.992 + try {
1.993 + oos.defaultWriteObject(); // serialize the BeanContextSupport object
1.994 +
1.995 + bcsPreSerializationHook(oos);
1.996 +
1.997 + if (serializable > 0 && this.equals(getBeanContextPeer()))
1.998 + writeChildren(oos);
1.999 +
1.1000 + serialize(oos, (Collection)bcmListeners);
1.1001 + } finally {
1.1002 + serializing = false;
1.1003 + }
1.1004 + }
1.1005 + }
1.1006 +
1.1007 + /**
1.1008 + * When an instance of this class is used as a delegate for the
1.1009 + * implementation of the BeanContext protocols (and its subprotocols)
1.1010 + * there exists a 'chicken and egg' problem during deserialization
1.1011 + */
1.1012 +
1.1013 + public final void readChildren(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1.1014 + int count = serializable;
1.1015 +
1.1016 + while (count-- > 0) {
1.1017 + Object child = null;
1.1018 + BeanContextSupport.BCSChild bscc = null;
1.1019 +
1.1020 + try {
1.1021 + child = ois.readObject();
1.1022 + bscc = (BeanContextSupport.BCSChild)ois.readObject();
1.1023 + } catch (IOException ioe) {
1.1024 + continue;
1.1025 + } catch (ClassNotFoundException cnfe) {
1.1026 + continue;
1.1027 + }
1.1028 +
1.1029 +
1.1030 + synchronized(child) {
1.1031 + BeanContextChild bcc = null;
1.1032 +
1.1033 + try {
1.1034 + bcc = (BeanContextChild)child;
1.1035 + } catch (ClassCastException cce) {
1.1036 + // do nothing;
1.1037 + }
1.1038 +
1.1039 + if (bcc != null) {
1.1040 + try {
1.1041 + bcc.setBeanContext(getBeanContextPeer());
1.1042 +
1.1043 + bcc.addPropertyChangeListener("beanContext", childPCL);
1.1044 + bcc.addVetoableChangeListener("beanContext", childVCL);
1.1045 +
1.1046 + } catch (PropertyVetoException pve) {
1.1047 + continue;
1.1048 + }
1.1049 + }
1.1050 +
1.1051 + childDeserializedHook(child, bscc);
1.1052 + }
1.1053 + }
1.1054 + }
1.1055 +
1.1056 + /**
1.1057 + * deserialize contents ... if this instance has a distinct peer the
1.1058 + * children are *not* serialized here, the peer's readObject() must call
1.1059 + * readChildren() after deserializing this instance.
1.1060 + */
1.1061 +
1.1062 + private synchronized void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1.1063 +
1.1064 + synchronized(BeanContext.globalHierarchyLock) {
1.1065 + ois.defaultReadObject();
1.1066 +
1.1067 + initialize();
1.1068 +
1.1069 + bcsPreDeserializationHook(ois);
1.1070 +
1.1071 + if (serializable > 0 && this.equals(getBeanContextPeer()))
1.1072 + readChildren(ois);
1.1073 +
1.1074 + deserialize(ois, bcmListeners = new ArrayList(1));
1.1075 + }
1.1076 + }
1.1077 +
1.1078 + /**
1.1079 + * subclasses may envelope to monitor veto child property changes.
1.1080 + */
1.1081 +
1.1082 + public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
1.1083 + String propertyName = pce.getPropertyName();
1.1084 + Object source = pce.getSource();
1.1085 +
1.1086 + synchronized(children) {
1.1087 + if ("beanContext".equals(propertyName) &&
1.1088 + containsKey(source) &&
1.1089 + !getBeanContextPeer().equals(pce.getNewValue())
1.1090 + ) {
1.1091 + if (!validatePendingRemove(source)) {
1.1092 + throw new PropertyVetoException("current BeanContext vetoes setBeanContext()", pce);
1.1093 + } else ((BCSChild)children.get(source)).setRemovePending(true);
1.1094 + }
1.1095 + }
1.1096 + }
1.1097 +
1.1098 + /**
1.1099 + * subclasses may envelope to monitor child property changes.
1.1100 + */
1.1101 +
1.1102 + public void propertyChange(PropertyChangeEvent pce) {
1.1103 + String propertyName = pce.getPropertyName();
1.1104 + Object source = pce.getSource();
1.1105 +
1.1106 + synchronized(children) {
1.1107 + if ("beanContext".equals(propertyName) &&
1.1108 + containsKey(source) &&
1.1109 + ((BCSChild)children.get(source)).isRemovePending()) {
1.1110 + BeanContext bc = getBeanContextPeer();
1.1111 +
1.1112 + if (bc.equals(pce.getOldValue()) && !bc.equals(pce.getNewValue())) {
1.1113 + remove(source, false);
1.1114 + } else {
1.1115 + ((BCSChild)children.get(source)).setRemovePending(false);
1.1116 + }
1.1117 + }
1.1118 + }
1.1119 + }
1.1120 +
1.1121 + /**
1.1122 + * <p>
1.1123 + * Subclasses of this class may override, or envelope, this method to
1.1124 + * add validation behavior for the BeanContext to examine child objects
1.1125 + * immediately prior to their being added to the BeanContext.
1.1126 + * </p>
1.1127 + *
1.1128 + * @return true iff the child may be added to this BeanContext, otherwise false.
1.1129 + */
1.1130 +
1.1131 + protected boolean validatePendingAdd(Object targetChild) {
1.1132 + return true;
1.1133 + }
1.1134 +
1.1135 + /**
1.1136 + * <p>
1.1137 + * Subclasses of this class may override, or envelope, this method to
1.1138 + * add validation behavior for the BeanContext to examine child objects
1.1139 + * immediately prior to their being removed from the BeanContext.
1.1140 + * </p>
1.1141 + *
1.1142 + * @return true iff the child may be removed from this BeanContext, otherwise false.
1.1143 + */
1.1144 +
1.1145 + protected boolean validatePendingRemove(Object targetChild) {
1.1146 + return true;
1.1147 + }
1.1148 +
1.1149 + /**
1.1150 + * subclasses may override this method to simply extend add() semantics
1.1151 + * after the child has been added and before the event notification has
1.1152 + * occurred. The method is called with the child synchronized.
1.1153 + */
1.1154 +
1.1155 + protected void childJustAddedHook(Object child, BCSChild bcsc) {
1.1156 + }
1.1157 +
1.1158 + /**
1.1159 + * subclasses may override this method to simply extend remove() semantics
1.1160 + * after the child has been removed and before the event notification has
1.1161 + * occurred. The method is called with the child synchronized.
1.1162 + */
1.1163 +
1.1164 + protected void childJustRemovedHook(Object child, BCSChild bcsc) {
1.1165 + }
1.1166 +
1.1167 + /**
1.1168 + * Gets the Component (if any) associated with the specified child.
1.1169 + * @param child the specified child
1.1170 + * @return the Component (if any) associated with the specified child.
1.1171 + */
1.1172 + protected static final Visibility getChildVisibility(Object child) {
1.1173 + try {
1.1174 + return (Visibility)child;
1.1175 + } catch (ClassCastException cce) {
1.1176 + return null;
1.1177 + }
1.1178 + }
1.1179 +
1.1180 + /**
1.1181 + * Gets the Serializable (if any) associated with the specified Child
1.1182 + * @param child the specified child
1.1183 + * @return the Serializable (if any) associated with the specified Child
1.1184 + */
1.1185 + protected static final Serializable getChildSerializable(Object child) {
1.1186 + try {
1.1187 + return (Serializable)child;
1.1188 + } catch (ClassCastException cce) {
1.1189 + return null;
1.1190 + }
1.1191 + }
1.1192 +
1.1193 + /**
1.1194 + * Gets the PropertyChangeListener
1.1195 + * (if any) of the specified child
1.1196 + * @param child the specified child
1.1197 + * @return the PropertyChangeListener (if any) of the specified child
1.1198 + */
1.1199 + protected static final PropertyChangeListener getChildPropertyChangeListener(Object child) {
1.1200 + try {
1.1201 + return (PropertyChangeListener)child;
1.1202 + } catch (ClassCastException cce) {
1.1203 + return null;
1.1204 + }
1.1205 + }
1.1206 +
1.1207 + /**
1.1208 + * Gets the VetoableChangeListener
1.1209 + * (if any) of the specified child
1.1210 + * @param child the specified child
1.1211 + * @return the VetoableChangeListener (if any) of the specified child
1.1212 + */
1.1213 + protected static final VetoableChangeListener getChildVetoableChangeListener(Object child) {
1.1214 + try {
1.1215 + return (VetoableChangeListener)child;
1.1216 + } catch (ClassCastException cce) {
1.1217 + return null;
1.1218 + }
1.1219 + }
1.1220 +
1.1221 + /**
1.1222 + * Gets the BeanContextMembershipListener
1.1223 + * (if any) of the specified child
1.1224 + * @param child the specified child
1.1225 + * @return the BeanContextMembershipListener (if any) of the specified child
1.1226 + */
1.1227 + protected static final BeanContextMembershipListener getChildBeanContextMembershipListener(Object child) {
1.1228 + try {
1.1229 + return (BeanContextMembershipListener)child;
1.1230 + } catch (ClassCastException cce) {
1.1231 + return null;
1.1232 + }
1.1233 + }
1.1234 +
1.1235 + /**
1.1236 + * Gets the BeanContextChild (if any) of the specified child
1.1237 + * @param child the specified child
1.1238 + * @return the BeanContextChild (if any) of the specified child
1.1239 + * @throws IllegalArgumentException if child implements both BeanContextChild and BeanContextProxy
1.1240 + */
1.1241 + protected static final BeanContextChild getChildBeanContextChild(Object child) {
1.1242 + try {
1.1243 + BeanContextChild bcc = (BeanContextChild)child;
1.1244 +
1.1245 + if (child instanceof BeanContextChild && child instanceof BeanContextProxy)
1.1246 + throw new IllegalArgumentException("child cannot implement both BeanContextChild and BeanContextProxy");
1.1247 + else
1.1248 + return bcc;
1.1249 + } catch (ClassCastException cce) {
1.1250 + try {
1.1251 + return ((BeanContextProxy)child).getBeanContextProxy();
1.1252 + } catch (ClassCastException cce1) {
1.1253 + return null;
1.1254 + }
1.1255 + }
1.1256 + }
1.1257 +
1.1258 + /**
1.1259 + * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
1.1260 + */
1.1261 +
1.1262 + protected final void fireChildrenAdded(BeanContextMembershipEvent bcme) {
1.1263 + Object[] copy;
1.1264 +
1.1265 + synchronized(bcmListeners) { copy = bcmListeners.toArray(); }
1.1266 +
1.1267 + for (int i = 0; i < copy.length; i++)
1.1268 + ((BeanContextMembershipListener)copy[i]).childrenAdded(bcme);
1.1269 + }
1.1270 +
1.1271 + /**
1.1272 + * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
1.1273 + */
1.1274 +
1.1275 + protected final void fireChildrenRemoved(BeanContextMembershipEvent bcme) {
1.1276 + Object[] copy;
1.1277 +
1.1278 + synchronized(bcmListeners) { copy = bcmListeners.toArray(); }
1.1279 +
1.1280 + for (int i = 0; i < copy.length; i++)
1.1281 + ((BeanContextMembershipListener)copy[i]).childrenRemoved(bcme);
1.1282 + }
1.1283 +
1.1284 + /**
1.1285 + * protected method called from constructor and readObject to initialize
1.1286 + * transient state of BeanContextSupport instance.
1.1287 + *
1.1288 + * This class uses this method to instantiate inner class listeners used
1.1289 + * to monitor PropertyChange and VetoableChange events on children.
1.1290 + *
1.1291 + * subclasses may envelope this method to add their own initialization
1.1292 + * behavior
1.1293 + */
1.1294 +
1.1295 + protected synchronized void initialize() {
1.1296 + children = new HashMap(serializable + 1);
1.1297 + bcmListeners = new ArrayList(1);
1.1298 +
1.1299 + childPCL = new PropertyChangeListener() {
1.1300 +
1.1301 + /*
1.1302 + * this adaptor is used by the BeanContextSupport class to forward
1.1303 + * property changes from a child to the BeanContext, avoiding
1.1304 + * accidential serialization of the BeanContext by a badly
1.1305 + * behaved Serializable child.
1.1306 + */
1.1307 +
1.1308 + public void propertyChange(PropertyChangeEvent pce) {
1.1309 + BeanContextSupport.this.propertyChange(pce);
1.1310 + }
1.1311 + };
1.1312 +
1.1313 + childVCL = new VetoableChangeListener() {
1.1314 +
1.1315 + /*
1.1316 + * this adaptor is used by the BeanContextSupport class to forward
1.1317 + * vetoable changes from a child to the BeanContext, avoiding
1.1318 + * accidential serialization of the BeanContext by a badly
1.1319 + * behaved Serializable child.
1.1320 + */
1.1321 +
1.1322 + public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
1.1323 + BeanContextSupport.this.vetoableChange(pce);
1.1324 + }
1.1325 + };
1.1326 + }
1.1327 +
1.1328 + /**
1.1329 + * Gets a copy of the this BeanContext's children.
1.1330 + * @return a copy of the current nested children
1.1331 + */
1.1332 + protected final Object[] copyChildren() {
1.1333 + synchronized(children) { return children.keySet().toArray(); }
1.1334 + }
1.1335 +
1.1336 + /**
1.1337 + * Tests to see if two class objects,
1.1338 + * or their names are equal.
1.1339 + * @param first the first object
1.1340 + * @param second the second object
1.1341 + * @return true if equal, false if not
1.1342 + */
1.1343 + protected static final boolean classEquals(Class first, Class second) {
1.1344 + return first.equals(second) || first.getName().equals(second.getName());
1.1345 + }
1.1346 +
1.1347 +
1.1348 + /*
1.1349 + * fields
1.1350 + */
1.1351 +
1.1352 +
1.1353 + /**
1.1354 + * all accesses to the <code> protected HashMap children </code> field
1.1355 + * shall be synchronized on that object.
1.1356 + */
1.1357 + protected transient HashMap children;
1.1358 +
1.1359 + private int serializable = 0; // children serializable
1.1360 +
1.1361 + /**
1.1362 + * all accesses to the <code> protected ArrayList bcmListeners </code> field
1.1363 + * shall be synchronized on that object.
1.1364 + */
1.1365 + protected transient ArrayList bcmListeners;
1.1366 +
1.1367 + //
1.1368 +
1.1369 + /**
1.1370 + * The current locale of this BeanContext.
1.1371 + */
1.1372 + protected Locale locale;
1.1373 +
1.1374 + /**
1.1375 + * A <tt>boolean</tt> indicating if this
1.1376 + * instance may now render a GUI.
1.1377 + */
1.1378 + protected boolean okToUseGui;
1.1379 +
1.1380 +
1.1381 + /**
1.1382 + * A <tt>boolean</tt> indicating whether or not
1.1383 + * this object is currently in design time mode.
1.1384 + */
1.1385 + protected boolean designTime;
1.1386 +
1.1387 + /*
1.1388 + * transient
1.1389 + */
1.1390 +
1.1391 + private transient PropertyChangeListener childPCL;
1.1392 +
1.1393 + private transient VetoableChangeListener childVCL;
1.1394 +
1.1395 + private transient boolean serializing;
1.1396 +}