In order to make javabeans module independent on applet and yet allow Beans class to have a method which references AppletInitializer, I am creating new module: deprecated7. This one shall consist of all the garbage identified in JDK7 development which has so many dependencies that it does not fit anywhere else. Beans class is moved there and instead of it, there is new BeanFactory class with the same methods (expect the one with AppletInitializer parameter).
2 * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
26 package java.beans.beancontext;
28 import java.awt.Component;
29 import java.awt.Container;
31 import java.beans.BeanFactory;
34 import java.beans.PropertyChangeEvent;
35 import java.beans.PropertyChangeListener;
37 import java.beans.VetoableChangeListener;
38 import java.beans.PropertyVetoException;
40 import java.beans.Visibility;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.io.ObjectInputStream;
45 import java.io.ObjectOutputStream;
46 import java.io.Serializable;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.HashMap;
53 import java.util.Iterator;
54 import java.util.Locale;
59 * This helper class provides a utility implementation of the
60 * java.beans.beancontext.BeanContext interface.
63 * Since this class directly implements the BeanContext interface, the class
64 * can, and is intended to be used either by subclassing this implementation,
65 * or via ad-hoc delegation of an instance of this class from another.
68 * @author Laurence P. G. Cable
71 public class BeanContextSupport extends BeanContextChildSupport
72 implements BeanContext,
74 PropertyChangeListener,
75 VetoableChangeListener {
77 // Fix for bug 4282900 to pass JCK regression test
78 static final long serialVersionUID = -4879613978649577204L;
82 * Construct a BeanContextSupport instance
85 * @param peer The peer <tt>BeanContext</tt> we are
86 * supplying an implementation for,
88 * if this object is its own peer
89 * @param lcle The current Locale for this BeanContext. If
90 * <tt>lcle</tt> is <tt>null</tt>, the default locale
91 * is assigned to the <tt>BeanContext</tt> instance.
92 * @param dTime The initial state,
93 * <tt>true</tt> if in design mode,
94 * <tt>false</tt> if runtime.
95 * @param visible The initial visibility.
96 * @see java.util.Locale#getDefault()
97 * @see java.util.Locale#setDefault(java.util.Locale)
99 public BeanContextSupport(BeanContext peer, Locale lcle, boolean dTime, boolean visible) {
102 locale = lcle != null ? lcle : Locale.getDefault();
104 okToUseGui = visible;
110 * Create an instance using the specified Locale and design mode.
112 * @param peer The peer <tt>BeanContext</tt> we
113 * are supplying an implementation for,
114 * or <tt>null</tt> if this object is its own peer
115 * @param lcle The current Locale for this <tt>BeanContext</tt>. If
116 * <tt>lcle</tt> is <tt>null</tt>, the default locale
117 * is assigned to the <tt>BeanContext</tt> instance.
118 * @param dtime The initial state, <tt>true</tt>
120 * <tt>false</tt> if runtime.
121 * @see java.util.Locale#getDefault()
122 * @see java.util.Locale#setDefault(java.util.Locale)
124 public BeanContextSupport(BeanContext peer, Locale lcle, boolean dtime) {
125 this (peer, lcle, dtime, true);
129 * Create an instance using the specified locale
131 * @param peer The peer BeanContext we are
132 * supplying an implementation for,
133 * or <tt>null</tt> if this object
135 * @param lcle The current Locale for this
136 * <tt>BeanContext</tt>. If
137 * <tt>lcle</tt> is <tt>null</tt>,
139 * is assigned to the <tt>BeanContext</tt>
141 * @see java.util.Locale#getDefault()
142 * @see java.util.Locale#setDefault(java.util.Locale)
144 public BeanContextSupport(BeanContext peer, Locale lcle) {
145 this (peer, lcle, false, true);
149 * Create an instance using with a default locale
151 * @param peer The peer <tt>BeanContext</tt> we are
152 * supplying an implementation for,
153 * or <tt>null</tt> if this object
156 public BeanContextSupport(BeanContext peer) {
157 this (peer, null, false, true);
161 * Create an instance that is not a delegate of another object
164 public BeanContextSupport() {
165 this (null, null, false, true);
169 * Gets the instance of <tt>BeanContext</tt> that
170 * this object is providing the implementation for.
171 * @return the BeanContext instance
173 public BeanContext getBeanContextPeer() { return (BeanContext)getBeanContextChildPeer(); }
177 * The instantiateChild method is a convenience hook
178 * in BeanContext to simplify
179 * the task of instantiating a Bean, nested,
180 * into a <tt>BeanContext</tt>.
183 * The semantics of the beanName parameter are defined by java.beans.Beans.instantate.
186 * @param beanName the name of the Bean to instantiate within this BeanContext
187 * @throws IOException if there is an I/O error when the bean is being deserialized
188 * @throws ClassNotFoundException if the class
189 * identified by the beanName parameter is not found
190 * @return the new object
192 public Object instantiateChild(String beanName)
193 throws IOException, ClassNotFoundException {
194 BeanContext bc = getBeanContextPeer();
196 return BeanFactory.instantiate(bc.getClass().getClassLoader(), beanName, bc);
200 * Gets the number of children currently nested in
203 * @return number of children
206 synchronized(children) {
207 return children.size();
212 * Reports whether or not this
213 * <tt>BeanContext</tt> is empty.
214 * A <tt>BeanContext</tt> is considered
215 * empty when it contains zero
217 * @return if there are not children
219 public boolean isEmpty() {
220 synchronized(children) {
221 return children.isEmpty();
226 * Determines whether or not the specified object
227 * is currently a child of this <tt>BeanContext</tt>.
228 * @param o the Object in question
229 * @return if this object is a child
231 public boolean contains(Object o) {
232 synchronized(children) {
233 return children.containsKey(o);
238 * Determines whether or not the specified object
239 * is currently a child of this <tt>BeanContext</tt>.
240 * @param o the Object in question
241 * @return if this object is a child
243 public boolean containsKey(Object o) {
244 synchronized(children) {
245 return children.containsKey(o);
250 * Gets all JavaBean or <tt>BeanContext</tt> instances
251 * currently nested in this <tt>BeanContext</tt>.
252 * @return an <tt>Iterator</tt> of the nested children
254 public Iterator iterator() {
255 synchronized(children) {
256 return new BCSIterator(children.keySet().iterator());
261 * Gets all JavaBean or <tt>BeanContext</tt>
262 * instances currently nested in this BeanContext.
264 public Object[] toArray() {
265 synchronized(children) {
266 return children.keySet().toArray();
271 * Gets an array containing all children of
272 * this <tt>BeanContext</tt> that match
273 * the types contained in arry.
274 * @param arry The array of object
275 * types that are of interest.
276 * @return an array of children
278 public Object[] toArray(Object[] arry) {
279 synchronized(children) {
280 return children.keySet().toArray(arry);
285 /************************************************************************/
288 * protected final subclass that encapsulates an iterator but implements
289 * a noop remove() method.
292 protected static final class BCSIterator implements Iterator {
293 BCSIterator(Iterator i) { super(); src = i; }
295 public boolean hasNext() { return src.hasNext(); }
296 public Object next() { return src.next(); }
297 public void remove() { /* do nothing */ }
299 private Iterator src;
302 /************************************************************************/
305 * protected nested class containing per child information, an instance
306 * of which is associated with each child in the "children" hashtable.
307 * subclasses can extend this class to include their own per-child state.
309 * Note that this 'value' is serialized with the corresponding child 'key'
310 * when the BeanContextSupport is serialized.
313 protected class BCSChild implements Serializable {
315 private static final long serialVersionUID = -5815286101609939109L;
317 BCSChild(Object bcc, Object peer) {
324 Object getChild() { return child; }
326 void setRemovePending(boolean v) { removePending = v; }
328 boolean isRemovePending() { return removePending; }
330 boolean isProxyPeer() { return proxyPeer != null; }
332 Object getProxyPeer() { return proxyPeer; }
338 private Object child;
339 private Object proxyPeer;
341 private transient boolean removePending;
346 * Subclasses can override this method to insert their own subclass
347 * of Child without having to override add() or the other Collection
348 * methods that add children to the set.
351 * @param targetChild the child to create the Child on behalf of
352 * @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy
355 protected BCSChild createBCSChild(Object targetChild, Object peer) {
356 return new BCSChild(targetChild, peer);
359 /************************************************************************/
362 * Adds/nests a child within this <tt>BeanContext</tt>.
364 * Invoked as a side effect of java.beans.Beans.instantiate().
365 * If the child object is not valid for adding then this method
366 * throws an IllegalStateException.
370 * @param targetChild The child objects to nest
371 * within this <tt>BeanContext</tt>
372 * @return true if the child was added successfully.
373 * @see #validatePendingAdd
375 public boolean add(Object targetChild) {
377 if (targetChild == null) throw new IllegalArgumentException();
379 // The specification requires that we do nothing if the child
380 // is already nested herein.
382 if (children.containsKey(targetChild)) return false; // test before locking
384 synchronized(BeanContext.globalHierarchyLock) {
385 if (children.containsKey(targetChild)) return false; // check again
387 if (!validatePendingAdd(targetChild)) {
388 throw new IllegalStateException();
392 // The specification requires that we invoke setBeanContext() on the
393 // newly added child if it implements the java.beans.beancontext.BeanContextChild interface
395 BeanContextChild cbcc = getChildBeanContextChild(targetChild);
396 BeanContextChild bccp = null;
398 synchronized(targetChild) {
400 if (targetChild instanceof BeanContextProxy) {
401 bccp = ((BeanContextProxy)targetChild).getBeanContextProxy();
403 if (bccp == null) throw new NullPointerException("BeanContextPeer.getBeanContextProxy()");
406 BCSChild bcsc = createBCSChild(targetChild, bccp);
407 BCSChild pbcsc = null;
409 synchronized (children) {
410 children.put(targetChild, bcsc);
412 if (bccp != null) children.put(bccp, pbcsc = createBCSChild(bccp, targetChild));
415 if (cbcc != null) synchronized(cbcc) {
417 cbcc.setBeanContext(getBeanContextPeer());
418 } catch (PropertyVetoException pve) {
420 synchronized (children) {
421 children.remove(targetChild);
423 if (bccp != null) children.remove(bccp);
426 throw new IllegalStateException();
429 cbcc.addPropertyChangeListener("beanContext", childPCL);
430 cbcc.addVetoableChangeListener("beanContext", childVCL);
433 Visibility v = getChildVisibility(targetChild);
442 if (getChildSerializable(targetChild) != null) serializable++;
444 childJustAddedHook(targetChild, bcsc);
447 v = getChildVisibility(bccp);
456 if (getChildSerializable(bccp) != null) serializable++;
458 childJustAddedHook(bccp, pbcsc);
464 // The specification requires that we fire a notification of the change
466 fireChildrenAdded(new BeanContextMembershipEvent(getBeanContextPeer(), bccp == null ? new Object[] { targetChild } : new Object[] { targetChild, bccp } ));
474 * Removes a child from this BeanContext. If the child object is not
475 * for adding then this method throws an IllegalStateException.
476 * @param targetChild The child objects to remove
477 * @see #validatePendingRemove
479 public boolean remove(Object targetChild) {
480 return remove(targetChild, true);
484 * internal remove used when removal caused by
485 * unexpected <tt>setBeanContext</tt> or
486 * by <tt>remove()</tt> invocation.
487 * @param targetChild the JavaBean, BeanContext, or Object to be removed
488 * @param callChildSetBC used to indicate that
489 * the child should be notified that it is no
490 * longer nested in this <tt>BeanContext</tt>.
492 protected boolean remove(Object targetChild, boolean callChildSetBC) {
494 if (targetChild == null) throw new IllegalArgumentException();
496 synchronized(BeanContext.globalHierarchyLock) {
497 if (!containsKey(targetChild)) return false;
499 if (!validatePendingRemove(targetChild)) {
500 throw new IllegalStateException();
503 BCSChild bcsc = (BCSChild)children.get(targetChild);
504 BCSChild pbcsc = null;
507 // we are required to notify the child that it is no longer nested here if
508 // it implements java.beans.beancontext.BeanContextChild
510 synchronized(targetChild) {
511 if (callChildSetBC) {
512 BeanContextChild cbcc = getChildBeanContextChild(targetChild);
513 if (cbcc != null) synchronized(cbcc) {
514 cbcc.removePropertyChangeListener("beanContext", childPCL);
515 cbcc.removeVetoableChangeListener("beanContext", childVCL);
518 cbcc.setBeanContext(null);
519 } catch (PropertyVetoException pve1) {
520 cbcc.addPropertyChangeListener("beanContext", childPCL);
521 cbcc.addVetoableChangeListener("beanContext", childVCL);
522 throw new IllegalStateException();
528 synchronized (children) {
529 children.remove(targetChild);
531 if (bcsc.isProxyPeer()) {
532 pbcsc = (BCSChild)children.get(peer = bcsc.getProxyPeer());
533 children.remove(peer);
537 if (getChildSerializable(targetChild) != null) serializable--;
539 childJustRemovedHook(targetChild, bcsc);
542 if (getChildSerializable(peer) != null) serializable--;
544 childJustRemovedHook(peer, pbcsc);
548 fireChildrenRemoved(new BeanContextMembershipEvent(getBeanContextPeer(), peer == null ? new Object[] { targetChild } : new Object[] { targetChild, peer } ));
556 * Tests to see if all objects in the
557 * specified <tt>Collection</tt> are children of
558 * this <tt>BeanContext</tt>.
559 * @param c the specified <tt>Collection</tt>
561 * @return <tt>true</tt> if all objects
562 * in the collection are children of
563 * this <tt>BeanContext</tt>, false if not.
565 public boolean containsAll(Collection c) {
566 synchronized(children) {
567 Iterator i = c.iterator();
569 if(!contains(i.next()))
577 * add Collection to set of Children (Unsupported)
578 * implementations must synchronized on the hierarchy lock and "children" protected field
579 * @throws UnsupportedOperationException
581 public boolean addAll(Collection c) {
582 throw new UnsupportedOperationException();
586 * remove all specified children (Unsupported)
587 * implementations must synchronized on the hierarchy lock and "children" protected field
588 * @throws UnsupportedOperationException
590 public boolean removeAll(Collection c) {
591 throw new UnsupportedOperationException();
596 * retain only specified children (Unsupported)
597 * implementations must synchronized on the hierarchy lock and "children" protected field
598 * @throws UnsupportedOperationException
600 public boolean retainAll(Collection c) {
601 throw new UnsupportedOperationException();
605 * clear the children (Unsupported)
606 * implementations must synchronized on the hierarchy lock and "children" protected field
607 * @throws UnsupportedOperationException
609 public void clear() {
610 throw new UnsupportedOperationException();
614 * Adds a BeanContextMembershipListener
616 * @param bcml the BeanContextMembershipListener to add
617 * @throws NullPointerException
620 public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) {
621 if (bcml == null) throw new NullPointerException("listener");
623 synchronized(bcmListeners) {
624 if (bcmListeners.contains(bcml))
627 bcmListeners.add(bcml);
632 * Removes a BeanContextMembershipListener
634 * @param bcml the BeanContextMembershipListener to remove
635 * @throws NullPointerException
638 public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) {
639 if (bcml == null) throw new NullPointerException("listener");
641 synchronized(bcmListeners) {
642 if (!bcmListeners.contains(bcml))
645 bcmListeners.remove(bcml);
650 * @param name the name of the resource requested.
651 * @param bcc the child object making the request.
653 * @return the requested resource as an InputStream
654 * @throws NullPointerException
657 public InputStream getResourceAsStream(String name, BeanContextChild bcc) {
658 if (name == null) throw new NullPointerException("name");
659 if (bcc == null) throw new NullPointerException("bcc");
661 if (containsKey(bcc)) {
662 ClassLoader cl = bcc.getClass().getClassLoader();
664 return cl != null ? cl.getResourceAsStream(name)
665 : ClassLoader.getSystemResourceAsStream(name);
666 } else throw new IllegalArgumentException("Not a valid child");
670 * @param name the name of the resource requested.
671 * @param bcc the child object making the request.
673 * @return the requested resource as an InputStream
676 public URL getResource(String name, BeanContextChild bcc) {
677 if (name == null) throw new NullPointerException("name");
678 if (bcc == null) throw new NullPointerException("bcc");
680 if (containsKey(bcc)) {
681 ClassLoader cl = bcc.getClass().getClassLoader();
683 return cl != null ? cl.getResource(name)
684 : ClassLoader.getSystemResource(name);
685 } else throw new IllegalArgumentException("Not a valid child");
689 * Sets the new design time value for this <tt>BeanContext</tt>.
690 * @param dTime the new designTime value
692 public synchronized void setDesignTime(boolean dTime) {
693 if (designTime != dTime) {
696 firePropertyChange("designMode", Boolean.valueOf(!dTime), Boolean.valueOf(dTime));
702 * Reports whether or not this object is in
703 * currently in design time mode.
704 * @return <tt>true</tt> if in design time mode,
705 * <tt>false</tt> if not
707 public synchronized boolean isDesignTime() { return designTime; }
710 * Sets the locale of this BeanContext.
711 * @param newLocale the new locale. This method call will have
712 * no effect if newLocale is <CODE>null</CODE>.
713 * @throws PropertyVetoException if the new value is rejected
715 public synchronized void setLocale(Locale newLocale) throws PropertyVetoException {
717 if ((locale != null && !locale.equals(newLocale)) && newLocale != null) {
720 fireVetoableChange("locale", old, newLocale); // throws
724 firePropertyChange("locale", old, newLocale);
729 * Gets the locale for this <tt>BeanContext</tt>.
731 * @return the current Locale of the <tt>BeanContext</tt>
733 public synchronized Locale getLocale() { return locale; }
737 * This method is typically called from the environment in order to determine
738 * if the implementor "needs" a GUI.
741 * The algorithm used herein tests the BeanContextPeer, and its current children
742 * to determine if they are either Containers, Components, or if they implement
743 * Visibility and return needsGui() == true.
745 * @return <tt>true</tt> if the implementor needs a GUI
747 public synchronized boolean needsGui() {
748 BeanContext bc = getBeanContextPeer();
751 if (bc instanceof Visibility) return ((Visibility)bc).needsGui();
753 if (bc instanceof Container || bc instanceof Component)
757 synchronized(children) {
758 for (Iterator i = children.keySet().iterator(); i.hasNext();) {
762 return ((Visibility)c).needsGui();
763 } catch (ClassCastException cce) {
767 if (c instanceof Container || c instanceof Component)
776 * notify this instance that it may no longer render a GUI.
779 public synchronized void dontUseGui() {
783 // lets also tell the Children that can that they may not use their GUI's
784 synchronized(children) {
785 for (Iterator i = children.keySet().iterator(); i.hasNext();) {
786 Visibility v = getChildVisibility(i.next());
788 if (v != null) v.dontUseGui();
795 * Notify this instance that it may now render a GUI
798 public synchronized void okToUseGui() {
802 // lets also tell the Children that can that they may use their GUI's
803 synchronized(children) {
804 for (Iterator i = children.keySet().iterator(); i.hasNext();) {
805 Visibility v = getChildVisibility(i.next());
807 if (v != null) v.okToUseGui();
814 * Used to determine if the <tt>BeanContext</tt>
815 * child is avoiding using its GUI.
816 * @return is this instance avoiding using its GUI?
819 public boolean avoidingGui() {
820 return !okToUseGui && needsGui();
824 * Is this <tt>BeanContext</tt> in the
825 * process of being serialized?
826 * @return if this <tt>BeanContext</tt> is
827 * currently being serialized
829 public boolean isSerializing() { return serializing; }
832 * Returns an iterator of all children
833 * of this <tt>BeanContext</tt>.
834 * @return an iterator for all the current BCSChild values
836 protected Iterator bcsChildren() { synchronized(children) { return children.values().iterator(); } }
839 * called by writeObject after defaultWriteObject() but prior to
840 * serialization of currently serializable children.
842 * This method may be overridden by subclasses to perform custom
843 * serialization of their state prior to this superclass serializing
846 * This method should not however be used by subclasses to replace their
847 * own implementation (if any) of writeObject().
850 protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException {
854 * called by readObject after defaultReadObject() but prior to
855 * deserialization of any children.
857 * This method may be overridden by subclasses to perform custom
858 * deserialization of their state prior to this superclass deserializing
861 * This method should not however be used by subclasses to replace their
862 * own implementation (if any) of readObject().
865 protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException {
869 * Called by readObject with the newly deserialized child and BCSChild.
870 * @param child the newly deserialized child
871 * @param bcsc the newly deserialized BCSChild
873 protected void childDeserializedHook(Object child, BCSChild bcsc) {
874 synchronized(children) {
875 children.put(child, bcsc);
880 * Used by writeObject to serialize a Collection.
881 * @param oos the <tt>ObjectOutputStream</tt>
882 * to use during serialization
883 * @param coll the <tt>Collection</tt> to serialize
884 * @throws IOException if serialization failed
886 protected final void serialize(ObjectOutputStream oos, Collection coll) throws IOException {
888 Object[] objects = coll.toArray();
890 for (int i = 0; i < objects.length; i++) {
891 if (objects[i] instanceof Serializable)
897 oos.writeInt(count); // number of subsequent objects
899 for (int i = 0; count > 0; i++) {
900 Object o = objects[i];
910 * used by readObject to deserialize a collection.
911 * @param ois the ObjectInputStream to use
912 * @param coll the Collection
914 protected final void deserialize(ObjectInputStream ois, Collection coll) throws IOException, ClassNotFoundException {
917 count = ois.readInt();
919 while (count-- > 0) {
920 coll.add(ois.readObject());
925 * Used to serialize all children of
926 * this <tt>BeanContext</tt>.
927 * @param oos the <tt>ObjectOutputStream</tt>
928 * to use during serialization
929 * @throws IOException if serialization failed
931 public final void writeChildren(ObjectOutputStream oos) throws IOException {
932 if (serializable <= 0) return;
934 boolean prev = serializing;
940 synchronized(children) {
941 Iterator i = children.entrySet().iterator();
943 while (i.hasNext() && count < serializable) {
944 Map.Entry entry = (Map.Entry)i.next();
946 if (entry.getKey() instanceof Serializable) {
948 oos.writeObject(entry.getKey()); // child
949 oos.writeObject(entry.getValue()); // BCSChild
950 } catch (IOException ioe) {
961 if (count != serializable) {
962 throw new IOException("wrote different number of children than expected");
968 * Serialize the BeanContextSupport, if this instance has a distinct
969 * peer (that is this object is acting as a delegate for another) then
970 * the children of this instance are not serialized here due to a
971 * 'chicken and egg' problem that occurs on deserialization of the
972 * children at the same time as this instance.
974 * Therefore in situations where there is a distinct peer to this instance
975 * it should always call writeObject() followed by writeChildren() and
976 * readObject() followed by readChildren().
978 * @param oos the ObjectOutputStream
981 private synchronized void writeObject(ObjectOutputStream oos) throws IOException, ClassNotFoundException {
984 synchronized (BeanContext.globalHierarchyLock) {
986 oos.defaultWriteObject(); // serialize the BeanContextSupport object
988 bcsPreSerializationHook(oos);
990 if (serializable > 0 && this.equals(getBeanContextPeer()))
993 serialize(oos, (Collection)bcmListeners);
1001 * When an instance of this class is used as a delegate for the
1002 * implementation of the BeanContext protocols (and its subprotocols)
1003 * there exists a 'chicken and egg' problem during deserialization
1006 public final void readChildren(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1007 int count = serializable;
1009 while (count-- > 0) {
1010 Object child = null;
1011 BeanContextSupport.BCSChild bscc = null;
1014 child = ois.readObject();
1015 bscc = (BeanContextSupport.BCSChild)ois.readObject();
1016 } catch (IOException ioe) {
1018 } catch (ClassNotFoundException cnfe) {
1023 synchronized(child) {
1024 BeanContextChild bcc = null;
1027 bcc = (BeanContextChild)child;
1028 } catch (ClassCastException cce) {
1034 bcc.setBeanContext(getBeanContextPeer());
1036 bcc.addPropertyChangeListener("beanContext", childPCL);
1037 bcc.addVetoableChangeListener("beanContext", childVCL);
1039 } catch (PropertyVetoException pve) {
1044 childDeserializedHook(child, bscc);
1050 * deserialize contents ... if this instance has a distinct peer the
1051 * children are *not* serialized here, the peer's readObject() must call
1052 * readChildren() after deserializing this instance.
1055 private synchronized void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
1057 synchronized(BeanContext.globalHierarchyLock) {
1058 ois.defaultReadObject();
1062 bcsPreDeserializationHook(ois);
1064 if (serializable > 0 && this.equals(getBeanContextPeer()))
1067 deserialize(ois, bcmListeners = new ArrayList(1));
1072 * subclasses may envelope to monitor veto child property changes.
1075 public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
1076 String propertyName = pce.getPropertyName();
1077 Object source = pce.getSource();
1079 synchronized(children) {
1080 if ("beanContext".equals(propertyName) &&
1081 containsKey(source) &&
1082 !getBeanContextPeer().equals(pce.getNewValue())
1084 if (!validatePendingRemove(source)) {
1085 throw new PropertyVetoException("current BeanContext vetoes setBeanContext()", pce);
1086 } else ((BCSChild)children.get(source)).setRemovePending(true);
1092 * subclasses may envelope to monitor child property changes.
1095 public void propertyChange(PropertyChangeEvent pce) {
1096 String propertyName = pce.getPropertyName();
1097 Object source = pce.getSource();
1099 synchronized(children) {
1100 if ("beanContext".equals(propertyName) &&
1101 containsKey(source) &&
1102 ((BCSChild)children.get(source)).isRemovePending()) {
1103 BeanContext bc = getBeanContextPeer();
1105 if (bc.equals(pce.getOldValue()) && !bc.equals(pce.getNewValue())) {
1106 remove(source, false);
1108 ((BCSChild)children.get(source)).setRemovePending(false);
1116 * Subclasses of this class may override, or envelope, this method to
1117 * add validation behavior for the BeanContext to examine child objects
1118 * immediately prior to their being added to the BeanContext.
1121 * @return true iff the child may be added to this BeanContext, otherwise false.
1124 protected boolean validatePendingAdd(Object targetChild) {
1130 * Subclasses of this class may override, or envelope, this method to
1131 * add validation behavior for the BeanContext to examine child objects
1132 * immediately prior to their being removed from the BeanContext.
1135 * @return true iff the child may be removed from this BeanContext, otherwise false.
1138 protected boolean validatePendingRemove(Object targetChild) {
1143 * subclasses may override this method to simply extend add() semantics
1144 * after the child has been added and before the event notification has
1145 * occurred. The method is called with the child synchronized.
1148 protected void childJustAddedHook(Object child, BCSChild bcsc) {
1152 * subclasses may override this method to simply extend remove() semantics
1153 * after the child has been removed and before the event notification has
1154 * occurred. The method is called with the child synchronized.
1157 protected void childJustRemovedHook(Object child, BCSChild bcsc) {
1161 * Gets the Component (if any) associated with the specified child.
1162 * @param child the specified child
1163 * @return the Component (if any) associated with the specified child.
1165 protected static final Visibility getChildVisibility(Object child) {
1167 return (Visibility)child;
1168 } catch (ClassCastException cce) {
1174 * Gets the Serializable (if any) associated with the specified Child
1175 * @param child the specified child
1176 * @return the Serializable (if any) associated with the specified Child
1178 protected static final Serializable getChildSerializable(Object child) {
1180 return (Serializable)child;
1181 } catch (ClassCastException cce) {
1187 * Gets the PropertyChangeListener
1188 * (if any) of the specified child
1189 * @param child the specified child
1190 * @return the PropertyChangeListener (if any) of the specified child
1192 protected static final PropertyChangeListener getChildPropertyChangeListener(Object child) {
1194 return (PropertyChangeListener)child;
1195 } catch (ClassCastException cce) {
1201 * Gets the VetoableChangeListener
1202 * (if any) of the specified child
1203 * @param child the specified child
1204 * @return the VetoableChangeListener (if any) of the specified child
1206 protected static final VetoableChangeListener getChildVetoableChangeListener(Object child) {
1208 return (VetoableChangeListener)child;
1209 } catch (ClassCastException cce) {
1215 * Gets the BeanContextMembershipListener
1216 * (if any) of the specified child
1217 * @param child the specified child
1218 * @return the BeanContextMembershipListener (if any) of the specified child
1220 protected static final BeanContextMembershipListener getChildBeanContextMembershipListener(Object child) {
1222 return (BeanContextMembershipListener)child;
1223 } catch (ClassCastException cce) {
1229 * Gets the BeanContextChild (if any) of the specified child
1230 * @param child the specified child
1231 * @return the BeanContextChild (if any) of the specified child
1232 * @throws IllegalArgumentException if child implements both BeanContextChild and BeanContextProxy
1234 protected static final BeanContextChild getChildBeanContextChild(Object child) {
1236 BeanContextChild bcc = (BeanContextChild)child;
1238 if (child instanceof BeanContextChild && child instanceof BeanContextProxy)
1239 throw new IllegalArgumentException("child cannot implement both BeanContextChild and BeanContextProxy");
1242 } catch (ClassCastException cce) {
1244 return ((BeanContextProxy)child).getBeanContextProxy();
1245 } catch (ClassCastException cce1) {
1252 * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
1255 protected final void fireChildrenAdded(BeanContextMembershipEvent bcme) {
1258 synchronized(bcmListeners) { copy = bcmListeners.toArray(); }
1260 for (int i = 0; i < copy.length; i++)
1261 ((BeanContextMembershipListener)copy[i]).childrenAdded(bcme);
1265 * Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
1268 protected final void fireChildrenRemoved(BeanContextMembershipEvent bcme) {
1271 synchronized(bcmListeners) { copy = bcmListeners.toArray(); }
1273 for (int i = 0; i < copy.length; i++)
1274 ((BeanContextMembershipListener)copy[i]).childrenRemoved(bcme);
1278 * protected method called from constructor and readObject to initialize
1279 * transient state of BeanContextSupport instance.
1281 * This class uses this method to instantiate inner class listeners used
1282 * to monitor PropertyChange and VetoableChange events on children.
1284 * subclasses may envelope this method to add their own initialization
1288 protected synchronized void initialize() {
1289 children = new HashMap(serializable + 1);
1290 bcmListeners = new ArrayList(1);
1292 childPCL = new PropertyChangeListener() {
1295 * this adaptor is used by the BeanContextSupport class to forward
1296 * property changes from a child to the BeanContext, avoiding
1297 * accidential serialization of the BeanContext by a badly
1298 * behaved Serializable child.
1301 public void propertyChange(PropertyChangeEvent pce) {
1302 BeanContextSupport.this.propertyChange(pce);
1306 childVCL = new VetoableChangeListener() {
1309 * this adaptor is used by the BeanContextSupport class to forward
1310 * vetoable changes from a child to the BeanContext, avoiding
1311 * accidential serialization of the BeanContext by a badly
1312 * behaved Serializable child.
1315 public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
1316 BeanContextSupport.this.vetoableChange(pce);
1322 * Gets a copy of the this BeanContext's children.
1323 * @return a copy of the current nested children
1325 protected final Object[] copyChildren() {
1326 synchronized(children) { return children.keySet().toArray(); }
1330 * Tests to see if two class objects,
1331 * or their names are equal.
1332 * @param first the first object
1333 * @param second the second object
1334 * @return true if equal, false if not
1336 protected static final boolean classEquals(Class first, Class second) {
1337 return first.equals(second) || first.getName().equals(second.getName());
1347 * all accesses to the <code> protected HashMap children </code> field
1348 * shall be synchronized on that object.
1350 protected transient HashMap children;
1352 private int serializable = 0; // children serializable
1355 * all accesses to the <code> protected ArrayList bcmListeners </code> field
1356 * shall be synchronized on that object.
1358 protected transient ArrayList bcmListeners;
1363 * The current locale of this BeanContext.
1365 protected Locale locale;
1368 * A <tt>boolean</tt> indicating if this
1369 * instance may now render a GUI.
1371 protected boolean okToUseGui;
1375 * A <tt>boolean</tt> indicating whether or not
1376 * this object is currently in design time mode.
1378 protected boolean designTime;
1384 private transient PropertyChangeListener childPCL;
1386 private transient VetoableChangeListener childVCL;
1388 private transient boolean serializing;