org.apache.felix.ipojo

## Class InstanceManager

- java.lang.Object
- - org.apache.felix.ipojo.InstanceManager

All Implemented Interfaces:
  ComponentInstance, InstanceBundleContextAware, InstanceStateListener

Direct Known Subclasses:
  HandlerManager

    public class InstanceManager
    extends java.lang.Object
    implements ComponentInstance, InstanceStateListener, InstanceBundleContextAware

This class defines the container of primitive instances. It manages content initialization and handlers cooperation.

Author:
  Felix Project Team

### Field Summary

Fields
`protected java.lang.String` `m_className` The name of the component type implementation class.
`protected HandlerManager[]` `m_handlers` The handler object list.
`protected java.util.List` `m_listeners` The instance state listener list.
`protected java.lang.String` `m_name` The name of the component instance.
`protected java.util.List` `m_pojoObjects` The content of the current instance.
`protected int` `m_state` The current instance state (`ComponentInstance.STOPPED` at the beginning).

### Fields inherited from interface org.apache.felix.ipojo.ComponentInstance

`DISPOSED, INVALID, STOPPED, VALID`

### Constructor Summary

Constructors
Constructor and Description
`InstanceManager(ComponentFactory factory, org.osgi.framework.BundleContext context, HandlerManager[] handlers)` Creates a new Component Manager.

### Method Summary

All Methods Instance Methods Concrete Methods Deprecated Methods
`void` `addInstanceStateListener(InstanceStateListener listener)` Registers an instance state listener.
`void` `configure(org.apache.felix.ipojo.metadata.Element metadata, java.util.Dictionary configuration)` Configures the instance manager.
`protected java.lang.Object` `createObject()` Creates a POJO objects.
`java.lang.Object` `createPojoObject()` Creates an instance of the content.
`void` `deletePojoObject(java.lang.Object pojo)` Deletes a POJO object.
`void` `dispose()` Disposes the instance.
`java.lang.String` `getClassName()` Gets the implementation class of the component type.
`java.lang.Class` `getClazz()` Gets the manipulated class.
`org.osgi.framework.BundleContext` `getContext()` Gets the bundle context used by this component instance.
`ComponentFactory` `getFactory()` Gets the factory which has created the current instance.
`java.lang.Object` `getFieldValue(java.lang.String fieldName)` Gives access to a field value of the first created pojo.
`java.lang.Object` `getFieldValue(java.lang.String fieldName, java.lang.Object pojo)` Gives access to a field value to the given created pojo.
`org.osgi.framework.BundleContext` `getGlobalContext()` Gets the global bundle context.
`Handler` `getHandler(java.lang.String name)` Returns a specified handler.
`org.osgi.framework.BundleContext` `getInstanceContext()` Gets the bundle context of the instance, i.e.
`InstanceDescription` `getInstanceDescription()` Gets the description of the current instance.
`java.lang.String` `getInstanceName()` Gets the instance name.
`ServiceContext` `getLocalServiceContext()` Gets the local service context.
`Logger` `getLogger()` The instance logger.
`java.lang.Object` `getPojoObject()` Gets the first object created by the instance.
`java.lang.Object[]` `getPojoObjects()` Gets the object array created by the instance.
`Handler[]` `getRegisteredHandlers()` Gets the list of handlers plugged (i.e.
`java.util.Set` `getRegistredFields()` Gets the list of registered fields (containing field names).
`java.util.Set` `getRegistredMethods()` Gets the list of registered methods (containing method ids).
`int` `getState()` Gets the actual state of the instance.
`boolean` `isStarted()` Checks if the instance is started.
`protected void` `load()` Loads the manipulated class.
`void` `onEntry(java.lang.Object pojo, java.lang.String methodId, java.lang.Object[] args)` Dispatches entry method events on registered method interceptors.
`void` `onError(java.lang.Object pojo, java.lang.String methodId, java.lang.Throwable error)` Dispatches error method events on registered method interceptors.
`void` `onExit(java.lang.Object pojo, java.lang.String methodId, java.lang.Object result)` Dispatches exit method events on registered method interceptors.
`java.lang.Object` `onGet(java.lang.Object pojo, java.lang.String fieldName)` This method is called by the manipulated class each time that a GETFIELD instruction is executed.
`void` `onSet(java.lang.Object pojo, java.lang.String fieldName, java.lang.Object objectValue)` This method is called by the manipulated class each time that a PUTFIELD instruction is executed.
`void` `reconfigure(java.util.Dictionary configuration)` Reconfigures the current instance.
`void` `register(FieldMetadata field, FieldInterceptor interceptor)` Registers a field interceptor.
`void` `register(int index, ConstructorInjector injector)` Registers a constructor injector.
`void` `register(MethodMetadata method, MethodInterceptor interceptor)` Registers a method interceptor.
`void` `register(MethodMetadata method, java.lang.String innerClass, MethodInterceptor interceptor)` Registers a method interceptor on a methods from an inner class.
`void` `register(PrimitiveHandler handler, FieldMetadata[] fields, MethodMetadata[] methods)` Deprecated. use `register(FieldMetadata, FieldInterceptor)` and `register(MethodMetadata, MethodInterceptor)` instead.
`void` `removeInstanceStateListener(InstanceStateListener listener)` Unregisters an instance state listener.
`void` `setInstanceBundleContext(org.osgi.framework.BundleContext context)` Sets the instance bundle context.
`void` `setState(int state)` Sets the state of the component instance.
`void` `start()` Starts the instance manager.
`void` `stateChanged(ComponentInstance instance, int newState)` State Change listener callback.
`void` `stop()` Stops the instance manager.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Field Detail

#### m_name

    protected java.lang.String m_name

The name of the component instance.

#### m_className

    protected java.lang.String m_className

The name of the component type implementation class.

#### m_handlers

    protected final HandlerManager[] m_handlers

The handler object list.

#### m_state

    protected int m_state

The current instance state (`ComponentInstance.STOPPED` at the beginning). Possible value are
`ComponentInstance.INVALID`
`ComponentInstance.VALID`
`ComponentInstance.DISPOSED`
`ComponentInstance.STOPPED`

#### m_listeners

    protected java.util.List m_listeners

The instance state listener list.

See Also:
  `InstanceStateListener`

#### m_pojoObjects

    protected java.util.List m_pojoObjects

The content of the current instance.

### Constructor Detail

#### InstanceManager

    public InstanceManager(ComponentFactory factory,
                           org.osgi.framework.BundleContext context,
                           HandlerManager[] handlers)

Creates a new Component Manager. The instance is not initialized.

Parameters:
  `factory` - the factory managing the instance manager
  `context` - the bundle context to give to the instance
  `handlers` - handler object array

### Method Detail

#### setInstanceBundleContext

    public void setInstanceBundleContext(org.osgi.framework.BundleContext context)

Sets the instance bundle context.

Specified by:
  `setInstanceBundleContext` in interface `InstanceBundleContextAware`
Parameters:
  `context` - the bundle context of the bundle having declared the instance
Since:
  1.11.2

#### getLogger

    public Logger getLogger()

The instance logger.

Returns:
  the logger

#### configure

    public void configure(org.apache.felix.ipojo.metadata.Element metadata,
                          java.util.Dictionary configuration)
                   throws ConfigurationException

Configures the instance manager. Sets the class name, and the instance name as well as the factory method. Initializes handlers.

Parameters:
  `metadata` - the component type metadata
  `configuration` - the configuration of the instance
Throws:
  `ConfigurationException` - if the metadata are not correct

#### getInstanceDescription

    public InstanceDescription getInstanceDescription()

Gets the description of the current instance.

Specified by:
  `getInstanceDescription` in interface `ComponentInstance`
Returns:
  the instance description.
See Also:
  `ComponentInstance.getInstanceDescription()`

#### getRegisteredHandlers

    public Handler[] getRegisteredHandlers()

Gets the list of handlers plugged (i.e. attached) on the instance. This method does not need a synchronized block as the handler set is constant.

Returns:
  the handler array of plugged handlers.

#### getHandler

    public Handler getHandler(java.lang.String name)

Returns a specified handler. This method allows cross-handler interactions. This must does not need a synchronized block as the handler set is constant.

Parameters:
  `name` - the class name of the handler to find or its qualified name (namespace:name)
Returns:
  the handler, or null if not found

#### getFieldValue

    public java.lang.Object getFieldValue(java.lang.String fieldName)

Gives access to a field value of the first created pojo. This method processes by analyzing both managed fields and pojo fields (by reflection). If no pojo were already created try only on managed fields.

Parameters:
  `fieldName` - the field name.
Returns:
  the field value, `null` is returned if the value is managed and not already set.

#### getFieldValue

    public java.lang.Object getFieldValue(java.lang.String fieldName,
                                          java.lang.Object pojo)

Gives access to a field value to the given created pojo. This method processes by analyzing both managed fields and pojo fields (by reflection). If the given pojo is `null`, tries only on managed fields.

Parameters:
  `fieldName` - the field name.
  `pojo` - the pojo on which computing field value.
Returns:
  the field value, `null` is returned if the value is managed and not already set.

#### start

    public void start()

Starts the instance manager. This method activates plugged handlers, and computes the initial instance state.

Specified by:
  `start` in interface `ComponentInstance`

#### stop

    public void stop()

Stops the instance manager. This methods sets the instance state to `ComponentInstance.STOPPED`, disables attached handlers, and notifies listeners (`InstanceStateListener`) of the instance stopping process.

Specified by:
  `stop` in interface `ComponentInstance`

#### dispose

    public void dispose()

Disposes the instance. This method does the following process:
Stop the instance is not `ComponentInstance.STOPPED`
Notifies listeners `InstanceStateListener` of the destruction
Disposes attached handlers
Clears structures

Specified by:
  `dispose` in interface `ComponentInstance`
See Also:
  `ComponentInstance.dispose()`

#### setState

    public void setState(int state)

Sets the state of the component instance. If the state changes, calls the `Handler.stateChanged(int)` method on the attached handlers. This method has a reentrant mechanism. If in the flow of the first call the method is called another times, the second call is stored and executed after the first one finished.

Parameters:
  `state` - the new state

#### getState

    public int getState()

Gets the actual state of the instance. Possible values are:
`ComponentInstance.INVALID`
`ComponentInstance.VALID`
`ComponentInstance.DISPOSED`
`ComponentInstance.STOPPED`

Specified by:
  `getState` in interface `ComponentInstance`
Returns:
  the actual state of the component instance.
See Also:
  `ComponentInstance.getState()`

#### isStarted

    public boolean isStarted()

Checks if the instance is started. An instance is started if the state is either `ComponentInstance.VALID` or `ComponentInstance.INVALID`.

Specified by:
  `isStarted` in interface `ComponentInstance`
Returns:
  `true` if the instance is started.
See Also:
  `ComponentInstance.isStarted()`

#### addInstanceStateListener

    public void addInstanceStateListener(InstanceStateListener listener)

Registers an instance state listener.

Specified by:
  `addInstanceStateListener` in interface `ComponentInstance`
Parameters:
  `listener` - the listener to register.
See Also:
  `ComponentInstance.addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)`

#### removeInstanceStateListener

    public void removeInstanceStateListener(InstanceStateListener listener)

Unregisters an instance state listener.

Specified by:
  `removeInstanceStateListener` in interface `ComponentInstance`
Parameters:
  `listener` - the listener to unregister.
See Also:
  `ComponentInstance.removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)`

#### getFactory

    public ComponentFactory getFactory()

Gets the factory which has created the current instance.

Specified by:
  `getFactory` in interface `ComponentInstance`
Returns:
  the factory of the component
See Also:
  `ComponentInstance.getFactory()`

#### load

    protected void load()

Loads the manipulated class.

#### getPojoObjects

    public java.lang.Object[] getPojoObjects()

Gets the object array created by the instance.

Returns:
  the created content objects of the component instance.

#### createObject

    protected java.lang.Object createObject()

Creates a POJO objects. This method is not synchronized and does not require any locks. If a `m_factoryMethod` is specified, this method called this static method to creates the object. Otherwise, the methods uses the regular constructor. All those methods can receive the `BundleContext` in argument.

Returns:
  the created object or `null` if an error occurs during the creation.

#### createPojoObject

    public java.lang.Object createPojoObject()

Creates an instance of the content. This method needs to be called once only for singleton provided service. This methods call the `createObject()` method, and adds the created object to the `m_pojoObjects` list. Then, it calls the `PrimitiveHandler.onCreation(Object)` methods on attached handlers.

Returns:
  a new instance or `null` if an error occurs during the creation.

#### deletePojoObject

    public void deletePojoObject(java.lang.Object pojo)

Deletes a POJO object.

Parameters:
  `pojo` - the pojo to remove from the list of created pojos.

#### getPojoObject

    public java.lang.Object getPojoObject()

Gets the first object created by the instance. If no object created, creates and returns a POJO object. This methods call the `createObject()` method, and adds the created object to the `m_pojoObjects` list. Then, it calls the `PrimitiveHandler.onCreation(Object)` methods on attached handlers.

TODO this method has a potential race condition if two threads require a pojo object at the same time. Only one object will be created, but the second thread can receive the created object before the `PrimitiveHandler.onCreation(Object)` calls.

Returns:
  the pojo object of the component instance to use for singleton component

#### getClazz

    public java.lang.Class getClazz()

Gets the manipulated class. The method does not need to be synchronized. Reassigning the internal class will use the same class object.

Returns:
  the manipulated class

#### register

    public void register(PrimitiveHandler handler,
                         FieldMetadata[] fields,
                         MethodMetadata[] methods)

Deprecated. use `register(FieldMetadata, FieldInterceptor)` and `register(MethodMetadata, MethodInterceptor)` instead.
Registers an handler. This methods is called by handler wanting to monitor fields and/or methods of the implementation class.

Parameters:
  `handler` - the handler to register
  `fields` - the field metadata list
  `methods` - the method metadata list

#### register

    public void register(FieldMetadata field,
                         FieldInterceptor interceptor)

Registers a field interceptor. A field interceptor will be notified of field access of the implementation class. Note that handlers are field interceptors.

Parameters:
  `field` - the field to monitor
  `interceptor` - the field interceptor object

#### register

    public void register(MethodMetadata method,
                         MethodInterceptor interceptor)

Registers a method interceptor. A method interceptor will be notified of method entries, exits and errors. Note that handlers are method interceptors.

Parameters:
  `method` - the field to monitor
  `interceptor` - the field interceptor object

#### register

    public void register(MethodMetadata method,
                         java.lang.String innerClass,
                         MethodInterceptor interceptor)

Registers a method interceptor on a methods from an inner class. A method interceptor will be notified of method entries, exits and errors. Note that handlers are method interceptors.

Parameters:
  `method` - the field to monitor
  `innerClass` - the inner class name
  `interceptor` - the field interceptor object

#### register

    public void register(int index,
                         ConstructorInjector injector)
                  throws ConfigurationException

Registers a constructor injector. The constructor injector will be called when a pojo object is going to be created.

Parameters:
  `index` - the index of the parameter. Only one injector per index can be registered.
  `injector` - the injector object.
Throws:
  `ConfigurationException` - if the given index is already injected by another injector

#### onGet

    public java.lang.Object onGet(java.lang.Object pojo,
                                  java.lang.String fieldName)

This method is called by the manipulated class each time that a GETFIELD instruction is executed. The method asks to each attached handler monitoring this field which value need to be injected (i.e. returned) by invoking the `PrimitiveHandler.onGet(Object, String, Object)` method. If the field value changes, this method call the `PrimitiveHandler.onSet(Object, String, Object)` method on each field interceptor monitoring the field in order to advertize the new value.

Parameters:
  `pojo` - the pojo object on which the field was get
  `fieldName` - the field name on which the GETFIELD instruction is called
Returns:
  the value decided by the last asked handler (throws a warning if two fields decide two different values)

#### onEntry

    public void onEntry(java.lang.Object pojo,
                        java.lang.String methodId,
                        java.lang.Object[] args)

Dispatches entry method events on registered method interceptors. This method calls the `MethodInterceptor.onEntry(Object, java.lang.reflect.Member, Object[])` methods on method interceptors monitoring the method.

Parameters:
  `pojo` - the pojo object on which method is invoked.
  `methodId` - the method id used to compute the `Method` object.
  `args` - the argument array

#### onExit

    public void onExit(java.lang.Object pojo,
                       java.lang.String methodId,
                       java.lang.Object result)

Dispatches exit method events on registered method interceptors. The given returned object is an instance of `Exception` if the method thrown an exception. If the given object is `null`, either the method returns `void`, or the method has returned `null` This method calls the `MethodInterceptor.onExit(Object, java.lang.reflect.Member, Object)` and the `MethodInterceptor.onFinally(Object, java.lang.reflect.Member)` methods on method interceptors monitoring the method.

Parameters:
  `pojo` - the pojo object on which method was invoked.
  `methodId` - the method id used to compute the `Method` object.
  `result` - the returned object.

#### onError

    public void onError(java.lang.Object pojo,
                        java.lang.String methodId,
                        java.lang.Throwable error)

Dispatches error method events on registered method interceptors. or the method has returned `null` This method calls the `MethodInterceptor.onError(Object, java.lang.reflect.Member, Throwable)` and the `MethodInterceptor.onFinally(Object, java.lang.reflect.Member)` methods on method interceptors monitoring the method.

Parameters:
  `pojo` - the pojo object on which the method was invoked
  `methodId` - the method id used to compute the `Method` object.
  `error` - the Throwable object.

#### onSet

    public void onSet(java.lang.Object pojo,
                      java.lang.String fieldName,
                      java.lang.Object objectValue)

This method is called by the manipulated class each time that a PUTFIELD instruction is executed. The method calls the `PrimitiveHandler.onSet(Object, String, Object)` method on each field interceptors monitoring this field. This method can be invoked with a `null` pojo argument when the changes comes from another handler.

Parameters:
  `pojo` - the pojo object on which the field was set
  `fieldName` - the field name on which the PUTFIELD instruction is called
  `objectValue` - the new value of the field

#### getContext

    public org.osgi.framework.BundleContext getContext()

Gets the bundle context used by this component instance.

Specified by:
  `getContext` in interface `ComponentInstance`
Returns:
  the context of the component.
See Also:
  `ComponentInstance.getContext()`

#### getGlobalContext

    public org.osgi.framework.BundleContext getGlobalContext()

Gets the global bundle context. This is the bundle context of the bundle declaring the component type.

Returns:
  the bundle context of the bundle declaring the component type.

#### getLocalServiceContext

    public ServiceContext getLocalServiceContext()

Gets the local service context. This service context gives access to the 'local' service registry (the composite one). If the instance lives in the global (i.e. OSGi) context, this method returns `null`

Returns:
  the local service context or `null` if the instance doesn't live in a composite.

#### getInstanceName

    public java.lang.String getInstanceName()

Gets the instance name.

Specified by:
  `getInstanceName` in interface `ComponentInstance`
Returns:
  the instance name.
See Also:
  `ComponentInstance.getInstanceName()`

#### reconfigure

    public void reconfigure(java.util.Dictionary configuration)

Reconfigures the current instance. Reconfiguring an instance means re-injecting a new instance configuration. Some properties are immutable such as the instance name. This methods calls the `Handler.reconfigure(Dictionary)` methods on each attached handler, and then recompute the instance state. Note that the reconfiguration process does not deactivate the instance.

Specified by:
  `reconfigure` in interface `ComponentInstance`
Parameters:
  `configuration` - the new configuration to push
See Also:
  `ComponentInstance.reconfigure(java.util.Dictionary)`

#### getClassName

    public java.lang.String getClassName()

Gets the implementation class of the component type. This method does not need to be synchronized as the class name is constant once set.

Returns:
  the class name of the component implementation.

#### stateChanged

    public void stateChanged(ComponentInstance instance,
                             int newState)

State Change listener callback. This method is called every time that a plugged handler becomes valid or invalid. This method computes the new instance state and applies it (by calling the `setState(int)` method.

Specified by:
  `stateChanged` in interface `InstanceStateListener`
Parameters:
  `instance` - the handler becoming valid or invalid
  `newState` - the new state of the handler
See Also:
  `InstanceStateListener.stateChanged(org.apache.felix.ipojo.ComponentInstance, int)`

#### getRegistredFields

    public java.util.Set getRegistredFields()

Gets the list of registered fields (containing field names). This method is invoked by the POJO itself during its initialization.

Returns:
  the set of registered fields.

#### getRegistredMethods

    public java.util.Set getRegistredMethods()

Gets the list of registered methods (containing method ids). This method is invoked by the POJO itself during its initialization.

Returns:
  the set of registered methods.

#### getInstanceContext

    public org.osgi.framework.BundleContext getInstanceContext()

Gets the bundle context of the instance, i.e. the bundle context of the bundle having declared this instance.

Specified by:
  `getInstanceContext` in interface `InstanceBundleContextAware`
Returns:
  the bundle context of the instance.
Since:
  1.11.2