You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2013/03/07 12:36:42 UTC
svn commit: r1453783 - in /aries/trunk/util/util-r42/src:
main/java/org/apache/aries/util/tracker/SingleServiceTracker.java
test/java/org/apache/aries/util/SingleServiceTrackerTest.java
Author: timothyjward
Date: Thu Mar 7 11:36:41 2013
New Revision: 1453783
URL: http://svn.apache.org/r1453783
Log:
ARIES-1024 : Fix SingleServiceTracker so that it finds pre-registered services properly when using a filter
Modified:
aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/tracker/SingleServiceTracker.java
aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/SingleServiceTrackerTest.java
Modified: aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/tracker/SingleServiceTracker.java
URL: http://svn.apache.org/viewvc/aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/tracker/SingleServiceTracker.java?rev=1453783&r1=1453782&r2=1453783&view=diff
==============================================================================
--- aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/tracker/SingleServiceTracker.java (original)
+++ aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/tracker/SingleServiceTracker.java Thu Mar 7 11:36:41 2013
@@ -23,7 +23,7 @@ import java.util.concurrent.atomic.Atomi
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
@@ -45,7 +45,7 @@ public final class SingleServiceTracker<
private final AtomicBoolean open = new AtomicBoolean(false);
private final SingleServiceListener serviceListener;
private String filterString;
- private Filter filter;
+ private boolean isCustomFilter;
private final ServiceListener listener = new ServiceListener()
{
@@ -69,13 +69,17 @@ public final class SingleServiceTracker<
ctx = context;
this.className = clazz.getName();
serviceListener = sl;
+ this.filterString = '(' + Constants.OBJECTCLASS + '=' + className + ')';
}
public SingleServiceTracker(BundleContext context, Class<T> clazz, String filterString, SingleServiceListener sl) throws InvalidSyntaxException
{
this(context, clazz, sl);
- this.filterString = filterString;
- if (filterString != null) filter = context.createFilter(filterString);
+ if (filterString != null) {
+ this.filterString = "(&" + this.filterString + filterString + ')';
+ isCustomFilter = true;
+ }
+ FrameworkUtil.createFilter(this.filterString);
}
public T getService()
@@ -92,8 +96,6 @@ public final class SingleServiceTracker<
{
if (open.compareAndSet(false, true)) {
try {
- String filterString = '(' + Constants.OBJECTCLASS + '=' + className + ')';
- if (filter != null) filterString = "(&" + filterString + filter + ')';
ctx.addServiceListener(listener, filterString);
findMatchingReference(null);
} catch (InvalidSyntaxException e) {
@@ -104,8 +106,23 @@ public final class SingleServiceTracker<
private void findMatchingReference(ServiceReference original) {
boolean clear = true;
- ServiceReference ref = ctx.getServiceReference(className);
- if (ref != null && (filter == null || filter.match(ref))) {
+ ServiceReference ref;
+ if(isCustomFilter) {
+ try {
+ ServiceReference[] refs = ctx.getServiceReferences(className, filterString);
+ if(refs == null || refs.length == 0) {
+ ref = null;
+ } else {
+ ref = refs[0];
+ }
+ } catch (InvalidSyntaxException e) {
+ //This can't happen, we'd have blown up in the constructor
+ ref = null;
+ }
+ } else {
+ ref = ctx.getServiceReference(className);
+ }
+ if (ref != null) {
@SuppressWarnings("unchecked")
T service = (T) ctx.getService(ref);
if (service != null) {
Modified: aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/SingleServiceTrackerTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/SingleServiceTrackerTest.java?rev=1453783&r1=1453782&r2=1453783&view=diff
==============================================================================
--- aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/SingleServiceTrackerTest.java (original)
+++ aries/trunk/util/util-r42/src/test/java/org/apache/aries/util/SingleServiceTrackerTest.java Thu Mar 7 11:36:41 2013
@@ -18,6 +18,10 @@
*/
package org.apache.aries.util;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
import org.apache.aries.mocks.BundleContextMock;
import org.apache.aries.unittest.mocks.MethodCall;
import org.apache.aries.unittest.mocks.Skeleton;
@@ -27,6 +31,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
import static org.junit.Assert.*;
@@ -46,12 +51,68 @@ public class SingleServiceTrackerTest {
}
private void createSut() {
+ createSut(null);
+ }
+
+ private void createSut(String filter) {
listener = Skeleton.newMock(SingleServiceListener.class);
- sut = new SingleServiceTracker<String>(ctx, String.class, listener);
+ try {
+ sut = new SingleServiceTracker<String>(ctx, String.class, filter, listener);
+ } catch (InvalidSyntaxException e) {
+ throw new RuntimeException(e);
+ }
sut.open();
}
@Test
+ public void testBeforeTheFactService() {
+ ctx.registerService("java.lang.String", "uno", null);
+ createSut();
+ Skeleton.getSkeleton(listener).assertCalled(Arrays.asList(new MethodCall(SingleServiceListener.class, "serviceFound")), true);
+ assertEquals("uno", sut.getService());
+ }
+
+ @Test
+ public void testBeforeTheFactServiceDoubleRegistration() {
+ testBeforeTheFactService();
+
+ ctx.registerService("java.lang.String", "due", null);
+ Skeleton.getSkeleton(listener).assertCalled(Arrays.asList(new MethodCall(SingleServiceListener.class, "serviceFound")), true);
+ assertEquals("uno", sut.getService());
+ }
+
+ @Test
+ public void testBeforeTheFactChoice() {
+ ctx.registerService("java.lang.String", "uno", null);
+ ctx.registerService("java.lang.String", "due", null);
+ createSut();
+ Skeleton.getSkeleton(listener).assertCalled(Arrays.asList(new MethodCall(SingleServiceListener.class, "serviceFound")), true);
+ assertEquals("uno", sut.getService());
+ }
+
+ @Test
+ public void testBeforeTheFactChoiceWithPropertiesAndFilterWithFirstMatch() {
+ Dictionary<String, String> props = new Hashtable<String, String>();
+ props.put("foo", "bar");
+ ctx.registerService("java.lang.String", "uno", props);
+ ctx.registerService("java.lang.String", "due", null);
+ createSut("(foo=bar)");
+ Skeleton.getSkeleton(listener).assertCalled(Arrays.asList(new MethodCall(SingleServiceListener.class, "serviceFound")), true);
+ assertEquals("uno", sut.getService());
+ }
+
+ @Test
+ public void testBeforeTheFactChoiceWithPropertiesAndFilterWithSecondMatch() {
+ Dictionary<String, String> props = new Hashtable<String, String>();
+ props.put("foo", "bar");
+ ctx.registerService("java.lang.String", "uno", null);
+ ctx.registerService("java.lang.String", "due", props);
+ createSut("(foo=bar)");
+ Skeleton.getSkeleton(listener).assertCalled(Arrays.asList(new MethodCall(SingleServiceListener.class, "serviceFound")), true);
+ assertEquals("due", sut.getService());
+ }
+
+ @Test
public void testAfterTheFactService()
{
createSut();