KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > beans > beancontext > BeanContextSupport


1 /*
2  * @(#)BeanContextSupport.java 1.46 03/01/13
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.beans.beancontext;
9
10 import java.awt.Component JavaDoc;
11 import java.awt.Container JavaDoc;
12
13 import java.beans.Beans JavaDoc;
14 import java.beans.AppletInitializer JavaDoc;
15
16 import java.beans.DesignMode JavaDoc;
17
18 import java.beans.PropertyChangeEvent JavaDoc;
19 import java.beans.PropertyChangeListener JavaDoc;
20 import java.beans.PropertyChangeSupport JavaDoc;
21
22 import java.beans.VetoableChangeListener JavaDoc;
23 import java.beans.VetoableChangeSupport JavaDoc;
24 import java.beans.PropertyVetoException JavaDoc;
25
26 import java.beans.Visibility JavaDoc;
27
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.io.ObjectInputStream JavaDoc;
31 import java.io.ObjectOutputStream JavaDoc;
32 import java.io.Serializable JavaDoc;
33
34 import java.net.URL JavaDoc;
35
36 import java.util.ArrayList JavaDoc;
37 import java.util.Collection JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.Locale JavaDoc;
41 import java.util.Map JavaDoc;
42
43
44 /**
45  * This helper class provides a utility implementation of the
46  * java.beans.beancontext.BeanContext interface.
47  * </p>
48  * <p>
49  * Since this class directly implements the BeanContext interface, the class
50  * can, and is intended to be used either by subclassing this implementation,
51  * or via ad-hoc delegation of an instance of this class from another.
52  * </p>
53  *
54  * @author Laurence P. G. Cable
55  * @version 1.46, 01/13/03
56  * @since 1.2
57  */

58 public class BeanContextSupport extends BeanContextChildSupport JavaDoc
59        implements BeanContext JavaDoc,
60           Serializable JavaDoc,
61           PropertyChangeListener JavaDoc,
62           VetoableChangeListener JavaDoc {
63
64     // Fix for bug 4282900 to pass JCK regression test
65
static final long serialVersionUID = -4879613978649577204L;
66
67     /**
68      *
69      * Construct a BeanContextSupport instance
70      *
71      *
72      * @param peer The peer <tt>BeanContext</tt> we are
73      * supplying an implementation for,
74      * or <tt>null</tt>
75      * if this object is its own peer
76      * @param lcle The current Locale for this BeanContext. If
77      * <tt>lcle</tt> is <tt>null</tt>, the default locale
78      * is assigned to the <tt>BeanContext</tt> instance.
79      * @param dTime The initial state,
80      * <tt>true</tt> if in design mode,
81      * <tt>false</tt> if runtime.
82      * @param visible The initial visibility.
83      * @see java.util.Locale#getDefault()
84      * @see java.util.Locale#setDefault(java.util.Locale)
85      */

86     public BeanContextSupport(BeanContext JavaDoc peer, Locale JavaDoc lcle, boolean dTime, boolean visible) {
87     super(peer);
88
89     locale = lcle != null ? lcle : Locale.getDefault();
90     designTime = dTime;
91     okToUseGui = visible;
92
93     initialize();
94     }
95
96     /**
97      * Create an instance using the specified Locale and design mode.
98      *
99      * @param peer The peer <tt>BeanContext</tt> we
100      * are supplying an implementation for,
101      * or <tt>null</tt> if this object is its own peer
102      * @param lcle The current Locale for this <tt>BeanContext</tt>. If
103      * <tt>lcle</tt> is <tt>null</tt>, the default locale
104      * is assigned to the <tt>BeanContext</tt> instance.
105      * @param dtime The initial state, <tt>true</tt>
106      * if in design mode,
107      * <tt>false</tt> if runtime.
108      * @see java.util.Locale#getDefault()
109      * @see java.util.Locale#setDefault(java.util.Locale)
110      */

111     public BeanContextSupport(BeanContext JavaDoc peer, Locale JavaDoc lcle, boolean dtime) {
112     this (peer, lcle, dtime, true);
113     }
114
115     /**
116      * Create an instance using the specified locale
117      *
118      * @param peer The peer BeanContext we are
119      * supplying an implementation for,
120      * or <tt>null</tt> if this object
121      * is its own peer
122      * @param lcle The current Locale for this
123      * <tt>BeanContext</tt>. If
124      * <tt>lcle</tt> is <tt>null</tt>,
125      * the default locale
126      * is assigned to the <tt>BeanContext</tt>
127      * instance.
128      * @see java.util.Locale#getDefault()
129      * @see java.util.Locale#setDefault(java.util.Locale)
130      */

131     public BeanContextSupport(BeanContext JavaDoc peer, Locale JavaDoc lcle) {
132     this (peer, lcle, false, true);
133     }
134
135     /**
136      * Create an instance using with a default locale
137      *
138      * @param peer The peer <tt>BeanContext</tt> we are
139      * supplying an implementation for,
140      * or <tt>null</tt> if this object
141      * is its own peer
142      */

143     public BeanContextSupport(BeanContext JavaDoc peer) {
144     this (peer, null, false, true);
145     }
146
147     /**
148      * Create an instance that is not a delegate of another object
149      */

150
151     public BeanContextSupport() {
152     this (null, null, false, true);
153     }
154
155     /**
156      * Gets the instance of <tt>BeanContext</tt> that
157      * this object is providing the implementation for.
158      * @return the BeanContext instance
159      */

160     public BeanContext JavaDoc getBeanContextPeer() { return (BeanContext JavaDoc)getBeanContextChildPeer(); }
161
162     /**
163      * <p>
164      * The instantiateChild method is a convenience hook
165      * in BeanContext to simplify
166      * the task of instantiating a Bean, nested,
167      * into a <tt>BeanContext</tt>.
168      * </p>
169      * <p>
170      * The semantics of the beanName parameter are defined by java.beans.Beans.instantate.
171      * </p>
172      *
173      * @param beanName the name of the Bean to instantiate within this BeanContext
174      * @throws IOException if there is an I/O error when the bean is being deserialized
175      * @throws ClassNotFoundException if the class
176      * identified by the beanName parameter is not found
177      * @return the new object
178      */

179     public Object JavaDoc instantiateChild(String JavaDoc beanName)
180        throws IOException JavaDoc, ClassNotFoundException JavaDoc {
181     BeanContext JavaDoc bc = getBeanContextPeer();
182
183     return Beans.instantiate(bc.getClass().getClassLoader(), beanName, bc);
184     }
185
186     /**
187      * Gets the number of children currently nested in
188      * this BeanContext.
189      *
190      * @return number of children
191      */

192     public int size() {
193     synchronized(children) {
194         return children.size();
195     }
196     }
197
198     /**
199      * Reports whether or not this
200      * <tt>BeanContext</tt> is empty.
201      * A <tt>BeanContext</tt> is considered
202      * empty when it contains zero
203      * nested children.
204      * @return if there are not children
205      */

206     public boolean isEmpty() {
207     synchronized(children) {
208         return children.isEmpty();
209     }
210     }
211
212     /**
213      * Determines whether or not the specified object
214      * is currently a child of this <tt>BeanContext</tt>.
215      * @param o the Object in question
216      * @return if this object is a child
217      */

218     public boolean contains(Object JavaDoc o) {
219     synchronized(children) {
220         return children.containsKey(o);
221     }
222     }
223
224     /**
225      * Determines whether or not the specified object
226      * is currently a child of this <tt>BeanContext</tt>.
227      * @param o the Object in question
228      * @return if this object is a child
229      */

230     public boolean containsKey(Object JavaDoc o) {
231     synchronized(children) {
232         return children.containsKey(o);
233     }
234     }
235
236     /**
237      * Gets all JavaBean or <tt>BeanContext</tt> instances
238      * currently nested in this <tt>BeanContext</tt>.
239      * @return an <tt>Iterator</tt> of the nested children
240      */

241     public Iterator JavaDoc iterator() {
242     synchronized(children) {
243         return new BCSIterator(children.keySet().iterator());
244     }
245     }
246
247     /**
248      * Gets all JavaBean or <tt>BeanContext</tt>
249      * instances currently nested in this BeanContext.
250      */

251     public Object JavaDoc[] toArray() {
252     synchronized(children) {
253         return children.keySet().toArray();
254     }
255     }
256
257     /**
258      * Gets an array containing all children of
259      * this <tt>BeanContext</tt> that match
260      * the types contained in arry.
261      * @param arry The array of object
262      * types that are of interest.
263      * @return an array of children
264      */

265     public Object JavaDoc[] toArray(Object JavaDoc[] arry) {
266     synchronized(children) {
267         return children.keySet().toArray(arry);
268     }
269     }
270
271
272     /************************************************************************/
273
274     /**
275      * protected final subclass that encapsulates an iterator but implements
276      * a noop remove() method.
277      */

278
279     protected static final class BCSIterator implements Iterator JavaDoc {
280     BCSIterator(Iterator JavaDoc i) { super(); src = i; }
281
282     public boolean hasNext() { return src.hasNext(); }
283     public Object JavaDoc next() { return src.next(); }
284     public void remove() { /* do nothing */ }
285
286     private Iterator JavaDoc src;
287     }
288
289     /************************************************************************/
290
291     /*
292      * protected nested class containing per child information, an instance
293      * of which is associated with each child in the "children" hashtable.
294      * subclasses can extend this class to include their own per-child state.
295      *
296      * Note that this 'value' is serialized with the corresponding child 'key'
297      * when the BeanContextSupport is serialized.
298      */

299
300     protected class BCSChild implements Serializable JavaDoc {
301
302     private static final long serialVersionUID = -5815286101609939109L;
303
304     BCSChild(Object JavaDoc bcc, Object JavaDoc peer) {
305         super();
306
307         child = bcc;
308         proxyPeer = peer;
309     }
310
311     Object JavaDoc getChild() { return child; }
312
313     void setRemovePending(boolean v) { removePending = v; }
314
315     boolean isRemovePending() { return removePending; }
316
317         boolean isProxyPeer() { return proxyPeer != null; }
318
319     Object JavaDoc getProxyPeer() { return proxyPeer; }
320     /*
321      * fields
322      */

323
324
325     private Object JavaDoc child;
326     private Object JavaDoc proxyPeer;
327
328     private transient boolean removePending;
329     }
330
331     /**
332      * <p>
333      * Subclasses can override this method to insert their own subclass
334      * of Child without having to override add() or the other Collection
335      * methods that add children to the set.
336      * </p>
337      *
338      * @param targetChild the child to create the Child on behalf of
339      * @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy
340      */

341
342     protected BCSChild createBCSChild(Object JavaDoc targetChild, Object JavaDoc peer) {
343     return new BCSChild(targetChild, peer);
344     }
345
346     /************************************************************************/
347
348     /**
349      * Adds/nests a child within this <tt>BeanContext</tt>.
350      * <p>
351      * Invoked as a side effect of java.beans.Beans.instantiate().
352      * If the child object is not valid for adding then this method
353      * throws an IllegalStateException.
354      * </p>
355      *
356      *
357      * @param targetChild The child objects to nest
358      * within this <tt>BeanContext</tt>
359      * @return true if the child was added successfully.
360      * @see #validatePendingAdd
361      */

362     public boolean add(Object JavaDoc targetChild) {
363
364     if (targetChild == null) throw new IllegalArgumentException JavaDoc();
365
366     // The specification requires that we do nothing if the child
367
// is already nested herein.
368

369     if (children.containsKey(targetChild)) return false; // test before locking
370

371     synchronized(BeanContext.globalHierarchyLock) {
372         if (children.containsKey(targetChild)) return false; // check again
373

374         if (!validatePendingAdd(targetChild)) {
375             throw new IllegalStateException JavaDoc();
376         }
377
378
379         // The specification requires that we invoke setBeanContext() on the
380
// newly added child if it implements the java.beans.beancontext.BeanContextChild interface
381

382         BeanContextChild JavaDoc cbcc = getChildBeanContextChild(targetChild);
383         BeanContextChild JavaDoc bccp = null;
384
385         synchronized(targetChild) {
386
387         if (targetChild instanceof BeanContextProxy JavaDoc) {
388             bccp = ((BeanContextProxy JavaDoc)targetChild).getBeanContextProxy();
389
390             if (bccp == null) throw new NullPointerException JavaDoc("BeanContextPeer.getBeanContextProxy()");
391         }
392
393             BCSChild bcsc = createBCSChild(targetChild, bccp);
394         BCSChild pbcsc = null;
395
396             synchronized (children) {
397             children.put(targetChild, bcsc);
398
399             if (bccp != null) children.put(bccp, pbcsc = createBCSChild(bccp, targetChild));
400         }
401
402             if (cbcc != null) synchronized(cbcc) {
403             try {
404                     cbcc.setBeanContext(getBeanContextPeer());
405                 } catch (PropertyVetoException JavaDoc pve) {
406
407                 synchronized (children) {
408                 children.remove(targetChild);
409
410                 if (bccp != null) children.remove(bccp);
411             }
412
413                     throw new IllegalStateException JavaDoc();
414                 }
415
416                 cbcc.addPropertyChangeListener("beanContext", childPCL);
417                 cbcc.addVetoableChangeListener("beanContext", childVCL);
418         }
419
420             Visibility JavaDoc v = getChildVisibility(targetChild);
421
422             if (v != null) {
423                 if (okToUseGui)
424                     v.okToUseGui();
425                 else
426                     v.dontUseGui();
427             }
428
429             if (getChildSerializable(targetChild) != null) serializable++;
430
431             childJustAddedHook(targetChild, bcsc);
432
433         if (bccp != null) {
434                 v = getChildVisibility(bccp);
435
436                 if (v != null) {
437                     if (okToUseGui)
438                         v.okToUseGui();
439                     else
440                         v.dontUseGui();
441                 }
442
443             if (getChildSerializable(bccp) != null) serializable++;
444
445                 childJustAddedHook(bccp, pbcsc);
446         }
447
448
449         }
450
451         // The specification requires that we fire a notification of the change
452

453         fireChildrenAdded(new BeanContextMembershipEvent JavaDoc(getBeanContextPeer(), bccp == null ? new Object JavaDoc[] { targetChild } : new Object JavaDoc[] { targetChild, bccp } ));
454
455         }
456
457     return true;
458     }
459
460     /**
461      * Removes a child from this BeanContext. If the child object is not
462      * for adding then this method throws an IllegalStateException.
463      * @param targetChild The child objects to remove
464      * @see #validatePendingRemove
465      */

466     public boolean remove(Object JavaDoc targetChild) {
467     return remove(targetChild, true);
468     }
469
470     /**
471      * internal remove used when removal caused by
472      * unexpected <tt>setBeanContext</tt> or
473      * by <tt>remove()</tt> invocation.
474      * @param targetChild the JavaBean, BeanContext, or Object to be removed
475      * @param callChildSetBC used to indicate that
476      * the child should be notified that it is no
477      * longer nested in this <tt>BeanContext</tt>.
478      */

479     protected boolean remove(Object JavaDoc targetChild, boolean callChildSetBC) {
480
481     if (targetChild == null) throw new IllegalArgumentException JavaDoc();
482
483     synchronized(BeanContext.globalHierarchyLock) {
484         if (!containsKey(targetChild)) return false;
485
486         if (!validatePendingRemove(targetChild)) {
487             throw new IllegalStateException JavaDoc();
488         }
489
490             BCSChild bcsc = (BCSChild)children.get(targetChild);
491         BCSChild pbcsc = null;
492         Object JavaDoc peer = null;
493
494         // we are required to notify the child that it is no longer nested here if
495
// it implements java.beans.beancontext.BeanContextChild
496

497         synchronized(targetChild) {
498             if (callChildSetBC) {
499                 BeanContextChild JavaDoc cbcc = getChildBeanContextChild(targetChild);
500                 if (cbcc != null) synchronized(cbcc) {
501                     cbcc.removePropertyChangeListener("beanContext", childPCL);
502                     cbcc.removeVetoableChangeListener("beanContext", childVCL);
503
504             try {
505                         cbcc.setBeanContext(null);
506                     } catch (PropertyVetoException JavaDoc pve1) {
507                         cbcc.addPropertyChangeListener("beanContext", childPCL);
508                         cbcc.addVetoableChangeListener("beanContext", childVCL);
509                         throw new IllegalStateException JavaDoc();
510                     }
511
512             }
513             }
514
515             synchronized (children) {
516             children.remove(targetChild);
517
518             if (bcsc.isProxyPeer()) {
519             pbcsc = (BCSChild)children.get(peer = bcsc.getProxyPeer());
520             children.remove(peer);
521             }
522         }
523
524             if (getChildSerializable(targetChild) != null) serializable--;
525
526             childJustRemovedHook(targetChild, bcsc);
527
528         if (peer != null) {
529                 if (getChildSerializable(peer) != null) serializable--;
530
531                 childJustRemovedHook(peer, pbcsc);
532         }
533         }
534
535         fireChildrenRemoved(new BeanContextMembershipEvent JavaDoc(getBeanContextPeer(), peer == null ? new Object JavaDoc[] { targetChild } : new Object JavaDoc[] { targetChild, peer } ));
536
537     }
538
539     return true;
540     }
541
542     /**
543      * Tests to see if all objects in the
544      * specified <tt>Collection</tt> are children of
545      * this <tt>BeanContext</tt>.
546      * @param c the specified <tt>Collection</tt>
547      *
548      * @return <tt>true</tt> if all objects
549      * in the collection are children of
550      * this <tt>BeanContext</tt>, false if not.
551      */

552     public boolean containsAll(Collection JavaDoc c) {
553     synchronized(children) {
554         Iterator JavaDoc i = c.iterator();
555         while (i.hasNext())
556             if(!contains(i.next()))
557             return false;
558
559         return true;
560     }
561     }
562
563     /**
564      * add Collection to set of Children (Unsupported)
565      * implementations must synchronized on the hierarchy lock and "children" protected field
566      * @throws UnsupportedOperationException
567      */

568     public boolean addAll(Collection JavaDoc c) {
569     throw new UnsupportedOperationException JavaDoc();
570     }
571
572     /**
573      * remove all specified children (Unsupported)
574      * implementations must synchronized on the hierarchy lock and "children" protected field
575      * @throws UnsupportedOperationException
576      */

577     public boolean removeAll(Collection JavaDoc c) {
578     throw new UnsupportedOperationException JavaDoc();
579     }
580
581
582     /**
583      * retain only specified children (Unsupported)
584      * implementations must synchronized on the hierarchy lock and "children" protected field
585      * @throws UnsupportedOperationException
586      */

587     public boolean retainAll(Collection JavaDoc c) {
588     throw new UnsupportedOperationException JavaDoc();
589     }
590
591     /**
592      * clear the children (Unsupported)
593      * implementations must synchronized on the hierarchy lock and "children" protected field
594      * @throws UnsupportedOperationException
595      */

596     public void clear() {
597     throw new UnsupportedOperationException JavaDoc();
598     }
599
600     /**
601      * Adds a BeanContextMembershipListener
602      *
603      * @param bcml the BeanContextMembershipListener to add
604      * @throws NullPointerException
605      */

606
607     public void addBeanContextMembershipListener(BeanContextMembershipListener JavaDoc bcml) {
608     if (bcml == null) throw new NullPointerException JavaDoc("listener");
609
610     synchronized(bcmListeners) {
611         if (bcmListeners.contains(bcml))
612         return;
613         else
614             bcmListeners.add(bcml);
615     }
616     }
617
618     /**
619      * Removes a BeanContextMembershipListener
620      *
621      * @param bcml the BeanContextMembershipListener to remove
622      * @throws NullPointerException
623      */

624
625     public void removeBeanContextMembershipListener(BeanContextMembershipListener JavaDoc bcml) {
626     if (bcml == null) throw new NullPointerException JavaDoc("listener");
627
628     synchronized(bcmListeners) {
629         if (!bcmListeners.contains(bcml))
630         return;
631         else
632             bcmListeners.remove(bcml);
633     }
634     }
635
636     /**
637      * @param name the name of the resource requested.
638      * @param bcc the child object making the request.
639      *
640      * @return the requested resource as an InputStream
641      * @throws NullPointerException
642      */

643
644     public InputStream JavaDoc getResourceAsStream(String JavaDoc name, BeanContextChild JavaDoc bcc) {
645     if (name == null) throw new NullPointerException JavaDoc("name");
646     if (bcc == null) throw new NullPointerException JavaDoc("bcc");
647
648     if (containsKey(bcc)) {
649         ClassLoader JavaDoc cl = bcc.getClass().getClassLoader();
650
651         return cl != null ? cl.getResourceAsStream(name)
652                   : ClassLoader.getSystemResourceAsStream(name);
653     } else throw new IllegalArgumentException JavaDoc("Not a valid child");
654     }
655
656     /**
657      * @param name the name of the resource requested.
658      * @param bcc the child object making the request.
659      *
660      * @return the requested resource as an InputStream
661      */

662
663     public URL JavaDoc getResource(String JavaDoc name, BeanContextChild JavaDoc bcc) {
664     if (name == null) throw new NullPointerException JavaDoc("name");
665     if (bcc == null) throw new NullPointerException JavaDoc("bcc");
666
667     if (containsKey(bcc)) {
668         ClassLoader JavaDoc cl = bcc.getClass().getClassLoader();
669
670         return cl != null ? cl.getResource(name)
671                   : ClassLoader.getSystemResource(name);
672     } else throw new IllegalArgumentException JavaDoc("Not a valid child");
673     }
674
675     /**
676      * Sets the new design time value for this <tt>BeanContext</tt>.
677      * @param dTime the new designTime value
678      */

679     public synchronized void setDesignTime(boolean dTime) {
680     if (designTime != dTime) {
681         designTime = dTime;
682
683         firePropertyChange("designMode", Boolean.valueOf(!dTime), Boolean.valueOf(dTime));
684     }
685     }
686
687   
688     /**
689      * Reports whether or not this object is in
690      * currently in design time mode.
691      * @return <tt>true</tt> if in design time mode,
692      * <tt>false</tt> if not
693      */

694     public synchronized boolean isDesignTime() { return designTime; }
695
696     /**
697      * Sets the locale of this BeanContext.
698      * @param newLocale the new locale. This method call will have
699      * no effect if newLocale is <CODE>null</CODE>.
700      * @throws PropertyVetoException if the new value is rejected
701      */

702     public synchronized void setLocale(Locale JavaDoc newLocale) throws PropertyVetoException JavaDoc {
703
704     if ((locale != null && !locale.equals(newLocale)) && newLocale != null) {
705         Locale JavaDoc old = locale;
706
707         fireVetoableChange("locale", old, newLocale); // throws
708

709         locale = newLocale;
710
711         firePropertyChange("locale", old, newLocale);
712     }
713     }
714
715     /**
716      * Gets the locale for this <tt>BeanContext</tt>.
717      *
718      * @return the current Locale of the <tt>BeanContext</tt>
719      */

720     public synchronized Locale JavaDoc getLocale() { return locale; }
721
722     /**
723      * <p>
724      * This method is typically called from the environment in order to determine
725      * if the implementor "needs" a GUI.
726      * </p>
727      * <p>
728      * The algorithm used herein tests the BeanContextPeer, and its current children
729      * to determine if they are either Containers, Components, or if they implement
730      * Visibility and return needsGui() == true.
731      * </p>
732      * @return <tt>true</tt> if the implementor needs a GUI
733      */

734     public synchronized boolean needsGui() {
735     BeanContext JavaDoc bc = getBeanContextPeer();
736
737     if (bc != this) {
738         if (bc instanceof Visibility JavaDoc) return ((Visibility JavaDoc)bc).needsGui();
739
740         if (bc instanceof Container JavaDoc || bc instanceof Component JavaDoc)
741         return true;
742     }
743
744     synchronized(children) {
745         for (Iterator JavaDoc i = children.keySet().iterator(); i.hasNext();) {
746             Object JavaDoc c = i.next();
747
748             try {
749                 return ((Visibility JavaDoc)c).needsGui();
750             } catch (ClassCastException JavaDoc cce) {
751                 // do nothing ...
752
}
753
754             if (c instanceof Container JavaDoc || c instanceof Component JavaDoc)
755                 return true;
756         }
757     }
758
759     return false;
760     }
761
762     /**
763      * notify this instance that it may no longer render a GUI.
764      */

765
766     public synchronized void dontUseGui() {
767     if (okToUseGui) {
768         okToUseGui = false;
769
770         // lets also tell the Children that can that they may not use their GUI's
771
synchronized(children) {
772             for (Iterator JavaDoc i = children.keySet().iterator(); i.hasNext();) {
773             Visibility JavaDoc v = getChildVisibility(i.next());
774
775             if (v != null) v.dontUseGui();
776            }
777         }
778     }
779     }
780
781     /**
782      * Notify this instance that it may now render a GUI
783      */

784
785     public synchronized void okToUseGui() {
786     if (!okToUseGui) {
787         okToUseGui = true;
788
789         // lets also tell the Children that can that they may use their GUI's
790
synchronized(children) {
791             for (Iterator JavaDoc i = children.keySet().iterator(); i.hasNext();) {
792             Visibility JavaDoc v = getChildVisibility(i.next());
793
794             if (v != null) v.okToUseGui();
795             }
796         }
797     }
798     }
799
800     /**
801      * Used to determine if the <tt>BeanContext</tt>
802      * child is avoiding using its GUI.
803      * @return is this instance avoiding using its GUI?
804      * @see Visibility
805      */

806     public boolean avoidingGui() {
807     return !okToUseGui && needsGui();
808     }
809
810     /**
811      * Is this <tt>BeanContext</tt> in the
812      * process of being serialized?
813      * @return if this <tt>BeanContext</tt> is
814      * currently being serialized
815      */

816     public boolean isSerializing() { return serializing; }
817
818     /**
819      * Returns an iterator of all children
820      * of this <tt>BeanContext</tt>.
821      * @return an iterator for all the current BCSChild values
822      */

823     protected Iterator JavaDoc bcsChildren() { synchronized(children) { return children.values().iterator(); } }
824
825     /**
826      * called by writeObject after defaultWriteObject() but prior to
827      * serialization of currently serializable children.
828      *
829      * This method may be overridden by subclasses to perform custom
830      * serialization of their state prior to this superclass serializing
831      * the children.
832      *
833      * This method should not however be used by subclasses to replace their
834      * own implementation (if any) of writeObject().
835      */

836
837     protected void bcsPreSerializationHook(ObjectOutputStream JavaDoc oos) throws IOException JavaDoc {
838     }
839
840     /**
841      * called by readObject after defaultReadObject() but prior to
842      * deserialization of any children.
843      *
844      * This method may be overridden by subclasses to perform custom
845      * deserialization of their state prior to this superclass deserializing
846      * the children.
847      *
848      * This method should not however be used by subclasses to replace their
849      * own implementation (if any) of readObject().
850      */

851
852     protected void bcsPreDeserializationHook(ObjectInputStream JavaDoc ois) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
853     }
854
855     /**
856      * Called by readObject with the newly deserialized child and BCSChild.
857      * @param child the newly deserialized child
858      * @param bcsc the newly deserialized BCSChild
859      */

860     protected void childDeserializedHook(Object JavaDoc child, BCSChild bcsc) {
861     synchronized(children) {
862         children.put(child, bcsc);
863     }
864     }
865
866     /**
867      * Used by writeObject to serialize a Collection.
868      * @param oos the <tt>ObjectOutputStream</tt>
869      * to use during serialization
870      * @param coll the <tt>Collection</tt> to serialize
871      * @throws IOException if serialization failed
872      */

873     protected final void serialize(ObjectOutputStream JavaDoc oos, Collection JavaDoc coll) throws IOException JavaDoc {
874     int count = 0;
875     Object JavaDoc[] objects = coll.toArray();
876     
877     for (int i = 0; i < objects.length; i++) {
878         if (objects[i] instanceof Serializable JavaDoc)
879         count++;
880         else
881         objects[i] = null;
882     }
883
884         oos.writeInt(count); // number of subsequent objects
885

886     for (int i = 0; count > 0; i++) {
887         Object JavaDoc o = objects[i];
888
889         if (o != null) {
890         oos.writeObject(o);
891         count--;
892         }
893     }
894     }
895
896     /**
897      * used by readObject to deserialize a collection.
898      * @param ois the ObjectInputStream to use
899      * @param coll the Collection
900      */

901     protected final void deserialize(ObjectInputStream JavaDoc ois, Collection JavaDoc coll) throws