Add a test checking an interceptor implementing both tracking and ranking.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1549051 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/interceptors/TrackerAndRankerInterceptor.java b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/interceptors/TrackerAndRankerInterceptor.java
new file mode 100644
index 0000000..9f7b4cf
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/main/java/org/apache/felix/ipojo/runtime/core/test/interceptors/TrackerAndRankerInterceptor.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.runtime.core.test.interceptors;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Provides;
+import org.apache.felix.ipojo.annotations.ServiceProperty;
+import org.apache.felix.ipojo.dependency.interceptors.DefaultDependencyInterceptor;
+import org.apache.felix.ipojo.dependency.interceptors.ServiceRankingInterceptor;
+import org.apache.felix.ipojo.dependency.interceptors.ServiceTrackingInterceptor;
+import org.apache.felix.ipojo.dependency.interceptors.TransformedServiceReference;
+import org.apache.felix.ipojo.runtime.core.test.services.Setter;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * An interceptor implements both ranking and tracking interfaces.
+ */
+@Component(immediate = true)
+@Provides
+public class TrackerAndRankerInterceptor extends DefaultDependencyInterceptor implements Setter,
+        ServiceTrackingInterceptor, ServiceRankingInterceptor {
+
+    private static final int HIGH = 1;
+    private static final int LOW = 0;
+
+    @ServiceProperty
+    private String target;
+
+    GradeComparator comparator = new GradeComparator();
+    private int mode = HIGH;
+    private boolean reverse = false;
+
+    @Override
+    public List<ServiceReference> getServiceReferences(DependencyModel dependency, List<ServiceReference> matching) {
+        List<ServiceReference> references = new ArrayList<ServiceReference>();
+        for (ServiceReference ref : matching) {
+            if (ref.getProperty("grade") != null) {
+                references.add(ref);
+            }
+        }
+
+        Collections.sort(references, comparator);
+        if (reverse) {
+            Collections.reverse(references);
+        }
+        return references;
+    }
+
+    @Override
+    public List<ServiceReference> onServiceArrival(DependencyModel dependency, List<ServiceReference> matching, ServiceReference<?> reference) {
+        return getServiceReferences(dependency, matching);
+    }
+
+    @Override
+    public List<ServiceReference> onServiceDeparture(DependencyModel dependency, List<ServiceReference> matching, ServiceReference<?> reference) {
+        return getServiceReferences(dependency, matching);
+    }
+
+    @Override
+    public List<ServiceReference> onServiceModified(DependencyModel dependency, List<ServiceReference> matching, ServiceReference<?> reference) {
+        return getServiceReferences(dependency, matching);
+    }
+
+    @Override
+    public <S> TransformedServiceReference<S> accept(DependencyModel dependency, BundleContext context, TransformedServiceReference<S> ref) {
+        // Only accept services having a grade in LOW or HIGH according to the mode.
+        if (mode == HIGH) {
+           if (((Integer) ref.get("grade")) > 3) {
+               return ref;
+           }
+        } else {
+            if (((Integer) ref.get("grade")) <= 3) {
+                return ref;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void set(String newValue) {
+        if (newValue.contains("HIGH")) {
+            mode = HIGH;
+            invalidateMatchingServices();
+        }
+        if (newValue.contains("LOW")) {
+            mode = LOW;
+            invalidateMatchingServices();
+        }
+        if (newValue.contains("REVERSE")) {
+            reverse = true;
+            invalidateSelectedServices();
+        }
+    }
+
+    /**
+     * Notifies the managed dependencies of a change in the set of services selected by this interceptor.
+     * The dependency will call the getServiceReferences method to recompute the set of selected services.
+     */
+    public void invalidateSelectedServices() {
+        List<DependencyModel> list = new ArrayList<DependencyModel>();
+        synchronized (this) {
+            list.addAll(dependencies);
+        }
+
+        for (DependencyModel dep : list) {
+            dep.invalidateSelectedServices();
+        }
+    }
+
+    /**
+     * Notifies the managed dependencies of a change in the set of services accepted by this interceptor.
+     * The dependency will call the accept method to recompute the set of matching services.
+     */
+    public void invalidateMatchingServices() {
+        List<DependencyModel> list = new ArrayList<DependencyModel>();
+        synchronized (this) {
+            list.addAll(dependencies);
+        }
+
+        for (DependencyModel dep : list) {
+            dep.invalidateMatchingServices();
+        }
+    }
+}
diff --git a/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestCombinationOfInterceptors.java b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestCombinationOfInterceptors.java
new file mode 100644
index 0000000..36108c5
--- /dev/null
+++ b/ipojo/runtime/core-it/ipojo-core-service-dependency-interceptor-test/src/test/java/org/apache/felix/ipojo/runtime/core/test/dependencies/TestCombinationOfInterceptors.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.runtime.core.test.dependencies;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.runtime.core.test.services.CheckService;
+import org.apache.felix.ipojo.runtime.core.test.services.Setter;
+import org.junit.Test;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+/**
+ * Checks the combination of tracking and ranking interceptors.
+ *
+ * First, the tracking interceptor selects the references, it also transforms them.
+ * Then, the ranking interceptor sorts the remaining references.
+ */
+public class TestCombinationOfInterceptors extends Common {
+
+    private ComponentInstance provider1;
+    private ComponentInstance provider2;
+    private ComponentInstance provider3;
+    private ComponentInstance provider4;
+    private ComponentInstance provider5;
+    private ComponentInstance provider6;
+
+    @Test
+    public void test() {
+
+        provider1 = provider(0);
+        provider2 = provider(1);
+        provider3 = provider(2);
+        provider4 = provider(3);
+        provider5 = provider(4);
+        provider6 = provider(5);
+
+        // Create the interceptor
+        Properties configuration = new Properties();
+        configuration.put("target", "(dependency.id=foo)");
+        ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.test.interceptors" +
+                ".TrackerAndRankerInterceptor", configuration);
+
+        // Create the FooConsumer
+        ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.test.components.FooConsumer");
+
+        // Check we are using provider 2
+        osgiHelper.waitForService(CheckService.class.getName(), null, 1000, true);
+        CheckService check = osgiHelper.getServiceObject(CheckService.class);
+        assertThat(check.getProps().get("grade")).isEqualTo(5);
+
+        provider6.dispose();
+
+        assertThat(check.getProps().get("grade")).isEqualTo(4);
+
+        // Change range
+        Setter setter = osgiHelper.getServiceObject(Setter.class);
+        setter.set("LOW REVERSE");
+
+//        check = osgiHelper.getServiceObject(CheckService.class);
+//        assertThat(check.getProps().get("grade")).isEqualTo(3);
+//
+//        setter.set("REVERSE");
+//        check = osgiHelper.getServiceObject(CheckService.class);
+        assertThat(check.getProps().get("grade")).isEqualTo(0);
+    }
+
+
+    private ComponentInstance provider(int i) {
+        Dictionary<String, String> configuration = new Hashtable<String, String>();
+        configuration.put("grade", Integer.toString(i));
+        return ipojoHelper.createComponentInstance("org.apache.felix.ipojo.runtime.core.test.components.FooProvider",
+                configuration);
+    }
+}