Bug 563987 - add a current method for ServiceCaller

Many cases it is useful to just get the current available service from
the ServiceCaller instance.

Change-Id: I6a1cc3968c1aca55bea30265f2d97fb21500455e
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/ServiceCallerTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/ServiceCallerTest.java
index fb71dd2..b77e5bf 100644
--- a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/ServiceCallerTest.java
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/ServiceCallerTest.java
@@ -116,6 +116,10 @@
 		assertFalse("Should not be called.", thisClassCallerFilter.call(IServiceExample::call));
 		assertFalse("Should not be called.", otherClassCaller.call(IServiceExample::call));
 
+		assertFalse("Should not be present.", thisClassCaller.current().isPresent());
+		assertFalse("Should not be present.", thisClassCallerFilter.current().isPresent());
+		assertFalse("Should not be present.", otherClassCaller.current().isPresent());
+
 		ServiceExampleFactory factory = new ServiceExampleFactory();
 		Dictionary<String, String> props = new Hashtable<>();
 		props.put("test", "value1");
@@ -123,6 +127,8 @@
 		try {
 			assertTrue("Call returned false.", thisClassCaller.call(IServiceExample::call));
 			assertTrue("Service called successfully", factory.lastCreated.called);
+			assertTrue("Should be present.", thisClassCaller.current().isPresent());
+			assertEquals("Unexpected current.", thisClassCaller.current().get(), factory.lastCreated);
 
 			assertFalse("Should not be called.", thisClassCallerFilter.call(IServiceExample::call));
 
@@ -137,7 +143,7 @@
 			assertEquals("Wrong createCount", 1, factory.getCreateCount(testBundle));
 
 			Bundle[] users = reg.getReference().getUsingBundles();
-			assertNotNull("Didn't expect users.", users);
+			assertNotNull("Expected some users", users);
 
 			Collection<Bundle> userCollection = Arrays.asList(users);
 			assertTrue("Missing bundle.", userCollection.contains(bundle));
@@ -146,10 +152,13 @@
 			reg.unregister();
 			assertFalse("Should not be called.", thisClassCaller.call(IServiceExample::call));
 			assertFalse("Should not be called.", otherClassCaller.call(IServiceExample::call));
+			assertFalse("Should not be present.", thisClassCaller.current().isPresent());
 
 			props.put("test", "value2");
 			reg = context.registerService(IServiceExample.class, factory, props);
 
+			assertTrue("Should be present.", thisClassCaller.current().isPresent());
+			assertEquals("Unexpected current.", thisClassCaller.current().get(), factory.lastCreated);
 			assertTrue("Call returned false.", thisClassCaller.call(IServiceExample::call));
 			assertTrue("Call returned false.", thisClassCallerFilter.call(IServiceExample::call));
 			assertTrue("Call returned false.", otherClassCaller.call(IServiceExample::call));
@@ -176,6 +185,7 @@
 			reg.setProperties(props);
 			assertTrue("Call returned false.", thisClassCaller.call(IServiceExample::call));
 			assertFalse("Should not be called.", thisClassCallerFilter.call(IServiceExample::call));
+			assertFalse("Should not be present.", thisClassCallerFilter.current().isPresent());
 		} finally {
 			testBundle.uninstall();
 			thisClassCaller.unget();
diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/ServiceCaller.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/ServiceCaller.java
index b05c05a..483ff7c 100644
--- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/ServiceCaller.java
+++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/ServiceCaller.java
@@ -262,6 +262,14 @@
 		}).orElse(Boolean.FALSE);
 	}
 
+	/**
+	 * Return the currently available service.
+	 * @return the currently available service or empty if the service cannot be found.
+	 */
+	public Optional<Service> current() {
+		return trackCurrent().map((r) -> r.instance);
+	}
+
 	private Optional<ReferenceAndService> trackCurrent() {
 		ReferenceAndService current = service;
 		if (current != null) {