Fix FELIX-4199 and FELIX-4200
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1516441 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java
index cf56966..21f9f22 100644
--- a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/dependency/impl/ServiceReferenceManager.java
@@ -77,12 +77,11 @@
private Tracker m_trackingInterceptorTracker;
/**
* The set of tracking interceptors.
- * TODO this set should be ranking according to the OSGi ranking policy.
+ * TODO this set should be sorted according to the OSGi ranking policy.
* The filter is always the last interceptor.
*/
private LinkedList<ServiceTrackingInterceptor> m_trackingInterceptors = new
LinkedList<ServiceTrackingInterceptor>();
- private List<ServiceReference> serviceReferencesList;
/**
* Creates the service reference manager.
@@ -94,9 +93,11 @@
public ServiceReferenceManager(DependencyModel dep, Filter filter, Comparator<ServiceReference> comparator) {
m_dependency = dep;
m_filter = filter;
- if (m_filter != null) {
- m_trackingInterceptors.addLast(new FilterBasedServiceTrackingInterceptor(m_filter));
- }
+ // The Filter based service tracking interceptor needs to be created every time even if the filter is null.
+ // This arises from the potential re-implementation of the match method in the dependency implementation.
+ // It must be the last interceptor as the chain ends on the filter matching. (FELIX-4199)
+ m_trackingInterceptors.addLast(new FilterBasedServiceTrackingInterceptor(m_filter));
+
if (comparator != null) {
m_comparator = comparator;
m_rankingInterceptor = new ComparatorBasedServiceRankingInterceptor(comparator);
@@ -134,7 +135,9 @@
}
public void removedService(ServiceReference reference, Object service) {
- if (service != null && m_trackingInterceptors.contains(service)) {
+ if (service != null && service instanceof ServiceTrackingInterceptor &&
+ m_trackingInterceptors.contains(service)
+ ) {
removeTrackingInterceptor((ServiceTrackingInterceptor) service);
}
}
@@ -235,7 +238,7 @@
ServiceReference oldBest = getFirstService();
// Recompute the matching services.
m_matchingReferences.clear();
- serviceReferencesList = m_dependency.getTracker().getServiceReferencesList();
+ final List<ServiceReference> serviceReferencesList = m_dependency.getTracker().getServiceReferencesList();
if (serviceReferencesList != null) {
for (ServiceReference reference : serviceReferencesList) {
TransformedServiceReference ref = new TransformedServiceReferenceImpl(reference);
@@ -345,13 +348,14 @@
* This method is called when holding the write lock on the dependency.
*
* @param reference the reference
- * @param <S>
+ * @param <S> the service interface
* @return the transformed reference, null if rejected
*/
private <S> TransformedServiceReference<S> accept(TransformedServiceReference<S> reference) {
TransformedServiceReference<S> accumulator = reference;
for (ServiceTrackingInterceptor interceptor : m_trackingInterceptors) {
- TransformedServiceReference<S> accepted = interceptor.accept(m_dependency, m_dependency.getBundleContext(), reference);
+ TransformedServiceReference<S> accepted = interceptor.accept(m_dependency,
+ m_dependency.getBundleContext(), accumulator);
if (accepted != null) {
accumulator = accepted;
} else {