Source Code Cross Referenced for ControlBeanContextSupport.java in  » Library » Apache-beehive-1.0.2-src » org » apache » beehive » controls » runtime » webcontext » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Library » Apache beehive 1.0.2 src » org.apache.beehive.controls.runtime.webcontext 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         *
017:         * $Header:$
018:         */
019:
020:        package org.apache.beehive.controls.runtime.webcontext;
021:
022:        import java.beans.Beans;
023:        import java.beans.PropertyChangeEvent;
024:        import java.beans.PropertyChangeListener;
025:        import java.beans.PropertyVetoException;
026:        import java.beans.VetoableChangeListener;
027:        import java.beans.Visibility;
028:        import java.beans.beancontext.BeanContext;
029:        import java.beans.beancontext.BeanContextChild;
030:        import java.beans.beancontext.BeanContextMembershipEvent;
031:        import java.beans.beancontext.BeanContextMembershipListener;
032:        import java.beans.beancontext.BeanContextProxy;
033:        import java.io.IOException;
034:        import java.io.InputStream;
035:        import java.io.ObjectInputStream;
036:        import java.io.ObjectOutputStream;
037:        import java.io.Serializable;
038:        import java.net.URL;
039:        import java.util.ArrayList;
040:        import java.util.Collection;
041:        import java.util.Collections;
042:        import java.util.HashMap;
043:        import java.util.Iterator;
044:        import java.util.List;
045:        import java.util.Map;
046:        import java.util.Set;
047:
048:        /**
049:         * BeanContext implementation for Beehive Controls.
050:         */
051:        public class ControlBeanContextSupport extends
052:                ControlBeanContextChildSupport implements  BeanContext,
053:                Serializable, PropertyChangeListener, VetoableChangeListener {
054:
055:            private static final long serialVersionUID = 1L;
056:
057:            private transient Map<Object, BCChild> _children;
058:            private transient List<BeanContextMembershipListener> _bcMembershipListeners;
059:
060:            // change listeners used for children, in an attempt to prevent
061:            // the unintentional serialization of this bean context by a
062:            // problematic child.
063:            private transient PropertyChangeListener _childPcl;
064:            private transient VetoableChangeListener _childVcl;
065:
066:            private boolean _designTime = false;
067:            private boolean _mayUseGui = false;
068:
069:            /**
070:             * Constructor.
071:             */
072:            public ControlBeanContextSupport() {
073:                super ();
074:                initialize();
075:            }
076:
077:            /**
078:             * Constructor.
079:             *
080:             * @param peer
081:             */
082:            public ControlBeanContextSupport(BeanContext peer) {
083:                super (peer);
084:                initialize();
085:            }
086:
087:            /**
088:             * Instantiate the javaBean named as a
089:             * child of this <code>BeanContext</code>.
090:             * The implementation of the JavaBean is
091:             * derived from the value of the beanName parameter,
092:             * and is defined by the
093:             * <code>java.beans.Beans.instantiate()</code> method.
094:             *
095:             * @param beanName The name of the JavaBean to instantiate
096:             *                 as a child of this <code>BeanContext</code>
097:             * @throws IOException
098:             * @throws ClassNotFoundException if the class identified
099:             *                                by the beanName parameter is not found
100:             */
101:            public Object instantiateChild(String beanName) throws IOException,
102:                    ClassNotFoundException {
103:                BeanContextChild bcc = getPeer();
104:                return Beans.instantiate(bcc.getClass().getClassLoader(),
105:                        beanName, (BeanContext) bcc);
106:            }
107:
108:            /**
109:             * Analagous to <code>java.lang.ClassLoader.getResourceAsStream()</code>,
110:             * this method allows a <code>BeanContext</code> implementation
111:             * to interpose behavior between the child <code>Component</code>
112:             * and underlying <code>ClassLoader</code>.
113:             *
114:             * @param name the resource name
115:             * @param bcc  the specified child
116:             * @return an <code>InputStream</code> for reading the resource,
117:             *         or <code>null</code> if the resource could not
118:             *         be found.
119:             * @throws IllegalArgumentException if the resource is not valid
120:             */
121:            public InputStream getResourceAsStream(String name,
122:                    BeanContextChild bcc) throws IllegalArgumentException {
123:
124:                // bcc must be a child of this context
125:                if (!contains(bcc)) {
126:                    throw new IllegalArgumentException(
127:                            "Child is not a member of this context");
128:                }
129:
130:                ClassLoader cl = bcc.getClass().getClassLoader();
131:                InputStream is;
132:                if (cl != null && (is = cl.getResourceAsStream(name)) != null) {
133:                    return is;
134:                }
135:                return ClassLoader.getSystemResourceAsStream(name);
136:            }
137:
138:            /**
139:             * Analagous to <code>java.lang.ClassLoader.getResource()</code>, this
140:             * method allows a <code>BeanContext</code> implementation to interpose
141:             * behavior between the child <code>Component</code>
142:             * and underlying <code>ClassLoader</code>.
143:             *
144:             * @param name the resource name
145:             * @param bcc  the specified child
146:             * @return a <code>URL</code> for the named
147:             *         resource for the specified child
148:             * @throws IllegalArgumentException if the resource is not valid
149:             */
150:            public URL getResource(String name, BeanContextChild bcc)
151:                    throws IllegalArgumentException {
152:
153:                // bcc must be a child of this context
154:                if (!contains(bcc)) {
155:                    throw new IllegalArgumentException(
156:                            "Child is not a member of this context");
157:                }
158:
159:                ClassLoader cl = bcc.getClass().getClassLoader();
160:                URL url;
161:                if (cl != null && (url = cl.getResource(name)) != null) {
162:                    return url;
163:                }
164:                return ClassLoader.getSystemResource(name);
165:            }
166:
167:            /**
168:             * Adds the specified <code>BeanContextMembershipListener</code>
169:             * to receive <code>BeanContextMembershipEvents</code> from
170:             * this <code>BeanContext</code> whenever it adds
171:             * or removes a child <code>Component</code>(s).
172:             *
173:             * @param bcml the <code>BeanContextMembershipListener</code> to be added
174:             */
175:            public void addBeanContextMembershipListener(
176:                    BeanContextMembershipListener bcml) {
177:                _bcMembershipListeners.add(bcml);
178:            }
179:
180:            /**
181:             * Removes the specified <code>BeanContextMembershipListener</code>
182:             * so that it no longer receives <code>BeanContextMembershipEvent</code>s
183:             * when the child <code>Component</code>(s) are added or removed.
184:             *
185:             * @param bcml the <code>BeanContextMembershipListener</code>
186:             *             to be removed
187:             */
188:            public void removeBeanContextMembershipListener(
189:                    BeanContextMembershipListener bcml) {
190:                _bcMembershipListeners.remove(bcml);
191:            }
192:
193:            /**
194:             * Returns the number of children in this BeanContext.  If this BeanContext
195:             * contains more than <tt>Integer.MAX_VALUE</tt> children, returns
196:             * <tt>Integer.MAX_VALUE</tt>.
197:             *
198:             * @return the number of elements in this collection
199:             */
200:            public int size() {
201:                return _children.size();
202:            }
203:
204:            /**
205:             * Returns <tt>true</tt> if this BeanContext has no children.
206:             */
207:            public boolean isEmpty() {
208:                return _children.isEmpty();
209:            }
210:
211:            /**
212:             * Returns true if this BeanContext contains the specified child.
213:             *
214:             * @param o element whose presence in this BeanContext is to be tested.
215:             * @return true if this BeanContext contains the specified child
216:             * @throws ClassCastException   if the type of the specified element
217:             *                              is incompatible with this collection (optional).
218:             * @throws NullPointerException if the specified element is null and this
219:             *                              collection does not support null elements (optional).
220:             */
221:            public boolean contains(Object o) {
222:                return _children.containsKey(o);
223:            }
224:
225:            /**
226:             * Returns an iterator over the elements in this collection.  The
227:             * iterator's collection is non-modifiable and element does not
228:             * correspond to the order that children are added.
229:             *
230:             * @return an <tt>Iterator</tt> over the children of this BeanContext
231:             */
232:            public Iterator iterator() {
233:                return Collections.unmodifiableSet(_children.keySet())
234:                        .iterator();
235:            }
236:
237:            /**
238:             * Returns an array containing all of the children in this BeanContext.
239:             * <p/>
240:             * The returned array will be "safe" in that no references to it are
241:             * maintained by this collection.  (In other words, this method must
242:             * allocate a new array even if this collection is backed by an array).
243:             * The caller is thus free to modify the returned array.<p>
244:             * <p/>
245:             * This method acts as bridge between array-based and collection-based
246:             * APIs.
247:             *
248:             * @return an array containing all of the elements in this collection
249:             */
250:            public Object[] toArray() {
251:                return _children.keySet().toArray();
252:            }
253:
254:            /**
255:             * Add a child to this BeanContext.  If the child is already a child
256:             * of this bean context this method returns immediately with a return
257:             * value of false.
258:             * <p/>
259:             * If the child implements the BeanContextProxy interface, the child
260:             * AND the BeanContextChild referenced by the proxy are added to this
261:             * BeanContext.
262:             *
263:             * @param o element whose presence in this collection is to be ensured.
264:             * @return <tt>true</tt> if this collection changed as a result of the
265:             *         call
266:             * @throws UnsupportedOperationException <tt>add</tt> is not supported by
267:             *                                       this collection.
268:             * @throws ClassCastException            class of the specified element prevents it
269:             *                                       from being added to this collection.
270:             * @throws NullPointerException          if the specified element is null and this
271:             *                                       collection does not support null elements.
272:             * @throws IllegalArgumentException      some aspect of this element prevents
273:             *                                       it from being added to this collection.
274:             */
275:            public boolean add(Object o) {
276:                return internalAdd(o, true);
277:            }
278:
279:            /**
280:             * Remove the specified child from this BeanContext.  If the child
281:             * to be removed implements the BeanContextProxy interface or is
282:             * referenced from an existing BeanContextProxy child both children
283:             * will be removed.
284:             *
285:             * @param o element to be removed from this collection, if present.
286:             * @return <tt>true</tt> if this collection changed as a result of the
287:             *         call
288:             * @throws ClassCastException            if the type of the specified element
289:             *                                       is incompatible with this collection (optional).
290:             * @throws NullPointerException          if the specified element is null and this
291:             *                                       collection does not support null elements (optional).
292:             * @throws UnsupportedOperationException remove is not supported by this
293:             *                                       collection.
294:             */
295:            public boolean remove(Object o) {
296:                return internalRemove(o, true);
297:            }
298:
299:            /**
300:             * Not supported.
301:             *
302:             * @throws UnsupportedOperationException
303:             */
304:            public boolean addAll(Collection c) {
305:                // NOOP : Not Supported
306:                throw new UnsupportedOperationException();
307:            }
308:
309:            /**
310:             * Not supported.
311:             *
312:             * @throws UnsupportedOperationException
313:             */
314:            public void clear() {
315:                // NOOP: Not supported
316:                throw new UnsupportedOperationException();
317:            }
318:
319:            /**
320:             * Not supported.
321:             *
322:             * @throws UnsupportedOperationException
323:             */
324:            public boolean retainAll(Collection c) {
325:                // NOOP: Not supported
326:                throw new UnsupportedOperationException();
327:            }
328:
329:            /**
330:             * Not supported.
331:             *
332:             * @throws UnsupportedOperationException
333:             */
334:            public boolean removeAll(Collection c) {
335:                throw new UnsupportedOperationException();
336:            }
337:
338:            /**
339:             * Returns <tt>true</tt> if this BeanContext contains all of the children
340:             * in the specified collection.
341:             *
342:             * @param c collection to be checked for containment in this collection.
343:             * @return <tt>true</tt> if this collection contains all of the elements
344:             *         in the specified collection
345:             * @throws ClassCastException   if the types of one or more elements
346:             *                              in the specified collection are incompatible with this
347:             *                              collection (optional).
348:             * @throws NullPointerException if the specified collection contains one
349:             *                              or more null elements and this collection does not support null
350:             *                              elements (optional).
351:             * @throws NullPointerException if the specified collection is
352:             *                              <tt>null</tt>.
353:             * @see #contains(Object)
354:             */
355:            public boolean containsAll(Collection c) {
356:                return _children.keySet().containsAll(c);
357:            }
358:
359:            /**
360:             * Returns an array containing all of the children of this BeanContext;
361:             * the runtime type of the returned array is that of the specified array.
362:             *
363:             * @param a the array into which the elements of this collection are to be
364:             *          stored, if it is big enough; otherwise, a new array of the same
365:             *          runtime type is allocated for this purpose.
366:             * @return an array containing the elements of this collection
367:             * @throws ArrayStoreException  the runtime type of the specified array is
368:             *                              not a supertype of the runtime type of every element in this
369:             *                              collection.
370:             * @throws NullPointerException if the specified array is <tt>null</tt>.
371:             */
372:            public Object[] toArray(Object[] a) {
373:                return _children.keySet().toArray(a);
374:            }
375:
376:            /**
377:             * Sets the "value" of the "designTime" property.
378:             * <p/>
379:             * If the implementing object is an instance of java.beans.beancontext.BeanContext,
380:             * or a subinterface thereof, then that BeanContext should fire a
381:             * PropertyChangeEvent, to its registered BeanContextMembershipListeners, with
382:             * parameters:
383:             * <ul>
384:             * <li><code>propertyName</code> - <code>java.beans.DesignMode.PROPERTYNAME</code>
385:             * <li><code>oldValue</code> - previous value of "designTime"
386:             * <li><code>newValue</code> - current value of "designTime"
387:             * </ul>
388:             * Note it is illegal for a BeanContextChild to invoke this method
389:             * associated with a BeanContext that it is nested within.
390:             *
391:             * @param designTime the current "value" of the "designTime" property
392:             * @see java.beans.beancontext.BeanContext
393:             * @see java.beans.beancontext.BeanContextMembershipListener
394:             * @see java.beans.PropertyChangeEvent
395:             */
396:            public void setDesignTime(boolean designTime) {
397:                if (designTime == _designTime)
398:                    return;
399:                _designTime = designTime;
400:                firePropertyChange("designTime", !_designTime, designTime);
401:            }
402:
403:            /**
404:             * A value of true denotes that JavaBeans should behave in design time
405:             * mode, a value of false denotes runtime behavior.
406:             *
407:             * @return the current "value" of the "designTime" property.
408:             */
409:            public boolean isDesignTime() {
410:                return _designTime;
411:            }
412:
413:            /**
414:             * Determines whether this bean needs a GUI.
415:             *
416:             * @return True if the bean absolutely needs a GUI available in
417:             *         order to get its work done.
418:             */
419:            public boolean needsGui() {
420:                BeanContextChild bcc = getPeer();
421:                if (bcc != this  && bcc instanceof  Visibility) {
422:                    return ((Visibility) bcc).needsGui();
423:                }
424:
425:                // check children
426:                for (Object o : _children.keySet()) {
427:                    if (o instanceof  Visibility) {
428:                        if (((Visibility) o).needsGui()) {
429:                            return true;
430:                        }
431:                    }
432:                }
433:                return false;
434:            }
435:
436:            /**
437:             * This method instructs the bean that it should not use the Gui.
438:             */
439:            public void dontUseGui() {
440:                if (!_mayUseGui)
441:                    return;
442:
443:                _mayUseGui = false;
444:
445:                for (Object o : _children.keySet()) {
446:                    if (o instanceof  Visibility) {
447:                        ((Visibility) o).dontUseGui();
448:                    }
449:                }
450:            }
451:
452:            /**
453:             * This method instructs the bean that it is OK to use the Gui.
454:             */
455:            public void okToUseGui() {
456:                if (_mayUseGui)
457:                    return;
458:
459:                _mayUseGui = true;
460:
461:                for (Object o : _children.keySet()) {
462:                    if (o instanceof  Visibility) {
463:                        ((Visibility) o).okToUseGui();
464:                    }
465:                }
466:            }
467:
468:            /**
469:             * Determines whether this bean is avoiding using a GUI.
470:             *
471:             * @return true if the bean is currently avoiding use of the Gui.
472:             *         e.g. due to a call on dontUseGui().
473:             */
474:            public boolean avoidingGui() {
475:                return !_mayUseGui && needsGui();
476:            }
477:
478:            /**
479:             * This method gets called when a bound property is changed.
480:             *
481:             * @param evt A PropertyChangeEvent object describing the event source
482:             *            and the property that has changed.
483:             */
484:            public void propertyChange(PropertyChangeEvent evt) {
485:                // monitor "beanContext" property
486:                if ("beanContext".equals(evt.getPropertyName())
487:                        && contains(evt.getSource())) {
488:                    BeanContext bc = (BeanContext) getPeer();
489:                    if (bc.equals(evt.getOldValue())
490:                            && !bc.equals(evt.getNewValue())) {
491:                        internalRemove(evt.getSource(), false);
492:                    }
493:                }
494:            }
495:
496:            /**
497:             * This method gets called when a constrained property is changed.
498:             *
499:             * @param evt a <code>PropertyChangeEvent</code> object describing the
500:             *            event source and the property that has changed.
501:             * @throws java.beans.PropertyVetoException
502:             *          if the recipient wishes the property
503:             *          change to be rolled back.
504:             */
505:            public void vetoableChange(PropertyChangeEvent evt)
506:                    throws PropertyVetoException {
507:                // monitor "beanContext" property
508:                if ("beanContext".equals(evt.getPropertyName())
509:                        && contains(evt.getOldValue())) {
510:                    // noop: at this point doesn't veto
511:                }
512:            }
513:
514:            /**
515:             * *************************************************************************************
516:             */
517:
518:            /**
519:             * Init this classes data structures.
520:             */
521:            protected void initialize() {
522:                _bcMembershipListeners = new ArrayList<BeanContextMembershipListener>();
523:                _children = Collections
524:                        .synchronizedMap(new HashMap<Object, BCChild>());
525:
526:                _childPcl = new PropertyChangeListener() {
527:                    public void propertyChange(PropertyChangeEvent pce) {
528:                        ControlBeanContextSupport.this .propertyChange(pce);
529:                    }
530:                };
531:
532:                _childVcl = new VetoableChangeListener() {
533:                    public void vetoableChange(PropertyChangeEvent pce)
534:                            throws PropertyVetoException {
535:                        ControlBeanContextSupport.this .vetoableChange(pce);
536:                    }
537:                };
538:            }
539:
540:            /**
541:             * Fire a BeanContextMembershipEvent.
542:             *
543:             * @param bcme          Event to fire.
544:             * @param childrenAdded True if add event, false if remove event.
545:             */
546:            private void fireMembershipEvent(BeanContextMembershipEvent bcme,
547:                    boolean childrenAdded) {
548:
549:                for (BeanContextMembershipListener bcml : _bcMembershipListeners) {
550:                    if (childrenAdded) {
551:                        bcml.childrenAdded(bcme);
552:                    } else {
553:                        bcml.childrenRemoved(bcme);
554:                    }
555:                }
556:            }
557:
558:            /**
559:             * The internalAdd method is used in two different cases. If an add is done
560:             * through the public add() api, this method is invoked with the publicApi
561:             * parameter set to true.  During deserialization of children this method
562:             * is invoked with publicApi set to false.  During deserialization it is
563:             * not necessary to set Visibility features or re-register as a listener.
564:             *
565:             * @param o
566:             * @param publicApi
567:             * @return true if added.
568:             */
569:            private boolean internalAdd(Object o, boolean publicApi) {
570:
571:                if (contains(o))
572:                    return false;
573:
574:                // todo: for multithreaded usage this block needs to be synchronized
575:                // spec: if the object being added implements BeanContextChild or BeanContextProxy
576:                // need to set the bean context of the object to this bean context.
577:                BeanContextChild bcc = null;
578:                BeanContextProxy bcp = null;
579:
580:                if (o instanceof  BeanContextProxy) {
581:                    if (o instanceof  BeanContext) {
582:                        throw new IllegalArgumentException(
583:                                "May not implement both BeanContextProxy and BeanContext!!");
584:                    }
585:                    bcp = (BeanContextProxy) o;
586:                    bcc = bcp.getBeanContextProxy();
587:                } else if (o instanceof  BeanContextChild) {
588:                    bcc = (BeanContextChild) o;
589:                }
590:
591:                if (bcc != null) {
592:                    try {
593:                        bcc.setBeanContext((BeanContext) getPeer());
594:                    } catch (PropertyVetoException e) {
595:                        throw new IllegalStateException(e);
596:                    }
597:
598:                    bcc.addPropertyChangeListener("beanContext", _childPcl);
599:                    bcc.addVetoableChangeListener("beanContext", _childVcl);
600:                }
601:
602:                if (publicApi) {
603:                    if (o instanceof  Visibility) {
604:                        if (_mayUseGui) {
605:                            ((Visibility) o).okToUseGui();
606:                        } else {
607:                            ((Visibility) o).dontUseGui();
608:                        }
609:                    }
610:                    if (o instanceof  BeanContextMembershipListener) {
611:                        addBeanContextMembershipListener((BeanContextMembershipListener) o);
612:                    }
613:                }
614:
615:                if (bcp == null) {
616:                    _children.put(o, new BCChild(o));
617:                } else {
618:                    _children.put(bcp, new BCChild(bcp, bcc, true));
619:                    _children.put(bcc, new BCChild(bcp, bcc, false));
620:                }
621:
622:                BeanContextMembershipEvent bcme = new BeanContextMembershipEvent(
623:                        (BeanContext) getPeer(), new Object[] { o });
624:                fireMembershipEvent(bcme, true);
625:                //        }
626:                return true;
627:            }
628:
629:            /**
630:             * There are two ways a object can be removed from a BeanContext, by either explicitly invoking the
631:             * remove() api or if the child implements BeanContextChild by calling its setBeanContext() api.
632:             *
633:             * @param o
634:             * @param publicApi
635:             * @return true if successful
636:             */
637:            private boolean internalRemove(Object o, boolean publicApi) {
638:
639:                if (!contains(o))
640:                    return false;
641:
642:                // todo: for multithreaded usage this block needs to be synchronized
643:                BeanContextChild bcc = null;
644:                if (o instanceof  BeanContextProxy) {
645:                    bcc = ((BeanContextProxy) o).getBeanContextProxy();
646:                } else if (o instanceof  BeanContextChild) {
647:                    bcc = (BeanContextChild) o;
648:                }
649:
650:                if (bcc != null) {
651:
652:                    /*
653:                     If remove invoked as a result of the BeanContext receiving an unexpected PropertyChangeEvent
654:                     notification as a result of a 3rd party invoking setBeanContext() then the remove implementation
655:                     shall not invoke setBeanContext(null) on that child as part of the remove() semantics, since
656:                     doing so would overwrite the value previously set by the 3rd party.
657:                     */
658:                    if (publicApi) {
659:
660:                        // remove the property/veto listeners -- we know we want to remove the bean
661:                        // and don't need to be notified if we have initiated the removal
662:                        bcc.removePropertyChangeListener("beanContext",
663:                                _childPcl);
664:                        bcc.removeVetoableChangeListener("beanContext",
665:                                _childVcl);
666:
667:                        try {
668:                            bcc.setBeanContext(null);
669:                        } catch (PropertyVetoException e) {
670:                            // rewire the listeners we removed above then except
671:                            bcc.addPropertyChangeListener("beanContext",
672:                                    _childPcl);
673:                            bcc.addVetoableChangeListener("beanContext",
674:                                    _childVcl);
675:                            throw new IllegalStateException(e);
676:                        }
677:                    }
678:                }
679:
680:                if (o instanceof  BeanContextMembershipListener) {
681:                    removeBeanContextMembershipListener((BeanContextMembershipListener) o);
682:                }
683:
684:                BCChild bc = _children.get(o);
685:                if (bc.isProxy()) {
686:                    _children.remove(bc.getChild());
687:                } else if (bc.hasProxy()) {
688:                    _children.remove(bc.getProxy());
689:                }
690:                _children.remove(o);
691:
692:                BeanContextMembershipEvent bcme = new BeanContextMembershipEvent(
693:                        (BeanContext) getPeer(), new Object[] { o });
694:                fireMembershipEvent(bcme, false);
695:                // end synchronized block
696:                return true;
697:            }
698:
699:            /**
700:             * Serialize all serializable children (unless this BeanContext has a peer).  Any
701:             * children which are not serializable not be present upon deserialization. Also
702:             * serialize any BeanContextMembership listeners which are serializable.
703:             *
704:             * @param out ObjectOutputStream to serialize to.
705:             */
706:            private synchronized void writeObject(ObjectOutputStream out)
707:                    throws IOException {
708:
709:                // todo: for multithreaded usage this block needs to be synchronized
710:                out.defaultWriteObject();
711:
712:                // spec: only write children if not using a peer
713:                if (this .equals(getPeer())) {
714:                    writeChildren(out);
715:                } else {
716:                    out.writeInt(0);
717:                }
718:
719:                // write event handlers
720:                int serializable = 0;
721:                for (BeanContextMembershipListener listener : _bcMembershipListeners) {
722:                    if (listener instanceof  Serializable)
723:                        serializable++;
724:                }
725:
726:                out.writeInt(serializable);
727:                if (serializable > 0) {
728:                    for (BeanContextMembershipListener listener : _bcMembershipListeners) {
729:                        if (listener instanceof  Serializable) {
730:                            out.writeObject(listener);
731:                        }
732:                    }
733:                }
734:                // end synchronized block
735:            }
736:
737:            /**
738:             * Necessary for the case of this bean context having a peer.  The specification
739:             * states that a bean context which has a peer should not serialize its children,
740:             * this hook is necessary to allow the peer to serialize children.
741:             *
742:             * @param oos ObjectOutputStream
743:             * @throws IOException
744:             */
745:            public final void writeChildren(ObjectOutputStream oos)
746:                    throws IOException {
747:                int serializable = 0;
748:                Set<Map.Entry<Object, BCChild>> bcChildren = _children
749:                        .entrySet();
750:                for (Map.Entry<Object, BCChild> entry : bcChildren) {
751:                    if (entry.getValue().isSerializable()) {
752:                        serializable++;
753:                    }
754:                }
755:
756:                oos.writeInt(serializable);
757:                if (serializable > 0) {
758:                    for (Map.Entry<Object, BCChild> bc : bcChildren) {
759:                        if (bc.getValue().isSerializable()) {
760:                            oos.writeObject(bc.getKey());
761:                        }
762:                    }
763:                }
764:            }
765:
766:            /**
767:             * Deserialize this an instance of this class, including any children and
768:             * BeanContextMembershipListeners which were present during serialization and
769:             * were serializable.
770:             *
771:             * @param in ObjectInputStream to deserialize from.
772:             * @throws IOException
773:             * @throws ClassNotFoundException
774:             */
775:            private synchronized void readObject(ObjectInputStream in)
776:                    throws IOException, ClassNotFoundException {
777:                // todo: for multithreaded usage this block needs to be synchronized
778:                in.defaultReadObject();
779:                initialize();
780:
781:                // only deserialize child if not using a peer
782:                if (this .equals(getPeer())) {
783:                    readChildren(in);
784:                }
785:
786:                int listenerCount = in.readInt();
787:                for (int i = 0; i < listenerCount; i++) {
788:                    addBeanContextMembershipListener((BeanContextMembershipListener) in
789:                            .readObject());
790:                }
791:                // end synchronized block
792:            }
793:
794:            /**
795:             * This public api is necessary to allow a bean context with a peer to deserialize its children.
796:             * This api is not part any standard api.
797:             *
798:             * @param in ObjectInputStream
799:             * @throws IOException
800:             * @throws ClassNotFoundException
801:             */
802:            public final void readChildren(ObjectInputStream in)
803:                    throws IOException, ClassNotFoundException {
804:                int childCount = in.readInt();
805:                for (int i = 0; i < childCount; i++) {
806:                    internalAdd(in.readObject(), false);
807:                }
808:            }
809:
810:            /**
811:             * A child of this BeanContext.  This class is used to manage the relationship
812:             * between a BeanContextProxy and its BeanContextChild.  When a BeanContextProxy
813:             * is added or removed from this context the BeanContextChild it references must
814:             * also be added or removed.  This requires that both the BeanContextChild and
815:             * BeanContextProxy are added/removed to the list of children.  This class
816:             * is used to map from the proxy -> child and child -> proxy.
817:             * <p/>
818:             * The _child field is always guarenteed to be non-null, the proxy field may
819:             * be null if this child does not have a proxy.
820:             */
821:            private final static class BCChild {
822:
823:                private Object _child;
824:                private BeanContextProxy _proxy;
825:                private boolean _isProxy;
826:                private boolean _serializable;
827:
828:                /**
829:                 * Construct a new BCChild for a child which is not related to a BeanContextProxy.
830:                 *
831:                 * @param child child to add -- must not be an instance of BeanContextProxy.
832:                 */
833:                protected BCChild(Object child) {
834:                    assert child != null;
835:                    assert !(child instanceof  BeanContextProxy);
836:
837:                    _child = child;
838:                    _proxy = null;
839:                    _isProxy = false;
840:                    _serializable = _child instanceof  Serializable;
841:                }
842:
843:                /**
844:                 * Construct a new BCChild for a proxy -> child relationship.
845:                 *
846:                 * @param proxy   BeanContextProxy
847:                 * @param child   BeanContextChild
848:                 * @param isProxy true if this will be entered into the child map keyed on the proxy.
849:                 */
850:                protected BCChild(BeanContextProxy proxy,
851:                        BeanContextChild child, boolean isProxy) {
852:                    assert child != null;
853:                    assert proxy != null;
854:
855:                    _child = child;
856:                    _proxy = proxy;
857:                    _isProxy = isProxy;
858:                    _serializable = (_isProxy)
859:                            && _child instanceof  Serializable
860:                            && _proxy instanceof  Serializable;
861:                }
862:
863:                /**
864:                 * Get the proxy.
865:                 */
866:                protected BeanContextProxy getProxy() {
867:                    return _proxy;
868:                }
869:
870:                /**
871:                 * Get the child.
872:                 */
873:                protected Object getChild() {
874:                    return _child;
875:                }
876:
877:                /**
878:                 * True if a proxy was set for this child.
879:                 */
880:                protected boolean hasProxy() {
881:                    return _proxy != null;
882:                }
883:
884:                /**
885:                 * True if this child was keyed by its proxy in the child map.
886:                 */
887:                protected boolean isProxy() {
888:                    return _isProxy;
889:                }
890:
891:                /**
892:                 * True if this BCChild is serializable.
893:                 */
894:                protected boolean isSerializable() {
895:                    return _serializable;
896:                }
897:            }
898:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.