OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [beans/] [beancontext/] [BeanContextSupport.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* BeanContextSupport.java --
2
   Copyright (C) 2003, 2005, 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.beans.beancontext;
40
 
41
import java.beans.Beans;
42
import java.beans.DesignMode;
43
import java.beans.PropertyChangeEvent;
44
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyVetoException;
46
import java.beans.VetoableChangeListener;
47
import java.beans.Visibility;
48
import java.io.IOException;
49
import java.io.InputStream;
50
import java.io.ObjectInputStream;
51
import java.io.ObjectOutputStream;
52
import java.io.Serializable;
53
import java.net.URL;
54
import java.util.ArrayList;
55
import java.util.Collection;
56
import java.util.HashMap;
57
import java.util.Iterator;
58
import java.util.List;
59
import java.util.Locale;
60
 
61
/**
62
 * This is a helper class for implementing a bean context.  It is
63
 * intended to be used either by subclassing or by calling methods
64
 * of this implementation from another.
65
 *
66
 * @author Michael Koch
67
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
68
 * @since 1.2
69
 */
70
public class BeanContextSupport extends BeanContextChildSupport
71
  implements BeanContext, Serializable, PropertyChangeListener,
72
  VetoableChangeListener
73
{
74
  private static final long serialVersionUID = -4879613978649577204L;
75
 
76
  /**
77
   * Deserializes a stored bean context.  Hook methods are provided to allow
78
   * subclasses to perform their own deserialization after the default
79
   * deserialization but prior to the deserialization of the children.  Note that
80
   * {@link #readChildren(ObjectInputStream)} is only called if there
81
   * is no distinct peer.  If there is, the peer is expected to call
82
   * the method instead.
83
   *
84
   * @param s the stream to deserialize.
85
   * @throws ClassNotFoundException if the class of an object being deserialized
86
   *                                could not be found.
87
   * @throws IOException if an I/O error occurs.
88
   */
89
  private void readObject (ObjectInputStream s)
90
    throws ClassNotFoundException, IOException
91
  {
92
    s.defaultReadObject();
93
    bcsPreDeserializationHook(s);
94
    BeanContext peer = getBeanContextPeer();
95
    if (peer == null || peer == this)
96
      readChildren(s);
97
  }
98
 
99
  /**
100
   * Serializes a bean context.  Hook methods are provided to allow
101
   * subclasses to perform their own serialization after the default
102
   * serialization but prior to serialization of the children.  Note that
103
   * {@link #writeChildren(ObjectOutputStream)} is only called if there
104
   * is no distinct peer.  If there is, the peer is expected to call
105
   * the method instead.
106
   *
107
   * @param s the stream to serialize.
108
   * @throws ClassNotFoundException if the class of an object being deserialized
109
   *                                could not be found.
110
   * @throws IOException if an I/O error occurs.
111
   */
112
  private void writeObject (ObjectOutputStream s)
113
    throws ClassNotFoundException, IOException
114
  {
115
    serializing = true;
116
    s.defaultWriteObject();
117
    bcsPreSerializationHook(s);
118
    BeanContext peer = getBeanContextPeer();
119
    if (peer == null || peer == this)
120
      writeChildren(s);
121
    serializing = false;
122
  }
123
 
124
  protected class BCSChild implements Serializable
125
  {
126
    private static final long serialVersionUID = -5815286101609939109L;
127
 
128
    private Object targetChild;
129
    private Object peer;
130
 
131
    BCSChild(Object targetChild, Object peer)
132
    {
133
      this.targetChild = targetChild;
134
      this.peer = peer;
135
    }
136
 
137
    private Object getTargetChild()
138
    {
139
      return targetChild;
140
    }
141
 
142
  }
143
 
144
  protected static final class BCSIterator implements Iterator
145
  {
146
    private Iterator child;
147
 
148
    BCSIterator(Iterator child)
149
    {
150
      this.child = child;
151
    }
152
 
153
    public boolean hasNext ()
154
    {
155
      return child.hasNext();
156
    }
157
 
158
    public Object next ()
159
    {
160
      return child.next();
161
    }
162
 
163
    public void remove ()
164
    {
165
      // This must be a noop remove operation.
166
    }
167
  }
168
 
169
  protected transient ArrayList bcmListeners;
170
 
171
  protected transient HashMap children;
172
 
173
  protected transient boolean designTime;
174
 
175
  protected transient Locale locale;
176
 
177
  protected transient boolean okToUseGui;
178
 
179
  private transient boolean serializing;
180
 
181
  /**
182
   * Construct a BeanContextSupport instance.
183
   */
184
  public BeanContextSupport ()
185
  {
186
    this (null, null, false, true);
187
  }
188
 
189
  /**
190
   * Construct a BeanContextSupport instance.
191
   *
192
   * @param peer  the bean context peer (<code>null</code> permitted).
193
   */
194
  public BeanContextSupport(BeanContext peer)
195
  {
196
    this (peer, null, false, true);
197
  }
198
 
199
  /**
200
   * Construct a BeanContextSupport instance.
201
   *
202
   * @param peer  the bean context peer (<code>null</code> permitted).
203
   * @param locale  the locale (<code>null</code> permitted, equivalent to
204
   *     the default locale).
205
   */
206
  public BeanContextSupport (BeanContext peer, Locale locale)
207
  {
208
    this (peer, locale, false, true);
209
  }
210
 
211
  /**
212
   * Construct a BeanContextSupport instance.
213
   *
214
   * @param peer  the bean context peer (<code>null</code> permitted).
215
   * @param locale  the locale (<code>null</code> permitted, equivalent to
216
   *     the default locale).
217
   * @param dtime  a flag indicating whether or not the bean context is in
218
   *     design time mode.
219
   */
220
  public BeanContextSupport (BeanContext peer, Locale locale, boolean dtime)
221
  {
222
    this (peer, locale, dtime, true);
223
  }
224
 
225
  /**
226
   * Construct a BeanContextSupport instance.
227
   *
228
   * @param peer  the bean context peer (<code>null</code> permitted).
229
   * @param locale  the locale (<code>null</code> permitted, equivalent to
230
   *     the default locale).
231
   * @param dtime  a flag indicating whether or not the bean context is in
232
   *     design time mode.
233
   * @param visible  initial value of the <code>okToUseGui</code> flag.
234
   */
235
  public BeanContextSupport (BeanContext peer, Locale locale, boolean dtime,
236
                             boolean visible)
237
  {
238
    super(peer);
239
 
240
    this.locale = locale == null ? Locale.getDefault() : locale;
241
    designTime = dtime;
242
    okToUseGui = visible;
243
 
244
    initialize ();
245
  }
246
 
247
  /**
248
   * <p>
249
   * Add a child to the bean context.  A child can be a simple
250
   * <code>Object</code>, a <code>BeanContextChild</code>
251
   * or another <code>BeanContext</code>.
252
   * </p>
253
   * <p>
254
   * The children of a <code>BeanContext</code> form a set.  As
255
   * a result, this method returns <code>false</code> if the given
256
   * object is already a child of this context.
257
   * </p>
258
   * <p>
259
   * If the child is a <code>BeanContextChild</code>, or a proxy
260
   * for such a child, the <code>setBeanContext()</code> method
261
   * is invoked on the child.  If this operation is vetoed by the
262
   * child, via throwing a <code>PropertyVetoException</code>,
263
   * then the current completion state of the <code>add()</code>
264
   * operation is rolled back and a <code>IllegalStateException</code>
265
   * is thrown.  If the <code>BeanContextChild</code> is successfully
266
   * added, then the context registers with its
267
   * <code>PropertyChangeListener</code> and
268
   * <code>VetoableChangeListener</code> for "beanContext" events.
269
   * </p>
270
   * <p>
271
   * If the child implements <code>java.beans.Visibility</code>,
272
   * then its ability to use a GUI is set based on that of
273
   * this context.
274
   * </p>
275
   * <p>
276
   * A <code>BeanContextMembershipEvent</code> is fired when the
277
   * child is successfully added to the bean context.
278
   * </p>
279
   * <p>
280
   * This method is synchronized over the global hierarchy lock.
281
   * </p>
282
   *
283
   * @param targetChild the child to add.
284
   * @return false if the child has already been added.
285
   * @throws IllegalArgumentException if the child is null.
286
   * @throws IllegalStateException if the child vetos the setting
287
   *                               of its context.
288
   */
289
  public boolean add(Object targetChild)
290
  {
291
    synchronized (globalHierarchyLock)
292
      {
293
        if (targetChild == null)
294
          throw new IllegalArgumentException();
295
 
296
        BCSChild child;
297
        synchronized (children)
298
          {
299
            if (children.containsKey(targetChild)
300
                || ! validatePendingAdd(targetChild))
301
              return false;
302
            child = createBCSChild(targetChild, beanContextChildPeer);
303
            children.put(targetChild, child);
304
          }
305
        synchronized (targetChild)
306
          {
307
            BeanContextChild bcChild = null;
308
            if (targetChild instanceof BeanContextChild)
309
              bcChild = (BeanContextChild) targetChild;
310
            if (targetChild instanceof BeanContextProxy)
311
              bcChild = ((BeanContextProxy) targetChild).getBeanContextProxy();
312
            if (bcChild != null)
313
              try
314
                {
315
                  bcChild.setBeanContext(this);
316
                  bcChild.addVetoableChangeListener("beanContext", this);
317
                  bcChild.addPropertyChangeListener("beanContext", this);
318
                }
319
              catch (PropertyVetoException e)
320
                {
321
                  synchronized (children)
322
                    {
323
                      children.remove(targetChild);
324
                    }
325
                  throw new IllegalStateException("The child refused to " +
326
                                                  "associate itself with " +
327
                                                  "this context.", e);
328
                }
329
            if (targetChild instanceof Visibility)
330
              {
331
                Visibility visibleChild = (Visibility) targetChild;
332
                if (okToUseGui)
333
                  visibleChild.okToUseGui();
334
                else
335
                  visibleChild.dontUseGui();
336
              }
337
            childJustAddedHook(targetChild, child);
338
          }
339
        fireChildrenAdded(new BeanContextMembershipEvent(this,
340
                                                         new Object[]{ targetChild }));
341
        return true;
342
      }
343
  }
344
 
345
  public boolean addAll (Collection c)
346
  {
347
    // Intentionally throws an exception.
348
    throw new UnsupportedOperationException();
349
  }
350
 
351
  public void addBeanContextMembershipListener
352
    (BeanContextMembershipListener listener)
353
  {
354
    synchronized (bcmListeners)
355
      {
356
        if (! bcmListeners.contains(listener))
357
          bcmListeners.add(listener);
358
      }
359
  }
360
 
361
  /**
362
   * Returns true if this bean needs a GUI
363
   * but is being prevented from using one.
364
   *
365
   * @return true if <code>needsGui()</code>
366
   *              is true but the bean has been
367
   *              told not to use it.
368
   */
369
  public boolean avoidingGui()
370
  {
371
    return needsGui() && (!okToUseGui);
372
  }
373
 
374
  protected Iterator bcsChildren ()
375
  {
376
    synchronized (children)
377
      {
378
        return new BCSIterator(children.values().iterator());
379
      }
380
  }
381
 
382
  /**
383
   * Subclasses may use this method to perform their own deserialization
384
   * after the default deserialization process has taken place, but
385
   * prior to the deserialization of the children.  It should not
386
   * be used to replace the implementation of <code>readObject</code>
387
   * in the subclass.
388
   *
389
   * @param ois the input stream.
390
   * @throws ClassNotFoundException if the class of an object being deserialized
391
   *                                could not be found.
392
   * @throws IOException if an I/O error occurs.
393
   */
394
  protected void bcsPreDeserializationHook (ObjectInputStream ois)
395
    throws ClassNotFoundException, IOException
396
  {
397
    /* Purposefully left empty */
398
  }
399
 
400
  /**
401
   * Subclasses may use this method to perform their own serialization
402
   * after the default serialization process has taken place, but
403
   * prior to the serialization of the children.  It should not
404
   * be used to replace the implementation of <code>writeObject</code>
405
   * in the subclass.
406
   *
407
   * @param oos the output stream.
408
   * @throws IOException if an I/O error occurs.
409
   */
410
  protected void bcsPreSerializationHook (ObjectOutputStream oos)
411
    throws IOException
412
  {
413
    /* Purposefully left empty */
414
  }
415
 
416
  /**
417
   * Called when a child is deserialized.
418
   *
419
   * @param child the deserialized child.
420
   * @param bcsc the deserialized context wrapper for the child.
421
   */
422
  protected void childDeserializedHook (Object child, BeanContextSupport.BCSChild bcsc)
423
  {
424
    // Do nothing in the base class.
425
  }
426
 
427
  protected void childJustAddedHook (Object child, BeanContextSupport.BCSChild bcsc)
428
  {
429
    // Do nothing in the base class.
430
  }
431
 
432
  protected void childJustRemovedHook (Object child, BeanContextSupport.BCSChild bcsc)
433
  {
434
    // Do nothing in the base class.
435
  }
436
 
437
  protected static final boolean classEquals (Class first, Class second)
438
  {
439
    // Lame function!
440
    return (first == second || first.getName().equals(second.getName()));
441
  }
442
 
443
  public void clear ()
444
  {
445
    // This is the right thing to do.
446
    // The JDK docs are really bad here.
447
    throw new UnsupportedOperationException();
448
  }
449
 
450
  public boolean contains (Object o)
451
  {
452
    synchronized (children)
453
      {
454
        return children.containsKey(o);
455
      }
456
  }
457
 
458
  public boolean containsAll (Collection c)
459
  {
460
    synchronized (children)
461
      {
462
        Iterator it = c.iterator();
463
        while (it.hasNext())
464
          if (! children.containsKey(it.next()))
465
            return false;
466
      }
467
    return true;
468
  }
469
 
470
  public boolean containsKey (Object o)
471
  {
472
    synchronized (children)
473
      {
474
        return children.containsKey(o);
475
      }
476
  }
477
 
478
  protected final Object[] copyChildren ()
479
  {
480
    synchronized (children)
481
      {
482
        return children.keySet().toArray();
483
      }
484
  }
485
 
486
  protected BeanContextSupport.BCSChild createBCSChild (Object targetChild, Object peer)
487
  {
488
    return new BCSChild(targetChild, peer);
489
  }
490
 
491
  /**
492
   * Deserializes objects (written by {@link #serialize(ObjectOutputStream,
493
   * Collection)}) and adds them to the specified collection.
494
   *
495
   * @param ois  the input stream (<code>null</code> not permitted).
496
   * @param coll  the collection to add the objects to (<code>null</code> not
497
   *     permitted).
498
   *
499
   * @throws ClassNotFoundException
500
   * @throws IOException
501
   *
502
   * @see #serialize(ObjectOutputStream, Collection)
503
   */
504
  protected final void deserialize (ObjectInputStream ois, Collection coll)
505
    throws ClassNotFoundException, IOException
506
  {
507
    int itemCount = ois.readInt();
508
    for (int i = 0; i < itemCount; i++)
509
      coll.add(ois.readObject());
510
  }
511
 
512
  /**
513
   * Informs this bean that is should not make
514
   * use of the GUI.
515
   */
516
  public void dontUseGui()
517
  {
518
    okToUseGui = false;
519
  }
520
 
521
  protected final void fireChildrenAdded (BeanContextMembershipEvent bcme)
522
  {
523
    synchronized (bcmListeners)
524
      {
525
        Iterator it = bcmListeners.iterator();
526
        while (it.hasNext())
527
          {
528
            BeanContextMembershipListener l
529
              = (BeanContextMembershipListener) it.next();
530
            l.childrenAdded(bcme);
531
          }
532
      }
533
  }
534
 
535
  protected final void fireChildrenRemoved (BeanContextMembershipEvent bcme)
536
  {
537
    synchronized (bcmListeners)
538
      {
539
        Iterator it = bcmListeners.iterator();
540
        while (it.hasNext())
541
          {
542
            BeanContextMembershipListener l
543
            = (BeanContextMembershipListener) it.next();
544
            l.childrenRemoved(bcme);
545
          }
546
      }
547
  }
548
 
549
  /**
550
   * Returns the bean context peer.
551
   *
552
   * @return The bean context peer.
553
   *
554
   * @see BeanContextChildSupport#beanContextChildPeer
555
   */
556
  public BeanContext getBeanContextPeer()
557
  {
558
    return (BeanContext) beanContextChildPeer;
559
  }
560
 
561
  /**
562
   * Returns the {@link BeanContextChild} implementation for the given child.
563
   *
564
   * @param child  the child (<code>null</code> permitted).
565
   *
566
   * @return The bean context child.
567
   *
568
   * @throws IllegalArgumentException if <code>child</code> implements both
569
   *     the {@link BeanContextChild} and {@link BeanContextProxy} interfaces.
570
   */
571
  protected static final BeanContextChild getChildBeanContextChild(Object child)
572
  {
573
    if (child == null)
574
      return null;
575
    if (child instanceof BeanContextChild && child instanceof BeanContextProxy)
576
      throw new IllegalArgumentException("Child cannot implement "
577
          + "BeanContextChild and BeanContextProxy simultaneously.");
578
    if (child instanceof BeanContextChild)
579
      return (BeanContextChild) child;
580
    if (child instanceof BeanContextProxy)
581
      return ((BeanContextProxy) child).getBeanContextProxy();
582
    return null;
583
  }
584
 
585
  /**
586
   * Returns <code>child</code> as an instance of
587
   * {@link BeanContextMembershipListener}, or <code>null</code> if
588
   * <code>child</code> does not implement that interface.
589
   *
590
   * @param child  the child (<code>null</code> permitted).
591
   *
592
   * @return The child cast to {@link BeanContextMembershipListener}.
593
   */
594
  protected static final BeanContextMembershipListener
595
      getChildBeanContextMembershipListener(Object child)
596
  {
597
    if (child instanceof BeanContextMembershipListener)
598
      return (BeanContextMembershipListener) child;
599
    else
600
      return null;
601
  }
602
 
603
  /**
604
   * Returns <code>child</code> as an instance of
605
   * {@link PropertyChangeListener}, or <code>null</code> if <code>child</code>
606
   * does not implement that interface.
607
   *
608
   * @param child  the child (<code>null</code> permitted).
609
   *
610
   * @return The child cast to {@link PropertyChangeListener}.
611
   */
612
  protected static final PropertyChangeListener getChildPropertyChangeListener(
613
      Object child)
614
  {
615
    if (child instanceof PropertyChangeListener)
616
      return (PropertyChangeListener) child;
617
    else
618
      return null;
619
  }
620
 
621
  /**
622
   * Returns <code>child</code> as an instance of {@link Serializable}, or
623
   * <code>null</code> if <code>child</code> does not implement that
624
   * interface.
625
   *
626
   * @param child  the child (<code>null</code> permitted).
627
   *
628
   * @return The child cast to {@link Serializable}.
629
   */
630
  protected static final Serializable getChildSerializable(Object child)
631
  {
632
    if (child instanceof Serializable)
633
      return (Serializable) child;
634
    else
635
      return null;
636
  }
637
 
638
  /**
639
   * Returns <code>child</code> as an instance of
640
   * {@link VetoableChangeListener}, or <code>null</code> if <code>child</code>
641
   * does not implement that interface.
642
   *
643
   * @param child  the child (<code>null</code> permitted).
644
   *
645
   * @return The child cast to {@link VetoableChangeListener}.
646
   */
647
  protected static final VetoableChangeListener getChildVetoableChangeListener(
648
      Object child)
649
  {
650
    if (child instanceof VetoableChangeListener)
651
      return (VetoableChangeListener) child;
652
    else
653
      return null;
654
  }
655
 
656
  /**
657
   * Returns <code>child</code> as an instance of {@link Visibility}, or
658
   * <code>null</code> if <code>child</code> does not implement that interface.
659
   *
660
   * @param child  the child (<code>null</code> permitted).
661
   *
662
   * @return The child cast to {@link Visibility}.
663
   */
664
  protected static final Visibility getChildVisibility(Object child)
665
  {
666
    if (child instanceof Visibility)
667
      return (Visibility) child;
668
    else
669
      return null;
670
  }
671
 
672
  public Locale getLocale ()
673
  {
674
    return locale;
675
  }
676
 
677
  public URL getResource (String name, BeanContextChild bcc)
678
  {
679
    if (! contains(bcc))
680
      throw new IllegalArgumentException("argument not a child");
681
    ClassLoader loader = bcc.getClass().getClassLoader();
682
    return (loader == null ? ClassLoader.getSystemResource(name)
683
            : loader.getResource(name));
684
  }
685
 
686
  public InputStream getResourceAsStream (String name, BeanContextChild bcc)
687
  {
688
    if (! contains(bcc))
689
      throw new IllegalArgumentException("argument not a child");
690
    ClassLoader loader = bcc.getClass().getClassLoader();
691
    return (loader == null ? ClassLoader.getSystemResourceAsStream(name)
692
            : loader.getResourceAsStream(name));
693
  }
694
 
695
  protected void initialize ()
696
  {
697
    bcmListeners = new ArrayList();
698
    children = new HashMap();
699
  }
700
 
701
  /**
702
   * This is a convenience method for instantiating a bean inside this
703
   * context.  It delegates to the appropriate method in
704
   * <code>java.beans.Beans</code> using the context's classloader.
705
   *
706
   * @param beanName the name of the class of bean to instantiate.
707
   * @throws IOException if an I/O error occurs in loading the class.
708
   * @throws ClassNotFoundException if the class, <code>beanName</code>,
709
   *                                can not be found.
710
   */
711
  public Object instantiateChild (String beanName)
712
    throws IOException, ClassNotFoundException
713
  {
714
    return Beans.instantiate(getClass().getClassLoader(), beanName, this);
715
  }
716
 
717
  /**
718
   * Returns <code>true</code> if the <code>BeanContext</code> is in
719
   * design time mode, and <code>false</code> if it is in runtime mode.
720
   *
721
   * @return A boolean.
722
   *
723
   * @see #setDesignTime(boolean)
724
   */
725
  public boolean isDesignTime()
726
  {
727
    return designTime;
728
  }
729
 
730
  /**
731
   * Returns true if this bean context has no children.
732
   *
733
   * @return true if there are no children.
734
   */
735
  public boolean isEmpty ()
736
  {
737
    synchronized (children)
738
      {
739
        return children.isEmpty();
740
      }
741
  }
742
 
743
  /**
744
   * Returns true if the bean context is in the process
745
   * of being serialized.
746
   *
747
   * @return true if the context is being serialized.
748
   */
749
  public boolean isSerializing()
750
  {
751
    return serializing;
752
  }
753
 
754
  public Iterator iterator ()
755
  {
756
    synchronized (children)
757
      {
758
        return children.keySet().iterator();
759
      }
760
  }
761
 
762
  /**
763
   * Returns false as this bean does not a
764
   * GUI for its operation.
765
   *
766
   * @return false
767
   */
768
  public boolean needsGui()
769
  {
770
    return false;
771
  }
772
 
773
  /**
774
   * Informs this bean that it is okay to make use of
775
   * the GUI.
776
   */
777
  public void okToUseGui ()
778
  {
779
    okToUseGui = true;
780
  }
781
 
782
  /**
783
   * Subclasses may use this method to catch property changes
784
   * arising from the children of this context.  At present,
785
   * we just listen for the beans being assigned to a different
786
   * context and remove them from here if such an event occurs.
787
   *
788
   * @param pce the property change event.
789
   */
790
  public void propertyChange (PropertyChangeEvent pce)
791
  {
792
    if (pce.getNewValue() != this)
793
      remove(pce.getSource(), false);
794
  }
795
 
796
  /**
797
   * Deserializes the children using the
798
   * {@link #deserialize(ObjectInputStream, Collection} method
799
   * and then calls {@link childDeserializedHook(Object, BCSChild)}
800
   * for each child deserialized.
801
   *
802
   * @param ois the input stream.
803
   * @throws IOException if an I/O error occurs.
804
   */
805
  public final void readChildren (ObjectInputStream ois)
806
    throws IOException, ClassNotFoundException
807
  {
808
    List temp = new ArrayList();
809
    deserialize(ois, temp);
810
    Iterator i = temp.iterator();
811
    synchronized (globalHierarchyLock)
812
      {
813
        synchronized (children)
814
          {
815
            while (i.hasNext())
816
              {
817
                BCSChild bcs = (BCSChild) i.next();
818
                childDeserializedHook(bcs.getTargetChild(), bcs);
819
                children.put(bcs.getTargetChild(), bcs);
820
              }
821
          }
822
      }
823
  }
824
 
825
  /**
826
   * Remove the specified child from the context.  This is
827
   * the same as calling <code>remove(Object,boolean)</code>
828
   * with a request for the <code>setBeanContext()</code> method
829
   * of the child to be called (i.e. the second argument is true).
830
   *
831
   * @param targetChild the child to remove.
832
   */
833
  public boolean remove (Object targetChild)
834
  {
835
    return remove(targetChild, true);
836
  }
837
 
838
  /**
839
   * <p>
840
   * Removes a child from the bean context.  A child can be a simple
841
   * <code>Object</code>, a <code>BeanContextChild</code>
842
   * or another <code>BeanContext</code>.  If the given child is not
843
   * a child of this context, this method returns <code>false</code>.
844
   * </p>
845
   * <p>
846
   * If the child is a <code>BeanContextChild</code>, or a proxy
847
   * for such a child, the <code>setBeanContext()</code> method
848
   * is invoked on the child (if specified).  If this operation is vetoed
849
   * by the child, via throwing a <code>PropertyVetoException</code>,
850
   * then the current completion state of the <code>remove()</code>
851
   * operation is rolled back and a <code>IllegalStateException</code>
852
   * is thrown.  If the <code>BeanContextChild</code> is successfully
853
   * removed, then the context deregisters with its
854
   * <code>PropertyChangeListener</code> and
855
   * <code>VetoableChangeListener</code> for "beanContext" events.
856
   * </p>
857
   * <p>
858
   * A <code>BeanContextMembershipEvent</code> is fired when the
859
   * child is successfully removed from the bean context.
860
   * </p>
861
   * <p>
862
   * This method is synchronized over the global hierarchy lock.
863
   * </p>
864
   *
865
   * @param targetChild the child to remove.
866
   * @param callChildSetBC true if the <code>setBeanContext()</code>
867
   *                       method of the child should be called.
868
   * @return false if the child doesn't exist.
869
   * @throws IllegalArgumentException if the child is null.
870
   * @throws IllegalStateException if the child vetos the setting
871
   *                               of its context.
872
   */
873
  protected boolean remove (Object targetChild, boolean callChildSetBC)
874
  {
875
    synchronized (globalHierarchyLock)
876
      {
877
        if (targetChild == null)
878
          throw new IllegalArgumentException();
879
 
880
        BCSChild child;
881
        synchronized (children)
882
          {
883
            if (!children.containsKey(targetChild)
884
                || !validatePendingRemove(targetChild))
885
              return false;
886
            child = (BCSChild) children.remove(targetChild);
887
          }
888
        synchronized (targetChild)
889
          {
890
            BeanContextChild bcChild = null;
891
            if (targetChild instanceof BeanContextChild)
892
              bcChild = (BeanContextChild) targetChild;
893
            if (targetChild instanceof BeanContextProxy)
894
              bcChild = ((BeanContextProxy) targetChild).getBeanContextProxy();
895
            if (bcChild != null)
896
              try
897
                {
898
                  if (callChildSetBC)
899
                    bcChild.setBeanContext(null);
900
                  bcChild.removeVetoableChangeListener("beanContext", this);
901
                  bcChild.removePropertyChangeListener("beanContext", this);
902
                }
903
              catch (PropertyVetoException e)
904
                {
905
                  synchronized (children)
906
                    {
907
                      children.put(targetChild, child);
908
                    }
909
                  throw new IllegalStateException("The child refused to " +
910
                                                  "disassociate itself with " +
911
                                                  "this context.", e);
912
                }
913
            childJustRemovedHook(targetChild, child);
914
          }
915
        fireChildrenRemoved(new BeanContextMembershipEvent(this,
916
                                                         new Object[]{ targetChild }));
917
        return true;
918
      }
919
  }
920
 
921
  public boolean removeAll (Collection c)
922
  {
923
    // Intentionally throws an exception.
924
    throw new UnsupportedOperationException();
925
  }
926
 
927
  public void removeBeanContextMembershipListener (BeanContextMembershipListener bcml)
928
  {
929
    synchronized (bcmListeners)
930
      {
931
        bcmListeners.remove(bcml);
932
      }
933
  }
934
 
935
  public boolean retainAll (Collection c)
936
  {
937
    // Intentionally throws an exception.
938
    throw new UnsupportedOperationException();
939
  }
940
 
941
  /**
942
   * Writes the items in the collection to the specified output stream.  Items
943
   * in the collection that are not instances of {@link Serializable}
944
   * (this includes <code>null</code>) are simply ignored.
945
   *
946
   * @param oos  the output stream (<code>null</code> not permitted).
947
   * @param coll  the collection (<code>null</code> not permitted).
948
   *
949
   * @throws IOException
950
   *
951
   * @see #deserialize(ObjectInputStream, Collection)
952
   */
953
  protected final void serialize(ObjectOutputStream oos, Collection coll)
954
    throws IOException
955
  {
956
    Object[] items = coll.toArray();
957
    int itemCount = 0;
958
    for (int i = 0; i < items.length; i++)
959
      {
960
        if (items[i] instanceof Serializable)
961
          itemCount++;
962
      }
963
    oos.writeInt(itemCount);
964
    for (int i = 0; i < items.length; i++)
965
      {
966
        if (items[i] instanceof Serializable)
967
          oos.writeObject(items[i]);
968
      }
969
  }
970
 
971
  /**
972
   * Sets the flag that indicates whether or not the
973
   * <code>BeanContext</code> is in design mode.  If the flag changes
974
   * value, a {@link PropertyChangeEvent} (with the property name 'designMode')
975
   * is sent to registered listeners.  Note that the property name used here
976
   * does NOT match the specification in the {@link DesignMode} interface, we
977
   * match the reference implementation instead - see bug parade entry 4295174.
978
   *
979
   * @param dtime  the new value for the flag.
980
   *
981
   * @see #isDesignTime()
982
   */
983
  public void setDesignTime(boolean dtime)
984
  {
985
    boolean save = designTime;
986
    designTime = dtime;
987
    // note that we use the same property name as Sun's implementation,
988
    // even though this is a known bug: see bug parade entry 4295174
989
    firePropertyChange("designMode", Boolean.valueOf(save),
990
                       Boolean.valueOf(dtime));
991
  }
992
 
993
  public void setLocale (Locale newLocale)
994
    throws PropertyVetoException
995
  {
996
    if (newLocale == null || locale == newLocale)
997
      return;
998
    fireVetoableChange("locale", locale, newLocale);
999
    Locale oldLocale = locale;
1000
    locale = newLocale;
1001
    firePropertyChange("locale", oldLocale, newLocale);
1002
  }
1003
 
1004
  public int size ()
1005
  {
1006
    synchronized (children)
1007
      {
1008
        return children.size();
1009
      }
1010
  }
1011
 
1012
  /**
1013
   * Returns an array containing the children of this <code>BeanContext</code>.
1014
   *
1015
   * @return An array containing the children.
1016
   */
1017
  public Object[] toArray()
1018
  {
1019
    synchronized (children)
1020
      {
1021
        return children.keySet().toArray();
1022
      }
1023
  }
1024
 
1025
  /**
1026
   * Populates, then returns, the supplied array with the children of this
1027
   * <code>BeanContext</code>.  If the array is too short to hold the
1028
   * children, a new array is allocated and returned.  If the array is too
1029
   * long, it is padded with <code>null</code> items at the end.
1030
   *
1031
   * @param array  an array to populate (<code>null</code> not permitted).
1032
   */
1033
  public Object[] toArray(Object[] array)
1034
  {
1035
    synchronized (children)
1036
      {
1037
        return children.keySet().toArray(array);
1038
      }
1039
  }
1040
 
1041
  protected boolean validatePendingAdd (Object targetChild)
1042
  {
1043
    return true;
1044
  }
1045
 
1046
  protected boolean validatePendingRemove (Object targetChild)
1047
  {
1048
    return true;
1049
  }
1050
 
1051
  /**
1052
   * Subclasses may use this method to veto changes arising
1053
   * from the children of this context.
1054
   *
1055
   * @param pce the vetoable property change event fired.
1056
   */
1057
  public void vetoableChange (PropertyChangeEvent pce)
1058
    throws PropertyVetoException
1059
  {
1060
    /* Purposefully left empty */
1061
  }
1062
 
1063
  /**
1064
   * Serializes the children using the
1065
   * {@link #serialize(ObjectOutputStream, Collection} method.
1066
   *
1067
   * @param oos the output stream.
1068
   * @throws IOException if an I/O error occurs.
1069
   */
1070
  public final void writeChildren (ObjectOutputStream oos)
1071
    throws IOException
1072
  {
1073
    synchronized (children)
1074
      {
1075
        serialize(oos, children.values());
1076
      }
1077
  }
1078
 
1079
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.