/* * Copyright (C) 2013 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.container.spi; import org.exoplatform.container.xml.InitParams; import org.exoplatform.management.ManagementContext; import org.picocontainer.Disposable; import org.picocontainer.Startable; import java.io.Serializable; import java.util.Collection; import java.util.List; import javax.management.MBeanServer; import javax.management.ObjectName; /** * This interface defines all the methods that we need to implement in order to allow eXo Kernel * to delegate the whole life cycle of the components. An implementation needs to be able to: * <ul> * <li>Register a new component</li> * <li>Manage the creation of the components</li> * <li>Manage the initialization of the components</li> * <li>Manage the startup of the components</li> * <li>Manage the shutdown of the components</li> * <li>Manage the destruction of the components</li> * <li>Provide the components matching with some specific criteria</li> * </ul> * * @author <a href="mailto:nfilotto@exoplatform.com">Nicolas Filotto</a> * @version $Id$ * */ public interface Container extends Startable, Disposable, Serializable { /** * Retrieve a component instance registered with a specific key. If a component cannot be found in this container, * the parent container (if one exists) will be searched. * * @param componentKey the key that the component was registered with. * @param bindType the expected type of the instance if one can be found. * @param autoRegistration indicates whether the auto registration should be performed or not * @return an instantiated component, or <code>null</code> if no component has been registered for the specified * key. */ <T> T getComponentInstance(Object componentKey, Class<T> bindType, boolean autoRegistration); /** * Find a component instance matching the specified type. * * @param componentType the type of the component. * @param autoRegistration indicates whether the auto registration should be performed or not * @return the adapter matching the class. */ <T> T getComponentInstanceOfType(Class<T> componentType, boolean autoRegistration); /** * Retrieve the successor of this container in the chain of {@link Interceptor}. * * @return a {@link Interceptor} instance, or <code>null</code> if this container does not have a successor. */ Interceptor getSuccessor(); /** * Find a component adapter associated with the specified key. If a component adapter cannot be found in this * container, the parent container (if one exists) will be searched. * * @param componentKey the key that the component was registered with. * @param bindType the expected raw type of the adapter if one can be found. * @param autoRegistration indicates whether the auto registration should be performed or not * @return the component adapter associated with this key, or <code>null</code> if no component has been registered * for the specified key. */ <T> ComponentAdapter<T> getComponentAdapter(Object componentKey, Class<T> bindType, boolean autoRegistration); /** * Find a component adapter associated with the specified type. If a component adapter cannot be found in this * container, the parent container (if one exists) will be searched. * * @param componentType the type of the component. * @param autoRegistration indicates whether the auto registration should be performed or not * @return the component adapter associated with this class, or <code>null</code> if no component has been * registered for the specified key. */ <T> ComponentAdapter<T> getComponentAdapterOfType(Class<T> componentType, boolean autoRegistration); /** * Retrieve all the component adapters inside this container. The component adapters from the parent container are * not returned. * * @return a collection containing all the {@link ComponentAdapter}s inside this container. The collection will * not be modifiable. * @see #getComponentAdaptersOfType(Class) a variant of this method which returns the component adapters inside this * container that are associated with the specified type. */ Collection<ComponentAdapter<?>> getComponentAdapters(); /** * Retrieve all component adapters inside this container that are associated with the specified type. The component * adapters from the parent container are not returned. * * @param componentType the type of the components. * @return a collection containing all the {@link ComponentAdapter}s inside this container that are associated with * the specified type. Changes to this collection will not be reflected in the container itself. */ <T> List<ComponentAdapter<T>> getComponentAdaptersOfType(Class<T> componentType); /** * Returns a List of components of a certain componentType. The list is ordered by instantiation order, * starting with the components instantiated first at the beginning. * @param componentType the searched type. * @return a List of components. */ <T> List<T> getComponentInstancesOfType(Class<T> componentType) throws ContainerException; /** * Accepts a visitor that should visit the child containers, component adapters and component instances. * @param visitor the visitor */ void accept(ContainerVisitor visitor); /** * Register a component. * * @param componentKey a key that identifies the component. Must be unique within the container. The type * of the key object has no semantic significance unless explicitly specified in the * documentation of the implementing container. * @param componentImplementation the component's implementation class. This must be a concrete class (ie, a * class that can be instantiated). * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return * value can be safely ignored, as one of the <code>getXXX()</code> methods of the * {@link Container} interface can be used to retrieve a reference to the component later on. * @throws ContainerException if registration of the component fails. */ <T> ComponentAdapter<T> registerComponentImplementation(Object componentKey, Class<T> componentImplementation) throws ContainerException; /** * Register an arbitrary object as a component in the container. This is handy when other components in the same * container have dependencies on this kind of object, but where letting the container manage and instantiate it is * impossible. * <br> * Beware that too much use of this method is an <a href="http://docs.codehaus.org/display/PICO/Instance+Registration">antipattern</a>. * * @param componentKey a key that identifies the component. Must be unique within the container. The type of the * key object has no semantic significance unless explicitly specified in the implementing * container. * @param componentInstance an arbitrary object. * @return the ComponentAdapter that has been associated with this component. In the majority of cases, this return * value can be safely ignored, as one of the <code>getXXX()</code> methods of the * {@link Container} interface can be used to retrieve a reference to the component later on. * @throws ContainerException if registration fails. */ <T> ComponentAdapter<T> registerComponentInstance(Object componentKey, T componentInstance) throws ContainerException; /** * Unregister a component by key. * * @param componentKey key of the component to unregister. * @return the ComponentAdapter that was associated with this component. */ ComponentAdapter<?> unregisterComponent(Object componentKey); /** * Gives the corresponding {@link ManagementContext} */ ManagementContext getManagementContext(); /** * Provides the {@link MBeanServer} this method is needed for backward compatibility */ MBeanServer getMBeanServer(); /** * Gives the ObjectName of the container build from the scoping data */ ObjectName getScopingObjectName(); /** * Creates a component corresponding to the given {@link Class} with the * given {@link InitParams} * @param clazz the Class of the object to create * @param params the parameters to use to create the component * @return an instance of the component * @throws Exception if any issue occurs while creating the component. */ <T> T createComponent(Class<T> clazz, InitParams params) throws Exception; /** * Initializes the container */ void initialize(); }