Source Code Cross Referenced for BeanContextServicesSupport.java in  » Apache-Harmony-Java-SE » java-package » java » beans » beancontext » 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 » Apache Harmony Java SE » java package » java.beans.beancontext 
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:
0018:        package java.beans.beancontext;
0019:
0020:        import java.io.IOException;
0021:        import java.io.ObjectInputStream;
0022:        import java.io.ObjectOutputStream;
0023:        import java.io.Serializable;
0024:        import java.util.ArrayList;
0025:        import java.util.HashMap;
0026:        import java.util.Iterator;
0027:        import java.util.Locale;
0028:        import java.util.TooManyListenersException;
0029:        import java.util.Map.Entry;
0030:
0031:        import org.apache.harmony.beans.internal.nls.Messages;
0032:
0033:        /**
0034:         * This support class implements <code>BeanContextServices</code> interface.
0035:         * This class can be used directly, or be a super class of your class, or be a
0036:         * delegate of your implementation that needs to support
0037:         * <code>BeanContextServices</code> interface.
0038:         * 
0039:         */
0040:        public class BeanContextServicesSupport extends BeanContextSupport
0041:                implements  BeanContextServices, Serializable {
0042:
0043:            private static class ServiceRecord {
0044:
0045:                BeanContextServiceProvider provider;
0046:
0047:                BeanContextChild child;
0048:
0049:                Object requestor;
0050:
0051:                Class serviceClass;
0052:
0053:                BeanContextServiceRevokedListener revokedListener;
0054:
0055:                Object service;
0056:
0057:                boolean isDelegate;
0058:
0059:                ServiceRecord(BeanContextServiceProvider provider,
0060:                        BeanContextChild child, Object requestor,
0061:                        Class serviceClass,
0062:                        BeanContextServiceRevokedListener revokedListener,
0063:                        Object service, boolean isDelegate) {
0064:                    this .provider = provider;
0065:                    this .child = child;
0066:                    this .requestor = requestor;
0067:                    this .serviceClass = serviceClass;
0068:                    this .revokedListener = revokedListener;
0069:                    this .service = service;
0070:                    this .isDelegate = isDelegate;
0071:                }
0072:            }
0073:
0074:            /**
0075:             * Every child of context is companied with a <code>BCSSChild</code>
0076:             * instance. It can hold implementation specific information about each
0077:             * child.
0078:             * <p>
0079:             * This class keeps records of all services requests submitted by this
0080:             * child.
0081:             * </p>
0082:             * 
0083:             */
0084:            protected class BCSSChild extends BeanContextSupport.BCSChild {
0085:
0086:                private static final long serialVersionUID = -3263851306889194873L;
0087:
0088:                transient ArrayList<ServiceRecord> serviceRecords;
0089:
0090:                BCSSChild(Object child, Object proxyPeer) {
0091:                    super (child, proxyPeer);
0092:                }
0093:
0094:            }
0095:
0096:            /**
0097:             * This class implements the <code>BeanContextServiceProvider</code>
0098:             * interface by wrapping a <code>BeanContextServices</code>. All services
0099:             * registered in the <code>BeanContextServices</code> are accessible via
0100:             * this wrapper service provider.
0101:             * <p>
0102:             * This class is used by <code>BeanContextServicesSupport</code> to access
0103:             * services provided by its parent context (if there is one).
0104:             * </p>
0105:             * 
0106:             */
0107:            protected class BCSSProxyServiceProvider implements 
0108:                    BeanContextServiceProvider,
0109:                    BeanContextServiceRevokedListener {
0110:
0111:                private BeanContextServices backBCS;
0112:
0113:                BCSSProxyServiceProvider(BeanContextServices backBCS) {
0114:                    this .backBCS = backBCS;
0115:                }
0116:
0117:                /**
0118:                 * Throws <code>UnsupportedOperationException</code>.
0119:                 */
0120:                public Iterator getCurrentServiceSelectors(
0121:                        BeanContextServices bcs, Class serviceClass) {
0122:                    throw new UnsupportedOperationException();
0123:                }
0124:
0125:                /**
0126:                 * Throws <code>UnsupportedOperationException</code>.
0127:                 */
0128:                public Object getService(BeanContextServices bcs,
0129:                        Object requestor, Class serviceClass,
0130:                        Object serviceSelector) {
0131:                    throw new UnsupportedOperationException();
0132:                }
0133:
0134:                /**
0135:                 * Delegate to the wrapped <code>BeanContextServices</code>.
0136:                 */
0137:                Object getService(BeanContextServices bcs, Object requestor,
0138:                        Class serviceClass, Object serviceSelector,
0139:                        BeanContextServiceRevokedListener listener)
0140:                        throws TooManyListenersException {
0141:                    return backBCS.getService(BeanContextServicesSupport.this 
0142:                            .getBeanContextServicesPeer(), requestor,
0143:                            serviceClass, serviceSelector,
0144:                            new ServiceRevokedListenerDelegator(listener));
0145:                }
0146:
0147:                /**
0148:                 * Delegate to the wrapped <code>BeanContextServices</code>.
0149:                 */
0150:                public void releaseService(BeanContextServices bcs,
0151:                        Object requestor, Object service) {
0152:                    backBCS.releaseService(BeanContextServicesSupport.this 
0153:                            .getBeanContextServicesPeer(), requestor, service);
0154:                }
0155:
0156:                /**
0157:                 * Throws <code>UnsupportedOperationException</code>.
0158:                 */
0159:                public void serviceRevoked(BeanContextServiceRevokedEvent bcsre) {
0160:                    throw new UnsupportedOperationException();
0161:                }
0162:
0163:            }
0164:
0165:            private class ServiceRevokedListenerDelegator implements 
0166:                    BeanContextServiceRevokedListener {
0167:
0168:                private BeanContextServiceRevokedListener backListener;
0169:
0170:                public ServiceRevokedListenerDelegator(
0171:                        BeanContextServiceRevokedListener backListener) {
0172:                    this .backListener = backListener;
0173:                }
0174:
0175:                public void serviceRevoked(BeanContextServiceRevokedEvent event) {
0176:                    backListener
0177:                            .serviceRevoked(new BeanContextServiceRevokedEvent(
0178:                                    BeanContextServicesSupport.this 
0179:                                            .getBeanContextServicesPeer(),
0180:                                    event.getServiceClass(), event
0181:                                            .isCurrentServiceInvalidNow()));
0182:                }
0183:
0184:            }
0185:
0186:            /**
0187:             * Every servie registered in this context is companied with a
0188:             * <code>BCSSServiceProvider</code> instance. It can hold implementation
0189:             * specific information about each registered service.
0190:             * <p>
0191:             * This class holds a reference to the service provider of the service.
0192:             * </p>
0193:             * 
0194:             */
0195:            protected static class BCSSServiceProvider implements  Serializable {
0196:
0197:                static final long serialVersionUID = 861278251667444782L;
0198:
0199:                /**
0200:                 * The service provider of the related service.
0201:                 */
0202:                protected BeanContextServiceProvider serviceProvider;
0203:
0204:                BCSSServiceProvider(BeanContextServiceProvider provider) {
0205:                    this .serviceProvider = provider;
0206:                }
0207:
0208:                /**
0209:                 * Returns the service provider of the related service.
0210:                 * 
0211:                 * @return the service provider of the related service
0212:                 */
0213:                protected BeanContextServiceProvider getServiceProvider() {
0214:                    return serviceProvider;
0215:                }
0216:
0217:            }
0218:
0219:            static final long serialVersionUID = -8494482757288719206L;
0220:
0221:            /**
0222:             * A map of all registered services - key is service class, value is
0223:             * <code>BCSSServiceProvider</code> object. All access to this object
0224:             * should be synchronized on itself.
0225:             */
0226:            @SuppressWarnings("unchecked")
0227:            protected transient HashMap services;
0228:
0229:            /**
0230:             * The number of serializable service providers currently registered.
0231:             */
0232:            protected transient int serializable;
0233:
0234:            /**
0235:             * A proxy service provider that delegates service requests to the parent
0236:             * context.
0237:             */
0238:            protected transient BCSSProxyServiceProvider proxy;
0239:
0240:            /**
0241:             * A list of registered <code>BeanContextServicesListener</code>s. All
0242:             * access to this object should be synchronized on itself.
0243:             */
0244:            @SuppressWarnings("unchecked")
0245:            protected transient ArrayList bcsListeners;
0246:
0247:            /**
0248:             * Constructs a standard <code>BeanContextServicesSupport</code>.
0249:             */
0250:            public BeanContextServicesSupport() {
0251:                super ();
0252:            }
0253:
0254:            /**
0255:             * Constructs a <code>BeanContextServicesSupport</code> which is a
0256:             * delegate of the given peer.
0257:             * 
0258:             * @param peer
0259:             *            the peer of this context
0260:             */
0261:            public BeanContextServicesSupport(BeanContextServices peer) {
0262:                super (peer);
0263:            }
0264:
0265:            /**
0266:             * Constructs a <code>BeanContextServicesSupport</code> which is a
0267:             * delegate of the given peer.
0268:             * 
0269:             * @param peer
0270:             *            the peer of this context
0271:             * @param locale
0272:             *            the locale of this context
0273:             */
0274:            public BeanContextServicesSupport(BeanContextServices peer,
0275:                    Locale locale) {
0276:                super (peer, locale);
0277:            }
0278:
0279:            /**
0280:             * Constructs a <code>BeanContextServicesSupport</code> which is a
0281:             * delegate of the given peer.
0282:             * 
0283:             * @param peer
0284:             *            the peer of this context
0285:             * @param locale
0286:             *            the locale of this context
0287:             * @param designTime
0288:             *            whether in design mode or not
0289:             */
0290:            public BeanContextServicesSupport(BeanContextServices peer,
0291:                    Locale locale, boolean designTime) {
0292:                super (peer, locale, designTime);
0293:            }
0294:
0295:            /**
0296:             * Constructs a <code>BeanContextServicesSupport</code> which is a
0297:             * delegate of the given peer.
0298:             * 
0299:             * @param peer
0300:             *            the peer of this context
0301:             * @param locale
0302:             *            the locale of this context
0303:             * @param designTime
0304:             *            whether in design mode or not
0305:             * @param okToUseGui
0306:             *            whether GUI is usable or not
0307:             */
0308:            public BeanContextServicesSupport(BeanContextServices peer,
0309:                    Locale locale, boolean designTime, boolean okToUseGui) {
0310:                super (peer, locale, designTime, okToUseGui);
0311:            }
0312:
0313:            /*
0314:             * (non-Javadoc)
0315:             * 
0316:             * @see java.beans.beancontext.BeanContextServices#addBeanContextServicesListener(java.beans.beancontext.BeanContextServicesListener)
0317:             */
0318:            public void addBeanContextServicesListener(
0319:                    BeanContextServicesListener listener) {
0320:                if (listener == null) {
0321:                    throw new NullPointerException();
0322:                }
0323:                synchronized (bcsListeners) {
0324:                    bcsListeners.add(listener);
0325:                }
0326:            }
0327:
0328:            /**
0329:             * Add a service to this context.
0330:             * <p>
0331:             * Delegate to <code>addService(serviceClass, provider, true)</code>.
0332:             * </p>
0333:             * 
0334:             * @see java.beans.beancontext.BeanContextServices#addService(java.lang.Class,
0335:             *      java.beans.beancontext.BeanContextServiceProvider)
0336:             */
0337:            public boolean addService(Class serviceClass,
0338:                    BeanContextServiceProvider provider) {
0339:                return addService(serviceClass, provider, true);
0340:            }
0341:
0342:            /**
0343:             * Add a service to this context.
0344:             * <p>
0345:             * If the service already exists in the context, simply return false.
0346:             * Otherwise, the service is added and event is fired if required.
0347:             * </p>
0348:             * 
0349:             * @param serviceClass
0350:             *            the service class
0351:             * @param provider
0352:             *            the provider of the service
0353:             * @param fireEvent
0354:             *            the flag indicating to fire event or not
0355:             * @return true if the service is added; or false if the context already has
0356:             *         this service
0357:             */
0358:            protected boolean addService(Class serviceClass,
0359:                    BeanContextServiceProvider provider, boolean fireEvent) {
0360:                if (serviceClass == null || provider == null) {
0361:                    throw new NullPointerException();
0362:                }
0363:
0364:                synchronized (globalHierarchyLock) {
0365:                    synchronized (services) {
0366:                        if (services.containsKey(serviceClass)) {
0367:                            return false;
0368:                        }
0369:                        // add to services
0370:                        services.put(serviceClass, createBCSSServiceProvider(
0371:                                serviceClass, provider));
0372:                        // count Serializable
0373:                        if (provider instanceof  Serializable) {
0374:                            serializable++;
0375:                        }
0376:                    }
0377:                }
0378:
0379:                if (fireEvent) {
0380:                    // notify all listeners and BeanContextServices children
0381:                    notifyServiceAvailable(new BeanContextServiceAvailableEvent(
0382:                            this , serviceClass));
0383:                }
0384:                return true;
0385:            }
0386:
0387:            private void notifyServiceAvailable(
0388:                    BeanContextServiceAvailableEvent event) {
0389:                fireServiceAdded(event);
0390:                Object childs[] = copyChildren();
0391:                for (int i = 0; i < childs.length; i++) {
0392:                    if (childs[i] instanceof  BeanContextServices) {
0393:                        ((BeanContextServices) childs[i])
0394:                                .serviceAvailable(event);
0395:                    }
0396:                }
0397:            }
0398:
0399:            /**
0400:             * Deserializes all serializable services and their providers before the
0401:             * children of this context is deserialized.
0402:             * <p>
0403:             * First a <code>int</code> is read, indicating the number of services to
0404:             * read. Then pairs of service class and service provider are read one by
0405:             * one.
0406:             * </p>
0407:             * 
0408:             * @see java.beans.beancontext.BeanContextSupport#bcsPreDeserializationHook(java.io.ObjectInputStream)
0409:             */
0410:            protected void bcsPreDeserializationHook(ObjectInputStream ois)
0411:                    throws IOException, ClassNotFoundException {
0412:                super .bcsPreDeserializationHook(ois);
0413:
0414:                // deserialize services
0415:                synchronized (services) {
0416:                    serializable = ois.readInt();
0417:                    for (int i = 0; i < serializable; i++) {
0418:                        Object serviceClass = ois.readObject();
0419:                        Object bcssProvider = ois.readObject();
0420:                        services.put((Class) serviceClass,
0421:                                (BCSSServiceProvider) bcssProvider);
0422:                    }
0423:                }
0424:            }
0425:
0426:            /**
0427:             * Serializes all serializable services and their providers before the
0428:             * children of this context is serialized.
0429:             * <p>
0430:             * First a <code>int</code> is writtern, indicating the number of
0431:             * serializable services. Then pairs of service class and service provider
0432:             * are writtern one by one.
0433:             * </p>
0434:             * 
0435:             * @see java.beans.beancontext.BeanContextSupport#bcsPreSerializationHook(java.io.ObjectOutputStream)
0436:             */
0437:            protected void bcsPreSerializationHook(ObjectOutputStream oos)
0438:                    throws IOException {
0439:                super .bcsPreSerializationHook(oos);
0440:
0441:                // serialize services
0442:                synchronized (services) {
0443:                    oos.writeInt(serializable);
0444:                    for (Iterator iter = services.entrySet().iterator(); iter
0445:                            .hasNext();) {
0446:                        Entry entry = (Entry) iter.next();
0447:                        if (((BCSSServiceProvider) entry.getValue())
0448:                                .getServiceProvider() instanceof  Serializable) {
0449:                            oos.writeObject(entry.getKey());
0450:                            oos.writeObject(entry.getValue());
0451:                        }
0452:                    }
0453:                }
0454:            }
0455:
0456:            /**
0457:             * This method is called everytime a child is removed from this context.
0458:             * <p>
0459:             * The implementation releases all services requested by the child.
0460:             * </p>
0461:             * 
0462:             * @see java.beans.beancontext.BeanContextSupport#childJustRemovedHook(java.lang.Object,
0463:             *      java.beans.beancontext.BeanContextSupport.BCSChild)
0464:             */
0465:            protected void childJustRemovedHook(Object child, BCSChild bcsChild) {
0466:                if (bcsChild instanceof  BCSSChild) {
0467:                    releaseServicesForChild((BCSSChild) bcsChild, false);
0468:                }
0469:            }
0470:
0471:            /**
0472:             * Release all services requested by the given child.
0473:             * 
0474:             * @param bcssChild
0475:             *            a child
0476:             * @param delegatedServices
0477:             *            only release services that are delegated to parent context
0478:             */
0479:            private void releaseServicesForChild(BCSSChild bcssChild,
0480:                    boolean delegatedServices) {
0481:                if (bcssChild.serviceRecords == null
0482:                        || bcssChild.serviceRecords.isEmpty()) {
0483:                    return;
0484:                }
0485:                synchronized (bcssChild.child) {
0486:                    Object records[] = bcssChild.serviceRecords.toArray();
0487:                    for (int i = 0; i < records.length; i++) {
0488:                        ServiceRecord rec = (ServiceRecord) records[i];
0489:                        if (delegatedServices) {
0490:                            if (rec.isDelegate) {
0491:                                releaseServiceWithoutCheck(rec.child,
0492:                                        bcssChild, rec.requestor, rec.service,
0493:                                        true);
0494:                            }
0495:                        } else {
0496:                            releaseServiceWithoutCheck(rec.child, bcssChild,
0497:                                    rec.requestor, rec.service, false);
0498:                        }
0499:                    }
0500:                }
0501:            }
0502:
0503:            /**
0504:             * Creates a <code>BCSSChild</code> object to company the given child.
0505:             * 
0506:             * @see java.beans.beancontext.BeanContextSupport#createBCSChild(java.lang.Object,
0507:             *      java.lang.Object)
0508:             */
0509:            protected BCSChild createBCSChild(Object child, Object proxyPeer) {
0510:                return new BCSSChild(child, proxyPeer);
0511:            }
0512:
0513:            /**
0514:             * Creates a <code>BCSSServiceProvider</code> to company the given
0515:             * service.
0516:             * 
0517:             * @param serviceClass
0518:             *            the service class
0519:             * @param provider
0520:             *            the service provider
0521:             * @return a <code>BCSSServiceProvider</code> to company the given service
0522:             */
0523:            protected BCSSServiceProvider createBCSSServiceProvider(
0524:                    Class serviceClass, BeanContextServiceProvider provider) {
0525:                return new BCSSServiceProvider(provider);
0526:            }
0527:
0528:            /**
0529:             * Fires a <code>BeanContextServiceAvailableEvent</code> to registered
0530:             * <code>BeanContextServicesListener</code>s.
0531:             * 
0532:             * @param serviceClass
0533:             *            the service that has been added
0534:             */
0535:            protected final void fireServiceAdded(Class serviceClass) {
0536:                fireServiceAdded(new BeanContextServiceAvailableEvent(this ,
0537:                        serviceClass));
0538:            }
0539:
0540:            /**
0541:             * Fires a <code>BeanContextServiceAvailableEvent</code> to registered
0542:             * <code>BeanContextServicesListener</code>s.
0543:             * 
0544:             * @param event
0545:             *            the event
0546:             */
0547:            protected final void fireServiceAdded(
0548:                    BeanContextServiceAvailableEvent event) {
0549:                Object listeners[];
0550:                synchronized (bcsListeners) {
0551:                    listeners = bcsListeners.toArray();
0552:                }
0553:                for (int i = 0; i < listeners.length; i++) {
0554:                    BeanContextServicesListener l = (BeanContextServicesListener) listeners[i];
0555:                    l.serviceAvailable(event);
0556:                }
0557:            }
0558:
0559:            /**
0560:             * Fires a <code>BeanContextServiceRevokedEvent</code> to registered
0561:             * <code>BeanContextServicesListener</code>s.
0562:             * 
0563:             * @param serviceClass
0564:             *            the service that has been revoked
0565:             * @param revokeNow
0566:             *            whether to terminate service immediately
0567:             */
0568:            protected final void fireServiceRevoked(Class serviceClass,
0569:                    boolean revokeNow) {
0570:                fireServiceRevoked(new BeanContextServiceRevokedEvent(this ,
0571:                        serviceClass, revokeNow));
0572:            }
0573:
0574:            /**
0575:             * Fires a <code>BeanContextServiceRevokedEvent</code> to registered
0576:             * <code>BeanContextServicesListener</code>s.
0577:             * 
0578:             * @param event
0579:             *            the event
0580:             */
0581:            protected final void fireServiceRevoked(
0582:                    BeanContextServiceRevokedEvent event) {
0583:                Object listeners[];
0584:                synchronized (bcsListeners) {
0585:                    listeners = bcsListeners.toArray();
0586:                }
0587:                for (int i = 0; i < listeners.length; i++) {
0588:                    BeanContextServicesListener l = (BeanContextServicesListener) listeners[i];
0589:                    l.serviceRevoked(event);
0590:                }
0591:            }
0592:
0593:            /**
0594:             * Returns the peer of this context casted as
0595:             * <code>BeanContextServices</code>.
0596:             * 
0597:             * @return the peer of this context casted as
0598:             *         <code>BeanContextServices</code>
0599:             */
0600:            public BeanContextServices getBeanContextServicesPeer() {
0601:                return (BeanContextServices) beanContextChildPeer;
0602:            }
0603:
0604:            /**
0605:             * Returns the given child casted to
0606:             * <code>BeanContextServicesListener</code>, or null if it does not
0607:             * implements the interface.
0608:             * 
0609:             * @param child
0610:             *            a child
0611:             * @return the given child casted to
0612:             *         <code>BeanContextServicesListener</code>, or null if it does
0613:             *         not implements the interface
0614:             */
0615:            protected static final BeanContextServicesListener getChildBeanContextServicesListener(
0616:                    Object child) {
0617:                if (child instanceof  BeanContextServicesListener) {
0618:                    return (BeanContextServicesListener) child;
0619:                }
0620:                return null;
0621:            }
0622:
0623:            /**
0624:             * Returns an iterator of all registered service classes, with
0625:             * <code>removed()</code> disabled.
0626:             * 
0627:             * @return an iterator of all registered service classes
0628:             * @see java.beans.beancontext.BeanContextServices#getCurrentServiceClasses()
0629:             */
0630:            public Iterator getCurrentServiceClasses() {
0631:                synchronized (services) {
0632:                    return new BCSIterator(services.keySet().iterator());
0633:                }
0634:            }
0635:
0636:            /**
0637:             * Returns the service selectors of the specified service. The iterator's
0638:             * <code>remove()</code> operation is disabled.
0639:             * 
0640:             * @see java.beans.beancontext.BeanContextServices#getCurrentServiceSelectors(java.lang.Class)
0641:             */
0642:            public Iterator getCurrentServiceSelectors(Class serviceClass) {
0643:                BeanContextServiceProvider provider = getLocalServiceProvider(serviceClass);
0644:                return provider == null ? null : new BCSIterator(provider
0645:                        .getCurrentServiceSelectors(
0646:                                getBeanContextServicesPeer(), serviceClass));
0647:            }
0648:
0649:            private BeanContextServiceProvider getLocalServiceProvider(
0650:                    Class serviceClass) {
0651:                synchronized (services) {
0652:                    BCSSServiceProvider bcssProvider = (BCSSServiceProvider) services
0653:                            .get(serviceClass);
0654:                    if (bcssProvider != null) {
0655:                        return bcssProvider.getServiceProvider();
0656:                    }
0657:                    return null;
0658:                }
0659:            }
0660:
0661:            /**
0662:             * Get a service instance on behalf of the specified child of this context,
0663:             * by calling the registered service provider, or by delegating to the
0664:             * parent context.
0665:             * 
0666:             * @param child
0667:             *            the child that request service
0668:             * @param requestor
0669:             *            the requestor object
0670:             * @param serviceClass
0671:             *            the service class
0672:             * @param serviceSelector
0673:             *            the service selectors
0674:             * @param bcsrl
0675:             *            the <code>BeanContextServiceRevokedListener</code>
0676:             * @return a service instance on behalf of the specified child of this
0677:             *         context
0678:             * @throws IllegalArgumentException
0679:             *             if <code>child</code> is not a child of this context
0680:             * @throws TooManyListenersException
0681:             * @see java.beans.beancontext.BeanContextServices#getService(java.beans.beancontext.BeanContextChild,
0682:             *      java.lang.Object, java.lang.Class, java.lang.Object,
0683:             *      java.beans.beancontext.BeanContextServiceRevokedListener)
0684:             */
0685:            public Object getService(BeanContextChild child, Object requestor,
0686:                    Class serviceClass, Object serviceSelector,
0687:                    BeanContextServiceRevokedListener bcsrl)
0688:                    throws TooManyListenersException {
0689:                if (child == null || requestor == null || serviceClass == null
0690:                        || bcsrl == null) {
0691:                    throw new NullPointerException();
0692:                }
0693:
0694:                BCSSChild bcssChild = null;
0695:                BeanContextServiceProvider provider = null;
0696:                Object service = null;
0697:                boolean isDelegate = false;
0698:
0699:                synchronized (globalHierarchyLock) {
0700:                    // check child
0701:                    synchronized (children) {
0702:                        bcssChild = (BCSSChild) children.get(child);
0703:                    }
0704:                    if (bcssChild == null) {
0705:                        throw new IllegalArgumentException(
0706:                                "not a child of this context");
0707:                    }
0708:
0709:                    // try local service
0710:                    provider = getLocalServiceProvider(serviceClass);
0711:                    if (provider != null) {
0712:                        service = provider.getService(
0713:                                getBeanContextServicesPeer(), requestor,
0714:                                serviceClass, serviceSelector);
0715:                    }
0716:
0717:                    // no local service, try delegate
0718:                    if (service == null && proxy != null) {
0719:                        provider = proxy;
0720:                        service = proxy.getService(
0721:                                getBeanContextServicesPeer(), requestor,
0722:                                serviceClass, serviceSelector, bcsrl);
0723:                        isDelegate = true;
0724:                    }
0725:                }
0726:
0727:                if (service != null) {
0728:                    // save record
0729:                    synchronized (child) {
0730:                        if (bcssChild.serviceRecords == null) {
0731:                            bcssChild.serviceRecords = new ArrayList<ServiceRecord>();
0732:                        }
0733:                        bcssChild.serviceRecords.add(new ServiceRecord(
0734:                                provider, child, requestor, serviceClass,
0735:                                bcsrl, service, isDelegate));
0736:                    }
0737:                }
0738:
0739:                return service;
0740:            }
0741:
0742:            /**
0743:             * Checks whether a service is registed in this context or the parent
0744:             * context.
0745:             * 
0746:             * @param serviceClass
0747:             *            the service class
0748:             * @return true if the service is registered
0749:             * @see java.beans.beancontext.BeanContextServices#hasService(java.lang.Class)
0750:             */
0751:            public boolean hasService(Class serviceClass) {
0752:                if (serviceClass == null) {
0753:                    throw new NullPointerException();
0754:                }
0755:
0756:                boolean has;
0757:                synchronized (services) {
0758:                    has = services.containsKey(serviceClass);
0759:                }
0760:                if (!has && getBeanContext() instanceof  BeanContextServices) {
0761:                    has = ((BeanContextServices) getBeanContext())
0762:                            .hasService(serviceClass);
0763:                }
0764:                return has;
0765:            }
0766:
0767:            /*
0768:             * (non-Javadoc)
0769:             * 
0770:             * @see java.beans.beancontext.BeanContextSupport#initialize()
0771:             */
0772:            public void initialize() {
0773:                super .initialize();
0774:                services = new HashMap<Class, BCSSServiceProvider>();
0775:                serializable = 0;
0776:                proxy = null;
0777:                bcsListeners = new ArrayList<BeanContextServicesListener>();
0778:            }
0779:
0780:            /**
0781:             * Called after the parent context is updated. The implementation checks if
0782:             * the parent context is a <code>BeanContextServices</code>. If it is,
0783:             * then a <code>BCSSProxyServiceProvider</code> is created to delegate
0784:             * service requests to the parent context.
0785:             * 
0786:             * @see java.beans.beancontext.BeanContextChildSupport#initializeBeanContextResources()
0787:             */
0788:            protected void initializeBeanContextResources() {
0789:                super .initializeBeanContextResources();
0790:
0791:                BeanContext context = getBeanContext();
0792:                if (context instanceof  BeanContextServices) {
0793:                    proxy = new BCSSProxyServiceProvider(
0794:                            (BeanContextServices) context);
0795:                } else {
0796:                    proxy = null;
0797:                }
0798:            }
0799:
0800:            /**
0801:             * Called before the parent context is updated. The implementation releases
0802:             * any service that is currently provided by the parent context.
0803:             * 
0804:             * @see java.beans.beancontext.BeanContextChildSupport#releaseBeanContextResources()
0805:             */
0806:            protected void releaseBeanContextResources() {
0807:                super .releaseBeanContextResources();
0808:
0809:                releaseAllDelegatedServices();
0810:                proxy = null;
0811:            }
0812:
0813:            private void releaseAllDelegatedServices() {
0814:                synchronized (children) {
0815:                    for (Iterator iter = bcsChildren(); iter.hasNext();) {
0816:                        releaseServicesForChild((BCSSChild) iter.next(), true);
0817:                    }
0818:                }
0819:            }
0820:
0821:            /**
0822:             * Release a service which has been requested previously.
0823:             * 
0824:             * @param child
0825:             *            the child that request the service
0826:             * @param requestor
0827:             *            the requestor object
0828:             * @param service
0829:             *            the service instance
0830:             * @throws IllegalArgumentException
0831:             *             if <code>child</code> is not a child of this context
0832:             */
0833:            public void releaseService(BeanContextChild child,
0834:                    Object requestor, Object service) {
0835:                if (child == null || requestor == null || service == null) {
0836:                    throw new NullPointerException();
0837:                }
0838:
0839:                synchronized (globalHierarchyLock) {
0840:                    BCSSChild bcssChild;
0841:                    synchronized (children) {
0842:                        bcssChild = (BCSSChild) children.get(child);
0843:                    }
0844:                    if (bcssChild == null) {
0845:                        throw new IllegalArgumentException(
0846:                                "not a child of this context");
0847:                    }
0848:
0849:                    releaseServiceWithoutCheck(child, bcssChild, requestor,
0850:                            service, false);
0851:                }
0852:            }
0853:
0854:            /**
0855:             * Releases a service without checking the membership of the child.
0856:             */
0857:            private void releaseServiceWithoutCheck(BeanContextChild child,
0858:                    BCSSChild bcssChild, Object requestor, Object service,
0859:                    boolean callRevokedListener) {
0860:
0861:                if (bcssChild.serviceRecords == null
0862:                        || bcssChild.serviceRecords.isEmpty()) {
0863:                    return;
0864:                }
0865:
0866:                synchronized (child) {
0867:                    // scan record
0868:                    for (Iterator iter = bcssChild.serviceRecords.iterator(); iter
0869:                            .hasNext();) {
0870:                        ServiceRecord rec = (ServiceRecord) iter.next();
0871:                        if (rec.requestor == requestor
0872:                                && rec.service == service) {
0873:                            // release service
0874:                            rec.provider.releaseService(
0875:                                    getBeanContextServicesPeer(), requestor,
0876:                                    service);
0877:                            // call service revoked listener
0878:                            if (callRevokedListener
0879:                                    && rec.revokedListener != null) {
0880:                                rec.revokedListener
0881:                                        .serviceRevoked(new BeanContextServiceRevokedEvent(
0882:                                                getBeanContextServicesPeer(),
0883:                                                rec.serviceClass, true));
0884:                            }
0885:                            // remove record
0886:                            iter.remove();
0887:                            break;
0888:                        }
0889:                    }
0890:                }
0891:            }
0892:
0893:            /*
0894:             * (non-Javadoc)
0895:             * 
0896:             * @see java.beans.beancontext.BeanContextServices#removeBeanContextServicesListener(java.beans.beancontext.BeanContextServicesListener)
0897:             */
0898:            public void removeBeanContextServicesListener(
0899:                    BeanContextServicesListener listener) {
0900:                if (listener == null) {
0901:                    throw new NullPointerException();
0902:                }
0903:                synchronized (bcsListeners) {
0904:                    bcsListeners.remove(listener);
0905:                }
0906:            }
0907:
0908:            /**
0909:             * Revokes a service in this bean context.
0910:             * <p>
0911:             * The given service provider is unregistered and a
0912:             * <code>BeanContextServiceRevokedEvent</code> is fired. All registered
0913:             * service listeners and current service users get notified.
0914:             * </p>
0915:             * 
0916:             * @param serviceClass
0917:             *            the service class
0918:             * @param serviceProvider
0919:             *            the service provider
0920:             * @param revokeCurrentServicesNow
0921:             *            true if service should be terminated immediantly
0922:             * @see java.beans.beancontext.BeanContextServices#revokeService(java.lang.Class,
0923:             *      java.beans.beancontext.BeanContextServiceProvider, boolean)
0924:             */
0925:            public void revokeService(Class serviceClass,
0926:                    BeanContextServiceProvider serviceProvider,
0927:                    boolean revokeCurrentServicesNow) {
0928:                if (serviceClass == null || serviceProvider == null) {
0929:                    throw new NullPointerException();
0930:                }
0931:
0932:                synchronized (globalHierarchyLock) {
0933:                    synchronized (services) {
0934:                        BCSSServiceProvider bcssProvider = (BCSSServiceProvider) services
0935:                                .get(serviceClass);
0936:                        if (bcssProvider == null) { // non-exist service
0937:                            return;
0938:                        }
0939:                        if (bcssProvider.getServiceProvider() != serviceProvider) {
0940:                            throw new IllegalArgumentException(
0941:                                    "not the service provider registered with this context");
0942:                        }
0943:
0944:                        services.remove(serviceClass);
0945:
0946:                        if (serviceProvider instanceof  Serializable) {
0947:                            serializable--;
0948:                        }
0949:                    }
0950:                }
0951:
0952:                // notify listeners
0953:                fireServiceRevoked(serviceClass, revokeCurrentServicesNow);
0954:
0955:                // notify service users
0956:                notifyServiceRevokedToServiceUsers(serviceClass,
0957:                        serviceProvider, revokeCurrentServicesNow);
0958:            }
0959:
0960:            /**
0961:             * Notify all children that a service has been revoked.
0962:             */
0963:            private void notifyServiceRevokedToServiceUsers(Class serviceClass,
0964:                    BeanContextServiceProvider serviceProvider,
0965:                    boolean revokeCurrentServicesNow) {
0966:                synchronized (children) {
0967:                    for (Iterator iter = bcsChildren(); iter.hasNext();) {
0968:                        BCSSChild bcssChild = (BCSSChild) iter.next();
0969:                        notifyServiceRevokedToServiceUsers(serviceClass,
0970:                                serviceProvider, revokeCurrentServicesNow,
0971:                                bcssChild);
0972:                    }
0973:                }
0974:            }
0975:
0976:            /**
0977:             * Notify the given child that a service has been revoked.
0978:             */
0979:            private void notifyServiceRevokedToServiceUsers(Class serviceClass,
0980:                    BeanContextServiceProvider serviceProvider,
0981:                    boolean revokeCurrentServicesNow, BCSSChild bcssChild) {
0982:                if (bcssChild.serviceRecords == null
0983:                        || bcssChild.serviceRecords.isEmpty()) {
0984:                    return;
0985:                }
0986:                synchronized (bcssChild.child) {
0987:                    for (Iterator it = bcssChild.serviceRecords.iterator(); it
0988:                            .hasNext();) {
0989:                        ServiceRecord rec = (ServiceRecord) it.next();
0990:                        if (rec.serviceClass == serviceClass
0991:                                && rec.provider == serviceProvider
0992:                                && rec.revokedListener != null
0993:                                && !rec.isDelegate) {
0994:                            rec.revokedListener
0995:                                    .serviceRevoked(new BeanContextServiceRevokedEvent(
0996:                                            getBeanContextServicesPeer(),
0997:                                            serviceClass,
0998:                                            revokeCurrentServicesNow));
0999:                            // prevent duplicate notification
1000:                            rec.revokedListener = null;
1001:                        }
1002:                    }
1003:                }
1004:            }
1005:
1006:            /**
1007:             * Notify all listeners and children that implements
1008:             * <code>BeanContextServices</code> of the event.
1009:             * 
1010:             * @see java.beans.beancontext.BeanContextServicesListener#serviceAvailable(java.beans.beancontext.BeanContextServiceAvailableEvent)
1011:             */
1012:            public void serviceAvailable(BeanContextServiceAvailableEvent event) {
1013:                if (null == event) {
1014:                    throw new NullPointerException(Messages
1015:                            .getString("beans.1C")); //$NON-NLS-1$
1016:                }
1017:                if (services.containsKey(event.serviceClass)) {
1018:                    return;
1019:                }
1020:                fireServiceAdded(event);
1021:                Object childs[] = copyChildren();
1022:                for (int i = 0; i < childs.length; i++) {
1023:                    if (childs[i] instanceof  BeanContextServices) {
1024:                        ((BeanContextServices) childs[i])
1025:                                .serviceAvailable(event);
1026:                    }
1027:                }
1028:            }
1029:
1030:            /**
1031:             * Notify all listeners and children that implements
1032:             * <code>BeanContextServices</code> of the event.
1033:             * 
1034:             * @see java.beans.beancontext.BeanContextServiceRevokedListener#serviceRevoked(java.beans.beancontext.BeanContextServiceRevokedEvent)
1035:             */
1036:            public void serviceRevoked(BeanContextServiceRevokedEvent event) {
1037:                if (null == event) {
1038:                    throw new NullPointerException(Messages
1039:                            .getString("beans.1C")); //$NON-NLS-1$
1040:                }
1041:                if (services.containsKey(event.serviceClass)) {
1042:                    return;
1043:                }
1044:                fireServiceRevoked(event);
1045:                Object childs[] = copyChildren();
1046:                for (int i = 0; i < childs.length; i++) {
1047:                    if (childs[i] instanceof  BeanContextServices) {
1048:                        ((BeanContextServices) childs[i]).serviceRevoked(event);
1049:                    }
1050:                }
1051:            }
1052:
1053:            /**
1054:             * The implementation goes through following steps:
1055:             * <p>
1056:             * <ol>
1057:             * <li>Calls <code>defaultWriteObject()</code>.</li>
1058:             * <li>Writes out serializable service listeners.</li>
1059:             * </ol>
1060:             * </p>
1061:             * 
1062:             * @param oos
1063:             *            the object output stream
1064:             * @throws IOException
1065:             *             if I/O exception occurs
1066:             */
1067:            private void writeObject(ObjectOutputStream oos) throws IOException {
1068:
1069:                oos.defaultWriteObject();
1070:
1071:                synchronized (bcsListeners) {
1072:                    serialize(oos, bcsListeners);
1073:                }
1074:            }
1075:
1076:            /**
1077:             * The implementation goes through following steps:
1078:             * <p>
1079:             * <ol>
1080:             * <li>Calls <code>defaultReadObject()</code>.</li>
1081:             * <li>Reads serializable service listeners.</li>
1082:             * </ol>
1083:             * </p>
1084:             * 
1085:             * @param ois
1086:             *            the object input stream
1087:             * @throws IOException
1088:             *             if I/O error occurs
1089:             * @throws ClassNotFoundException
1090:             *             if class of read object is not found
1091:             */
1092:            private void readObject(ObjectInputStream ois) throws IOException,
1093:                    ClassNotFoundException {
1094:
1095:                ois.defaultReadObject();
1096:
1097:                synchronized (bcsListeners) {
1098:                    deserialize(ois, bcsListeners);
1099:                }
1100:            }
1101:
1102:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.