org.apache.felix.ipojo.util

## Class DependencyModel

- java.lang.Object
- - org.apache.felix.ipojo.util.DependencyModel

Direct Known Subclasses:
  Dependency

    public abstract class DependencyModel
    extends java.lang.Object

Abstract dependency model. This class is the parent class of every service dependency. It manages the most part of dependency management. This class creates an interface between the service tracker and the concrete dependency.

Author:
  Felix Project Team

### Nested Class Summary

Nested Classes
`static class` `DependencyModel.DependencyEventType`
`class` `DependencyModel.ServiceBindingHolder` Service binding structure.

### Field Summary

Fields
`static int` `BROKEN` Dependency state : BROKEN.
`static int` `DYNAMIC_BINDING_POLICY` Binding policy : Dynamic.
`static int` `DYNAMIC_PRIORITY_BINDING_POLICY` Binding policy : Dynamic-Priority.
`protected ServiceReferenceManager` `m_serviceReferenceManager` The service reference manager.
`static int` `RESOLVED` Dependency state : RESOLVED.
`static int` `STATIC_BINDING_POLICY` Binding policy : Static.
`static int` `UNRESOLVED` Dependency state : UNRESOLVED.

### Constructor Summary

Constructors
Constructor and Description
`DependencyModel(java.lang.Class specification, boolean aggregate, boolean optional, org.osgi.framework.Filter filter, java.util.Comparator<org.osgi.framework.ServiceReference> comparator, int policy, org.osgi.framework.BundleContext context, DependencyStateListener listener, ComponentInstance ci)` Creates a DependencyModel.

### Method Summary

All Methods Instance Methods Abstract Methods Concrete Methods
`boolean` `acquireReadLockIfNotHeld()` Acquires the read lock only and only if no read lock is already held by the current thread.
`boolean` `acquireWriteLockIfNotHeld()` Acquires the write lock only and only if the write lock is not already held by the current thread.
`void` `addListener(DependencyModelListener listener)` Add the given listener to the dependency model's list of listeners.
`void` `applyReconfiguration(ServiceReferenceManager.ChangeSet changeSet)` Applies the given reconfiguration.
`void` `cleanup()` Removes all the listeners from this dependency before it gets disposed.
`int` `getBindingPolicy()` Gets the used binding policy.
`org.osgi.framework.BundleContext` `getBundleContext()` Gets the bundle context used by the dependency.
`java.lang.String` `getComparator()` Gets the used comparator name.
`ComponentInstance` `getComponentInstance()`
`ContextSourceManager` `getContextSourceManager()`
`java.lang.String` `getFilter()` Returns the dependency filter (String form).
`java.lang.String` `getId()` Gets the dependency id.
`java.lang.Object` `getService(org.osgi.framework.ServiceReference ref)` Gets a service object for the given reference.
`java.lang.Object` `getService(org.osgi.framework.ServiceReference ref, boolean store)` Gets a service object for the given reference.
`org.osgi.framework.ServiceReference` `getServiceReference()` Gets the first bound service reference.
`ServiceReferenceManager` `getServiceReferenceManager()`
`org.osgi.framework.ServiceReference[]` `getServiceReferences()` Gets bound service references.
`int` `getSize()` Gets the number of actual matching references.
`java.lang.Class` `getSpecification()` Gets the tracked specification.
`int` `getState()` Gets the actual state of the dependency.
`Tracker` `getTracker()`
`java.util.List<org.osgi.framework.ServiceReference>` `getUsedServiceReferences()` Gets the list of currently used service references.
`void` `invalidateMatchingServices()`
`void` `invalidateSelectedServices()` This callback is called by ranking interceptor to notify the dependency that the selected service set has changed and must be recomputed.
`boolean` `isAggregate()`
`boolean` `isFrozen()` Is the reference set frozen (cannot change anymore)? This method must be override by concrete dependency to support the static binding policy.
`boolean` `isOptional()`
`boolean` `match(org.osgi.framework.ServiceReference ref)` Does the service reference match ? This method must be overridden by concrete dependencies if they need advanced testing on service reference (that cannot be expressed in the LDAP filter).
`void` `notifyListeners(DependencyModel.DependencyEventType type, org.osgi.framework.ServiceReference<?> service, java.lang.Object object)` Notify all listeners that a change has occurred in this dependency model.
`void` `onChange(ServiceReferenceManager.ChangeSet set)` Callbacks call by the ServiceReferenceManager when the selected service set has changed.
`abstract void` `onDependencyReconfiguration(org.osgi.framework.ServiceReference[] departs, org.osgi.framework.ServiceReference[] arrivals)` Concrete dependency callback.
`abstract void` `onServiceArrival(org.osgi.framework.ServiceReference ref)` Concrete dependency callback.
`abstract void` `onServiceDeparture(org.osgi.framework.ServiceReference ref)` Concrete dependency callback.
`abstract void` `onServiceModification(org.osgi.framework.ServiceReference ref)` Concrete dependency callback.
`boolean` `releaseReadLockIfHeld()` Releases the read lock only and only if the read lock is held by the current thread.
`boolean` `releaseWriteLockIfHeld()` Releases the write lock only and only if the write lock is held by the current thread.
`void` `removeListener(DependencyModelListener listener)` Remove the given listener from the dependency model's list of listeners.
`void` `setAggregate(boolean isAggregate)` Sets the aggregate attribute of the current dependency.
`void` `setBundleContext(org.osgi.framework.BundleContext context)` Sets the bundle context used by this dependency.
`void` `setComparator(java.util.Comparator<org.osgi.framework.ServiceReference> cmp)`
`void` `setFilter(org.osgi.framework.Filter filter)` Sets the filter of the dependency.
`void` `setOptionality(boolean isOptional)` Sets the optionality attribute of the current dependency.
`void` `setSpecification(java.lang.Class specification)` Sets the required specification of this service dependency.
`void` `start()` Opens the tracking.
`void` `stop()` Closes the tracking.
`void` `unfreeze()` Unfreezes the dependency.
`void` `ungetService(org.osgi.framework.ServiceReference ref)` Ungets a used service reference.

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

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

### Field Detail

#### BROKEN

    public static final int BROKEN

Dependency state : BROKEN. A broken dependency cannot be fulfilled anymore. The dependency becomes broken when a used service disappears in the static binding policy.

See Also:
  Constant Field Values

#### UNRESOLVED

    public static final int UNRESOLVED

Dependency state : UNRESOLVED. A dependency is unresolved if the dependency is not valid and no service providers are available.

See Also:
  Constant Field Values

#### RESOLVED

    public static final int RESOLVED

Dependency state : RESOLVED. A dependency is resolved if the dependency is optional or at least one provider is available.

See Also:
  Constant Field Values

#### DYNAMIC_BINDING_POLICY

    public static final int DYNAMIC_BINDING_POLICY

Binding policy : Dynamic. In this policy, services can appears and departs without special treatment.

See Also:
  Constant Field Values

#### STATIC_BINDING_POLICY

    public static final int STATIC_BINDING_POLICY

Binding policy : Static. Once a service is used, if this service disappears the dependency becomes `BROKEN`. The instance needs to be recreated.

See Also:
  Constant Field Values

#### DYNAMIC_PRIORITY_BINDING_POLICY

    public static final int DYNAMIC_PRIORITY_BINDING_POLICY

Binding policy : Dynamic-Priority. In this policy, services can appears and departs. However, once a service with a highest ranking (according to the used comparator) appears, this new service is re-injected.

See Also:
  Constant Field Values

#### m_serviceReferenceManager

    protected final ServiceReferenceManager m_serviceReferenceManager

The service reference manager.

### Constructor Detail

#### DependencyModel

    public DependencyModel(java.lang.Class specification,
                           boolean aggregate,
                           boolean optional,
                           org.osgi.framework.Filter filter,
                           java.util.Comparator<org.osgi.framework.ServiceReference> comparator,
                           int policy,
                           org.osgi.framework.BundleContext context,
                           DependencyStateListener listener,
                           ComponentInstance ci)

Creates a DependencyModel. If the dependency has no comparator and follows the `DYNAMIC_PRIORITY_BINDING_POLICY` policy the OSGi Service Reference Comparator is used.

Parameters:
  `specification` - the required specification
  `aggregate` - is the dependency aggregate ?
  `optional` - is the dependency optional ?
  `filter` - the LDAP filter
  `comparator` - the comparator object to sort references
  `policy` - the binding policy
  `context` - the bundle context (or service context)
  `listener` - the dependency lifecycle listener to notify from dependency
  `ci` - instance managing the dependency state changes.

### Method Detail

#### start

    public void start()

Opens the tracking. This method computes the dependency state.

As the dependency is starting, locking is not required here.

See Also:
  `computeAndSetDependencyState()`

#### getBundleContext

    public org.osgi.framework.BundleContext getBundleContext()

Gets the bundle context used by the dependency.

Returns:
  the bundle context

#### invalidateSelectedServices

    public void invalidateSelectedServices()

This callback is called by ranking interceptor to notify the dependency that the selected service set has changed and must be recomputed.

#### invalidateMatchingServices

    public void invalidateMatchingServices()

#### stop

    public void stop()

Closes the tracking. The dependency becomes `UNRESOLVED` at the end of this method.

#### isFrozen

    public boolean isFrozen()

Is the reference set frozen (cannot change anymore)? This method must be override by concrete dependency to support the static binding policy. In fact, this method allows optimizing the static dependencies to become frozen only when needed. This method returns `false` by default. The method must always return `false` for non-static dependencies.

Returns:
  `true` if the reference set is frozen.

#### unfreeze

    public void unfreeze()

Unfreezes the dependency. This method must be override by concrete dependency to support the static binding policy. This method is called after tracking restarting.

#### match

    public boolean match(org.osgi.framework.ServiceReference ref)

Does the service reference match ? This method must be overridden by concrete dependencies if they need advanced testing on service reference (that cannot be expressed in the LDAP filter). By default this method returns `true`.

Parameters:
  `ref` - the tested reference.
Returns:
  `true` if the service reference matches.

#### getServiceReference

    public org.osgi.framework.ServiceReference getServiceReference()

Gets the first bound service reference.

Returns:
  `null` if no more provider is available, else returns the first reference from the matching set.

#### getServiceReferences

    public org.osgi.framework.ServiceReference[] getServiceReferences()

Gets bound service references.

Returns:
  the sorted (if a comparator is used) array of matching service references, `null` if no references are available.

#### getUsedServiceReferences

    public java.util.List<org.osgi.framework.ServiceReference> getUsedServiceReferences()

Gets the list of currently used service references. If no service references, returns `null`

Returns:
  the list of used reference (according to the service tracker).

#### getComponentInstance

    public ComponentInstance getComponentInstance()

Returns:
  the component instance on which this dependency is plugged.

#### getSize

    public int getSize()

Gets the number of actual matching references.

Returns:
  the number of matching references

#### onServiceArrival

    public abstract void onServiceArrival(org.osgi.framework.ServiceReference ref)

Concrete dependency callback. This method is called when a new service needs to be re-injected in the underlying concrete dependency.

Parameters:
  `ref` - the service reference to inject.

#### onServiceDeparture

    public abstract void onServiceDeparture(org.osgi.framework.ServiceReference ref)

Concrete dependency callback. This method is called when a used service (already injected) is leaving.

Parameters:
  `ref` - the leaving service reference.

#### onServiceModification

    public abstract void onServiceModification(org.osgi.framework.ServiceReference ref)

Concrete dependency callback. This method is called when a used service (already injected) is modified.

Parameters:
  `ref` - the modified service reference.

#### onDependencyReconfiguration

    public abstract void onDependencyReconfiguration(org.osgi.framework.ServiceReference[] departs,
                                                     org.osgi.framework.ServiceReference[] arrivals)

Concrete dependency callback. This method is called when the dependency is reconfigured and when this reconfiguration implies changes on the matching service set ( and by the way on the injected service).

Parameters:
  `departs` - the service leaving the matching set.
  `arrivals` - the service arriving in the matching set.

#### getState

    public int getState()

Gets the actual state of the dependency.

Returns:
  the state of the dependency.

#### getSpecification

    public java.lang.Class getSpecification()

Gets the tracked specification.

Returns:
  the Class object tracked by the dependency.

#### setSpecification

    public void setSpecification(java.lang.Class specification)

Sets the required specification of this service dependency. This operation is not supported if the dependency tracking has already begun. So, we don't have to hold a lock.

Parameters:
  `specification` - the required specification.

#### acquireWriteLockIfNotHeld

    public boolean acquireWriteLockIfNotHeld()

Acquires the write lock only and only if the write lock is not already held by the current thread.

Returns:
  true if the lock was acquired within the method, false otherwise.

#### releaseWriteLockIfHeld

    public boolean releaseWriteLockIfHeld()

Releases the write lock only and only if the write lock is held by the current thread.

Returns:
  true if the lock has no more holders, false otherwise.

#### acquireReadLockIfNotHeld

    public boolean acquireReadLockIfNotHeld()

Acquires the read lock only and only if no read lock is already held by the current thread. As the introspection methods provided by this method are java 6+, we just take a read lock.

Returns:
  true if the lock was acquired within the method, false otherwise.

#### releaseReadLockIfHeld

    public boolean releaseReadLockIfHeld()

Releases the read lock only and only if the read lock is held by the current thread. * As the introspection methods provided by this method are java 6+, we just unlock the read lock.

Returns:
  true if the lock has no more holders, false otherwise.

#### getFilter

    public java.lang.String getFilter()

Returns the dependency filter (String form).

Returns:
  the String form of the LDAP filter used by this dependency, `null` if not set.

#### setFilter

    public void setFilter(org.osgi.framework.Filter filter)

Sets the filter of the dependency. This method recomputes the matching set and call the onDependencyReconfiguration callback.

Parameters:
  `filter` - the new LDAP filter.

#### applyReconfiguration

    public void applyReconfiguration(ServiceReferenceManager.ChangeSet changeSet)

Applies the given reconfiguration. This method check if the current thread is holding the write lock, if not, acquire it. The lock will be released before calling callbacks. As a consequence, the caller has to check if the lock is still hold when this method returns.

Parameters:
  `changeSet` - the reconfiguration changes

#### isAggregate

    public boolean isAggregate()

#### setAggregate

    public void setAggregate(boolean isAggregate)

Sets the aggregate attribute of the current dependency. If the tracking is opened, it will call arrival and departure callbacks.

Parameters:
  `isAggregate` - the new aggregate attribute value.

#### setOptionality

    public void setOptionality(boolean isOptional)

Sets the optionality attribute of the current dependency.

Parameters:
  `isOptional` - the new optional attribute value.

#### isOptional

    public boolean isOptional()

#### getBindingPolicy

    public int getBindingPolicy()

Gets the used binding policy.

Returns:
  the current binding policy.

#### getComparator

    public java.lang.String getComparator()

Gets the used comparator name. `null` if no comparator (i.e. the OSGi one is used).

Returns:
  the comparator class name or `null` if the dependency doesn't use a comparator.

#### setComparator

    public void setComparator(java.util.Comparator<org.osgi.framework.ServiceReference> cmp)

#### setBundleContext

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

Sets the bundle context used by this dependency. This operation is not supported if the tracker is already opened, and as a consequence does not require locking.

Parameters:
  `context` - the bundle context or service context to use

#### getService

    public java.lang.Object getService(org.osgi.framework.ServiceReference ref)

Gets a service object for the given reference. The service object is stored to handle custom policies.

Parameters:
  `ref` - the wanted service reference
Returns:
  the service object attached to the given reference

#### getService

    public java.lang.Object getService(org.osgi.framework.ServiceReference ref,
                                       boolean store)

Gets a service object for the given reference.

Parameters:
  `ref` - the wanted service reference
  `store` - enables / disables the storing of the reference.
Returns:
  the service object attached to the given reference

#### ungetService

    public void ungetService(org.osgi.framework.ServiceReference ref)

Ungets a used service reference.

Parameters:
  `ref` - the reference to unget.

#### getContextSourceManager

    public ContextSourceManager getContextSourceManager()

#### getId

    public java.lang.String getId()

Gets the dependency id.

Returns:
  the dependency id. Specification name by default.

#### onChange

    public void onChange(ServiceReferenceManager.ChangeSet set)

Callbacks call by the ServiceReferenceManager when the selected service set has changed.

Parameters:
  `set` - the change set.

#### getServiceReferenceManager

    public ServiceReferenceManager getServiceReferenceManager()

#### getTracker

    public Tracker getTracker()

#### addListener

    public void addListener(DependencyModelListener listener)

Add the given listener to the dependency model's list of listeners.

Parameters:
  `listener` - the `DependencyModelListener` object to be added
Throws:
  `java.lang.NullPointerException` - if `listener` is `null`

#### removeListener

    public void removeListener(DependencyModelListener listener)

Remove the given listener from the dependency model's list of listeners.

Parameters:
  `listener` - the `DependencyModelListener` object to be removed
Throws:
  `java.lang.NullPointerException` - if `listener` is `null`
  `java.util.NoSuchElementException` - if `listener` wasn't present in the dependency model's list of listeners

#### notifyListeners

    public void notifyListeners(DependencyModel.DependencyEventType type,
                                org.osgi.framework.ServiceReference<?> service,
                                java.lang.Object object)

Notify all listeners that a change has occurred in this dependency model.

Parameters:
  `type` - the type of event
  `service` - the reference of the concerned service (may be null)
  `object` - the concerned service object (may be null)

#### cleanup

    public void cleanup()

Removes all the listeners from this dependency before it gets disposed.