duke@0
|
1 |
/*
|
duke@0
|
2 |
* Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
|
duke@0
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
duke@0
|
4 |
*
|
duke@0
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
duke@0
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
duke@0
|
7 |
* published by the Free Software Foundation. Sun designates this
|
duke@0
|
8 |
* particular file as subject to the "Classpath" exception as provided
|
duke@0
|
9 |
* by Sun in the LICENSE file that accompanied this code.
|
duke@0
|
10 |
*
|
duke@0
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
duke@0
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
duke@0
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
duke@0
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that
|
duke@0
|
15 |
* accompanied this code).
|
duke@0
|
16 |
*
|
duke@0
|
17 |
* You should have received a copy of the GNU General Public License version
|
duke@0
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
duke@0
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
duke@0
|
20 |
*
|
duke@0
|
21 |
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
duke@0
|
22 |
* CA 95054 USA or visit www.sun.com if you need additional information or
|
duke@0
|
23 |
* have any questions.
|
duke@0
|
24 |
*/
|
duke@0
|
25 |
|
duke@0
|
26 |
package java.beans.beancontext;
|
duke@0
|
27 |
|
duke@0
|
28 |
import java.awt.Component;
|
duke@0
|
29 |
import java.awt.Container;
|
duke@0
|
30 |
|
duke@0
|
31 |
import java.beans.Beans;
|
duke@0
|
32 |
|
duke@0
|
33 |
|
duke@0
|
34 |
import java.beans.PropertyChangeEvent;
|
duke@0
|
35 |
import java.beans.PropertyChangeListener;
|
duke@0
|
36 |
|
duke@0
|
37 |
import java.beans.VetoableChangeListener;
|
duke@0
|
38 |
import java.beans.PropertyVetoException;
|
duke@0
|
39 |
|
duke@0
|
40 |
import java.beans.Visibility;
|
duke@0
|
41 |
|
duke@0
|
42 |
import java.io.IOException;
|
duke@0
|
43 |
import java.io.InputStream;
|
duke@0
|
44 |
import java.io.ObjectInputStream;
|
duke@0
|
45 |
import java.io.ObjectOutputStream;
|
duke@0
|
46 |
import java.io.Serializable;
|
duke@0
|
47 |
|
duke@0
|
48 |
import java.net.URL;
|
duke@0
|
49 |
|
duke@0
|
50 |
import java.util.ArrayList;
|
duke@0
|
51 |
import java.util.Collection;
|
duke@0
|
52 |
import java.util.HashMap;
|
duke@0
|
53 |
import java.util.Iterator;
|
duke@0
|
54 |
import java.util.Locale;
|
duke@0
|
55 |
import java.util.Map;
|
duke@0
|
56 |
|
duke@0
|
57 |
|
duke@0
|
58 |
/**
|
duke@0
|
59 |
* This helper class provides a utility implementation of the
|
duke@0
|
60 |
* java.beans.beancontext.BeanContext interface.
|
duke@0
|
61 |
* </p>
|
duke@0
|
62 |
* <p>
|
duke@0
|
63 |
* Since this class directly implements the BeanContext interface, the class
|
duke@0
|
64 |
* can, and is intended to be used either by subclassing this implementation,
|
duke@0
|
65 |
* or via ad-hoc delegation of an instance of this class from another.
|
duke@0
|
66 |
* </p>
|
duke@0
|
67 |
*
|
duke@0
|
68 |
* @author Laurence P. G. Cable
|
duke@0
|
69 |
* @since 1.2
|
duke@0
|
70 |
*/
|
duke@0
|
71 |
public class BeanContextSupport extends BeanContextChildSupport
|
duke@0
|
72 |
implements BeanContext,
|
duke@0
|
73 |
Serializable,
|
duke@0
|
74 |
PropertyChangeListener,
|
duke@0
|
75 |
VetoableChangeListener {
|
duke@0
|
76 |
|
duke@0
|
77 |
// Fix for bug 4282900 to pass JCK regression test
|
duke@0
|
78 |
static final long serialVersionUID = -4879613978649577204L;
|
duke@0
|
79 |
|
duke@0
|
80 |
/**
|
duke@0
|
81 |
*
|
duke@0
|
82 |
* Construct a BeanContextSupport instance
|
duke@0
|
83 |
*
|
duke@0
|
84 |
*
|
duke@0
|
85 |
* @param peer The peer <tt>BeanContext</tt> we are
|
duke@0
|
86 |
* supplying an implementation for,
|
duke@0
|
87 |
* or <tt>null</tt>
|
duke@0
|
88 |
* if this object is its own peer
|
duke@0
|
89 |
* @param lcle The current Locale for this BeanContext. If
|
duke@0
|
90 |
* <tt>lcle</tt> is <tt>null</tt>, the default locale
|
duke@0
|
91 |
* is assigned to the <tt>BeanContext</tt> instance.
|
duke@0
|
92 |
* @param dTime The initial state,
|
duke@0
|
93 |
* <tt>true</tt> if in design mode,
|
duke@0
|
94 |
* <tt>false</tt> if runtime.
|
duke@0
|
95 |
* @param visible The initial visibility.
|
duke@0
|
96 |
* @see java.util.Locale#getDefault()
|
duke@0
|
97 |
* @see java.util.Locale#setDefault(java.util.Locale)
|
duke@0
|
98 |
*/
|
duke@0
|
99 |
public BeanContextSupport(BeanContext peer, Locale lcle, boolean dTime, boolean visible) {
|
duke@0
|
100 |
super(peer);
|
duke@0
|
101 |
|
duke@0
|
102 |
locale = lcle != null ? lcle : Locale.getDefault();
|
duke@0
|
103 |
designTime = dTime;
|
duke@0
|
104 |
okToUseGui = visible;
|
duke@0
|
105 |
|
duke@0
|
106 |
initialize();
|
duke@0
|
107 |
}
|
duke@0
|
108 |
|
duke@0
|
109 |
/**
|
duke@0
|
110 |
* Create an instance using the specified Locale and design mode.
|
duke@0
|
111 |
*
|
duke@0
|
112 |
* @param peer The peer <tt>BeanContext</tt> we
|
duke@0
|
113 |
* are supplying an implementation for,
|
duke@0
|
114 |
* or <tt>null</tt> if this object is its own peer
|
duke@0
|
115 |
* @param lcle The current Locale for this <tt>BeanContext</tt>. If
|
duke@0
|
116 |
* <tt>lcle</tt> is <tt>null</tt>, the default locale
|
duke@0
|
117 |
* is assigned to the <tt>BeanContext</tt> instance.
|
duke@0
|
118 |
* @param dtime The initial state, <tt>true</tt>
|
duke@0
|
119 |
* if in design mode,
|
duke@0
|
120 |
* <tt>false</tt> if runtime.
|
duke@0
|
121 |
* @see java.util.Locale#getDefault()
|
duke@0
|
122 |
* @see java.util.Locale#setDefault(java.util.Locale)
|
duke@0
|
123 |
*/
|
duke@0
|
124 |
public BeanContextSupport(BeanContext peer, Locale lcle, boolean dtime) {
|
duke@0
|
125 |
this (peer, lcle, dtime, true);
|
duke@0
|
126 |
}
|
duke@0
|
127 |
|
duke@0
|
128 |
/**
|
duke@0
|
129 |
* Create an instance using the specified locale
|
duke@0
|
130 |
*
|
duke@0
|
131 |
* @param peer The peer BeanContext we are
|
duke@0
|
132 |
* supplying an implementation for,
|
duke@0
|
133 |
* or <tt>null</tt> if this object
|
duke@0
|
134 |
* is its own peer
|
duke@0
|
135 |
* @param lcle The current Locale for this
|
duke@0
|
136 |
* <tt>BeanContext</tt>. If
|
duke@0
|
137 |
* <tt>lcle</tt> is <tt>null</tt>,
|
duke@0
|
138 |
* the default locale
|
duke@0
|
139 |
* is assigned to the <tt>BeanContext</tt>
|
duke@0
|
140 |
* instance.
|
duke@0
|
141 |
* @see java.util.Locale#getDefault()
|
duke@0
|
142 |
* @see java.util.Locale#setDefault(java.util.Locale)
|
duke@0
|
143 |
*/
|
duke@0
|
144 |
public BeanContextSupport(BeanContext peer, Locale lcle) {
|
duke@0
|
145 |
this (peer, lcle, false, true);
|
duke@0
|
146 |
}
|
duke@0
|
147 |
|
duke@0
|
148 |
/**
|
duke@0
|
149 |
* Create an instance using with a default locale
|
duke@0
|
150 |
*
|
duke@0
|
151 |
* @param peer The peer <tt>BeanContext</tt> we are
|
duke@0
|
152 |
* supplying an implementation for,
|
duke@0
|
153 |
* or <tt>null</tt> if this object
|
duke@0
|
154 |
* is its own peer
|
duke@0
|
155 |
*/
|
duke@0
|
156 |
public BeanContextSupport(BeanContext peer) {
|
duke@0
|
157 |
this (peer, null, false, true);
|
duke@0
|
158 |
}
|
duke@0
|
159 |
|
duke@0
|
160 |
/**
|
duke@0
|
161 |
* Create an instance that is not a delegate of another object
|
duke@0
|
162 |
*/
|
duke@0
|
163 |
|
duke@0
|
164 |
public BeanContextSupport() {
|
duke@0
|
165 |
this (null, null, false, true);
|
duke@0
|
166 |
}
|
duke@0
|
167 |
|
duke@0
|
168 |
/**
|
duke@0
|
169 |
* Gets the instance of <tt>BeanContext</tt> that
|
duke@0
|
170 |
* this object is providing the implementation for.
|
duke@0
|
171 |
* @return the BeanContext instance
|
duke@0
|
172 |
*/
|
duke@0
|
173 |
public BeanContext getBeanContextPeer() { return (BeanContext)getBeanContextChildPeer(); }
|
duke@0
|
174 |
|
duke@0
|
175 |
/**
|
duke@0
|
176 |
* <p>
|
duke@0
|
177 |
* The instantiateChild method is a convenience hook
|
duke@0
|
178 |
* in BeanContext to simplify
|
duke@0
|
179 |
* the task of instantiating a Bean, nested,
|
duke@0
|
180 |
* into a <tt>BeanContext</tt>.
|
duke@0
|
181 |
* </p>
|
duke@0
|
182 |
* <p>
|
duke@0
|
183 |
* The semantics of the beanName parameter are defined by java.beans.Beans.instantate.
|
duke@0
|
184 |
* </p>
|
duke@0
|
185 |
*
|
duke@0
|
186 |
* @param beanName the name of the Bean to instantiate within this BeanContext
|
duke@0
|
187 |
* @throws IOException if there is an I/O error when the bean is being deserialized
|
duke@0
|
188 |
* @throws ClassNotFoundException if the class
|
duke@0
|
189 |
* identified by the beanName parameter is not found
|
duke@0
|
190 |
* @return the new object
|
duke@0
|
191 |
*/
|
duke@0
|
192 |
public Object instantiateChild(String beanName)
|
duke@0
|
193 |
throws IOException, ClassNotFoundException {
|
duke@0
|
194 |
BeanContext bc = getBeanContextPeer();
|
duke@0
|
195 |
|
duke@0
|
196 |
return Beans.instantiate(bc.getClass().getClassLoader(), beanName, bc);
|
duke@0
|
197 |
}
|
duke@0
|
198 |
|
duke@0
|
199 |
/**
|
duke@0
|
200 |
* Gets the number of children currently nested in
|
duke@0
|
201 |
* this BeanContext.
|
duke@0
|
202 |
*
|
duke@0
|
203 |
* @return number of children
|
duke@0
|
204 |
*/
|
duke@0
|
205 |
public int size() {
|
duke@0
|
206 |
synchronized(children) {
|
duke@0
|
207 |
return children.size();
|
duke@0
|
208 |
}
|
duke@0
|
209 |
}
|
duke@0
|
210 |
|
duke@0
|
211 |
/**
|
duke@0
|
212 |
* Reports whether or not this
|
duke@0
|
213 |
* <tt>BeanContext</tt> is empty.
|
duke@0
|
214 |
* A <tt>BeanContext</tt> is considered
|
duke@0
|
215 |
* empty when it contains zero
|
duke@0
|
216 |
* nested children.
|
duke@0
|
217 |
* @return if there are not children
|
duke@0
|
218 |
*/
|
duke@0
|
219 |
public boolean isEmpty() {
|
duke@0
|
220 |
synchronized(children) {
|
duke@0
|
221 |
return children.isEmpty();
|
duke@0
|
222 |
}
|
duke@0
|
223 |
}
|
duke@0
|
224 |
|
duke@0
|
225 |
/**
|
duke@0
|
226 |
* Determines whether or not the specified object
|
duke@0
|
227 |
* is currently a child of this <tt>BeanContext</tt>.
|
duke@0
|
228 |
* @param o the Object in question
|
duke@0
|
229 |
* @return if this object is a child
|
duke@0
|
230 |
*/
|
duke@0
|
231 |
public boolean contains(Object o) {
|
duke@0
|
232 |
synchronized(children) {
|
duke@0
|
233 |
return children.containsKey(o);
|
duke@0
|
234 |
}
|
duke@0
|
235 |
}
|
duke@0
|
236 |
|
duke@0
|
237 |
/**
|
duke@0
|
238 |
* Determines whether or not the specified object
|
duke@0
|
239 |
* is currently a child of this <tt>BeanContext</tt>.
|
duke@0
|
240 |
* @param o the Object in question
|
duke@0
|
241 |
* @return if this object is a child
|
duke@0
|
242 |
*/
|
duke@0
|
243 |
public boolean containsKey(Object o) {
|
duke@0
|
244 |
synchronized(children) {
|
duke@0
|
245 |
return children.containsKey(o);
|
duke@0
|
246 |
}
|
duke@0
|
247 |
}
|
duke@0
|
248 |
|
duke@0
|
249 |
/**
|
duke@0
|
250 |
* Gets all JavaBean or <tt>BeanContext</tt> instances
|
duke@0
|
251 |
* currently nested in this <tt>BeanContext</tt>.
|
duke@0
|
252 |
* @return an <tt>Iterator</tt> of the nested children
|
duke@0
|
253 |
*/
|
duke@0
|
254 |
public Iterator iterator() {
|
duke@0
|
255 |
synchronized(children) {
|
duke@0
|
256 |
return new BCSIterator(children.keySet().iterator());
|
duke@0
|
257 |
}
|
duke@0
|
258 |
}
|
duke@0
|
259 |
|
duke@0
|
260 |
/**
|
duke@0
|
261 |
* Gets all JavaBean or <tt>BeanContext</tt>
|
duke@0
|
262 |
* instances currently nested in this BeanContext.
|
duke@0
|
263 |
*/
|
duke@0
|
264 |
public Object[] toArray() {
|
duke@0
|
265 |
synchronized(children) {
|
duke@0
|
266 |
return children.keySet().toArray();
|
duke@0
|
267 |
}
|
duke@0
|
268 |
}
|
duke@0
|
269 |
|
duke@0
|
270 |
/**
|
duke@0
|
271 |
* Gets an array containing all children of
|
duke@0
|
272 |
* this <tt>BeanContext</tt> that match
|
duke@0
|
273 |
* the types contained in arry.
|
duke@0
|
274 |
* @param arry The array of object
|
duke@0
|
275 |
* types that are of interest.
|
duke@0
|
276 |
* @return an array of children
|
duke@0
|
277 |
*/
|
duke@0
|
278 |
public Object[] toArray(Object[] arry) {
|
duke@0
|
279 |
synchronized(children) {
|
duke@0
|
280 |
return children.keySet().toArray(arry);
|
duke@0
|
281 |
}
|
duke@0
|
282 |
}
|
duke@0
|
283 |
|
duke@0
|
284 |
|
duke@0
|
285 |
/************************************************************************/
|
duke@0
|
286 |
|
duke@0
|
287 |
/**
|
duke@0
|
288 |
* protected final subclass that encapsulates an iterator but implements
|
duke@0
|
289 |
* a noop remove() method.
|
duke@0
|
290 |
*/
|
duke@0
|
291 |
|
duke@0
|
292 |
protected static final class BCSIterator implements Iterator {
|
duke@0
|
293 |
BCSIterator(Iterator i) { super(); src = i; }
|
duke@0
|
294 |
|
duke@0
|
295 |
public boolean hasNext() { return src.hasNext(); }
|
duke@0
|
296 |
public Object next() { return src.next(); }
|
duke@0
|
297 |
public void remove() { /* do nothing */ }
|
duke@0
|
298 |
|
duke@0
|
299 |
private Iterator src;
|
duke@0
|
300 |
}
|
duke@0
|
301 |
|
duke@0
|
302 |
/************************************************************************/
|
duke@0
|
303 |
|
duke@0
|
304 |
/*
|
duke@0
|
305 |
* protected nested class containing per child information, an instance
|
duke@0
|
306 |
* of which is associated with each child in the "children" hashtable.
|
duke@0
|
307 |
* subclasses can extend this class to include their own per-child state.
|
duke@0
|
308 |
*
|
duke@0
|
309 |
* Note that this 'value' is serialized with the corresponding child 'key'
|
duke@0
|
310 |
* when the BeanContextSupport is serialized.
|
duke@0
|
311 |
*/
|
duke@0
|
312 |
|
duke@0
|
313 |
protected class BCSChild implements Serializable {
|
duke@0
|
314 |
|
duke@0
|
315 |
private static final long serialVersionUID = -5815286101609939109L;
|
duke@0
|
316 |
|
duke@0
|
317 |
BCSChild(Object bcc, Object peer) {
|
duke@0
|
318 |
super();
|
duke@0
|
319 |
|
duke@0
|
320 |
child = bcc;
|
duke@0
|
321 |
proxyPeer = peer;
|
duke@0
|
322 |
}
|
duke@0
|
323 |
|
duke@0
|
324 |
Object getChild() { return child; }
|
duke@0
|
325 |
|
duke@0
|
326 |
void setRemovePending(boolean v) { removePending = v; }
|
duke@0
|
327 |
|
duke@0
|
328 |
boolean isRemovePending() { return removePending; }
|
duke@0
|
329 |
|
duke@0
|
330 |
boolean isProxyPeer() { return proxyPeer != null; }
|
duke@0
|
331 |
|
duke@0
|
332 |
Object getProxyPeer() { return proxyPeer; }
|
duke@0
|
333 |
/*
|
duke@0
|
334 |
* fields
|
duke@0
|
335 |
*/
|
duke@0
|
336 |
|
duke@0
|
337 |
|
duke@0
|
338 |
private Object child;
|
duke@0
|
339 |
private Object proxyPeer;
|
duke@0
|
340 |
|
duke@0
|
341 |
private transient boolean removePending;
|
duke@0
|
342 |
}
|
duke@0
|
343 |
|
duke@0
|
344 |
/**
|
duke@0
|
345 |
* <p>
|
duke@0
|
346 |
* Subclasses can override this method to insert their own subclass
|
duke@0
|
347 |
* of Child without having to override add() or the other Collection
|
duke@0
|
348 |
* methods that add children to the set.
|
duke@0
|
349 |
* </p>
|
duke@0
|
350 |
*
|
duke@0
|
351 |
* @param targetChild the child to create the Child on behalf of
|
duke@0
|
352 |
* @param peer the peer if the tragetChild and the peer are related by an implementation of BeanContextProxy
|
duke@0
|
353 |
*/
|
duke@0
|
354 |
|
duke@0
|
355 |
protected BCSChild createBCSChild(Object targetChild, Object peer) {
|
duke@0
|
356 |
return new BCSChild(targetChild, peer);
|
duke@0
|
357 |
}
|
duke@0
|
358 |
|
duke@0
|
359 |
/************************************************************************/
|
duke@0
|
360 |
|
duke@0
|
361 |
/**
|
duke@0
|
362 |
* Adds/nests a child within this <tt>BeanContext</tt>.
|
duke@0
|
363 |
* <p>
|
duke@0
|
364 |
* Invoked as a side effect of java.beans.Beans.instantiate().
|
duke@0
|
365 |
* If the child object is not valid for adding then this method
|
duke@0
|
366 |
* throws an IllegalStateException.
|
duke@0
|
367 |
* </p>
|
duke@0
|
368 |
*
|
duke@0
|
369 |
*
|
duke@0
|
370 |
* @param targetChild The child objects to nest
|
duke@0
|
371 |
* within this <tt>BeanContext</tt>
|
duke@0
|
372 |
* @return true if the child was added successfully.
|
duke@0
|
373 |
* @see #validatePendingAdd
|
duke@0
|
374 |
*/
|
duke@0
|
375 |
public boolean add(Object targetChild) {
|
duke@0
|
376 |
|
duke@0
|
377 |
if (targetChild == null) throw new IllegalArgumentException();
|
duke@0
|
378 |
|
duke@0
|
379 |
// The specification requires that we do nothing if the child
|
duke@0
|
380 |
// is already nested herein.
|
duke@0
|
381 |
|
duke@0
|
382 |
if (children.containsKey(targetChild)) return false; // test before locking
|
duke@0
|
383 |
|
duke@0
|
384 |
synchronized(BeanContext.globalHierarchyLock) {
|
duke@0
|
385 |
if (children.containsKey(targetChild)) return false; // check again
|
duke@0
|
386 |
|
duke@0
|
387 |
if (!validatePendingAdd(targetChild)) {
|
duke@0
|
388 |
throw new IllegalStateException();
|
duke@0
|
389 |
}
|
duke@0
|
390 |
|
duke@0
|
391 |
|
duke@0
|
392 |
// The specification requires that we invoke setBeanContext() on the
|
duke@0
|
393 |
// newly added child if it implements the java.beans.beancontext.BeanContextChild interface
|
duke@0
|
394 |
|
duke@0
|
395 |
BeanContextChild cbcc = getChildBeanContextChild(targetChild);
|
duke@0
|
396 |
BeanContextChild bccp = null;
|
duke@0
|
397 |
|
duke@0
|
398 |
synchronized(targetChild) {
|
duke@0
|
399 |
|
duke@0
|
400 |
if (targetChild instanceof BeanContextProxy) {
|
duke@0
|
401 |
bccp = ((BeanContextProxy)targetChild).getBeanContextProxy();
|
duke@0
|
402 |
|
duke@0
|
403 |
if (bccp == null) throw new NullPointerException("BeanContextPeer.getBeanContextProxy()");
|
duke@0
|
404 |
}
|
duke@0
|
405 |
|
duke@0
|
406 |
BCSChild bcsc = createBCSChild(targetChild, bccp);
|
duke@0
|
407 |
BCSChild pbcsc = null;
|
duke@0
|
408 |
|
duke@0
|
409 |
synchronized (children) {
|
duke@0
|
410 |
children.put(targetChild, bcsc);
|
duke@0
|
411 |
|
duke@0
|
412 |
if (bccp != null) children.put(bccp, pbcsc = createBCSChild(bccp, targetChild));
|
duke@0
|
413 |
}
|
duke@0
|
414 |
|
duke@0
|
415 |
if (cbcc != null) synchronized(cbcc) {
|
duke@0
|
416 |
try {
|
duke@0
|
417 |
cbcc.setBeanContext(getBeanContextPeer());
|
duke@0
|
418 |
} catch (PropertyVetoException pve) {
|
duke@0
|
419 |
|
duke@0
|
420 |
synchronized (children) {
|
duke@0
|
421 |
children.remove(targetChild);
|
duke@0
|
422 |
|
duke@0
|
423 |
if (bccp != null) children.remove(bccp);
|
duke@0
|
424 |
}
|
duke@0
|
425 |
|
duke@0
|
426 |
throw new IllegalStateException();
|
duke@0
|
427 |
}
|
duke@0
|
428 |
|
duke@0
|
429 |
cbcc.addPropertyChangeListener("beanContext", childPCL);
|
duke@0
|
430 |
cbcc.addVetoableChangeListener("beanContext", childVCL);
|
duke@0
|
431 |
}
|
duke@0
|
432 |
|
duke@0
|
433 |
Visibility v = getChildVisibility(targetChild);
|
duke@0
|
434 |
|
duke@0
|
435 |
if (v != null) {
|
duke@0
|
436 |
if (okToUseGui)
|
duke@0
|
437 |
v.okToUseGui();
|
duke@0
|
438 |
else
|
duke@0
|
439 |
v.dontUseGui();
|
duke@0
|
440 |
}
|
duke@0
|
441 |
|
duke@0
|
442 |
if (getChildSerializable(targetChild) != null) serializable++;
|
duke@0
|
443 |
|
duke@0
|
444 |
childJustAddedHook(targetChild, bcsc);
|
duke@0
|
445 |
|
duke@0
|
446 |
if (bccp != null) {
|
duke@0
|
447 |
v = getChildVisibility(bccp);
|
duke@0
|
448 |
|
duke@0
|
449 |
if (v != null) {
|
duke@0
|
450 |
if (okToUseGui)
|
duke@0
|
451 |
v.okToUseGui();
|
duke@0
|
452 |
else
|
duke@0
|
453 |
v.dontUseGui();
|
duke@0
|
454 |
}
|
duke@0
|
455 |
|
duke@0
|
456 |
if (getChildSerializable(bccp) != null) serializable++;
|
duke@0
|
457 |
|
duke@0
|
458 |
childJustAddedHook(bccp, pbcsc);
|
duke@0
|
459 |
}
|
duke@0
|
460 |
|
duke@0
|
461 |
|
duke@0
|
462 |
}
|
duke@0
|
463 |
|
duke@0
|
464 |
// The specification requires that we fire a notification of the change
|
duke@0
|
465 |
|
duke@0
|
466 |
fireChildrenAdded(new BeanContextMembershipEvent(getBeanContextPeer(), bccp == null ? new Object[] { targetChild } : new Object[] { targetChild, bccp } ));
|
duke@0
|
467 |
|
duke@0
|
468 |
}
|
duke@0
|
469 |
|
duke@0
|
470 |
return true;
|
duke@0
|
471 |
}
|
duke@0
|
472 |
|
duke@0
|
473 |
/**
|
duke@0
|
474 |
* Removes a child from this BeanContext. If the child object is not
|
duke@0
|
475 |
* for adding then this method throws an IllegalStateException.
|
duke@0
|
476 |
* @param targetChild The child objects to remove
|
duke@0
|
477 |
* @see #validatePendingRemove
|
duke@0
|
478 |
*/
|
duke@0
|
479 |
public boolean remove(Object targetChild) {
|
duke@0
|
480 |
return remove(targetChild, true);
|
duke@0
|
481 |
}
|
duke@0
|
482 |
|
duke@0
|
483 |
/**
|
duke@0
|
484 |
* internal remove used when removal caused by
|
duke@0
|
485 |
* unexpected <tt>setBeanContext</tt> or
|
duke@0
|
486 |
* by <tt>remove()</tt> invocation.
|
duke@0
|
487 |
* @param targetChild the JavaBean, BeanContext, or Object to be removed
|
duke@0
|
488 |
* @param callChildSetBC used to indicate that
|
duke@0
|
489 |
* the child should be notified that it is no
|
duke@0
|
490 |
* longer nested in this <tt>BeanContext</tt>.
|
duke@0
|
491 |
*/
|
duke@0
|
492 |
protected boolean remove(Object targetChild, boolean callChildSetBC) {
|
duke@0
|
493 |
|
duke@0
|
494 |
if (targetChild == null) throw new IllegalArgumentException();
|
duke@0
|
495 |
|
duke@0
|
496 |
synchronized(BeanContext.globalHierarchyLock) {
|
duke@0
|
497 |
if (!containsKey(targetChild)) return false;
|
duke@0
|
498 |
|
duke@0
|
499 |
if (!validatePendingRemove(targetChild)) {
|
duke@0
|
500 |
throw new IllegalStateException();
|
duke@0
|
501 |
}
|
duke@0
|
502 |
|
duke@0
|
503 |
BCSChild bcsc = (BCSChild)children.get(targetChild);
|
duke@0
|
504 |
BCSChild pbcsc = null;
|
duke@0
|
505 |
Object peer = null;
|
duke@0
|
506 |
|
duke@0
|
507 |
// we are required to notify the child that it is no longer nested here if
|
duke@0
|
508 |
// it implements java.beans.beancontext.BeanContextChild
|
duke@0
|
509 |
|
duke@0
|
510 |
synchronized(targetChild) {
|
duke@0
|
511 |
if (callChildSetBC) {
|
duke@0
|
512 |
BeanContextChild cbcc = getChildBeanContextChild(targetChild);
|
duke@0
|
513 |
if (cbcc != null) synchronized(cbcc) {
|
duke@0
|
514 |
cbcc.removePropertyChangeListener("beanContext", childPCL);
|
duke@0
|
515 |
cbcc.removeVetoableChangeListener("beanContext", childVCL);
|
duke@0
|
516 |
|
duke@0
|
517 |
try {
|
duke@0
|
518 |
cbcc.setBeanContext(null);
|
duke@0
|
519 |
} catch (PropertyVetoException pve1) {
|
duke@0
|
520 |
cbcc.addPropertyChangeListener("beanContext", childPCL);
|
duke@0
|
521 |
cbcc.addVetoableChangeListener("beanContext", childVCL);
|
duke@0
|
522 |
throw new IllegalStateException();
|
duke@0
|
523 |
}
|
duke@0
|
524 |
|
duke@0
|
525 |
}
|
duke@0
|
526 |
}
|
duke@0
|
527 |
|
duke@0
|
528 |
synchronized (children) {
|
duke@0
|
529 |
children.remove(targetChild);
|
duke@0
|
530 |
|
duke@0
|
531 |
if (bcsc.isProxyPeer()) {
|
duke@0
|
532 |
pbcsc = (BCSChild)children.get(peer = bcsc.getProxyPeer());
|
duke@0
|
533 |
children.remove(peer);
|
duke@0
|
534 |
}
|
duke@0
|
535 |
}
|
duke@0
|
536 |
|
duke@0
|
537 |
if (getChildSerializable(targetChild) != null) serializable--;
|
duke@0
|
538 |
|
duke@0
|
539 |
childJustRemovedHook(targetChild, bcsc);
|
duke@0
|
540 |
|
duke@0
|
541 |
if (peer != null) {
|
duke@0
|
542 |
if (getChildSerializable(peer) != null) serializable--;
|
duke@0
|
543 |
|
duke@0
|
544 |
childJustRemovedHook(peer, pbcsc);
|
duke@0
|
545 |
}
|
duke@0
|
546 |
}
|
duke@0
|
547 |
|
duke@0
|
548 |
fireChildrenRemoved(new BeanContextMembershipEvent(getBeanContextPeer(), peer == null ? new Object[] { targetChild } : new Object[] { targetChild, peer } ));
|
duke@0
|
549 |
|
duke@0
|
550 |
}
|
duke@0
|
551 |
|
duke@0
|
552 |
return true;
|
duke@0
|
553 |
}
|
duke@0
|
554 |
|
duke@0
|
555 |
/**
|
duke@0
|
556 |
* Tests to see if all objects in the
|
duke@0
|
557 |
* specified <tt>Collection</tt> are children of
|
duke@0
|
558 |
* this <tt>BeanContext</tt>.
|
duke@0
|
559 |
* @param c the specified <tt>Collection</tt>
|
duke@0
|
560 |
*
|
duke@0
|
561 |
* @return <tt>true</tt> if all objects
|
duke@0
|
562 |
* in the collection are children of
|
duke@0
|
563 |
* this <tt>BeanContext</tt>, false if not.
|
duke@0
|
564 |
*/
|
duke@0
|
565 |
public boolean containsAll(Collection c) {
|
duke@0
|
566 |
synchronized(children) {
|
duke@0
|
567 |
Iterator i = c.iterator();
|
duke@0
|
568 |
while (i.hasNext())
|
duke@0
|
569 |
if(!contains(i.next()))
|
duke@0
|
570 |
return false;
|
duke@0
|
571 |
|
duke@0
|
572 |
return true;
|
duke@0
|
573 |
}
|
duke@0
|
574 |
}
|
duke@0
|
575 |
|
duke@0
|
576 |
/**
|
duke@0
|
577 |
* add Collection to set of Children (Unsupported)
|
duke@0
|
578 |
* implementations must synchronized on the hierarchy lock and "children" protected field
|
duke@0
|
579 |
* @throws UnsupportedOperationException
|
duke@0
|
580 |
*/
|
duke@0
|
581 |
public boolean addAll(Collection c) {
|
duke@0
|
582 |
throw new UnsupportedOperationException();
|
duke@0
|
583 |
}
|
duke@0
|
584 |
|
duke@0
|
585 |
/**
|
duke@0
|
586 |
* remove all specified children (Unsupported)
|
duke@0
|
587 |
* implementations must synchronized on the hierarchy lock and "children" protected field
|
duke@0
|
588 |
* @throws UnsupportedOperationException
|
duke@0
|
589 |
*/
|
duke@0
|
590 |
public boolean removeAll(Collection c) {
|
duke@0
|
591 |
throw new UnsupportedOperationException();
|
duke@0
|
592 |
}
|
duke@0
|
593 |
|
duke@0
|
594 |
|
duke@0
|
595 |
/**
|
duke@0
|
596 |
* retain only specified children (Unsupported)
|
duke@0
|
597 |
* implementations must synchronized on the hierarchy lock and "children" protected field
|
duke@0
|
598 |
* @throws UnsupportedOperationException
|
duke@0
|
599 |
*/
|
duke@0
|
600 |
public boolean retainAll(Collection c) {
|
duke@0
|
601 |
throw new UnsupportedOperationException();
|
duke@0
|
602 |
}
|
duke@0
|
603 |
|
duke@0
|
604 |
/**
|
duke@0
|
605 |
* clear the children (Unsupported)
|
duke@0
|
606 |
* implementations must synchronized on the hierarchy lock and "children" protected field
|
duke@0
|
607 |
* @throws UnsupportedOperationException
|
duke@0
|
608 |
*/
|
duke@0
|
609 |
public void clear() {
|
duke@0
|
610 |
throw new UnsupportedOperationException();
|
duke@0
|
611 |
}
|
duke@0
|
612 |
|
duke@0
|
613 |
/**
|
duke@0
|
614 |
* Adds a BeanContextMembershipListener
|
duke@0
|
615 |
*
|
duke@0
|
616 |
* @param bcml the BeanContextMembershipListener to add
|
duke@0
|
617 |
* @throws NullPointerException
|
duke@0
|
618 |
*/
|
duke@0
|
619 |
|
duke@0
|
620 |
public void addBeanContextMembershipListener(BeanContextMembershipListener bcml) {
|
duke@0
|
621 |
if (bcml == null) throw new NullPointerException("listener");
|
duke@0
|
622 |
|
duke@0
|
623 |
synchronized(bcmListeners) {
|
duke@0
|
624 |
if (bcmListeners.contains(bcml))
|
duke@0
|
625 |
return;
|
duke@0
|
626 |
else
|
duke@0
|
627 |
bcmListeners.add(bcml);
|
duke@0
|
628 |
}
|
duke@0
|
629 |
}
|
duke@0
|
630 |
|
duke@0
|
631 |
/**
|
duke@0
|
632 |
* Removes a BeanContextMembershipListener
|
duke@0
|
633 |
*
|
duke@0
|
634 |
* @param bcml the BeanContextMembershipListener to remove
|
duke@0
|
635 |
* @throws NullPointerException
|
duke@0
|
636 |
*/
|
duke@0
|
637 |
|
duke@0
|
638 |
public void removeBeanContextMembershipListener(BeanContextMembershipListener bcml) {
|
duke@0
|
639 |
if (bcml == null) throw new NullPointerException("listener");
|
duke@0
|
640 |
|
duke@0
|
641 |
synchronized(bcmListeners) {
|
duke@0
|
642 |
if (!bcmListeners.contains(bcml))
|
duke@0
|
643 |
return;
|
duke@0
|
644 |
else
|
duke@0
|
645 |
bcmListeners.remove(bcml);
|
duke@0
|
646 |
}
|
duke@0
|
647 |
}
|
duke@0
|
648 |
|
duke@0
|
649 |
/**
|
duke@0
|
650 |
* @param name the name of the resource requested.
|
duke@0
|
651 |
* @param bcc the child object making the request.
|
duke@0
|
652 |
*
|
duke@0
|
653 |
* @return the requested resource as an InputStream
|
duke@0
|
654 |
* @throws NullPointerException
|
duke@0
|
655 |
*/
|
duke@0
|
656 |
|
duke@0
|
657 |
public InputStream getResourceAsStream(String name, BeanContextChild bcc) {
|
duke@0
|
658 |
if (name == null) throw new NullPointerException("name");
|
duke@0
|
659 |
if (bcc == null) throw new NullPointerException("bcc");
|
duke@0
|
660 |
|
duke@0
|
661 |
if (containsKey(bcc)) {
|
duke@0
|
662 |
ClassLoader cl = bcc.getClass().getClassLoader();
|
duke@0
|
663 |
|
duke@0
|
664 |
return cl != null ? cl.getResourceAsStream(name)
|
duke@0
|
665 |
: ClassLoader.getSystemResourceAsStream(name);
|
duke@0
|
666 |
} else throw new IllegalArgumentException("Not a valid child");
|
duke@0
|
667 |
}
|
duke@0
|
668 |
|
duke@0
|
669 |
/**
|
duke@0
|
670 |
* @param name the name of the resource requested.
|
duke@0
|
671 |
* @param bcc the child object making the request.
|
duke@0
|
672 |
*
|
duke@0
|
673 |
* @return the requested resource as an InputStream
|
duke@0
|
674 |
*/
|
duke@0
|
675 |
|
duke@0
|
676 |
public URL getResource(String name, BeanContextChild bcc) {
|
duke@0
|
677 |
if (name == null) throw new NullPointerException("name");
|
duke@0
|
678 |
if (bcc == null) throw new NullPointerException("bcc");
|
duke@0
|
679 |
|
duke@0
|
680 |
if (containsKey(bcc)) {
|
duke@0
|
681 |
ClassLoader cl = bcc.getClass().getClassLoader();
|
duke@0
|
682 |
|
duke@0
|
683 |
return cl != null ? cl.getResource(name)
|
duke@0
|
684 |
: ClassLoader.getSystemResource(name);
|
duke@0
|
685 |
} else throw new IllegalArgumentException("Not a valid child");
|
duke@0
|
686 |
}
|
duke@0
|
687 |
|
duke@0
|
688 |
/**
|
duke@0
|
689 |
* Sets the new design time value for this <tt>BeanContext</tt>.
|
duke@0
|
690 |
* @param dTime the new designTime value
|
duke@0
|
691 |
*/
|
duke@0
|
692 |
public synchronized void setDesignTime(boolean dTime) {
|
duke@0
|
693 |
if (designTime != dTime) {
|
duke@0
|
694 |
designTime = dTime;
|
duke@0
|
695 |
|
duke@0
|
696 |
firePropertyChange("designMode", Boolean.valueOf(!dTime), Boolean.valueOf(dTime));
|
duke@0
|
697 |
}
|
duke@0
|
698 |
}
|
duke@0
|
699 |
|
duke@0
|
700 |
|
duke@0
|
701 |
/**
|
duke@0
|
702 |
* Reports whether or not this object is in
|
duke@0
|
703 |
* currently in design time mode.
|
duke@0
|
704 |
* @return <tt>true</tt> if in design time mode,
|
duke@0
|
705 |
* <tt>false</tt> if not
|
duke@0
|
706 |
*/
|
duke@0
|
707 |
public synchronized boolean isDesignTime() { return designTime; }
|
duke@0
|
708 |
|
duke@0
|
709 |
/**
|
duke@0
|
710 |
* Sets the locale of this BeanContext.
|
duke@0
|
711 |
* @param newLocale the new locale. This method call will have
|
duke@0
|
712 |
* no effect if newLocale is <CODE>null</CODE>.
|
duke@0
|
713 |
* @throws PropertyVetoException if the new value is rejected
|
duke@0
|
714 |
*/
|
duke@0
|
715 |
public synchronized void setLocale(Locale newLocale) throws PropertyVetoException {
|
duke@0
|
716 |
|
duke@0
|
717 |
if ((locale != null && !locale.equals(newLocale)) && newLocale != null) {
|
duke@0
|
718 |
Locale old = locale;
|
duke@0
|
719 |
|
duke@0
|
720 |
fireVetoableChange("locale", old, newLocale); // throws
|
duke@0
|
721 |
|
duke@0
|
722 |
locale = newLocale;
|
duke@0
|
723 |
|
duke@0
|
724 |
firePropertyChange("locale", old, newLocale);
|
duke@0
|
725 |
}
|
duke@0
|
726 |
}
|
duke@0
|
727 |
|
duke@0
|
728 |
/**
|
duke@0
|
729 |
* Gets the locale for this <tt>BeanContext</tt>.
|
duke@0
|
730 |
*
|
duke@0
|
731 |
* @return the current Locale of the <tt>BeanContext</tt>
|
duke@0
|
732 |
*/
|
duke@0
|
733 |
public synchronized Locale getLocale() { return locale; }
|
duke@0
|
734 |
|
duke@0
|
735 |
/**
|
duke@0
|
736 |
* <p>
|
duke@0
|
737 |
* This method is typically called from the environment in order to determine
|
duke@0
|
738 |
* if the implementor "needs" a GUI.
|
duke@0
|
739 |
* </p>
|
duke@0
|
740 |
* <p>
|
duke@0
|
741 |
* The algorithm used herein tests the BeanContextPeer, and its current children
|
duke@0
|
742 |
* to determine if they are either Containers, Components, or if they implement
|
duke@0
|
743 |
* Visibility and return needsGui() == true.
|
duke@0
|
744 |
* </p>
|
duke@0
|
745 |
* @return <tt>true</tt> if the implementor needs a GUI
|
duke@0
|
746 |
*/
|
duke@0
|
747 |
public synchronized boolean needsGui() {
|
duke@0
|
748 |
BeanContext bc = getBeanContextPeer();
|
duke@0
|
749 |
|
duke@0
|
750 |
if (bc != this) {
|
duke@0
|
751 |
if (bc instanceof Visibility) return ((Visibility)bc).needsGui();
|
duke@0
|
752 |
|
duke@0
|
753 |
if (bc instanceof Container || bc instanceof Component)
|
duke@0
|
754 |
return true;
|
duke@0
|
755 |
}
|
duke@0
|
756 |
|
duke@0
|
757 |
synchronized(children) {
|
duke@0
|
758 |
for (Iterator i = children.keySet().iterator(); i.hasNext();) {
|
duke@0
|
759 |
Object c = i.next();
|
duke@0
|
760 |
|
duke@0
|
761 |
try {
|
duke@0
|
762 |
return ((Visibility)c).needsGui();
|
duke@0
|
763 |
} catch (ClassCastException cce) {
|
duke@0
|
764 |
// do nothing ...
|
duke@0
|
765 |
}
|
duke@0
|
766 |
|
duke@0
|
767 |
if (c instanceof Container || c instanceof Component)
|
duke@0
|
768 |
return true;
|
duke@0
|
769 |
}
|
duke@0
|
770 |
}
|
duke@0
|
771 |
|
duke@0
|
772 |
return false;
|
duke@0
|
773 |
}
|
duke@0
|
774 |
|
duke@0
|
775 |
/**
|
duke@0
|
776 |
* notify this instance that it may no longer render a GUI.
|
duke@0
|
777 |
*/
|
duke@0
|
778 |
|
duke@0
|
779 |
public synchronized void dontUseGui() {
|
duke@0
|
780 |
if (okToUseGui) {
|
duke@0
|
781 |
okToUseGui = false;
|
duke@0
|
782 |
|
duke@0
|
783 |
// lets also tell the Children that can that they may not use their GUI's
|
duke@0
|
784 |
synchronized(children) {
|
duke@0
|
785 |
for (Iterator i = children.keySet().iterator(); i.hasNext();) {
|
duke@0
|
786 |
Visibility v = getChildVisibility(i.next());
|
duke@0
|
787 |
|
duke@0
|
788 |
if (v != null) v.dontUseGui();
|
duke@0
|
789 |
}
|
duke@0
|
790 |
}
|
duke@0
|
791 |
}
|
duke@0
|
792 |
}
|
duke@0
|
793 |
|
duke@0
|
794 |
/**
|
duke@0
|
795 |
* Notify this instance that it may now render a GUI
|
duke@0
|
796 |
*/
|
duke@0
|
797 |
|
duke@0
|
798 |
public synchronized void okToUseGui() {
|
duke@0
|
799 |
if (!okToUseGui) {
|
duke@0
|
800 |
okToUseGui = true;
|
duke@0
|
801 |
|
duke@0
|
802 |
// lets also tell the Children that can that they may use their GUI's
|
duke@0
|
803 |
synchronized(children) {
|
duke@0
|
804 |
for (Iterator i = children.keySet().iterator(); i.hasNext();) {
|
duke@0
|
805 |
Visibility v = getChildVisibility(i.next());
|
duke@0
|
806 |
|
duke@0
|
807 |
if (v != null) v.okToUseGui();
|
duke@0
|
808 |
}
|
duke@0
|
809 |
}
|
duke@0
|
810 |
}
|
duke@0
|
811 |
}
|
duke@0
|
812 |
|
duke@0
|
813 |
/**
|
duke@0
|
814 |
* Used to determine if the <tt>BeanContext</tt>
|
duke@0
|
815 |
* child is avoiding using its GUI.
|
duke@0
|
816 |
* @return is this instance avoiding using its GUI?
|
duke@0
|
817 |
* @see Visibility
|
duke@0
|
818 |
*/
|
duke@0
|
819 |
public boolean avoidingGui() {
|
duke@0
|
820 |
return !okToUseGui && needsGui();
|
duke@0
|
821 |
}
|
duke@0
|
822 |
|
duke@0
|
823 |
/**
|
duke@0
|
824 |
* Is this <tt>BeanContext</tt> in the
|
duke@0
|
825 |
* process of being serialized?
|
duke@0
|
826 |
* @return if this <tt>BeanContext</tt> is
|
duke@0
|
827 |
* currently being serialized
|
duke@0
|
828 |
*/
|
duke@0
|
829 |
public boolean isSerializing() { return serializing; }
|
duke@0
|
830 |
|
duke@0
|
831 |
/**
|
duke@0
|
832 |
* Returns an iterator of all children
|
duke@0
|
833 |
* of this <tt>BeanContext</tt>.
|
duke@0
|
834 |
* @return an iterator for all the current BCSChild values
|
duke@0
|
835 |
*/
|
duke@0
|
836 |
protected Iterator bcsChildren() { synchronized(children) { return children.values().iterator(); } }
|
duke@0
|
837 |
|
duke@0
|
838 |
/**
|
duke@0
|
839 |
* called by writeObject after defaultWriteObject() but prior to
|
duke@0
|
840 |
* serialization of currently serializable children.
|
duke@0
|
841 |
*
|
duke@0
|
842 |
* This method may be overridden by subclasses to perform custom
|
duke@0
|
843 |
* serialization of their state prior to this superclass serializing
|
duke@0
|
844 |
* the children.
|
duke@0
|
845 |
*
|
duke@0
|
846 |
* This method should not however be used by subclasses to replace their
|
duke@0
|
847 |
* own implementation (if any) of writeObject().
|
duke@0
|
848 |
*/
|
duke@0
|
849 |
|
duke@0
|
850 |
protected void bcsPreSerializationHook(ObjectOutputStream oos) throws IOException {
|
duke@0
|
851 |
}
|
duke@0
|
852 |
|
duke@0
|
853 |
/**
|
duke@0
|
854 |
* called by readObject after defaultReadObject() but prior to
|
duke@0
|
855 |
* deserialization of any children.
|
duke@0
|
856 |
*
|
duke@0
|
857 |
* This method may be overridden by subclasses to perform custom
|
duke@0
|
858 |
* deserialization of their state prior to this superclass deserializing
|
duke@0
|
859 |
* the children.
|
duke@0
|
860 |
*
|
duke@0
|
861 |
* This method should not however be used by subclasses to replace their
|
duke@0
|
862 |
* own implementation (if any) of readObject().
|
duke@0
|
863 |
*/
|
duke@0
|
864 |
|
duke@0
|
865 |
protected void bcsPreDeserializationHook(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
duke@0
|
866 |
}
|
duke@0
|
867 |
|
duke@0
|
868 |
/**
|
duke@0
|
869 |
* Called by readObject with the newly deserialized child and BCSChild.
|
duke@0
|
870 |
* @param child the newly deserialized child
|
duke@0
|
871 |
* @param bcsc the newly deserialized BCSChild
|
duke@0
|
872 |
*/
|
duke@0
|
873 |
protected void childDeserializedHook(Object child, BCSChild bcsc) {
|
duke@0
|
874 |
synchronized(children) {
|
duke@0
|
875 |
children.put(child, bcsc);
|
duke@0
|
876 |
}
|
duke@0
|
877 |
}
|
duke@0
|
878 |
|
duke@0
|
879 |
/**
|
duke@0
|
880 |
* Used by writeObject to serialize a Collection.
|
duke@0
|
881 |
* @param oos the <tt>ObjectOutputStream</tt>
|
duke@0
|
882 |
* to use during serialization
|
duke@0
|
883 |
* @param coll the <tt>Collection</tt> to serialize
|
duke@0
|
884 |
* @throws IOException if serialization failed
|
duke@0
|
885 |
*/
|
duke@0
|
886 |
protected final void serialize(ObjectOutputStream oos, Collection coll) throws IOException {
|
duke@0
|
887 |
int count = 0;
|
duke@0
|
888 |
Object[] objects = coll.toArray();
|
duke@0
|
889 |
|
duke@0
|
890 |
for (int i = 0; i < objects.length; i++) {
|
duke@0
|
891 |
if (objects[i] instanceof Serializable)
|
duke@0
|
892 |
count++;
|
duke@0
|
893 |
else
|
duke@0
|
894 |
objects[i] = null;
|
duke@0
|
895 |
}
|
duke@0
|
896 |
|
duke@0
|
897 |
oos.writeInt(count); // number of subsequent objects
|
duke@0
|
898 |
|
duke@0
|
899 |
for (int i = 0; count > 0; i++) {
|
duke@0
|
900 |
Object o = objects[i];
|
duke@0
|
901 |
|
duke@0
|
902 |
if (o != null) {
|
duke@0
|
903 |
oos.writeObject(o);
|
duke@0
|
904 |
count--;
|
duke@0
|
905 |
}
|
duke@0
|
906 |
}
|
duke@0
|
907 |
}
|
duke@0
|
908 |
|
duke@0
|
909 |
/**
|
duke@0
|
910 |
* used by readObject to deserialize a collection.
|
duke@0
|
911 |
* @param ois the ObjectInputStream to use
|
duke@0
|
912 |
* @param coll the Collection
|
duke@0
|
913 |
*/
|
duke@0
|
914 |
protected final void deserialize(ObjectInputStream ois, Collection coll) throws IOException, ClassNotFoundException {
|
duke@0
|
915 |
int count = 0;
|
duke@0
|
916 |
|
duke@0
|
917 |
count = ois.readInt();
|
duke@0
|
918 |
|
duke@0
|
919 |
while (count-- > 0) {
|
duke@0
|
920 |
coll.add(ois.readObject());
|
duke@0
|
921 |
}
|
duke@0
|
922 |
}
|
duke@0
|
923 |
|
duke@0
|
924 |
/**
|
duke@0
|
925 |
* Used to serialize all children of
|
duke@0
|
926 |
* this <tt>BeanContext</tt>.
|
duke@0
|
927 |
* @param oos the <tt>ObjectOutputStream</tt>
|
duke@0
|
928 |
* to use during serialization
|
duke@0
|
929 |
* @throws IOException if serialization failed
|
duke@0
|
930 |
*/
|
duke@0
|
931 |
public final void writeChildren(ObjectOutputStream oos) throws IOException {
|
duke@0
|
932 |
if (serializable <= 0) return;
|
duke@0
|
933 |
|
duke@0
|
934 |
boolean prev = serializing;
|
duke@0
|
935 |
|
duke@0
|
936 |
serializing = true;
|
duke@0
|
937 |
|
duke@0
|
938 |
int count = 0;
|
duke@0
|
939 |
|
duke@0
|
940 |
synchronized(children) {
|
duke@0
|
941 |
Iterator i = children.entrySet().iterator();
|
duke@0
|
942 |
|
duke@0
|
943 |
while (i.hasNext() && count < serializable) {
|
duke@0
|
944 |
Map.Entry entry = (Map.Entry)i.next();
|
duke@0
|
945 |
|
duke@0
|
946 |
if (entry.getKey() instanceof Serializable) {
|
duke@0
|
947 |
try {
|
duke@0
|
948 |
oos.writeObject(entry.getKey()); // child
|
duke@0
|
949 |
oos.writeObject(entry.getValue()); // BCSChild
|
duke@0
|
950 |
} catch (IOException ioe) {
|
duke@0
|
951 |
serializing = prev;
|
duke@0
|
952 |
throw ioe;
|
duke@0
|
953 |
}
|
duke@0
|
954 |
count++;
|
duke@0
|
955 |
}
|
duke@0
|
956 |
}
|
duke@0
|
957 |
}
|
duke@0
|
958 |
|
duke@0
|
959 |
serializing = prev;
|
duke@0
|
960 |
|
duke@0
|
961 |
if (count != serializable) {
|
duke@0
|
962 |
throw new IOException("wrote different number of children than expected");
|
duke@0
|
963 |
}
|
duke@0
|
964 |
|
duke@0
|
965 |
}
|
duke@0
|
966 |
|
duke@0
|
967 |
/**
|
duke@0
|
968 |
* Serialize the BeanContextSupport, if this instance has a distinct
|
duke@0
|
969 |
* peer (that is this object is acting as a delegate for another) then
|
duke@0
|
970 |
* the children of this instance are not serialized here due to a
|
duke@0
|
971 |
* 'chicken and egg' problem that occurs on deserialization of the
|
duke@0
|
972 |
* children at the same time as this instance.
|
duke@0
|
973 |
*
|
duke@0
|
974 |
* Therefore in situations where there is a distinct peer to this instance
|
duke@0
|
975 |
* it should always call writeObject() followed by writeChildren() and
|
duke@0
|
976 |
* readObject() followed by readChildren().
|
duke@0
|
977 |
*
|
duke@0
|
978 |
* @param oos the ObjectOutputStream
|
duke@0
|
979 |
*/
|
duke@0
|
980 |
|
duke@0
|
981 |
private synchronized void writeObject(ObjectOutputStream oos) throws IOException, ClassNotFoundException {
|
duke@0
|
982 |
serializing = true;
|
duke@0
|
983 |
|
duke@0
|
984 |
synchronized (BeanContext.globalHierarchyLock) {
|
duke@0
|
985 |
try {
|
duke@0
|
986 |
oos.defaultWriteObject(); // serialize the BeanContextSupport object
|
duke@0
|
987 |
|
duke@0
|
988 |
bcsPreSerializationHook(oos);
|
duke@0
|
989 |
|
duke@0
|
990 |
if (serializable > 0 && this.equals(getBeanContextPeer()))
|
duke@0
|
991 |
writeChildren(oos);
|
duke@0
|
992 |
|
duke@0
|
993 |
serialize(oos, (Collection)bcmListeners);
|
duke@0
|
994 |
} finally {
|
duke@0
|
995 |
serializing = false;
|
duke@0
|
996 |
}
|
duke@0
|
997 |
}
|
duke@0
|
998 |
}
|
duke@0
|
999 |
|
duke@0
|
1000 |
/**
|
duke@0
|
1001 |
* When an instance of this class is used as a delegate for the
|
duke@0
|
1002 |
* implementation of the BeanContext protocols (and its subprotocols)
|
duke@0
|
1003 |
* there exists a 'chicken and egg' problem during deserialization
|
duke@0
|
1004 |
*/
|
duke@0
|
1005 |
|
duke@0
|
1006 |
public final void readChildren(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
duke@0
|
1007 |
int count = serializable;
|
duke@0
|
1008 |
|
duke@0
|
1009 |
while (count-- > 0) {
|
duke@0
|
1010 |
Object child = null;
|
duke@0
|
1011 |
BeanContextSupport.BCSChild bscc = null;
|
duke@0
|
1012 |
|
duke@0
|
1013 |
try {
|
duke@0
|
1014 |
child = ois.readObject();
|
duke@0
|
1015 |
bscc = (BeanContextSupport.BCSChild)ois.readObject();
|
duke@0
|
1016 |
} catch (IOException ioe) {
|
duke@0
|
1017 |
continue;
|
duke@0
|
1018 |
} catch (ClassNotFoundException cnfe) {
|
duke@0
|
1019 |
continue;
|
duke@0
|
1020 |
}
|
duke@0
|
1021 |
|
duke@0
|
1022 |
|
duke@0
|
1023 |
synchronized(child) {
|
duke@0
|
1024 |
BeanContextChild bcc = null;
|
duke@0
|
1025 |
|
duke@0
|
1026 |
try {
|
duke@0
|
1027 |
bcc = (BeanContextChild)child;
|
duke@0
|
1028 |
} catch (ClassCastException cce) {
|
duke@0
|
1029 |
// do nothing;
|
duke@0
|
1030 |
}
|
duke@0
|
1031 |
|
duke@0
|
1032 |
if (bcc != null) {
|
duke@0
|
1033 |
try {
|
duke@0
|
1034 |
bcc.setBeanContext(getBeanContextPeer());
|
duke@0
|
1035 |
|
duke@0
|
1036 |
bcc.addPropertyChangeListener("beanContext", childPCL);
|
duke@0
|
1037 |
bcc.addVetoableChangeListener("beanContext", childVCL);
|
duke@0
|
1038 |
|
duke@0
|
1039 |
} catch (PropertyVetoException pve) {
|
duke@0
|
1040 |
continue;
|
duke@0
|
1041 |
}
|
duke@0
|
1042 |
}
|
duke@0
|
1043 |
|
duke@0
|
1044 |
childDeserializedHook(child, bscc);
|
duke@0
|
1045 |
}
|
duke@0
|
1046 |
}
|
duke@0
|
1047 |
}
|
duke@0
|
1048 |
|
duke@0
|
1049 |
/**
|
duke@0
|
1050 |
* deserialize contents ... if this instance has a distinct peer the
|
duke@0
|
1051 |
* children are *not* serialized here, the peer's readObject() must call
|
duke@0
|
1052 |
* readChildren() after deserializing this instance.
|
duke@0
|
1053 |
*/
|
duke@0
|
1054 |
|
duke@0
|
1055 |
private synchronized void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
duke@0
|
1056 |
|
duke@0
|
1057 |
synchronized(BeanContext.globalHierarchyLock) {
|
duke@0
|
1058 |
ois.defaultReadObject();
|
duke@0
|
1059 |
|
duke@0
|
1060 |
initialize();
|
duke@0
|
1061 |
|
duke@0
|
1062 |
bcsPreDeserializationHook(ois);
|
duke@0
|
1063 |
|
duke@0
|
1064 |
if (serializable > 0 && this.equals(getBeanContextPeer()))
|
duke@0
|
1065 |
readChildren(ois);
|
duke@0
|
1066 |
|
duke@0
|
1067 |
deserialize(ois, bcmListeners = new ArrayList(1));
|
duke@0
|
1068 |
}
|
duke@0
|
1069 |
}
|
duke@0
|
1070 |
|
duke@0
|
1071 |
/**
|
duke@0
|
1072 |
* subclasses may envelope to monitor veto child property changes.
|
duke@0
|
1073 |
*/
|
duke@0
|
1074 |
|
duke@0
|
1075 |
public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
|
duke@0
|
1076 |
String propertyName = pce.getPropertyName();
|
duke@0
|
1077 |
Object source = pce.getSource();
|
duke@0
|
1078 |
|
duke@0
|
1079 |
synchronized(children) {
|
duke@0
|
1080 |
if ("beanContext".equals(propertyName) &&
|
duke@0
|
1081 |
containsKey(source) &&
|
duke@0
|
1082 |
!getBeanContextPeer().equals(pce.getNewValue())
|
duke@0
|
1083 |
) {
|
duke@0
|
1084 |
if (!validatePendingRemove(source)) {
|
duke@0
|
1085 |
throw new PropertyVetoException("current BeanContext vetoes setBeanContext()", pce);
|
duke@0
|
1086 |
} else ((BCSChild)children.get(source)).setRemovePending(true);
|
duke@0
|
1087 |
}
|
duke@0
|
1088 |
}
|
duke@0
|
1089 |
}
|
duke@0
|
1090 |
|
duke@0
|
1091 |
/**
|
duke@0
|
1092 |
* subclasses may envelope to monitor child property changes.
|
duke@0
|
1093 |
*/
|
duke@0
|
1094 |
|
duke@0
|
1095 |
public void propertyChange(PropertyChangeEvent pce) {
|
duke@0
|
1096 |
String propertyName = pce.getPropertyName();
|
duke@0
|
1097 |
Object source = pce.getSource();
|
duke@0
|
1098 |
|
duke@0
|
1099 |
synchronized(children) {
|
duke@0
|
1100 |
if ("beanContext".equals(propertyName) &&
|
duke@0
|
1101 |
containsKey(source) &&
|
duke@0
|
1102 |
((BCSChild)children.get(source)).isRemovePending()) {
|
duke@0
|
1103 |
BeanContext bc = getBeanContextPeer();
|
duke@0
|
1104 |
|
duke@0
|
1105 |
if (bc.equals(pce.getOldValue()) && !bc.equals(pce.getNewValue())) {
|
duke@0
|
1106 |
remove(source, false);
|
duke@0
|
1107 |
} else {
|
duke@0
|
1108 |
((BCSChild)children.get(source)).setRemovePending(false);
|
duke@0
|
1109 |
}
|
duke@0
|
1110 |
}
|
duke@0
|
1111 |
}
|
duke@0
|
1112 |
}
|
duke@0
|
1113 |
|
duke@0
|
1114 |
/**
|
duke@0
|
1115 |
* <p>
|
duke@0
|
1116 |
* Subclasses of this class may override, or envelope, this method to
|
duke@0
|
1117 |
* add validation behavior for the BeanContext to examine child objects
|
duke@0
|
1118 |
* immediately prior to their being added to the BeanContext.
|
duke@0
|
1119 |
* </p>
|
duke@0
|
1120 |
*
|
duke@0
|
1121 |
* @return true iff the child may be added to this BeanContext, otherwise false.
|
duke@0
|
1122 |
*/
|
duke@0
|
1123 |
|
duke@0
|
1124 |
protected boolean validatePendingAdd(Object targetChild) {
|
duke@0
|
1125 |
return true;
|
duke@0
|
1126 |
}
|
duke@0
|
1127 |
|
duke@0
|
1128 |
/**
|
duke@0
|
1129 |
* <p>
|
duke@0
|
1130 |
* Subclasses of this class may override, or envelope, this method to
|
duke@0
|
1131 |
* add validation behavior for the BeanContext to examine child objects
|
duke@0
|
1132 |
* immediately prior to their being removed from the BeanContext.
|
duke@0
|
1133 |
* </p>
|
duke@0
|
1134 |
*
|
duke@0
|
1135 |
* @return true iff the child may be removed from this BeanContext, otherwise false.
|
duke@0
|
1136 |
*/
|
duke@0
|
1137 |
|
duke@0
|
1138 |
protected boolean validatePendingRemove(Object targetChild) {
|
duke@0
|
1139 |
return true;
|
duke@0
|
1140 |
}
|
duke@0
|
1141 |
|
duke@0
|
1142 |
/**
|
duke@0
|
1143 |
* subclasses may override this method to simply extend add() semantics
|
duke@0
|
1144 |
* after the child has been added and before the event notification has
|
duke@0
|
1145 |
* occurred. The method is called with the child synchronized.
|
duke@0
|
1146 |
*/
|
duke@0
|
1147 |
|
duke@0
|
1148 |
protected void childJustAddedHook(Object child, BCSChild bcsc) {
|
duke@0
|
1149 |
}
|
duke@0
|
1150 |
|
duke@0
|
1151 |
/**
|
duke@0
|
1152 |
* subclasses may override this method to simply extend remove() semantics
|
duke@0
|
1153 |
* after the child has been removed and before the event notification has
|
duke@0
|
1154 |
* occurred. The method is called with the child synchronized.
|
duke@0
|
1155 |
*/
|
duke@0
|
1156 |
|
duke@0
|
1157 |
protected void childJustRemovedHook(Object child, BCSChild bcsc) {
|
duke@0
|
1158 |
}
|
duke@0
|
1159 |
|
duke@0
|
1160 |
/**
|
duke@0
|
1161 |
* Gets the Component (if any) associated with the specified child.
|
duke@0
|
1162 |
* @param child the specified child
|
duke@0
|
1163 |
* @return the Component (if any) associated with the specified child.
|
duke@0
|
1164 |
*/
|
duke@0
|
1165 |
protected static final Visibility getChildVisibility(Object child) {
|
duke@0
|
1166 |
try {
|
duke@0
|
1167 |
return (Visibility)child;
|
duke@0
|
1168 |
} catch (ClassCastException cce) {
|
duke@0
|
1169 |
return null;
|
duke@0
|
1170 |
}
|
duke@0
|
1171 |
}
|
duke@0
|
1172 |
|
duke@0
|
1173 |
/**
|
duke@0
|
1174 |
* Gets the Serializable (if any) associated with the specified Child
|
duke@0
|
1175 |
* @param child the specified child
|
duke@0
|
1176 |
* @return the Serializable (if any) associated with the specified Child
|
duke@0
|
1177 |
*/
|
duke@0
|
1178 |
protected static final Serializable getChildSerializable(Object child) {
|
duke@0
|
1179 |
try {
|
duke@0
|
1180 |
return (Serializable)child;
|
duke@0
|
1181 |
} catch (ClassCastException cce) {
|
duke@0
|
1182 |
return null;
|
duke@0
|
1183 |
}
|
duke@0
|
1184 |
}
|
duke@0
|
1185 |
|
duke@0
|
1186 |
/**
|
duke@0
|
1187 |
* Gets the PropertyChangeListener
|
duke@0
|
1188 |
* (if any) of the specified child
|
duke@0
|
1189 |
* @param child the specified child
|
duke@0
|
1190 |
* @return the PropertyChangeListener (if any) of the specified child
|
duke@0
|
1191 |
*/
|
duke@0
|
1192 |
protected static final PropertyChangeListener getChildPropertyChangeListener(Object child) {
|
duke@0
|
1193 |
try {
|
duke@0
|
1194 |
return (PropertyChangeListener)child;
|
duke@0
|
1195 |
} catch (ClassCastException cce) {
|
duke@0
|
1196 |
return null;
|
duke@0
|
1197 |
}
|
duke@0
|
1198 |
}
|
duke@0
|
1199 |
|
duke@0
|
1200 |
/**
|
duke@0
|
1201 |
* Gets the VetoableChangeListener
|
duke@0
|
1202 |
* (if any) of the specified child
|
duke@0
|
1203 |
* @param child the specified child
|
duke@0
|
1204 |
* @return the VetoableChangeListener (if any) of the specified child
|
duke@0
|
1205 |
*/
|
duke@0
|
1206 |
protected static final VetoableChangeListener getChildVetoableChangeListener(Object child) {
|
duke@0
|
1207 |
try {
|
duke@0
|
1208 |
return (VetoableChangeListener)child;
|
duke@0
|
1209 |
} catch (ClassCastException cce) {
|
duke@0
|
1210 |
return null;
|
duke@0
|
1211 |
}
|
duke@0
|
1212 |
}
|
duke@0
|
1213 |
|
duke@0
|
1214 |
/**
|
duke@0
|
1215 |
* Gets the BeanContextMembershipListener
|
duke@0
|
1216 |
* (if any) of the specified child
|
duke@0
|
1217 |
* @param child the specified child
|
duke@0
|
1218 |
* @return the BeanContextMembershipListener (if any) of the specified child
|
duke@0
|
1219 |
*/
|
duke@0
|
1220 |
protected static final BeanContextMembershipListener getChildBeanContextMembershipListener(Object child) {
|
duke@0
|
1221 |
try {
|
duke@0
|
1222 |
return (BeanContextMembershipListener)child;
|
duke@0
|
1223 |
} catch (ClassCastException cce) {
|
duke@0
|
1224 |
return null;
|
duke@0
|
1225 |
}
|
duke@0
|
1226 |
}
|
duke@0
|
1227 |
|
duke@0
|
1228 |
/**
|
duke@0
|
1229 |
* Gets the BeanContextChild (if any) of the specified child
|
duke@0
|
1230 |
* @param child the specified child
|
duke@0
|
1231 |
* @return the BeanContextChild (if any) of the specified child
|
duke@0
|
1232 |
* @throws IllegalArgumentException if child implements both BeanContextChild and BeanContextProxy
|
duke@0
|
1233 |
*/
|
duke@0
|
1234 |
protected static final BeanContextChild getChildBeanContextChild(Object child) {
|
duke@0
|
1235 |
try {
|
duke@0
|
1236 |
BeanContextChild bcc = (BeanContextChild)child;
|
duke@0
|
1237 |
|
duke@0
|
1238 |
if (child instanceof BeanContextChild && child instanceof BeanContextProxy)
|
duke@0
|
1239 |
throw new IllegalArgumentException("child cannot implement both BeanContextChild and BeanContextProxy");
|
duke@0
|
1240 |
else
|
duke@0
|
1241 |
return bcc;
|
duke@0
|
1242 |
} catch (ClassCastException cce) {
|
duke@0
|
1243 |
try {
|
duke@0
|
1244 |
return ((BeanContextProxy)child).getBeanContextProxy();
|
duke@0
|
1245 |
} catch (ClassCastException cce1) {
|
duke@0
|
1246 |
return null;
|
duke@0
|
1247 |
}
|
duke@0
|
1248 |
}
|
duke@0
|
1249 |
}
|
duke@0
|
1250 |
|
duke@0
|
1251 |
/**
|
duke@0
|
1252 |
* Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
|
duke@0
|
1253 |
*/
|
duke@0
|
1254 |
|
duke@0
|
1255 |
protected final void fireChildrenAdded(BeanContextMembershipEvent bcme) {
|
duke@0
|
1256 |
Object[] copy;
|
duke@0
|
1257 |
|
duke@0
|
1258 |
synchronized(bcmListeners) { copy = bcmListeners.toArray(); }
|
duke@0
|
1259 |
|
duke@0
|
1260 |
for (int i = 0; i < copy.length; i++)
|
duke@0
|
1261 |
((BeanContextMembershipListener)copy[i]).childrenAdded(bcme);
|
duke@0
|
1262 |
}
|
duke@0
|
1263 |
|
duke@0
|
1264 |
/**
|
duke@0
|
1265 |
* Fire a BeanContextshipEvent on the BeanContextMembershipListener interface
|
duke@0
|
1266 |
*/
|
duke@0
|
1267 |
|
duke@0
|
1268 |
protected final void fireChildrenRemoved(BeanContextMembershipEvent bcme) {
|
duke@0
|
1269 |
Object[] copy;
|
duke@0
|
1270 |
|
duke@0
|
1271 |
synchronized(bcmListeners) { copy = bcmListeners.toArray(); }
|
duke@0
|
1272 |
|
duke@0
|
1273 |
for (int i = 0; i < copy.length; i++)
|
duke@0
|
1274 |
((BeanContextMembershipListener)copy[i]).childrenRemoved(bcme);
|
duke@0
|
1275 |
}
|
duke@0
|
1276 |
|
duke@0
|
1277 |
/**
|
duke@0
|
1278 |
* protected method called from constructor and readObject to initialize
|
duke@0
|
1279 |
* transient state of BeanContextSupport instance.
|
duke@0
|
1280 |
*
|
duke@0
|
1281 |
* This class uses this method to instantiate inner class listeners used
|
duke@0
|
1282 |
* to monitor PropertyChange and VetoableChange events on children.
|
duke@0
|
1283 |
*
|
duke@0
|
1284 |
* subclasses may envelope this method to add their own initialization
|
duke@0
|
1285 |
* behavior
|
duke@0
|
1286 |
*/
|
duke@0
|
1287 |
|
duke@0
|
1288 |
protected synchronized void initialize() {
|
duke@0
|
1289 |
children = new HashMap(serializable + 1);
|
duke@0
|
1290 |
bcmListeners = new ArrayList(1);
|
duke@0
|
1291 |
|
duke@0
|
1292 |
childPCL = new PropertyChangeListener() {
|
duke@0
|
1293 |
|
duke@0
|
1294 |
/*
|
duke@0
|
1295 |
* this adaptor is used by the BeanContextSupport class to forward
|
duke@0
|
1296 |
* property changes from a child to the BeanContext, avoiding
|
duke@0
|
1297 |
* accidential serialization of the BeanContext by a badly
|
duke@0
|
1298 |
* behaved Serializable child.
|
duke@0
|
1299 |
*/
|
duke@0
|
1300 |
|
duke@0
|
1301 |
public void propertyChange(PropertyChangeEvent pce) {
|
duke@0
|
1302 |
BeanContextSupport.this.propertyChange(pce);
|
duke@0
|
1303 |
}
|
duke@0
|
1304 |
};
|
duke@0
|
1305 |
|
duke@0
|
1306 |
childVCL = new VetoableChangeListener() {
|
duke@0
|
1307 |
|
duke@0
|
1308 |
/*
|
duke@0
|
1309 |
* this adaptor is used by the BeanContextSupport class to forward
|
duke@0
|
1310 |
* vetoable changes from a child to the BeanContext, avoiding
|
duke@0
|
1311 |
* accidential serialization of the BeanContext by a badly
|
duke@0
|
1312 |
* behaved Serializable child.
|
duke@0
|
1313 |
*/
|
duke@0
|
1314 |
|
duke@0
|
1315 |
public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
|
duke@0
|
1316 |
BeanContextSupport.this.vetoableChange(pce);
|
duke@0
|
1317 |
}
|
duke@0
|
1318 |
};
|
duke@0
|
1319 |
}
|
duke@0
|
1320 |
|
duke@0
|
1321 |
/**
|
duke@0
|
1322 |
* Gets a copy of the this BeanContext's children.
|
duke@0
|
1323 |
* @return a copy of the current nested children
|
duke@0
|
1324 |
*/
|
duke@0
|
1325 |
protected final Object[] copyChildren() {
|
duke@0
|
1326 |
synchronized(children) { return children.keySet().toArray(); }
|
duke@0
|
1327 |
}
|
duke@0
|
1328 |
|
duke@0
|
1329 |
/**
|
duke@0
|
1330 |
* Tests to see if two class objects,
|
duke@0
|
1331 |
* or their names are equal.
|
duke@0
|
1332 |
* @param first the first object
|
duke@0
|
1333 |
* @param second the second object
|
duke@0
|
1334 |
* @return true if equal, false if not
|
duke@0
|
1335 |
*/
|
duke@0
|
1336 |
protected static final boolean classEquals(Class first, Class second) {
|
duke@0
|
1337 |
return first.equals(second) || first.getName().equals(second.getName());
|
duke@0
|
1338 |
}
|
duke@0
|
1339 |
|
duke@0
|
1340 |
|
duke@0
|
1341 |
/*
|
duke@0
|
1342 |
* fields
|
duke@0
|
1343 |
*/
|
duke@0
|
1344 |
|
duke@0
|
1345 |
|
duke@0
|
1346 |
/**
|
duke@0
|
1347 |
* all accesses to the <code> protected HashMap children </code> field
|
duke@0
|
1348 |
* shall be synchronized on that object.
|
duke@0
|
1349 |
*/
|
duke@0
|
1350 |
protected transient HashMap children;
|
duke@0
|
1351 |
|
duke@0
|
1352 |
private int serializable = 0; // children serializable
|
duke@0
|
1353 |
|
duke@0
|
1354 |
/**
|
duke@0
|
1355 |
* all accesses to the <code> protected ArrayList bcmListeners </code> field
|
duke@0
|
1356 |
* shall be synchronized on that object.
|
duke@0
|
1357 |
*/
|
duke@0
|
1358 |
protected transient ArrayList bcmListeners;
|
duke@0
|
1359 |
|
duke@0
|
1360 |
//
|
duke@0
|
1361 |
|
duke@0
|
1362 |
/**
|
duke@0
|
1363 |
* The current locale of this BeanContext.
|
duke@0
|
1364 |
*/
|
duke@0
|
1365 |
protected Locale locale;
|
duke@0
|
1366 |
|
duke@0
|
1367 |
/**
|
duke@0
|
1368 |
* A <tt>boolean</tt> indicating if this
|
duke@0
|
1369 |
* instance may now render a GUI.
|
duke@0
|
1370 |
*/
|
duke@0
|
1371 |
protected boolean okToUseGui;
|
duke@0
|
1372 |
|
duke@0
|
1373 |
|
duke@0
|
1374 |
/**
|
duke@0
|
1375 |
* A <tt>boolean</tt> indicating whether or not
|
duke@0
|
1376 |
* this object is currently in design time mode.
|
duke@0
|
1377 |
*/
|
duke@0
|
1378 |
protected boolean designTime;
|
duke@0
|
1379 |
|
duke@0
|
1380 |
/*
|
duke@0
|
1381 |
* transient
|
duke@0
|
1382 |
*/
|
duke@0
|
1383 |
|
duke@0
|
1384 |
private transient PropertyChangeListener childPCL;
|
duke@0
|
1385 |
|
duke@0
|
1386 |
private transient VetoableChangeListener childVCL;
|
duke@0
|
1387 |
|
duke@0
|
1388 |
private transient boolean serializing;
|
duke@0
|
1389 |
}
|