Source Code Cross Referenced for ControlBeanContext.java in  » Library » Apache-beehive-1.0.2-src » org » apache » beehive » controls » runtime » bean » 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.bean 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         *
0017:         * $Header:$
0018:         */
0019:        package org.apache.beehive.controls.runtime.bean;
0020:
0021:        import java.beans.PropertyChangeEvent;
0022:        import java.beans.PropertyVetoException;
0023:        import java.beans.PropertyChangeListener;
0024:        import java.beans.VetoableChangeListener;
0025:        import java.beans.beancontext.BeanContext;
0026:        import java.beans.beancontext.BeanContextServiceRevokedEvent;
0027:        import java.beans.beancontext.BeanContextServiceProvider;
0028:        import java.beans.beancontext.BeanContextServices;
0029:        import java.beans.beancontext.BeanContextChild;
0030:        import java.beans.beancontext.BeanContextServiceRevokedListener;
0031:        import java.beans.beancontext.BeanContextServicesListener;
0032:        import java.beans.beancontext.BeanContextMembershipListener;
0033:        import java.beans.beancontext.BeanContextServiceAvailableEvent;
0034:        import java.lang.annotation.Annotation;
0035:        import java.lang.reflect.AnnotatedElement;
0036:        import java.lang.reflect.Field;
0037:        import java.lang.reflect.Method;
0038:        import java.util.Collections;
0039:        import java.util.HashMap;
0040:        import java.util.HashSet;
0041:        import java.util.Iterator;
0042:        import java.util.Map;
0043:        import java.util.Set;
0044:        import java.util.TooManyListenersException;
0045:        import java.util.Vector;
0046:        import java.util.Collection;
0047:        import java.io.IOException;
0048:        import java.io.InputStream;
0049:        import java.io.ObjectOutputStream;
0050:        import java.io.ObjectInputStream;
0051:        import java.net.URL;
0052:
0053:        import org.apache.beehive.controls.api.ControlException;
0054:        import org.apache.beehive.controls.api.context.ControlHandle;
0055:        import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
0056:        import org.apache.beehive.controls.api.properties.BeanPropertyMap;
0057:        import org.apache.beehive.controls.api.properties.PropertyMap;
0058:        import org.apache.beehive.controls.api.properties.PropertySet;
0059:        import org.apache.beehive.controls.api.properties.PropertySetProxy;
0060:
0061:        /**
0062:         * The ControlBeanContext implements the basic BeanContextServices implementation
0063:         * for ControlBeans.
0064:         *
0065:         * It provides several basic functions:
0066:         *  - it defines the generic services that are available for all control containers
0067:         *  - it acts as the base class for other container service implementations
0068:         *  - it acts as the BeanContextServicesRevokedListener when an associated control
0069:         *    bean has lost access to services.
0070:         */
0071:        public class ControlBeanContext implements 
0072:                org.apache.beehive.controls.api.context.ControlBeanContext,
0073:                java.beans.PropertyChangeListener,
0074:                java.beans.VetoableChangeListener, java.io.Serializable {
0075:            /**
0076:             * Creates a new ControlBeanContext instance associated with a specific control bean.  If the
0077:             * <code>ControlBean</code> is null, this ControlBeanContext object represents a top-level Control
0078:             * container.  This constructor uses the default implementation of the
0079:             * {@link java.beans.beancontext.BeanContextServices} interface from the JDK.
0080:             *
0081:             * @param bean The control bean that contains/scopes the ControlBeanContext.  If null, it means the
0082:             *        ControlBeanContext is for a top-level container.
0083:             */
0084:            protected ControlBeanContext(ControlBean bean) {
0085:                this (bean, DEFAULT_BEAN_CONTEXT_SERVICES_FACTORY);
0086:            }
0087:
0088:            /**
0089:             * Creates a new ControlBeanContext instance associated with a specific control bean.  If the
0090:             * <code>ControlBean</code> is null, this ControlBeanContext object represents a top-level Control
0091:             * container.  This constructor uses the <code>beanContextServicesDelegate</code> instance as the
0092:             * implementation of the {@link java.beans.beancontext.BeanContextServices} interface.
0093:             *
0094:             * @param bean The control bean
0095:             * @param beanContextServicesFactory A factory that can be used to create the BeanContextServicesFactory object
0096:             *        that implements support for the {@link BeanContextServices} interface.
0097:             */
0098:            protected ControlBeanContext(ControlBean bean,
0099:                    BeanContextServicesFactory beanContextServicesFactory) {
0100:                super ();
0101:
0102:                _bean = bean;
0103:
0104:                // ensure that there is a valid factory for creating the BCS delegate
0105:                if (beanContextServicesFactory == null)
0106:                    beanContextServicesFactory = DEFAULT_BEAN_CONTEXT_SERVICES_FACTORY;
0107:
0108:                _beanContextServicesDelegate = beanContextServicesFactory
0109:                        .instantiate(this );
0110:                initialize();
0111:            }
0112:
0113:            /**
0114:             * Called by BeanContextSupport superclass during construction and deserialization to
0115:             * initialize subclass transient state
0116:             */
0117:            public void initialize() {
0118:                //
0119:                // Register the ControlBeanContext provider on all new context instances.
0120:                //
0121:                addService(
0122:                        org.apache.beehive.controls.api.context.ControlBeanContext.class,
0123:                        CONTROL_BEAN_CONTEXT_PROVIDER);
0124:            }
0125:
0126:            /**
0127:             * Implements the
0128:             * {@link java.beans.beancontext.BeanContextServiceRevokedListener#serviceRevoked(java.beans.beancontext.BeanContextServiceRevokedEvent)}
0129:             * method.  This is called if the associated {@link ControlBean} has requested a service that is being subsequently
0130:             * revoked.
0131:             */
0132:            public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) {
0133:                //
0134:                // This can happen, if the control is disassociated from a parent context that is
0135:                // providing services.
0136:                //
0137:            }
0138:
0139:            /**
0140:             * Overrides the {@link java.beans.beancontext.BeanContextChild#setBeanContext(java.beans.beancontext.BeanContext)}
0141:             * method.  This hook is used to perform additional processing that needs to occur when the control is associated
0142:             * with a new nesting context.
0143:             */
0144:            public synchronized void setBeanContext(BeanContext beanContext)
0145:                    throws PropertyVetoException {
0146:                ControlBeanContext cbcs = null;
0147:
0148:                if (beanContext != null) {
0149:                    //
0150:                    // ControlBeans can only be nested in context service instances that derive
0151:                    // from ControlBeanContext.
0152:                    //
0153:                    if (!(beanContext instanceof  ControlBeanContext)) {
0154:                        PropertyChangeEvent pce = new PropertyChangeEvent(
0155:                                _bean, "beanContext", getBeanContext(),
0156:                                beanContext);
0157:                        throw new PropertyVetoException(
0158:                                "Context does not support nesting controls: "
0159:                                        + beanContext.getClass(), pce);
0160:                    }
0161:
0162:                    cbcs = (ControlBeanContext) beanContext;
0163:                }
0164:
0165:                _beanContextServicesDelegate.setBeanContext(beanContext);
0166:
0167:                resetControlID();
0168:
0169:                _hasSingleThreadedParent = cbcs != null ? cbcs
0170:                        .isSingleThreadedContainer() : false;
0171:
0172:                //
0173:                // Notify the bean that its context (container) has been set.
0174:                //
0175:                if (_bean != null)
0176:                    _bean.setBeanContext(beanContext);
0177:            }
0178:
0179:            /**
0180:             * The NameGenerator class is a simple helper class that creates new unique names based
0181:             * upon a base prefix and an incrementing counter
0182:             */
0183:            private static class NameGenerator implements  java.io.Serializable {
0184:                NameGenerator(String namePrefix) {
0185:                    _namePrefix = namePrefix;
0186:                }
0187:
0188:                /**
0189:                 * Get the next unique name
0190:                 */
0191:                public synchronized String next() {
0192:                    return _namePrefix + _nextIndex++;
0193:                }
0194:
0195:                int _nextIndex = 0;
0196:                String _namePrefix;
0197:            }
0198:
0199:            /**
0200:             * Returns a new NameGenerator instance based upon a particular naming
0201:             * prefix.
0202:             */
0203:            private NameGenerator getNameGenerator(String namePrefix) {
0204:                synchronized (this ) {
0205:                    if (_nameGenerators == null)
0206:                        _nameGenerators = new HashMap<String, NameGenerator>();
0207:
0208:                    NameGenerator nameGenerator = _nameGenerators
0209:                            .get(namePrefix);
0210:                    if (nameGenerator == null) {
0211:                        nameGenerator = new NameGenerator(namePrefix);
0212:                        _nameGenerators.put(namePrefix, nameGenerator);
0213:                    }
0214:                    return nameGenerator;
0215:                }
0216:            }
0217:
0218:            /**
0219:             * Generates a new unique control ID for an instance of the target class
0220:             */
0221:            public String generateUniqueID(Class clazz) {
0222:                String namePrefix = clazz.getName();
0223:                int dotIndex = namePrefix.lastIndexOf('.');
0224:                if (dotIndex > 0)
0225:                    namePrefix = namePrefix.substring(dotIndex + 1);
0226:                NameGenerator nameGenerator = getNameGenerator(namePrefix);
0227:                return nameGenerator.next();
0228:            }
0229:
0230:            /**
0231:             * Overrides the BeanContextSupport.add() method to perform additional validation
0232:             * that is unique for ControlBeans containers.
0233:             */
0234:            public boolean add(Object targetChild) {
0235:                //
0236:                // The context can contain ControlBeans and other types of objects, such as a control
0237:                // factory.
0238:                //
0239:                String beanID = null;
0240:                if (targetChild instanceof  ControlBean) {
0241:                    ControlBean bean = (ControlBean) targetChild;
0242:                    beanID = bean.getLocalID();
0243:
0244:                    //
0245:                    // The bean is anonymous, so we must generate a new unique name within this context.
0246:                    //
0247:                    if (beanID == null) {
0248:                        beanID = generateUniqueID(bean.getClass());
0249:                        bean.setLocalID(beanID);
0250:                    }
0251:
0252:                    ControlBean existingBean = (ControlBean) _childMap
0253:                            .get(beanID);
0254:                    if (existingBean != null && existingBean != targetChild) {
0255:                        throw new IllegalArgumentException(
0256:                                "Attempting to add control with duplicate ID: "
0257:                                        + beanID);
0258:                    }
0259:                }
0260:
0261:                boolean added = _beanContextServicesDelegate.add(targetChild);
0262:                if (added && beanID != null)
0263:                    _childMap.put(beanID, targetChild);
0264:
0265:                return added;
0266:            }
0267:
0268:            /**
0269:             * Overrides the BeanContextSupport.remove() method to perform additional post-processing
0270:             * on child removal.
0271:             */
0272:            public boolean remove(Object targetChild) {
0273:                assert targetChild instanceof  ControlBean; // should be guaranteed above
0274:                boolean removed = _beanContextServicesDelegate
0275:                        .remove(targetChild);
0276:
0277:                if (removed) {
0278:                    //
0279:                    // Remove from the locally maintained child map
0280:                    //
0281:                    String localID = ((ControlBean) targetChild).getLocalID();
0282:                    Object removedChild = _childMap.remove(localID);
0283:                    assert removedChild == targetChild; // just being safe
0284:                }
0285:                return removed;
0286:            }
0287:
0288:            /**
0289:             * Returns a ControlBean instance nested the current BeanContext.
0290:             * @param id the identifier for the target control, relative to the current
0291:             *           context.
0292:             */
0293:            public ControlBean getBean(String id) {
0294:                // If no control id separator found, the bean is a direct child of this context
0295:                int delim = id
0296:                        .indexOf(org.apache.beehive.controls.api.bean.ControlBean.IDSeparator);
0297:                if (delim < 0) // child is a direct descendent
0298:                    return (ControlBean) _childMap.get(id);
0299:
0300:                // Find the child referenced by the first element in the path
0301:                ControlBean bean = (ControlBean) _childMap.get(id.substring(0,
0302:                        delim));
0303:                if (bean == null)
0304:                    return bean;
0305:
0306:                // Get the BeanContext associated with the found child, and then ask it
0307:                // to resolve the rest of the path
0308:                return bean.getBeanContextProxy().getBean(
0309:                        id.substring(delim + 1));
0310:            }
0311:
0312:            /**
0313:             * Returns the ControlBean associated directly with the ControlBeanContext.  If the
0314:             * context represents a top-level container, will return null.
0315:             */
0316:            public ControlBean getControlBean() {
0317:                return _bean;
0318:            }
0319:
0320:            public synchronized boolean hasSingleThreadedParent() {
0321:                return _hasSingleThreadedParent;
0322:            }
0323:
0324:            /**
0325:             *  Returns true if this container associated with this context service enforces
0326:             *  single-threaded invocation, false otherwise.
0327:             *
0328:             *  This MUST be overridden by container-specific subclasses in order to change
0329:             * the default behavior.  If a single-threaded container intends to guarantee
0330:             *  single-threaded behavior (such as the EJB container), this should return true.
0331:             */
0332:            public synchronized boolean isSingleThreadedContainer() {
0333:                return (hasSingleThreadedParent() || (_bean != null && _bean
0334:                        .hasSingleThreadedImpl()));
0335:            }
0336:
0337:            /**
0338:             * The initializeControl method is invoked when the implementation instance associated
0339:             * with the context has been instantiated and initialized.
0340:             */
0341:            public void initializeControl() {
0342:                //
0343:                // Deliver the onCreate event to any register lifecycle listeners
0344:                //
0345:                if (_lifeCycleListeners != null) {
0346:                    for (LifeCycle lifeCycleListener : _lifeCycleListeners) {
0347:                        lifeCycleListener.onCreate();
0348:                    }
0349:                }
0350:            }
0351:
0352:            /**
0353:             * Returns the PropertyMap containing default properties for an AnnotatedElement
0354:             * in the current context.  The initialization of PropertyMap binding is always
0355:             * done by delegating to a {@link ControlContainerContext}, enabling containers to implement
0356:             * property binding mechanisms (such as external config) that may override the values
0357:             * contained within the element annotations.
0358:             */
0359:            public PropertyMap getAnnotationMap(AnnotatedElement annotElem) {
0360:                ControlBeanContext beanContext = this ;
0361:                while (beanContext != null) {
0362:                    // REVIEW: should ControlContainerContext-derived classes override getBeanAnnotationMap?  Not sure
0363:                    // that name makes sense, and perhaps it shouldn't take a ControlBean.
0364:                    if (beanContext instanceof  ControlContainerContext)
0365:                        return beanContext.getBeanAnnotationMap(_bean,
0366:                                annotElem);
0367:                    beanContext = (ControlBeanContext) beanContext
0368:                            .getBeanContext();
0369:                }
0370:
0371:                // No ControlContainerContext was found, so just use the default implementation
0372:                return getBeanAnnotationMap(_bean, annotElem);
0373:            }
0374:
0375:            /**
0376:             * The default implementation of getBeanAnnotationMap.  This returns a map based purely
0377:             * upon annotation reflection
0378:             */
0379:            protected PropertyMap getBeanAnnotationMap(ControlBean bean,
0380:                    AnnotatedElement annotElem) {
0381:                PropertyMap map = new AnnotatedElementMap(annotElem);
0382:
0383:                // REVIEW: is this the right place to handle the general control client case?
0384:                if (bean != null)
0385:                    setDelegateMap(map, bean, annotElem);
0386:
0387:                return map;
0388:            }
0389:
0390:            static protected void setDelegateMap(PropertyMap map,
0391:                    ControlBean bean, AnnotatedElement annotElem) {
0392:                //
0393:                // If building an annotation map for a method or field, we want to delegate back
0394:                // to the base control type.
0395:                //
0396:                Class annotClass = null;
0397:                if (annotElem instanceof  Field) {
0398:                    annotClass = ((Field) annotElem).getType();
0399:                } else if (annotElem instanceof  Method) {
0400:                    annotClass = bean.getControlInterface();
0401:                }
0402:
0403:                if (annotClass != null) {
0404:                    PropertyMap delegateMap = bean.getAnnotationMap(annotClass);
0405:                    map.setDelegateMap(delegateMap);
0406:                }
0407:            }
0408:
0409:            //
0410:            // ControlBeanContext.getControlInterface
0411:            //
0412:            public Class getControlInterface() {
0413:                return _bean.getControlInterface();
0414:            }
0415:
0416:            //
0417:            // ControlBeanContext.getControlPropertySet
0418:            //
0419:            public <T extends Annotation> T getControlPropertySet(
0420:                    Class<T> propertySet) {
0421:                PropertyMap map = _bean.getPropertyMap();
0422:
0423:                //
0424:                // Optional properties are not exposed to clients using traditional JavaBean
0425:                // setters/getters (because there is way to represent an 'unset' value); for
0426:                // these properties, the impl can tell if the PropertySet is unset because
0427:                // this method will return null.
0428:                //
0429:                if (!map.containsPropertySet(propertySet)) {
0430:                    PropertySet psAnnot = propertySet
0431:                            .getAnnotation(PropertySet.class);
0432:                    if (psAnnot.optional())
0433:                        return null;
0434:                }
0435:
0436:                //
0437:                // Construct a new PropertySet proxy instance that derives its values from
0438:                // the bean property map.
0439:                //
0440:                return PropertySetProxy.getProxy(propertySet, map);
0441:            }
0442:
0443:            //
0444:            // ControlBeanContext.getMethodPropertySet
0445:            //
0446:            public <T extends Annotation> T getMethodPropertySet(Method m,
0447:                    Class<T> propertySet) {
0448:                PropertyMap map = _bean.getAnnotationMap(m);
0449:
0450:                //
0451:                // Optional properties are not exposed to clients using traditional JavaBean
0452:                // setters/getters (because there is way to represent an 'unset' value); for
0453:                // these properties, the impl can tell if the PropertySet is unset because
0454:                // this method will return null.
0455:                //
0456:                if (!map.containsPropertySet(propertySet)) {
0457:                    PropertySet psAnnot = propertySet
0458:                            .getAnnotation(PropertySet.class);
0459:                    if (psAnnot.optional())
0460:                        return null;
0461:                }
0462:
0463:                //
0464:                // Construct a new PropertySet proxy instance that derives its values from
0465:                // the method property map.
0466:                //
0467:                return PropertySetProxy.getProxy(propertySet, _bean
0468:                        .getAnnotationMap(m));
0469:            }
0470:
0471:            //
0472:            // ControlBeanContext.getParameterPropertySet
0473:            //
0474:            public <T extends Annotation> T getParameterPropertySet(Method m,
0475:                    int i, Class<T> propertySet)
0476:                    throws IllegalArgumentException, IndexOutOfBoundsException {
0477:                if (i >= m.getParameterTypes().length)
0478:                    throw new IndexOutOfBoundsException(
0479:                            "Invalid parameter index for method:" + m);
0480:
0481:                // todo: Currently, there is no external override mechanism for method parameters
0482:                Annotation[] paramAnnots = m.getParameterAnnotations()[i];
0483:                for (Annotation paramAnnot : paramAnnots)
0484:                    if (propertySet.isAssignableFrom(paramAnnot.getClass()))
0485:                        return (T) paramAnnot;
0486:
0487:                return null;
0488:            }
0489:
0490:            //
0491:            // ControlBeanContext.getParameterNames
0492:            //
0493:            public String[] getParameterNames(Method m)
0494:                    throws IllegalArgumentException {
0495:                return _bean.getParameterNames(m);
0496:            }
0497:
0498:            //
0499:            // ControlBeanContext.getNamedParameterValue
0500:            //
0501:            public Object getParameterValue(Method m, String parameterName,
0502:                    Object[] parameters) throws IllegalArgumentException {
0503:                String[] names = getParameterNames(m);
0504:
0505:                // Validate the input parameter array
0506:                if (parameters.length != names.length)
0507:                    throw new IllegalArgumentException("Expected "
0508:                            + names.length + " parameters," + "Found "
0509:                            + parameters.length);
0510:
0511:                // Finding the index of the matching parameter name
0512:                int i = 0;
0513:                while (i < names.length) {
0514:                    if (names[i].equals(parameterName))
0515:                        break;
0516:                    i++;
0517:                }
0518:                if (i == names.length)
0519:                    throw new IllegalArgumentException(
0520:                            "No method parameter with name: " + parameterName);
0521:
0522:                // Return the parameter value at the matched index
0523:                return parameters[i];
0524:            }
0525:
0526:            //
0527:            // ControlBeanContext.getPropertyMap
0528:            //
0529:            public PropertyMap getControlPropertyMap() {
0530:                //
0531:                // Return a wrapped copy of the original bean property map, so any edits
0532:                // don't impact the bean properties.
0533:                //
0534:                return new BeanPropertyMap(_bean.getPropertyMap());
0535:            }
0536:
0537:            //
0538:            // ControlBeanContext.getService
0539:            //
0540:            public <T> T getService(Class<T> serviceClass, Object selector) {
0541:                //
0542:                // If the requested service is a ControlBeanContext instance, the current instance
0543:                // can be returned.
0544:                //
0545:                if (serviceClass
0546:                        .equals(org.apache.beehive.controls.api.context.ControlBeanContext.class))
0547:                    return (T) this ;
0548:
0549:                //
0550:                // The parent BeanContext is responsible for providing requested services.  If
0551:                // no parent context is available or it is does not manage services, then no service.
0552:                //
0553:                BeanContext bc = getBeanContext();
0554:                if (bc == null || !(bc instanceof  BeanContextServices))
0555:                    return null;
0556:
0557:                //
0558:                // Call getService on the parent context, using this bean as the requestor and the
0559:                // this context as the child context and ServicesRevoked event listener parameters.
0560:                //
0561:                try {
0562:                    return (T) ((BeanContextServices) bc).getService(this ,
0563:                            _bean, serviceClass, selector, this );
0564:                } catch (TooManyListenersException tmle) {
0565:                    // This would be highly unusual... it implies that the registration for service
0566:                    // revocation notifications failed for some reason.
0567:                    throw new ControlException(
0568:                            "Unable to register for service events", tmle);
0569:                }
0570:            }
0571:
0572:            //
0573:            // ControlBeanContext.getControlHandle
0574:            //
0575:            public ControlHandle getControlHandle() {
0576:                //
0577:                // Find the associated ControlContainerContext, which provides a container-specific
0578:                // implementation of ControlHandle
0579:                //
0580:                ControlBeanContext beanContext = this ;
0581:                while (beanContext != null
0582:                        && !(beanContext instanceof  ControlContainerContext))
0583:                    beanContext = (ControlBeanContext) beanContext
0584:                            .getBeanContext();
0585:
0586:                if (beanContext == null)
0587:                    return null;
0588:
0589:                //
0590:                // Ask the container for a ControlHandle instance referencing the target bean
0591:                //
0592:                return ((ControlContainerContext) beanContext)
0593:                        .getControlHandle(_bean);
0594:            }
0595:
0596:            //
0597:            // ControlBeanContext.getClassLoader
0598:            //
0599:            public java.lang.ClassLoader getClassLoader() {
0600:                return getControlInterface().getClassLoader();
0601:            }
0602:
0603:            //
0604:            // ControlBeanContext.addLifeCycleListener
0605:            //
0606:            synchronized public void addLifeCycleListener(LifeCycle listener) {
0607:                if (_lifeCycleListeners == null) {
0608:                    _lifeCycleListeners = new Vector<LifeCycle>();
0609:
0610:                    //
0611:                    // Since bound/constrained property changes are exposed as lifecycle events, we
0612:                    // need to register ourselves as a listener for these events the first time a
0613:                    // lifecycle listener is added.
0614:                    //
0615:                    _bean.getPropertyChangeSupport().addPropertyChangeListener(
0616:                            this );
0617:                    _bean.getVetoableChangeSupport().addVetoableChangeListener(
0618:                            this );
0619:                }
0620:                _lifeCycleListeners.addElement(listener);
0621:            }
0622:
0623:            //
0624:            // ControlBeanContext.removeLifeCycleListener
0625:            //
0626:            synchronized public void removeLifeCycleListener(LifeCycle listener) {
0627:                if (_lifeCycleListeners != null)
0628:                    _lifeCycleListeners.removeElement(listener);
0629:            }
0630:
0631:            //
0632:            // PropertyChangeListener.propertyChange
0633:            //
0634:            public void propertyChange(PropertyChangeEvent pce) {
0635:                if (_lifeCycleListeners != null) {
0636:                    for (LifeCycle lifeCycleListener : _lifeCycleListeners) {
0637:                        lifeCycleListener.onPropertyChange(pce);
0638:                    }
0639:                }
0640:            }
0641:
0642:            //
0643:            // VetoableChangeListener.vetoableChange
0644:            //
0645:            public void vetoableChange(PropertyChangeEvent pce)
0646:                    throws PropertyVetoException {
0647:                if (_lifeCycleListeners != null) {
0648:                    for (LifeCycle lifeCycleListener : _lifeCycleListeners) {
0649:                        lifeCycleListener.onVetoableChange(pce);
0650:                    }
0651:                }
0652:            }
0653:
0654:            /* package */String getControlID() {
0655:                if (_controlID != null || _bean == null)
0656:                    return _controlID;
0657:
0658:                // Initially set to the local beans relative ID
0659:                String id = _bean.getLocalID();
0660:
0661:                // If there is a parent context, prepend its ID and the ID separator
0662:                BeanContext bc = getBeanContext();
0663:                if (bc != null && bc instanceof  ControlBeanContext) {
0664:                    String parentID = ((ControlBeanContext) bc).getControlID();
0665:                    if (parentID != null) {
0666:                        id = parentID
0667:                                + org.apache.beehive.controls.api.bean.ControlBean.IDSeparator
0668:                                + id;
0669:                    }
0670:                }
0671:
0672:                // Cache the computed value
0673:                _controlID = id;
0674:
0675:                return id;
0676:            }
0677:
0678:            /**
0679:             * Resets the composite control ID for this context and all children beneath it.  This
0680:             * can be used to invalidate cached values when necessary (for example, when a context
0681:             * is reparented).
0682:             */
0683:            private void resetControlID() {
0684:                _controlID = null;
0685:                for (Object child : this ) {
0686:                    if (child instanceof  ControlBeanContext)
0687:                        ((ControlBeanContext) child).resetControlID();
0688:                }
0689:            }
0690:
0691:            //
0692:            // BeanContextServices.getCurrentServiceClasses
0693:            // Override the default implementation of getCurrentServiceClasses inherited from
0694:            // java.beans.beancontext.BeanContextServicesSuppport.  The reason for this is a bug/
0695:            // flaw in its underlying implementation.  It does not include any services exposed
0696:            // by any nesting contexts.  This is contradictory to the implementation of hasService()
0697:            // and getService() which do delegate up to a parent context to find services if not
0698:            // available on the local context.  This means hasService() could return 'true' for a
0699:            // service that isn't returned by getCurrentServiceClasses(), which seems like a bug.
0700:            //
0701:            synchronized public Iterator getCurrentServiceClasses() {
0702:                Set classSet = new HashSet();
0703:                BeanContextServices bcs = _beanContextServicesDelegate;
0704:
0705:                while (bcs != null) {
0706:                    Iterator iter = bcs.getCurrentServiceClasses();
0707:                    while (iter.hasNext())
0708:                        classSet.add(iter.next());
0709:
0710:                    // Go up to the parent, if it is a service provider as well
0711:                    BeanContext bc = getBeanContext();
0712:                    if (bc instanceof  BeanContextServices && bcs != bc)
0713:                        bcs = (BeanContextServices) bc;
0714:                    else
0715:                        bcs = null;
0716:                }
0717:                return classSet.iterator();
0718:            }
0719:
0720:            //
0721:            // BeanContextServices.getCurrentServiceSelectors
0722:            // Override getCurrentServiceSelectors for the same reason as above
0723:            //
0724:            public Iterator getCurrentServiceSelectors(Class serviceClass) {
0725:                if (hasService(serviceClass))
0726:                    return _beanContextServicesDelegate
0727:                            .getCurrentServiceSelectors(serviceClass);
0728:
0729:                BeanContext bc = getBeanContext();
0730:                if (bc instanceof  BeanContextServices)
0731:                    return ((BeanContextServices) bc)
0732:                            .getCurrentServiceSelectors(serviceClass);
0733:
0734:                return null;
0735:            }
0736:
0737:            private synchronized void writeObject(ObjectOutputStream oos)
0738:                    throws IOException {
0739:                oos.defaultWriteObject();
0740:                if (_beanContextServicesDelegate instanceof  java.beans.beancontext.BeanContextSupport) {
0741:                    ((java.beans.beancontext.BeanContextSupport) _beanContextServicesDelegate)
0742:                            .writeChildren(oos);
0743:                } else if (_beanContextServicesDelegate instanceof  org.apache.beehive.controls.runtime.webcontext.ControlBeanContextSupport) {
0744:                    ((org.apache.beehive.controls.runtime.webcontext.ControlBeanContextSupport) _beanContextServicesDelegate)
0745:                            .writeChildren(oos);
0746:                } else
0747:                    assert false;
0748:            }
0749:
0750:            private synchronized void readObject(ObjectInputStream ois)
0751:                    throws IOException, ClassNotFoundException {
0752:                ois.defaultReadObject();
0753:
0754:                if (_beanContextServicesDelegate instanceof  java.beans.beancontext.BeanContextSupport) {
0755:                    ((java.beans.beancontext.BeanContextSupport) _beanContextServicesDelegate)
0756:                            .readChildren(ois);
0757:                } else if (_beanContextServicesDelegate instanceof  org.apache.beehive.controls.runtime.webcontext.ControlBeanContextSupport) {
0758:                    ((org.apache.beehive.controls.runtime.webcontext.ControlBeanContextSupport) _beanContextServicesDelegate)
0759:                            .readChildren(ois);
0760:                } else
0761:                    assert false;
0762:
0763:                // Re-initialize a deserialized control hierarchy.
0764:                initialize();
0765:            }
0766:
0767:            protected BeanContextServicesFactory getBeanContextServicesFactory() {
0768:                return DEFAULT_BEAN_CONTEXT_SERVICES_FACTORY;
0769:            }
0770:
0771:            public boolean equals(Object o) {
0772:                /* todo: make sure this logic is right / sufficient */
0773:                if (this  == o)
0774:                    return true;
0775:
0776:                if (!(o instanceof  org.apache.beehive.controls.api.context.ControlBeanContext))
0777:                    return false;
0778:
0779:                return o instanceof  ControlBeanContext
0780:                        && _beanContextServicesDelegate
0781:                                .equals(((ControlBeanContext) o)._beanContextServicesDelegate);
0782:            }
0783:
0784:            public int hashCode() {
0785:                /* todo: make sure this logic is right / sufficient */
0786:                int result;
0787:                result = (_bean != null ? _bean.hashCode() : 0);
0788:                result = 31
0789:                        * result
0790:                        + (_beanContextServicesDelegate != null ? _beanContextServicesDelegate
0791:                                .hashCode()
0792:                                : 0);
0793:                return result;
0794:            }
0795:
0796:            /* --------------------------------------------------------------------------
0797:
0798:               Implementation of java.beans.beancontext.BeanContextServices
0799:
0800:               -------------------------------------------------------------------------- */
0801:            public boolean addService(Class serviceClass,
0802:                    BeanContextServiceProvider serviceProvider) {
0803:                return _beanContextServicesDelegate.addService(serviceClass,
0804:                        serviceProvider);
0805:            }
0806:
0807:            public void revokeService(Class serviceClass,
0808:                    BeanContextServiceProvider serviceProvider,
0809:                    boolean revokeCurrentServicesNow) {
0810:                _beanContextServicesDelegate.revokeService(serviceClass,
0811:                        serviceProvider, revokeCurrentServicesNow);
0812:            }
0813:
0814:            public boolean hasService(Class serviceClass) {
0815:                return _beanContextServicesDelegate.hasService(serviceClass);
0816:            }
0817:
0818:            public Object getService(BeanContextChild child, Object requestor,
0819:                    Class serviceClass, Object serviceSelector,
0820:                    BeanContextServiceRevokedListener bcsrl)
0821:                    throws TooManyListenersException {
0822:                return _beanContextServicesDelegate.getService(child,
0823:                        requestor, serviceClass, serviceSelector, bcsrl);
0824:            }
0825:
0826:            public void releaseService(BeanContextChild child,
0827:                    Object requestor, Object service) {
0828:                _beanContextServicesDelegate.releaseService(child, requestor,
0829:                        service);
0830:            }
0831:
0832:            public void addBeanContextServicesListener(
0833:                    BeanContextServicesListener bcsl) {
0834:                _beanContextServicesDelegate
0835:                        .addBeanContextServicesListener(bcsl);
0836:            }
0837:
0838:            public void removeBeanContextServicesListener(
0839:                    BeanContextServicesListener bcsl) {
0840:                _beanContextServicesDelegate
0841:                        .removeBeanContextServicesListener(bcsl);
0842:            }
0843:
0844:            public Object instantiateChild(String beanName) throws IOException,
0845:                    ClassNotFoundException {
0846:                return _beanContextServicesDelegate.instantiateChild(beanName);
0847:            }
0848:
0849:            public InputStream getResourceAsStream(String name,
0850:                    BeanContextChild bcc) throws IllegalArgumentException {
0851:                return _beanContextServicesDelegate.getResourceAsStream(name,
0852:                        bcc);
0853:            }
0854:
0855:            public URL getResource(String name, BeanContextChild bcc)
0856:                    throws IllegalArgumentException {
0857:                return _beanContextServicesDelegate.getResource(name, bcc);
0858:            }
0859:
0860:            public void addBeanContextMembershipListener(
0861:                    BeanContextMembershipListener bcml) {
0862:                _beanContextServicesDelegate
0863:                        .addBeanContextMembershipListener(bcml);
0864:            }
0865:
0866:            public void removeBeanContextMembershipListener(
0867:                    BeanContextMembershipListener bcml) {
0868:                _beanContextServicesDelegate
0869:                        .removeBeanContextMembershipListener(bcml);
0870:            }
0871:
0872:            public BeanContext getBeanContext() {
0873:                return _beanContextServicesDelegate.getBeanContext();
0874:            }
0875:
0876:            public void addPropertyChangeListener(String name,
0877:                    PropertyChangeListener pcl) {
0878:                _beanContextServicesDelegate.addPropertyChangeListener(name,
0879:                        pcl);
0880:            }
0881:
0882:            public void removePropertyChangeListener(String name,
0883:                    PropertyChangeListener pcl) {
0884:                _beanContextServicesDelegate.removePropertyChangeListener(name,
0885:                        pcl);
0886:            }
0887:
0888:            public void addVetoableChangeListener(String name,
0889:                    VetoableChangeListener vcl) {
0890:                _beanContextServicesDelegate.addVetoableChangeListener(name,
0891:                        vcl);
0892:            }
0893:
0894:            public void removeVetoableChangeListener(String name,
0895:                    VetoableChangeListener vcl) {
0896:                _beanContextServicesDelegate.removeVetoableChangeListener(name,
0897:                        vcl);
0898:            }
0899:
0900:            public int size() {
0901:                return _beanContextServicesDelegate.size();
0902:            }
0903:
0904:            public boolean isEmpty() {
0905:                return _beanContextServicesDelegate.isEmpty();
0906:            }
0907:
0908:            public boolean contains(Object o) {
0909:                return _beanContextServicesDelegate.contains(o);
0910:            }
0911:
0912:            public Iterator iterator() {
0913:                return _beanContextServicesDelegate.iterator();
0914:            }
0915:
0916:            public Object[] toArray() {
0917:                return _beanContextServicesDelegate.toArray();
0918:            }
0919:
0920:            public Object[] toArray(Object[] a) {
0921:                return _beanContextServicesDelegate.toArray(a);
0922:            }
0923:
0924:            public boolean containsAll(Collection c) {
0925:                return _beanContextServicesDelegate.containsAll(c);
0926:            }
0927:
0928:            public boolean addAll(Collection c) {
0929:                return _beanContextServicesDelegate.addAll(c);
0930:            }
0931:
0932:            public boolean removeAll(Collection c) {
0933:                return _beanContextServicesDelegate.removeAll(c);
0934:            }
0935:
0936:            public boolean retainAll(Collection c) {
0937:                return _beanContextServicesDelegate.retainAll(c);
0938:            }
0939:
0940:            public void clear() {
0941:                _beanContextServicesDelegate.clear();
0942:            }
0943:
0944:            public void setDesignTime(boolean designTime) {
0945:                _beanContextServicesDelegate.setDesignTime(designTime);
0946:            }
0947:
0948:            public boolean isDesignTime() {
0949:                return _beanContextServicesDelegate.isDesignTime();
0950:            }
0951:
0952:            public boolean needsGui() {
0953:                return _beanContextServicesDelegate.needsGui();
0954:            }
0955:
0956:            public void dontUseGui() {
0957:                _beanContextServicesDelegate.dontUseGui();
0958:            }
0959:
0960:            public void okToUseGui() {
0961:                _beanContextServicesDelegate.okToUseGui();
0962:            }
0963:
0964:            public boolean avoidingGui() {
0965:                return _beanContextServicesDelegate.avoidingGui();
0966:            }
0967:
0968:            public void serviceAvailable(BeanContextServiceAvailableEvent bcsae) {
0969:                _beanContextServicesDelegate.serviceAvailable(bcsae);
0970:            }
0971:
0972:            /* --------------------------------------------------------------------------
0973:
0974:               Static / deprecated methods.
0975:
0976:               -------------------------------------------------------------------------- */
0977:
0978:            /**
0979:             * Applies externally defined (via INTERCEPTOR_CONFIG_FILE) ordering priority for
0980:             * controls interceptor services.
0981:             *
0982:             * @param interceptors
0983:             * @return String[]
0984:             * @deprecated Use {@link InterceptorUtils#prioritizeInterceptors(String[])} instead.  This method will
0985:             *             be removed in the next point release.
0986:             */
0987:            public static String[] prioritizeInterceptors(String[] interceptors) {
0988:                return InterceptorUtils.prioritizeInterceptors(interceptors);
0989:            }
0990:
0991:            /**
0992:             * Returns the default binding based entirely upon annotations or naming conventions.
0993:             * @param controlIntf the control interface class
0994:             * @return the class name of the default control implementation binding
0995:             * @deprecated Use {@link ControlUtils#getDefaultControlBinding(Class)} insated.  This method will be
0996:             *             removed in the next point release.
0997:             */
0998:            public static String getDefaultControlBinding(Class controlIntf) {
0999:                return ControlUtils.getDefaultControlBinding(controlIntf);
1000:            }
1001:
1002:            /**
1003:             * Implements the default control implementation binding algorithm ( <InterfaceName> + "Impl" ).  See
1004:             * documentation for the org.apache.beehive.controls.api.bean.ControlInterface annotation.
1005:             *
1006:             * @param implBinding the value of the defaultBinding attribute returned from a ControlInterface annotation
1007:             * @param controlClass the actual name of the interface decorated by the ControlInterface annotation
1008:             * @return the resolved defaultBinding value
1009:             * @deprecated Use {@link ControlUtils#resolveDefaultBinding(String, String)} insated.  This method
1010:             *             will be removed in the next point release.
1011:             */
1012:            public static String resolveDefaultBinding(String implBinding,
1013:                    String controlClass) {
1014:                return ControlUtils.resolveDefaultBinding(implBinding,
1015:                        controlClass);
1016:            }
1017:
1018:            /**
1019:             * The ControlBeanContextProvider inner class acts as a single BeanContext service
1020:             * provider for the ControlBeanContext service class.  The implementation is simple,
1021:             * because the runtime ControlBeanContext implementation class directly implements
1022:             * this interface.
1023:             */
1024:            private static class ControlBeanContextProvider implements 
1025:                    BeanContextServiceProvider {
1026:                //
1027:                // BeanContextServiceProvider.getService()
1028:                //
1029:                public Object getService(BeanContextServices bcs,
1030:                        Object requestor, Class serviceClass,
1031:                        Object serviceSelector) {
1032:                    //
1033:                    // Contextual services for a ControlBean is provided by the peer context
1034:                    // instance.
1035:                    //
1036:                    if (requestor instanceof  ControlBean)
1037:                        return ((ControlBean) requestor)
1038:                                .getControlBeanContext();
1039:
1040:                    return null;
1041:                }
1042:
1043:                //
1044:                // BeanContextServiceProvider.releaseService()
1045:                //
1046:                public void releaseService(BeanContextServices bcs,
1047:                        Object requestor, Object service) {
1048:                    // noop, because context exists whether referenced or not
1049:                }
1050:
1051:                //
1052:                // BeanContextServiceProvider.getContextServiceSelectors()
1053:                //
1054:                public Iterator getCurrentServiceSelectors(
1055:                        BeanContextServices bcs, Class serviceClass) {
1056:                    return null; // no selectors
1057:                }
1058:            }
1059:
1060:            /*package*/static abstract class BeanContextServicesFactory {
1061:                protected abstract BeanContextServices instantiate(
1062:                        ControlBeanContext controlBeanContext);
1063:            }
1064:
1065:            private static final class DefaultBeanContextServicesFactory extends
1066:                    BeanContextServicesFactory {
1067:                protected BeanContextServices instantiate(
1068:                        ControlBeanContext controlBeanContext) {
1069:                    return new java.beans.beancontext.BeanContextServicesSupport(
1070:                            controlBeanContext);
1071:                }
1072:            }
1073:
1074:            /**
1075:             * A singleton instance of the ControlBeanContextProvider class is that will be registered
1076:             * on all ControlBeanContext instances.  The provider can be a singleton because it is
1077:             * completely stateless and thread-safe.
1078:             */
1079:            private static final ControlBeanContextProvider CONTROL_BEAN_CONTEXT_PROVIDER = new ControlBeanContextProvider();
1080:
1081:            /**
1082:             * A singleton instance of the BeanContextServicesFactory class that can be implemented by subclasses
1083:             * to allow top-level Control containers to provide their own implementations of the
1084:             * {@link java.beans.beancontext.BeanContextServices} interface.  This field is considered an implementation
1085:             * detail and should not be referenced directly.
1086:             */
1087:            private static final BeanContextServicesFactory DEFAULT_BEAN_CONTEXT_SERVICES_FACTORY = new DefaultBeanContextServicesFactory();
1088:
1089:            /**
1090:             * The ControlBean instance that this context is providing services for.  This value can
1091:             * be null, if the context instance is associated with top-level (non-control) context.
1092:             */
1093:            private ControlBean _bean;
1094:
1095:            /**
1096:             * Indicates whether this context's parent guarantees single-threaded behaviour.
1097:             */
1098:            private boolean _hasSingleThreadedParent = false;
1099:
1100:            /**
1101:             * Maps children by the local (relative) ID of the child to the actual bean instance.
1102:             * This needs to be synchronized, because adds/removes/gets are not necessarily guaranteed
1103:             * to happen within the scope of the global hierarchy lock.   It would be relatively easy
1104:             * to synchronize add/remove, since setBeanContext on the child is inside this lock scope,
1105:             * but gets on the map are another story.
1106:             */
1107:            private Map<String, Object> _childMap = Collections
1108:                    .synchronizedMap(new HashMap<String, Object>());
1109:
1110:            /**
1111:             * Maintains a set of NameGenerators (for control ID generation) keyed by a
1112:             * base prefix.  The map itself is lazily constructed, so there is minimal
1113:             * overhead of no id generation is needed in this context.
1114:             */
1115:            private Map<String, NameGenerator> _nameGenerators;
1116:
1117:            /**
1118:             * Maintains the list of lifecycle event listeners (if any) for this context.
1119:             */
1120:            private transient Vector<LifeCycle> _lifeCycleListeners;
1121:
1122:            /**
1123:             * Caches the full composite control ID, that includes the entire path from the root
1124:             * ContainerContext to the associated bean.  This value can be transient, since it
1125:             * can be easily recomputed when needed.
1126:             */
1127:            private transient String _controlID;
1128:
1129:            /**
1130:             * Object that implements the java.beans.beancontext APIs from the JDK to provide compliance with the
1131:             * JavaBeans BeanContext / BeanContextChild specification.  The ControlBeanContext class uses
1132:             * this object as a delegate to provide this functionality rather than extending the BeanContext
1133:             * support classes directly.  This allows for more flexibility in how the BeanContextServices (et al)
1134:             * API implementations evolve over time.
1135:             */
1136:            private BeanContextServices _beanContextServicesDelegate;
1137:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.