001/*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved.            *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD      *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file.                                                     *
007 *                                                                           *
008 * Original code by                                                          *
009 *****************************************************************************/
010package org.picocontainer;
011
012import java.util.Collection;
013import java.util.List;
014import java.lang.annotation.Annotation;
015import java.lang.reflect.Type;
016
017/**
018 * This is the core interface for PicoContainer. It is used to retrieve component instances from the container; it only
019 * has accessor methods (in addition to the {@link #accept(PicoVisitor)} method). In order to register components in a
020 * PicoContainer, use a {@link MutablePicoContainer}, such as {@link DefaultPicoContainer}.
021 *
022 * @author Paul Hammant
023 * @author Aslak Hellesøy
024 * @author Jon Tirsén
025 * @see <a href="package-summary.html#package_description">See package description for basic overview how to use
026 *      PicoContainer.</a>
027 */
028public interface PicoContainer {
029
030    /**
031     * Retrieve a component instance registered with a specific key or type. If a component cannot be found in this container,
032     * the parent container (if one exists) will be searched.
033     *
034     * @param componentKeyOrType the key or Type that the component was registered with.
035     * @return an instantiated component, or <code>null</code> if no component has been registered for the specified
036     *         key.
037     */
038    Object getComponent(Object componentKeyOrType);
039
040    Object getComponent(Object componentKeyOrType, Type into);
041
042    /**
043     * Retrieve a component keyed by the component type.
044     * @param componentType the type of the component
045     * @return the typed resulting object instance or null if the object does not exist.
046     */
047    <T> T getComponent(Class<T> componentType);
048
049    /**
050     * Retrieve a component keyed by the component type and binding type.
051     * @param componentType the type of the component
052     * @param binding the binding type of the component
053     * @return the typed resulting object instance or null if the object does not exist.
054     */
055    <T> T getComponent(Class<T> componentType, Class<? extends Annotation> binding);
056
057    /**
058     * Retrieve all the registered component instances in the container, (not including those in the parent container).
059     * The components are returned in their order of instantiation, which depends on the dependency order between them.
060     *
061     * @return all the components.
062     * @throws PicoException if the instantiation of the component fails
063     */
064    List<Object> getComponents();
065
066    /**
067     * Retrieve the parent container of this container.
068     *
069     * @return a {@link PicoContainer} instance, or <code>null</code> if this container does not have a parent.
070     */
071    PicoContainer getParent();
072
073    /**
074     * Find a component adapter associated with the specified key. If a component adapter cannot be found in this
075     * container, the parent container (if one exists) will be searched.
076     *
077     * @param componentKey the key that the component was registered with.
078     * @return the component adapter associated with this key, or <code>null</code> if no component has been
079     *         registered for the specified key.
080     */
081    ComponentAdapter<?> getComponentAdapter(Object componentKey);
082
083    /**
084     * Find a component adapter associated with the specified type and binding name. If a component adapter cannot be found in this
085     * container, the parent container (if one exists) will be searched.
086     *
087     * @param componentType the type of the component.
088     * @return the component adapter associated with this class, or <code>null</code> if no component has been
089     *         registered for the specified key.
090     * @param componentNameBinding the name binding to use
091     */
092    <T> ComponentAdapter<T> getComponentAdapter(Class<T> componentType, NameBinding componentNameBinding);
093
094    /**
095     * Find a component adapter associated with the specified type and binding type. If a component adapter cannot be found in this
096     * container, the parent container (if one exists) will be searched.
097     *
098     * @param componentType the type of the component.
099     * @return the component adapter associated with this class, or <code>null</code> if no component has been
100     *         registered for the specified key.
101     * @param binding the typed binding to use
102     */
103    <T> ComponentAdapter<T> getComponentAdapter(Class<T> componentType, Class<? extends Annotation> binding);
104
105    /**
106     * Retrieve all the component adapters inside this container. The component adapters from the parent container are
107     * not returned.
108     *
109     * @return a collection containing all the {@link ComponentAdapter}s inside this container. The collection will not
110     *         be modifiable.
111     * @see #getComponentAdapters(Class) a variant of this method which returns the component adapters inside this
112     *      container that are associated with the specified type.
113     */
114    Collection<ComponentAdapter<?>> getComponentAdapters();
115
116    /**
117     * Retrieve all component adapters inside this container that are associated with the specified type. The addComponent
118     * adapters from the parent container are not returned.
119     *
120     * @param componentType the type of the components.
121     * @return a collection containing all the {@link ComponentAdapter}s inside this container that are associated with
122     *         the specified type. Changes to this collection will not be reflected in the container itself.
123     */
124    <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType);
125
126    /**
127     * Retrieve all component adapters inside this container that are associated with the specified type and binding type. The addComponent
128     * adapters from the parent container are not returned.
129     *
130     * @param componentType the type of the components.
131     * @param binding the typed binding to use
132     * @return a collection containing all the {@link ComponentAdapter}s inside this container that are associated with
133     *         the specified type. Changes to this collection will not be reflected in the container itself.
134     */
135    <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, Class<? extends Annotation> binding);
136
137    /**
138     * Returns a List of components of a certain componentType. The list is ordered by instantiation order, starting
139     * with the components instantiated first at the beginning.
140     *
141     * @param componentType the searched type.
142     * @return a List of components.
143     * @throws PicoException if the instantiation of a component fails
144     */
145    <T> List<T> getComponents(Class<T> componentType);
146
147    /**
148     * Accepts a visitor that should visit the child containers, component adapters and component instances.
149     *
150     * @param visitor the visitor
151     */
152    void accept(PicoVisitor visitor);
153
154}