Class ConfigurableComponentHolder<S>
- java.lang.Object
-
- org.apache.felix.scr.impl.manager.ConfigurableComponentHolder<S>
-
- All Implemented Interfaces:
ComponentContainer<S>
,ComponentHolder<S>
- Direct Known Subclasses:
ComponentRegistry.DefaultConfigurableComponentHolder
public abstract class ConfigurableComponentHolder<S> extends java.lang.Object implements ComponentHolder<S>, ComponentContainer<S>
TheConfigurableComponentHolder
class is aComponentHolder
for automatically configured components instances that may or may not be configured through Config Admin.The holder copes with three situations:
- No configuration is available for the held component. That is there is
no configuration whose
service.pid
orservice.factoryPid
equals the component name. - A singleton configuration is available whose
service.pid
equals the component name. - One or more factory configurations exist whose
service.factoryPid
equals the component name.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
ConfigurableComponentHolder.PSFLoader
-
Field Summary
Fields Modifier and Type Field Description private java.lang.Object
enableLock
private ComponentLogger
logger
private ComponentActivator
m_activator
The activator owning the per-bundle componentsprivate java.lang.Long[]
m_changeCount
private ComponentMetadata
m_componentMetadata
TheComponentMetadata
describing the held component(s)private ComponentMethods<S>
m_componentMethods
private java.util.Map<java.lang.String,AbstractComponentManager<S>>
m_components
A map of components configured with factory configuration.private java.util.Dictionary<java.lang.String,java.lang.Object>[]
m_configurations
the non-factory configurations shared between all instances.private org.osgi.util.promise.Promise<java.lang.Void>
m_disablePromise
private boolean
m_enabled
Whether components have already been enabled by calling theenableComponents(boolean)
method.private org.osgi.util.promise.Promise<java.lang.Void>
m_enablePromise
private java.util.Map<java.lang.String,java.lang.Long>
m_factoryChangeCount
private java.util.Map<java.lang.String,java.util.Dictionary<java.lang.String,java.lang.Object>>
m_factoryConfigurations
the factory configurations indexed by pid (which cannot be a TargetedPID since it's generated by CA).private java.lang.Integer
m_factoryPidIndex
the index in metadata.getConfigurationPid() of the base factory pid, if any.private java.util.Map<java.lang.String,TargetedPID>
m_factoryTargetedPids
Each factory config may be from a different TargetedPID (sharing the same base service pid, but with different level of detail)private AbstractComponentManager<S>
m_singleComponent
The special component used if there is no configuration or a singleton configuration.private TargetedPID[]
m_targetedPids
the targeted pids corresponding to the pids specified in the config metadata, except possibly for the single factory pid
-
Constructor Summary
Constructors Constructor Description ConfigurableComponentHolder(ComponentActivator activator, ComponentMetadata metadata, ComponentLogger logger)
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description private void
checkFactoryPidIndex(TargetedPID factoryPid)
(package private) void
clearComponents()
void
configurationDeleted(TargetedPID pid, TargetedPID factoryPid)
The configuration with the givenpid
(service.pid
of the configuration object) is deleted.boolean
configurationUpdated(TargetedPID pid, TargetedPID factoryPid, java.util.Dictionary<java.lang.String,java.lang.Object> props, long changeCount)
Configures a component with the given configuration.protected static void
copyTo(java.util.Map<java.lang.String,java.lang.Object> target, java.util.Dictionary<java.lang.String,?> source)
protected AbstractComponentManager<S>
createComponentManager(boolean factoryConfiguration)
protected abstract ComponentMethods<S>
createComponentMethods()
org.osgi.util.promise.Promise<java.lang.Void>
disableComponents(boolean async)
Disables all components of this holder.void
disposeComponents(int reason)
Disposes off all components of this holder.void
disposed(SingleComponentManager<S> component)
Informs the holder that the component has been disposed as a result of calling the dispose method.org.osgi.util.promise.Promise<java.lang.Void>
enableComponents(boolean async)
Enables all components of this holder and if satisfied activates them.boolean
equals(java.lang.Object object)
Compares thisImmediateComponentHolder
object to another object.ComponentActivator
getActivator()
Returns theComponentActivator
owning this component holder.(package private) java.util.List<AbstractComponentManager<S>>
getComponentManagers()
Returns all component managers from the map and the single component manager, optionally also removing them from the map.ComponentMetadata
getComponentMetadata()
Returns theComponentMetadata
describing and declaring this component.protected ComponentMethods<S>
getComponentMethods()
java.util.List<? extends ComponentManager<?>>
getComponents()
Returns allComponent
instances held by this holder.TargetedPID
getConfigurationTargetedPID(TargetedPID pid, TargetedPID factoryPid)
Returns the targeted PID used to configure this component(package private) java.util.List<AbstractComponentManager<S>>
getDirectComponentManagers()
ComponentLogger
getLogger()
(package private) java.lang.String
getName()
private int
getSingletonPidIndex(TargetedPID pid)
int
hashCode()
Returns a hash code value for the object.boolean
isEnabled()
whether the component is currently enabledprivate boolean
isSatisfied()
Determine if the holder is satisfied with configurationsprivate java.util.Map<java.lang.String,java.lang.Object>
mergeProperties(java.lang.String servicePid)
java.lang.String
toString()
private void
wait(org.osgi.util.promise.Promise<java.lang.Void> promise)
-
-
-
Field Detail
-
m_activator
private final ComponentActivator m_activator
The activator owning the per-bundle components
-
m_componentMetadata
private final ComponentMetadata m_componentMetadata
TheComponentMetadata
describing the held component(s)
-
m_targetedPids
private final TargetedPID[] m_targetedPids
the targeted pids corresponding to the pids specified in the config metadata, except possibly for the single factory pid
-
m_changeCount
private final java.lang.Long[] m_changeCount
-
m_factoryChangeCount
private final java.util.Map<java.lang.String,java.lang.Long> m_factoryChangeCount
-
m_factoryPidIndex
private volatile java.lang.Integer m_factoryPidIndex
the index in metadata.getConfigurationPid() of the base factory pid, if any. Each component created from a factory configuration might have a different targeted pid.
-
m_configurations
private final java.util.Dictionary<java.lang.String,java.lang.Object>[] m_configurations
the non-factory configurations shared between all instances.
-
m_factoryConfigurations
private final java.util.Map<java.lang.String,java.util.Dictionary<java.lang.String,java.lang.Object>> m_factoryConfigurations
the factory configurations indexed by pid (which cannot be a TargetedPID since it's generated by CA). We have to track these since other required configs may not yet be present so we can't create the component manager yet.
-
m_factoryTargetedPids
private final java.util.Map<java.lang.String,TargetedPID> m_factoryTargetedPids
Each factory config may be from a different TargetedPID (sharing the same base service pid, but with different level of detail)
-
m_components
private final java.util.Map<java.lang.String,AbstractComponentManager<S>> m_components
A map of components configured with factory configuration. The indices are the PIDs (service.pid
) of the configuration objects. The values are thecomponent instances
created on behalf of the configurations.
-
m_singleComponent
private volatile AbstractComponentManager<S> m_singleComponent
The special component used if there is no configuration or a singleton configuration. This field is onlynull
once all components held by this holder have been disposed of bydisposeComponents(int)
and is first created in the constructor. As factory configurations are provided this instance may be configured or "deconfigured".Expected invariants:
- This field is only
null
after disposal of all held components - The
m_components
map is empty or the component pointed to by this field is also contained in the map
- This field is only
-
m_enabled
private volatile boolean m_enabled
Whether components have already been enabled by calling theenableComponents(boolean)
method. If this field istrue
component instances created per configuration by theconfigurationUpdated(TargetedPID, TargetedPID, Dictionary, long)
method are also enabled. Otherwise they are not enabled immediately.
-
enableLock
private final java.lang.Object enableLock
-
m_enablePromise
private volatile org.osgi.util.promise.Promise<java.lang.Void> m_enablePromise
-
m_disablePromise
private volatile org.osgi.util.promise.Promise<java.lang.Void> m_disablePromise
-
m_componentMethods
private final ComponentMethods<S> m_componentMethods
-
logger
private final ComponentLogger logger
-
-
Constructor Detail
-
ConfigurableComponentHolder
public ConfigurableComponentHolder(ComponentActivator activator, ComponentMetadata metadata, ComponentLogger logger)
-
-
Method Detail
-
createComponentMethods
protected abstract ComponentMethods<S> createComponentMethods()
-
getComponentMethods
protected ComponentMethods<S> getComponentMethods()
-
createComponentManager
protected AbstractComponentManager<S> createComponentManager(boolean factoryConfiguration)
-
getActivator
public final ComponentActivator getActivator()
Description copied from interface:ComponentHolder
Returns theComponentActivator
owning this component holder. (overlaps ComponentContaienr)- Specified by:
getActivator
in interfaceComponentContainer<S>
- Specified by:
getActivator
in interfaceComponentHolder<S>
-
getComponentMetadata
public final ComponentMetadata getComponentMetadata()
Description copied from interface:ComponentHolder
Returns theComponentMetadata
describing and declaring this component. (overlaps ComponentContaienr)- Specified by:
getComponentMetadata
in interfaceComponentContainer<S>
- Specified by:
getComponentMetadata
in interfaceComponentHolder<S>
-
configurationDeleted
public void configurationDeleted(TargetedPID pid, TargetedPID factoryPid)
The configuration with the givenpid
(service.pid
of the configuration object) is deleted.The following situations are supported:
- The configuration was a singleton configuration (pid equals the component name). In this case the internal component map is empty and the single component has been configured by the singleton configuration and is no "deconfigured".
- A factory configuration object has been deleted and the configured object is set as the single component. If the single component held the last factory configuration object, it is deconfigured. Otherwise the single component is disposed off and replaced by another component in the map of existing components.
- A factory configuration object has been deleted and the configured object is not set as the single component. In this case the component is simply disposed off and removed from the internal map.
- Specified by:
configurationDeleted
in interfaceComponentHolder<S>
- Parameters:
pid
- The PID of the deleted configurationfactoryPid
- The factory PID of the deleted configuration
-
configurationUpdated
public boolean configurationUpdated(TargetedPID pid, TargetedPID factoryPid, java.util.Dictionary<java.lang.String,java.lang.Object> props, long changeCount)
Configures a component with the given configuration. This configuration update may happen in various situations:- The
pid
equals the component name. Hence we have a singleton configuration for the single component held by this holder - The configuration is a factory configuration and is the first configuration provided. In this case the single component is provided with the configuration and also stored in the map.
- The configuration is a factory configuration but not the first. In this case a new component is created, configured and stored in the map
- Specified by:
configurationUpdated
in interfaceComponentHolder<S>
- Parameters:
pid
- Targeted PID for the configurationfactoryPid
- the (targeted) factory pid or null for a singleton pidprops
- the property dictionary from the configuration.changeCount
- change count of the configuration, or R4 imitation.- Returns:
- true if a new configuration was created, false otherwise. TODO there are now 3 states..... still not satisfied, existing, and new
- The
-
mergeProperties
private java.util.Map<java.lang.String,java.lang.Object> mergeProperties(java.lang.String servicePid)
-
getSingletonPidIndex
private int getSingletonPidIndex(TargetedPID pid)
-
checkFactoryPidIndex
private void checkFactoryPidIndex(TargetedPID factoryPid)
-
copyTo
protected static void copyTo(java.util.Map<java.lang.String,java.lang.Object> target, java.util.Dictionary<java.lang.String,?> source)
-
isSatisfied
private boolean isSatisfied()
Determine if the holder is satisfied with configurations- Returns:
- true if configuration optional or all pids supplied with configurations
-
getComponents
public java.util.List<? extends ComponentManager<?>> getComponents()
Description copied from interface:ComponentHolder
Returns allComponent
instances held by this holder.- Specified by:
getComponents
in interfaceComponentHolder<S>
-
isEnabled
public boolean isEnabled()
Description copied from interface:ComponentHolder
whether the component is currently enabled- Specified by:
isEnabled
in interfaceComponentHolder<S>
- Returns:
- whether the component is enabled
-
wait
private void wait(org.osgi.util.promise.Promise<java.lang.Void> promise)
-
enableComponents
public org.osgi.util.promise.Promise<java.lang.Void> enableComponents(boolean async)
Description copied from interface:ComponentHolder
Enables all components of this holder and if satisfied activates them.- Specified by:
enableComponents
in interfaceComponentHolder<S>
- Parameters:
async
- Whether the actual activation should take place asynchronously or not.
-
disableComponents
public org.osgi.util.promise.Promise<java.lang.Void> disableComponents(boolean async)
Description copied from interface:ComponentHolder
Disables all components of this holder.- Specified by:
disableComponents
in interfaceComponentHolder<S>
- Parameters:
async
- Whether the actual deactivation should take place asynchronously or not.
-
disposeComponents
public void disposeComponents(int reason)
Description copied from interface:ComponentHolder
Disposes off all components of this holder.- Specified by:
disposeComponents
in interfaceComponentHolder<S>
-
disposed
public void disposed(SingleComponentManager<S> component)
Description copied from interface:ComponentContainer
Informs the holder that the component has been disposed as a result of calling the dispose method.- Specified by:
disposed
in interfaceComponentContainer<S>
-
equals
public boolean equals(java.lang.Object object)
Compares thisImmediateComponentHolder
object to another object.A ImmediateComponentHolder is considered to be equal to another ImmediateComponentHolder if the component names are equal(using
String.equals
) and they have the same bundle activator- Overrides:
equals
in classjava.lang.Object
- Parameters:
object
- TheImmediateComponentHolder
object to be compared.- Returns:
true
ifobject
is aImmediateComponentHolder
and is equal to this object;false
otherwise.
-
hashCode
public int hashCode()
Returns a hash code value for the object.- Overrides:
hashCode
in classjava.lang.Object
- Returns:
- An integer which is a hash code value for this object.
-
toString
public java.lang.String toString()
- Overrides:
toString
in classjava.lang.Object
-
getName
java.lang.String getName()
-
getComponentManagers
java.util.List<AbstractComponentManager<S>> getComponentManagers()
Returns all component managers from the map and the single component manager, optionally also removing them from the map. If there are no component managers,null
is returned. Must be called synchronized on m_components.
-
getDirectComponentManagers
java.util.List<AbstractComponentManager<S>> getDirectComponentManagers()
-
clearComponents
void clearComponents()
-
getLogger
public ComponentLogger getLogger()
- Specified by:
getLogger
in interfaceComponentContainer<S>
-
getConfigurationTargetedPID
public TargetedPID getConfigurationTargetedPID(TargetedPID pid, TargetedPID factoryPid)
Description copied from interface:ComponentHolder
Returns the targeted PID used to configure this component- Specified by:
getConfigurationTargetedPID
in interfaceComponentHolder<S>
- Parameters:
pid
- a targetedPID containing the service pid for the component desired (the rest of the targeted pid is ignored)factoryPid
- a targetedPID containing the factory pid for the component desired.- Returns:
- the complete targeted pid actually used to configure the comonent.
-
-