Source Code Cross Referenced for DefaultPicoContainer.java in  » Inversion-of-Control » PicoContainer » org » picocontainer » 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 » Inversion of Control » PicoContainer » org.picocontainer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*****************************************************************************
0002:         * Copyright (C) PicoContainer Organization. All rights reserved.            *
0003:         * ------------------------------------------------------------------------- *
0004:         * The software in this package is published under the terms of the BSD      *
0005:         * style license a copy of which has been included with this distribution in *
0006:         * the LICENSE.txt file.                                                     *
0007:         *                                                                           *
0008:         * Original code by                                                          *
0009:         *****************************************************************************/package org.picocontainer;
0010:
0011:        import java.io.Serializable;
0012:        import java.lang.annotation.Annotation;
0013:        import java.lang.ref.WeakReference;
0014:        import java.util.ArrayList;
0015:        import java.util.Collection;
0016:        import java.util.Collections;
0017:        import java.util.Enumeration;
0018:        import java.util.HashMap;
0019:        import java.util.HashSet;
0020:        import java.util.List;
0021:        import java.util.Map;
0022:        import java.util.Properties;
0023:        import java.util.Set;
0024:
0025:        import org.picocontainer.adapters.InstanceAdapter;
0026:        import org.picocontainer.behaviors.AbstractBehaviorFactory;
0027:        import org.picocontainer.behaviors.AdaptingBehavior;
0028:        import org.picocontainer.behaviors.Cached;
0029:        import org.picocontainer.behaviors.Caching;
0030:        import org.picocontainer.behaviors.HiddenImplementation;
0031:        import org.picocontainer.containers.AbstractDelegatingMutablePicoContainer;
0032:        import org.picocontainer.containers.AbstractDelegatingPicoContainer;
0033:        import org.picocontainer.containers.EmptyPicoContainer;
0034:        import org.picocontainer.containers.ImmutablePicoContainer;
0035:        import org.picocontainer.injectors.AbstractInjector;
0036:        import org.picocontainer.injectors.AdaptingInjection;
0037:        import org.picocontainer.lifecycle.LifecycleState;
0038:        import static org.picocontainer.lifecycle.LifecycleState.*;
0039:        import org.picocontainer.lifecycle.StartableLifecycleStrategy;
0040:        import org.picocontainer.monitors.NullComponentMonitor;
0041:
0042:        /**
0043:         * <p/>
0044:         * The Standard {@link PicoContainer}/{@link MutablePicoContainer} implementation.
0045:         * Constructing a container c with a parent p container will cause c to look up components
0046:         * in p if they cannot be found inside c itself.
0047:         * </p>
0048:         * <p/>
0049:         * Using {@link Class} objects as keys to the various registerXXX() methods makes
0050:         * a subtle semantic difference:
0051:         * </p>
0052:         * <p/>
0053:         * If there are more than one registered components of the same type and one of them are
0054:         * registered with a {@link java.lang.Class} key of the corresponding type, this addComponent
0055:         * will take precedence over other components during type resolution.
0056:         * </p>
0057:         * <p/>
0058:         * Another place where keys that are classes make a subtle difference is in
0059:         * {@link HiddenImplementation}.
0060:         * </p>
0061:         * <p/>
0062:         * This implementation of {@link MutablePicoContainer} also supports
0063:         * {@link ComponentMonitorStrategy}.
0064:         * </p>
0065:         *
0066:         * @author Paul Hammant
0067:         * @author Aslak Helles&oslash;y
0068:         * @author Jon Tirs&eacute;n
0069:         * @author Thomas Heller
0070:         * @author Mauro Talevi
0071:         */
0072:        public class DefaultPicoContainer implements  MutablePicoContainer,
0073:                ComponentMonitorStrategy, Serializable {
0074:
0075:            /**
0076:             * Serialization UUID.
0077:             */
0078:            private static final long serialVersionUID = -8987815732600681148L;
0079:
0080:            /**
0081:             * Component factory instance.
0082:             */
0083:            private final ComponentFactory componentFactory;
0084:
0085:            /**
0086:             * Parent picocontainer
0087:             */
0088:            private PicoContainer parent;
0089:
0090:            /**
0091:             * All picocontainer children.
0092:             */
0093:            private final Set<PicoContainer> children = new HashSet<PicoContainer>();
0094:
0095:            /**
0096:             * Current state of the container.
0097:             */
0098:            private LifecycleState lifecycleState = CONSTRUCTED;
0099:
0100:            /** 
0101:             * Keeps track of child containers started status.
0102:             */
0103:            private final Set<WeakReference<PicoContainer>> childrenStarted = new HashSet<WeakReference<PicoContainer>>();
0104:
0105:            /**
0106:             * Lifecycle strategy instance.
0107:             */
0108:            private final LifecycleStrategy lifecycleStrategy;
0109:
0110:            private final Properties componentProperties = new Properties();
0111:
0112:            /**
0113:             * Component monitor instance.  Receives event callbacks.
0114:             */
0115:            private ComponentMonitor componentMonitor;
0116:
0117:            /** List collecting the CAs which have been successfully started */
0118:            private final List<WeakReference<ComponentAdapter<?>>> startedComponentAdapters = new ArrayList<WeakReference<ComponentAdapter<?>>>();
0119:
0120:            /**
0121:             * Map used for looking up component adapters by their key.
0122:             */
0123:            private final Map<Object, ComponentAdapter<?>> componentKeyToAdapterCache = new HashMap<Object, ComponentAdapter<?>>();
0124:
0125:            private final List<ComponentAdapter<?>> componentAdapters = new ArrayList<ComponentAdapter<?>>();
0126:
0127:            protected final List<ComponentAdapter<?>> orderedComponentAdapters = new ArrayList<ComponentAdapter<?>>();
0128:
0129:            /**
0130:             * Creates a new container with a custom ComponentFactory and a parent container.
0131:             * <p/>
0132:             * <em>
0133:             * Important note about caching: If you intend the components to be cached, you should pass
0134:             * in a factory that creates {@link Cached} instances, such as for example
0135:             * {@link Caching}. Caching can delegate to
0136:             * other ComponentAdapterFactories.
0137:             * </em>
0138:             *
0139:             * @param componentFactory the factory to use for creation of ComponentAdapters.
0140:             * @param parent                  the parent container (used for component dependency lookups).
0141:             */
0142:            public DefaultPicoContainer(
0143:                    final ComponentFactory componentFactory,
0144:                    final PicoContainer parent) {
0145:                this (componentFactory, new StartableLifecycleStrategy(
0146:                        new NullComponentMonitor()), parent,
0147:                        new NullComponentMonitor());
0148:            }
0149:
0150:            /**
0151:             * Creates a new container with a custom ComponentFactory, LifecycleStrategy for instance registration,
0152:             * and a parent container.
0153:             * <p/>
0154:             * <em>
0155:             * Important note about caching: If you intend the components to be cached, you should pass
0156:             * in a factory that creates {@link Cached} instances, such as for example
0157:             * {@link Caching}. Caching can delegate to
0158:             * other ComponentAdapterFactories.
0159:             * </em>
0160:             *
0161:             * @param componentFactory the factory to use for creation of ComponentAdapters.
0162:             * @param lifecycleStrategy
0163:             *                                the lifecycle strategy chosen for registered
0164:             *                                instance (not implementations!)
0165:             * @param parent                  the parent container (used for component dependency lookups).
0166:             */
0167:            public DefaultPicoContainer(
0168:                    final ComponentFactory componentFactory,
0169:                    final LifecycleStrategy lifecycleStrategy,
0170:                    final PicoContainer parent) {
0171:                this (componentFactory, lifecycleStrategy, parent,
0172:                        new NullComponentMonitor());
0173:            }
0174:
0175:            public DefaultPicoContainer(
0176:                    final ComponentFactory componentFactory,
0177:                    final LifecycleStrategy lifecycleStrategy,
0178:                    final PicoContainer parent,
0179:                    final ComponentMonitor componentMonitor) {
0180:                if (componentFactory == null) {
0181:                    throw new NullPointerException("componentFactory");
0182:                }
0183:                if (lifecycleStrategy == null) {
0184:                    throw new NullPointerException("lifecycleStrategy");
0185:                }
0186:                this .componentFactory = componentFactory;
0187:                this .lifecycleStrategy = lifecycleStrategy;
0188:                this .parent = parent;
0189:                if (parent != null && !(parent instanceof  EmptyPicoContainer)) {
0190:                    this .parent = new ImmutablePicoContainer(parent);
0191:                }
0192:                this .componentMonitor = componentMonitor;
0193:            }
0194:
0195:            /**
0196:             * Creates a new container with the AdaptingInjection using a
0197:             * custom ComponentMonitor
0198:             *
0199:             * @param monitor the ComponentMonitor to use
0200:             * @param parent  the parent container (used for component dependency lookups).
0201:             */
0202:            public DefaultPicoContainer(final ComponentMonitor monitor,
0203:                    final PicoContainer parent) {
0204:                this (new AdaptingBehavior(), new StartableLifecycleStrategy(
0205:                        monitor), parent, monitor);
0206:            }
0207:
0208:            /**
0209:             * Creates a new container with the AdaptingInjection using a
0210:             * custom ComponentMonitor and lifecycle strategy
0211:             *
0212:             * @param monitor           the ComponentMonitor to use
0213:             * @param lifecycleStrategy the lifecycle strategy to use.
0214:             * @param parent            the parent container (used for component dependency lookups).
0215:             */
0216:            public DefaultPicoContainer(final ComponentMonitor monitor,
0217:                    final LifecycleStrategy lifecycleStrategy,
0218:                    final PicoContainer parent) {
0219:                this (new AdaptingBehavior(), lifecycleStrategy, parent, monitor);
0220:            }
0221:
0222:            /**
0223:             * Creates a new container with the AdaptingInjection using a
0224:             * custom lifecycle strategy
0225:             *
0226:             * @param lifecycleStrategy the lifecycle strategy to use.
0227:             * @param parent            the parent container (used for component dependency lookups).
0228:             */
0229:            public DefaultPicoContainer(
0230:                    final LifecycleStrategy lifecycleStrategy,
0231:                    final PicoContainer parent) {
0232:                this (new NullComponentMonitor(), lifecycleStrategy, parent);
0233:            }
0234:
0235:            /**
0236:             * Creates a new container with a custom ComponentFactory and no parent container.
0237:             *
0238:             * @param componentFactory the ComponentFactory to use.
0239:             */
0240:            public DefaultPicoContainer(final ComponentFactory componentFactory) {
0241:                this (componentFactory, null);
0242:            }
0243:
0244:            /**
0245:             * Creates a new container with the AdaptingInjection using a
0246:             * custom ComponentMonitor
0247:             *
0248:             * @param monitor the ComponentMonitor to use
0249:             */
0250:            public DefaultPicoContainer(final ComponentMonitor monitor) {
0251:                this (monitor, new StartableLifecycleStrategy(monitor), null);
0252:            }
0253:
0254:            /**
0255:             * Creates a new container with a (caching) {@link AdaptingInjection}
0256:             * and a parent container.
0257:             *
0258:             * @param parent the parent container (used for component dependency lookups).
0259:             */
0260:            public DefaultPicoContainer(final PicoContainer parent) {
0261:                this (new AdaptingBehavior(), parent);
0262:            }
0263:
0264:            /** Creates a new container with a {@link AdaptingBehavior} and no parent container. */
0265:            public DefaultPicoContainer() {
0266:                this (new AdaptingBehavior(), null);
0267:            }
0268:
0269:            /** {@inheritDoc} **/
0270:            public Collection<ComponentAdapter<?>> getComponentAdapters() {
0271:                return Collections
0272:                        .unmodifiableList(getModifiableComponentAdapterList());
0273:            }
0274:
0275:            /** {@inheritDoc} **/
0276:            public final ComponentAdapter<?> getComponentAdapter(
0277:                    final Object componentKey) {
0278:                ComponentAdapter<?> adapter = getComponentKeyToAdapterCache()
0279:                        .get(componentKey);
0280:                if (adapter == null && parent != null) {
0281:                    adapter = parent.getComponentAdapter(componentKey);
0282:                }
0283:                return adapter;
0284:            }
0285:
0286:            /** {@inheritDoc} **/
0287:            public <T> ComponentAdapter<T> getComponentAdapter(
0288:                    final Class<T> componentType,
0289:                    final NameBinding componentNameBinding) {
0290:                return getComponentAdapter(componentType, componentNameBinding,
0291:                        null);
0292:            }
0293:
0294:            /** {@inheritDoc} **/
0295:            private <T> ComponentAdapter<T> getComponentAdapter(
0296:                    final Class<T> componentType,
0297:                    final NameBinding componentNameBinding,
0298:                    final Class<? extends Annotation> binding) {
0299:                // See http://jira.codehaus.org/secure/ViewIssue.jspa?key=PICO-115
0300:                ComponentAdapter<?> adapterByKey = getComponentAdapter(componentType);
0301:                if (adapterByKey != null) {
0302:                    return typeComponentAdapter(adapterByKey);
0303:                }
0304:
0305:                List<ComponentAdapter<T>> found = binding == null ? getComponentAdapters(componentType)
0306:                        : getComponentAdapters(componentType, binding);
0307:
0308:                if (found.size() == 1) {
0309:                    return found.get(0);
0310:                } else if (found.isEmpty()) {
0311:                    if (parent != null) {
0312:                        return parent.getComponentAdapter(componentType,
0313:                                componentNameBinding);
0314:                    } else {
0315:                        return null;
0316:                    }
0317:                } else {
0318:                    if (componentNameBinding != null) {
0319:                        String parameterName = componentNameBinding.getName();
0320:                        if (parameterName != null) {
0321:                            ComponentAdapter<?> ca = getComponentAdapter(parameterName);
0322:                            if (ca != null
0323:                                    && componentType.isAssignableFrom(ca
0324:                                            .getComponentImplementation())) {
0325:                                return typeComponentAdapter(ca);
0326:                            }
0327:                        }
0328:                    }
0329:                    Class<?>[] foundClasses = new Class[found.size()];
0330:                    for (int i = 0; i < foundClasses.length; i++) {
0331:                        foundClasses[i] = found.get(i)
0332:                                .getComponentImplementation();
0333:                    }
0334:
0335:                    throw new AbstractInjector.AmbiguousComponentResolutionException(
0336:                            componentType, foundClasses);
0337:                }
0338:            }
0339:
0340:            /** {@inheritDoc} **/
0341:            public <T> ComponentAdapter<T> getComponentAdapter(
0342:                    final Class<T> componentType,
0343:                    final Class<? extends Annotation> binding) {
0344:                return getComponentAdapter(componentType, null, binding);
0345:            }
0346:
0347:            /** {@inheritDoc} **/
0348:            public <T> List<ComponentAdapter<T>> getComponentAdapters(
0349:                    final Class<T> componentType) {
0350:                return getComponentAdapters(componentType, null);
0351:            }
0352:
0353:            /** {@inheritDoc} **/
0354:            public <T> List<ComponentAdapter<T>> getComponentAdapters(
0355:                    final Class<T> componentType,
0356:                    final Class<? extends Annotation> binding) {
0357:                if (componentType == null) {
0358:                    return Collections.emptyList();
0359:                }
0360:                List<ComponentAdapter<T>> found = new ArrayList<ComponentAdapter<T>>();
0361:                for (ComponentAdapter<?> componentAdapter : getComponentAdapters()) {
0362:                    Object k = componentAdapter.getComponentKey();
0363:
0364:                    if (componentType.isAssignableFrom(componentAdapter
0365:                            .getComponentImplementation())
0366:                            && (!(k instanceof  BindKey) || (k instanceof  BindKey && (((BindKey<?>) k)
0367:                                    .getAnnotation() == null
0368:                                    || binding == null || ((BindKey<?>) k)
0369:                                    .getAnnotation() == binding)))) {
0370:                        found
0371:                                .add((ComponentAdapter<T>) typeComponentAdapter(componentAdapter));
0372:                    }
0373:                }
0374:                return found;
0375:            }
0376:
0377:            protected MutablePicoContainer addAdapterInternal(
0378:                    final ComponentAdapter<?> componentAdapter) {
0379:                Object componentKey = componentAdapter.getComponentKey();
0380:                if (getComponentKeyToAdapterCache().containsKey(componentKey)) {
0381:                    throw new PicoCompositionException(
0382:                            "Duplicate Keys not allowed. Duplicate for '"
0383:                                    + componentKey + "'");
0384:                }
0385:                getModifiableComponentAdapterList().add(componentAdapter);
0386:                getComponentKeyToAdapterCache().put(componentKey,
0387:                        componentAdapter);
0388:                return this ;
0389:            }
0390:
0391:            /**
0392:             * {@inheritDoc}
0393:             * This method can be used to override the ComponentAdapter created by the {@link ComponentFactory}
0394:             * passed to the constructor of this container.
0395:             */
0396:            public MutablePicoContainer addAdapter(
0397:                    final ComponentAdapter<?> componentAdapter) {
0398:                return addAdapter(componentAdapter, this .componentProperties);
0399:            }
0400:
0401:            /** {@inheritDoc} **/
0402:            public MutablePicoContainer addAdapter(
0403:                    final ComponentAdapter<?> componentAdapter,
0404:                    final Properties properties) {
0405:                Properties tmpProperties = (Properties) properties.clone();
0406:                if (AbstractBehaviorFactory.removePropertiesIfPresent(
0407:                        tmpProperties, Characteristics.NONE) == false
0408:                        && componentFactory instanceof  BehaviorFactory) {
0409:                    MutablePicoContainer container = addAdapterInternal(((BehaviorFactory) componentFactory)
0410:                            .addComponentAdapter(componentMonitor,
0411:                                    lifecycleStrategy, tmpProperties,
0412:                                    componentAdapter));
0413:                    throwIfPropertiesLeft(tmpProperties);
0414:                    return container;
0415:                } else {
0416:                    return addAdapterInternal(componentAdapter);
0417:                }
0418:
0419:            }
0420:
0421:            /** {@inheritDoc} **/
0422:            public <T> ComponentAdapter<T> removeComponent(
0423:                    final Object componentKey) {
0424:                if (lifecycleState == STARTED) {
0425:                    throw new PicoCompositionException(
0426:                            "Cannot remove components after the container has started");
0427:                }
0428:
0429:                if (lifecycleState == DISPOSED) {
0430:                    throw new PicoCompositionException(
0431:                            "Cannot remove components after the container has been disposed");
0432:                }
0433:
0434:                ComponentAdapter<T> adapter = (ComponentAdapter<T>) getComponentKeyToAdapterCache()
0435:                        .remove(componentKey);
0436:                getModifiableComponentAdapterList().remove(adapter);
0437:                getOrderedComponentAdapters().remove(adapter);
0438:                return adapter;
0439:            }
0440:
0441:            /**
0442:             * {@inheritDoc}
0443:             * The returned ComponentAdapter will be an {@link org.picocontainer.adapters.InstanceAdapter}.
0444:             */
0445:            public MutablePicoContainer addComponent(final Object implOrInstance) {
0446:                return addComponent(implOrInstance, this .componentProperties);
0447:            }
0448:
0449:            private MutablePicoContainer addComponent(
0450:                    final Object implOrInstance, final Properties props) {
0451:                Class<?> clazz;
0452:                if (implOrInstance instanceof  String) {
0453:                    return addComponent(implOrInstance, implOrInstance);
0454:                }
0455:                if (implOrInstance instanceof  Class) {
0456:                    clazz = (Class<?>) implOrInstance;
0457:                } else {
0458:                    clazz = implOrInstance.getClass();
0459:                }
0460:                return addComponent(clazz, implOrInstance, props);
0461:            }
0462:
0463:            public MutablePicoContainer addConfig(final String name,
0464:                    final Object val) {
0465:                return addAdapterInternal(new InstanceAdapter<Object>(name,
0466:                        val, lifecycleStrategy, componentMonitor));
0467:            }
0468:
0469:            /**
0470:             * {@inheritDoc}
0471:             * The returned ComponentAdapter will be instantiated by the {@link ComponentFactory}
0472:             * passed to the container's constructor.
0473:             */
0474:            public MutablePicoContainer addComponent(final Object componentKey,
0475:                    final Object componentImplementationOrInstance,
0476:                    final Parameter... parameters) {
0477:                return this .addComponent(componentKey,
0478:                        componentImplementationOrInstance,
0479:                        this .componentProperties, parameters);
0480:            }
0481:
0482:            private MutablePicoContainer addComponent(
0483:                    final Object componentKey,
0484:                    final Object componentImplementationOrInstance,
0485:                    final Properties properties, Parameter... parameters) {
0486:                if (parameters != null && parameters.length == 0
0487:                        && parameters != Parameter.ZERO) {
0488:                    parameters = null; // backwards compatibility!  solve this better later - Paul
0489:                }
0490:                if (componentImplementationOrInstance instanceof  Class) {
0491:                    Properties tmpProperties = (Properties) properties.clone();
0492:                    ComponentAdapter<?> componentAdapter = componentFactory
0493:                            .createComponentAdapter(
0494:                                    componentMonitor,
0495:                                    lifecycleStrategy,
0496:                                    tmpProperties,
0497:                                    componentKey,
0498:                                    (Class<?>) componentImplementationOrInstance,
0499:                                    parameters);
0500:                    throwIfPropertiesLeft(tmpProperties);
0501:                    return addAdapterInternal(componentAdapter);
0502:                } else {
0503:                    ComponentAdapter<?> componentAdapter = new InstanceAdapter<Object>(
0504:                            componentKey, componentImplementationOrInstance,
0505:                            lifecycleStrategy, componentMonitor);
0506:                    return addAdapter(componentAdapter, properties);
0507:                }
0508:            }
0509:
0510:            private void throwIfPropertiesLeft(final Properties tmpProperties) {
0511:                if (tmpProperties.size() > 0) {
0512:                    throw new PicoCompositionException(
0513:                            "Unprocessed Characteristics:"
0514:                                    + tmpProperties
0515:                                    + ", refer http://picocontainer.org/unprocessed-properties-help.html");
0516:                }
0517:            }
0518:
0519:            private void addOrderedComponentAdapter(
0520:                    final ComponentAdapter<?> componentAdapter) {
0521:                if (!getOrderedComponentAdapters().contains(componentAdapter)) {
0522:                    getOrderedComponentAdapters().add(componentAdapter);
0523:                }
0524:            }
0525:
0526:            public List<Object> getComponents() throws PicoException {
0527:                return getComponents(Object.class);
0528:            }
0529:
0530:            public <T> List<T> getComponents(final Class<T> componentType) {
0531:                if (componentType == null) {
0532:                    return Collections.emptyList();
0533:                }
0534:
0535:                Map<ComponentAdapter<T>, T> adapterToInstanceMap = new HashMap<ComponentAdapter<T>, T>();
0536:                for (ComponentAdapter<?> componentAdapter : getModifiableComponentAdapterList()) {
0537:                    if (componentType.isAssignableFrom(componentAdapter
0538:                            .getComponentImplementation())) {
0539:                        ComponentAdapter<T> typedComponentAdapter = typeComponentAdapter(componentAdapter);
0540:                        T componentInstance = getLocalInstance(typedComponentAdapter);
0541:
0542:                        adapterToInstanceMap.put(typedComponentAdapter,
0543:                                componentInstance);
0544:                    }
0545:                }
0546:                List<T> result = new ArrayList<T>();
0547:                for (ComponentAdapter<?> componentAdapter : getOrderedComponentAdapters()) {
0548:                    final T componentInstance = adapterToInstanceMap
0549:                            .get(componentAdapter);
0550:                    if (componentInstance != null) {
0551:                        // may be null in the case of the "implicit" addAdapter
0552:                        // representing "this".
0553:                        result.add(componentInstance);
0554:                    }
0555:                }
0556:                return result;
0557:            }
0558:
0559:            private <T> T getLocalInstance(
0560:                    final ComponentAdapter<T> typedComponentAdapter) {
0561:                T componentInstance = typedComponentAdapter
0562:                        .getComponentInstance(this );
0563:
0564:                // This is to ensure all are added. (Indirect dependencies will be added
0565:                // from InstantiatingComponentAdapter).
0566:                addOrderedComponentAdapter(typedComponentAdapter);
0567:
0568:                return componentInstance;
0569:            }
0570:
0571:            @SuppressWarnings({"unchecked"})
0572:            private static <T> ComponentAdapter<T> typeComponentAdapter(
0573:                    final ComponentAdapter<?> componentAdapter) {
0574:                return (ComponentAdapter<T>) componentAdapter;
0575:            }
0576:
0577:            public Object getComponent(final Object componentKeyOrType) {
0578:                return getComponent(componentKeyOrType, null);
0579:            }
0580:
0581:            public Object getComponent(final Object componentKeyOrType,
0582:                    final Class<? extends Annotation> annotation) {
0583:                Object retVal;
0584:                if (annotation != null) {
0585:                    final ComponentAdapter<?> componentAdapter = getComponentAdapter(
0586:                            (Class<?>) componentKeyOrType, annotation);
0587:                    retVal = componentAdapter == null ? null
0588:                            : getInstance(componentAdapter);
0589:                } else if (componentKeyOrType instanceof  Class) {
0590:                    final ComponentAdapter<?> componentAdapter = getComponentAdapter(
0591:                            (Class<?>) componentKeyOrType, (NameBinding) null);
0592:                    retVal = componentAdapter == null ? null
0593:                            : getInstance(componentAdapter);
0594:                } else {
0595:                    ComponentAdapter<?> componentAdapter = getComponentAdapter(componentKeyOrType);
0596:                    retVal = componentAdapter == null ? null
0597:                            : getInstance(componentAdapter);
0598:                }
0599:                if (retVal == null) {
0600:                    retVal = componentMonitor.noComponentFound(this ,
0601:                            componentKeyOrType);
0602:                }
0603:                return retVal;
0604:            }
0605:
0606:            public <T> T getComponent(final Class<T> componentType) {
0607:                Object o = getComponent((Object) componentType, null);
0608:                return componentType.cast(o);
0609:            }
0610:
0611:            public <T> T getComponent(final Class<T> componentType,
0612:                    final Class<? extends Annotation> binding) {
0613:                Object o = getComponent((Object) componentType, binding);
0614:                return componentType.cast(o);
0615:            }
0616:
0617:            private Object getInstance(
0618:                    final ComponentAdapter<?> componentAdapter) {
0619:                // check whether this is our adapter
0620:                // we need to check this to ensure up-down dependencies cannot be followed
0621:                final boolean isLocal = getModifiableComponentAdapterList()
0622:                        .contains(componentAdapter);
0623:
0624:                if (isLocal) {
0625:                    Object instance;
0626:                    try {
0627:                        instance = componentAdapter.getComponentInstance(this );
0628:                    } catch (AbstractInjector.CyclicDependencyException e) {
0629:                        if (parent != null) {
0630:                            instance = parent.getComponent(componentAdapter
0631:                                    .getComponentKey());
0632:                            if (instance != null) {
0633:                                return instance;
0634:                            }
0635:                        }
0636:                        throw e;
0637:                    }
0638:                    addOrderedComponentAdapter(componentAdapter);
0639:
0640:                    return instance;
0641:                } else if (parent != null) {
0642:                    return parent.getComponent(componentAdapter
0643:                            .getComponentKey());
0644:                }
0645:
0646:                return null;
0647:            }
0648:
0649:            /** {@inheritDoc} **/
0650:            public PicoContainer getParent() {
0651:                return parent;
0652:            }
0653:
0654:            /** {@inheritDoc} **/
0655:            public <T> ComponentAdapter<T> removeComponentByInstance(
0656:                    final T componentInstance) {
0657:                for (ComponentAdapter<?> componentAdapter : getModifiableComponentAdapterList()) {
0658:                    if (getLocalInstance(componentAdapter).equals(
0659:                            componentInstance)) {
0660:                        return removeComponent(componentAdapter
0661:                                .getComponentKey());
0662:                    }
0663:                }
0664:                return null;
0665:            }
0666:
0667:            /**
0668:             * Start the components of this PicoContainer and all its logical child containers.
0669:             * The starting of the child container is only attempted if the parent
0670:             * container start successfully.  The child container for which start is attempted
0671:             * is tracked so that upon stop, only those need to be stopped.
0672:             * The lifecycle operation is delegated to the component adapter,
0673:             * if it is an instance of {@link Behavior lifecycle manager}.
0674:             * The actual {@link LifecycleStrategy lifecycle strategy} supported
0675:             * depends on the concrete implementation of the adapter.
0676:             *
0677:             * @see Behavior
0678:             * @see LifecycleStrategy
0679:             * @see #makeChildContainer()
0680:             * @see #addChildContainer(PicoContainer)
0681:             * @see #removeChildContainer(PicoContainer)
0682:             */
0683:            public void start() {
0684:
0685:                if (!lifecycleState.isStartAllowed()) {
0686:                    throw new IllegalStateException(
0687:                            "Cannot start.  Current container state was: "
0688:                                    + lifecycleState);
0689:                }
0690:
0691:                lifecycleState = STARTED;
0692:
0693:                startAdapters();
0694:                childrenStarted.clear();
0695:                for (PicoContainer child : children) {
0696:                    childrenStarted
0697:                            .add(new WeakReference<PicoContainer>(child));
0698:                    if (child instanceof  Startable) {
0699:                        ((Startable) child).start();
0700:                    }
0701:                }
0702:            }
0703:
0704:            /**
0705:             * Stop the components of this PicoContainer and all its logical child containers.
0706:             * The stopping of the child containers is only attempted for those that have been
0707:             * started, possibly not successfully.
0708:             * The lifecycle operation is delegated to the component adapter,
0709:             * if it is an instance of {@link Behavior lifecycle manager}.
0710:             * The actual {@link LifecycleStrategy lifecycle strategy} supported
0711:             * depends on the concrete implementation of the adapter.
0712:             *
0713:             * @see Behavior
0714:             * @see LifecycleStrategy
0715:             * @see #makeChildContainer()
0716:             * @see #addChildContainer(PicoContainer)
0717:             * @see #removeChildContainer(PicoContainer)
0718:             */
0719:            public void stop() {
0720:                if (!lifecycleState.isStopAllowed()) {
0721:                    throw new IllegalStateException(
0722:                            "Cannot stop.  Current container state was: "
0723:                                    + lifecycleState);
0724:                }
0725:
0726:                for (PicoContainer child : children) {
0727:                    if (childStarted(child)) {
0728:                        if (child instanceof  Startable) {
0729:                            ((Startable) child).stop();
0730:                        }
0731:                    }
0732:                }
0733:                stopAdapters();
0734:                lifecycleState = STOPPED;
0735:            }
0736:
0737:            /**
0738:             * Checks the status of the child container to see if it's been started
0739:             * to prevent IllegalStateException upon stop
0740:             *
0741:             * @param child the child PicoContainer
0742:             *
0743:             * @return A boolean, <code>true</code> if the container is started
0744:             */
0745:            private boolean childStarted(final PicoContainer child) {
0746:                for (WeakReference<PicoContainer> eachChild : childrenStarted) {
0747:                    PicoContainer ref = eachChild.get();
0748:                    if (ref == null) {
0749:                        continue;
0750:                    }
0751:
0752:                    if (child.equals(ref)) {
0753:                        return true;
0754:                    }
0755:                }
0756:                return false;
0757:            }
0758:
0759:            /**
0760:             * Dispose the components of this PicoContainer and all its logical child containers.
0761:             * The lifecycle operation is delegated to the component adapter,
0762:             * if it is an instance of {@link Behavior lifecycle manager}.
0763:             * The actual {@link LifecycleStrategy lifecycle strategy} supported
0764:             * depends on the concrete implementation of the adapter.
0765:             *
0766:             * @see Behavior
0767:             * @see LifecycleStrategy
0768:             * @see #makeChildContainer()
0769:             * @see #addChildContainer(PicoContainer)
0770:             * @see #removeChildContainer(PicoContainer)
0771:             */
0772:            public void dispose() {
0773:                if (lifecycleState.isStarted()) {
0774:                    stop();
0775:                }
0776:
0777:                if (!lifecycleState.isDisposedAllowed()) {
0778:                    throw new IllegalStateException(
0779:                            "Cannot dispose.  Current lifecycle state is: "
0780:                                    + lifecycleState);
0781:                }
0782:
0783:                for (PicoContainer child : children) {
0784:                    if (child instanceof  MutablePicoContainer) {
0785:                        ((Disposable) child).dispose();
0786:                    }
0787:                }
0788:                disposeAdapters();
0789:                lifecycleState = DISPOSED;
0790:            }
0791:
0792:            public MutablePicoContainer makeChildContainer() {
0793:                DefaultPicoContainer pc = new DefaultPicoContainer(
0794:                        componentFactory, lifecycleStrategy, this );
0795:                addChildContainer(pc);
0796:                return pc;
0797:            }
0798:
0799:            /**
0800:             * Checks for identical references in the child container.  It doesn't
0801:             * traverse an entire hierarchy, namely it simply checks for child containers
0802:             * that are equal to the current container.
0803:             * @param child
0804:             */
0805:            private void checkCircularChildDependencies(PicoContainer child) {
0806:                final String MESSAGE = "Cannot have circular dependency between parent "
0807:                        + this  + " and child: " + child;
0808:                if (child == this ) {
0809:                    throw new IllegalArgumentException(MESSAGE);
0810:                }
0811:
0812:                //Todo: Circular Import Dependency on AbstractDelegatingPicoContainer
0813:                if (child instanceof  AbstractDelegatingPicoContainer) {
0814:                    AbstractDelegatingPicoContainer delegateChild = (AbstractDelegatingPicoContainer) child;
0815:                    while (delegateChild != null) {
0816:                        PicoContainer delegateInstance = delegateChild
0817:                                .getDelegate();
0818:                        if (this  == delegateInstance) {
0819:                            throw new IllegalArgumentException(MESSAGE);
0820:                        }
0821:                        if (delegateInstance instanceof  AbstractDelegatingPicoContainer) {
0822:                            delegateChild = (AbstractDelegatingPicoContainer) delegateInstance;
0823:                        } else {
0824:                            delegateChild = null;
0825:                        }
0826:
0827:                    }
0828:                }
0829:
0830:            }
0831:
0832:            public MutablePicoContainer addChildContainer(
0833:                    final PicoContainer child) {
0834:                checkCircularChildDependencies(child);
0835:                if (children.add(child)) {
0836:                    // @todo Should only be added if child container has also be started
0837:                    if (lifecycleState == STARTED) {
0838:                        childrenStarted.add(new WeakReference<PicoContainer>(
0839:                                child));
0840:                    }
0841:                }
0842:                return this ;
0843:            }
0844:
0845:            public boolean removeChildContainer(final PicoContainer child) {
0846:                final boolean result = children.remove(child);
0847:                WeakReference<PicoContainer> foundRef = null;
0848:                for (WeakReference<PicoContainer> eachChild : childrenStarted) {
0849:                    PicoContainer ref = eachChild.get();
0850:                    if (ref.equals(child)) {
0851:                        foundRef = eachChild;
0852:                        break;
0853:                    }
0854:                }
0855:
0856:                if (foundRef != null) {
0857:                    childrenStarted.remove(foundRef);
0858:                }
0859:
0860:                return result;
0861:            }
0862:
0863:            public MutablePicoContainer change(final Properties... properties) {
0864:                for (Properties c : properties) {
0865:                    Enumeration<String> e = (Enumeration<String>) c
0866:                            .propertyNames();
0867:                    while (e.hasMoreElements()) {
0868:                        String s = e.nextElement();
0869:                        componentProperties.setProperty(s, c.getProperty(s));
0870:                    }
0871:                }
0872:                return this ;
0873:            }
0874:
0875:            public MutablePicoContainer as(final Properties... properties) {
0876:                return new AsPropertiesPicoContainer(properties);
0877:            }
0878:
0879:            public void accept(final PicoVisitor visitor) {
0880:                visitor.visitContainer(this );
0881:                final List<ComponentAdapter<?>> componentAdapters = new ArrayList<ComponentAdapter<?>>(
0882:                        getComponentAdapters());
0883:                for (ComponentAdapter<?> componentAdapter : componentAdapters) {
0884:                    componentAdapter.accept(visitor);
0885:                }
0886:                final List<PicoContainer> allChildren = new ArrayList<PicoContainer>(
0887:                        children);
0888:                for (PicoContainer child : allChildren) {
0889:                    child.accept(visitor);
0890:                }
0891:            }
0892:
0893:            /**
0894:             * Changes monitor in the ComponentFactory, the component adapters
0895:             * and the child containers, if these support a ComponentMonitorStrategy.
0896:             * {@inheritDoc}
0897:             */
0898:            public void changeMonitor(final ComponentMonitor monitor) {
0899:                this .componentMonitor = monitor;
0900:                if (lifecycleStrategy instanceof  ComponentMonitorStrategy) {
0901:                    ((ComponentMonitorStrategy) lifecycleStrategy)
0902:                            .changeMonitor(monitor);
0903:                }
0904:                for (ComponentAdapter<?> adapter : getModifiableComponentAdapterList()) {
0905:                    if (adapter instanceof  ComponentMonitorStrategy) {
0906:                        ((ComponentMonitorStrategy) adapter)
0907:                                .changeMonitor(monitor);
0908:                    }
0909:                }
0910:                for (PicoContainer child : children) {
0911:                    if (child instanceof  ComponentMonitorStrategy) {
0912:                        ((ComponentMonitorStrategy) child)
0913:                                .changeMonitor(monitor);
0914:                    }
0915:                }
0916:            }
0917:
0918:            /**
0919:             * Returns the first current monitor found in the ComponentFactory, the component adapters
0920:             * and the child containers, if these support a ComponentMonitorStrategy.
0921:             * {@inheritDoc}
0922:             *
0923:             * @throws PicoCompositionException if no component monitor is found in container or its children
0924:             */
0925:            public ComponentMonitor currentMonitor() {
0926:                return componentMonitor;
0927:            }
0928:
0929:            /**
0930:             * {@inheritDoc}
0931:             * Loops over all component adapters and invokes
0932:             * start(PicoContainer) method on the ones which are LifecycleManagers
0933:             */
0934:            private void startAdapters() {
0935:                Collection<ComponentAdapter<?>> adapters = getComponentAdapters();
0936:                for (ComponentAdapter<?> adapter : adapters) {
0937:                    if (adapter instanceof  Behavior) {
0938:                        Behavior<?> behaviorAdapter = (Behavior<?>) adapter;
0939:                        if (behaviorAdapter.componentHasLifecycle()) {
0940:                            // create an instance, it will be added to the ordered CA list
0941:                            adapter
0942:                                    .getComponentInstance(DefaultPicoContainer.this );
0943:                            addOrderedComponentAdapter(adapter);
0944:                        }
0945:                    }
0946:                }
0947:                adapters = getOrderedComponentAdapters();
0948:                // clear list of started CAs
0949:                startedComponentAdapters.clear();
0950:                // clone the adapters
0951:                List<ComponentAdapter<?>> adaptersClone = new ArrayList<ComponentAdapter<?>>(
0952:                        adapters);
0953:                for (final ComponentAdapter<?> adapter : adaptersClone) {
0954:                    if (adapter instanceof  Behavior) {
0955:                        Behavior<?> manager = (Behavior<?>) adapter;
0956:                        manager.start(DefaultPicoContainer.this );
0957:                        startedComponentAdapters
0958:                                .add(new WeakReference<ComponentAdapter<?>>(
0959:                                        adapter));
0960:                    }
0961:                }
0962:            }
0963:
0964:            /**
0965:             * {@inheritDoc}
0966:             * Loops over started component adapters (in inverse order) and invokes
0967:             * stop(PicoContainer) method on the ones which are LifecycleManagers
0968:             */
0969:            private void stopAdapters() {
0970:                for (int i = startedComponentAdapters.size() - 1; 0 <= i; i--) {
0971:                    ComponentAdapter<?> adapter = startedComponentAdapters.get(
0972:                            i).get();
0973:                    if (adapter == null) {
0974:                        //Weak reference -- may be null
0975:                        continue;
0976:                    }
0977:                    if (adapter instanceof  Behavior) {
0978:                        Behavior<?> manager = (Behavior<?>) adapter;
0979:                        manager.stop(DefaultPicoContainer.this );
0980:                    }
0981:                }
0982:            }
0983:
0984:            /**
0985:             * {@inheritDoc}
0986:             * Loops over all component adapters (in inverse order) and invokes
0987:             * dispose(PicoContainer) method on the ones which are LifecycleManagers
0988:             */
0989:            private void disposeAdapters() {
0990:                for (int i = getOrderedComponentAdapters().size() - 1; 0 <= i; i--) {
0991:                    ComponentAdapter<?> adapter = getOrderedComponentAdapters()
0992:                            .get(i);
0993:                    if (adapter instanceof  Behavior) {
0994:                        Behavior<?> manager = (Behavior<?>) adapter;
0995:                        manager.dispose(DefaultPicoContainer.this );
0996:                    }
0997:                }
0998:            }
0999:
1000:            /**
1001:             * @return the orderedComponentAdapters
1002:             */
1003:            protected List<ComponentAdapter<?>> getOrderedComponentAdapters() {
1004:                return orderedComponentAdapters;
1005:            }
1006:
1007:            /**
1008:             * @return the componentKeyToAdapterCache
1009:             */
1010:            protected Map<Object, ComponentAdapter<?>> getComponentKeyToAdapterCache() {
1011:                return componentKeyToAdapterCache;
1012:            }
1013:
1014:            /**
1015:             * @return the componentAdapters
1016:             */
1017:            protected List<ComponentAdapter<?>> getModifiableComponentAdapterList() {
1018:                return componentAdapters;
1019:            }
1020:
1021:            private class AsPropertiesPicoContainer extends
1022:                    AbstractDelegatingMutablePicoContainer {
1023:                /**
1024:                 * Serialization UUID.
1025:                 */
1026:                private static final long serialVersionUID = -4846748925372564136L;
1027:
1028:                private final Properties properties;
1029:
1030:                public AsPropertiesPicoContainer(final Properties... props) {
1031:                    super (DefaultPicoContainer.this );
1032:                    properties = (Properties) componentProperties.clone();
1033:                    for (Properties c : props) {
1034:                        Enumeration<?> e = c.propertyNames();
1035:                        while (e.hasMoreElements()) {
1036:                            String s = (String) e.nextElement();
1037:                            properties.setProperty(s, c.getProperty(s));
1038:                        }
1039:                    }
1040:                }
1041:
1042:                @Override
1043:                public MutablePicoContainer makeChildContainer() {
1044:                    return getDelegate().makeChildContainer();
1045:                }
1046:
1047:                @Override
1048:                public MutablePicoContainer addComponent(
1049:                        final Object componentKey,
1050:                        final Object componentImplementationOrInstance,
1051:                        final Parameter... parameters)
1052:                        throws PicoCompositionException {
1053:                    return DefaultPicoContainer.this .addComponent(componentKey,
1054:                            componentImplementationOrInstance, properties,
1055:                            parameters);
1056:                }
1057:
1058:                @Override
1059:                public MutablePicoContainer addComponent(
1060:                        final Object implOrInstance)
1061:                        throws PicoCompositionException {
1062:                    return DefaultPicoContainer.this .addComponent(
1063:                            implOrInstance, properties);
1064:                }
1065:
1066:                @Override
1067:                public MutablePicoContainer addAdapter(
1068:                        final ComponentAdapter<?> componentAdapter)
1069:                        throws PicoCompositionException {
1070:                    return DefaultPicoContainer.this.addAdapter(
1071:                            componentAdapter, properties);
1072:                }
1073:            }
1074:
1075:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.