+++ /dev/null
-package org.argeo.osgi.util;
-
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.function.Function;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-public class OnServiceRegistration<R> implements Future<R> {
- private BundleContext ownBundleContext = FrameworkUtil.getBundle(OnServiceRegistration.class).getBundleContext();
-
- private ServiceTracker<?, ?> st;
-
- private R result;
- private boolean cancelled = false;
- private Throwable exception;
-
- public <T> OnServiceRegistration(Class<T> clss, Function<T, R> function) {
- this(null, clss, function);
- }
-
- public <T> OnServiceRegistration(BundleContext bundleContext, Class<T> clss, Function<T, R> function) {
- st = new ServiceTracker<T, T>(bundleContext != null ? bundleContext : ownBundleContext, clss, null) {
-
- @Override
- public T addingService(ServiceReference<T> reference) {
- T service = super.addingService(reference);
- try {
- if (result != null)// we only want the first one
- return service;
- result = function.apply(service);
- return service;
- } catch (Exception e) {
- exception = e;
- return service;
- } finally {
- close();
- }
- }
- };
- st.open(bundleContext == null);
- }
-
- @Override
- public boolean cancel(boolean mayInterruptIfRunning) {
- if (result != null || exception != null || cancelled)
- return false;
- st.close();
- cancelled = true;
- return true;
- }
-
- @Override
- public boolean isCancelled() {
- return cancelled;
- }
-
- @Override
- public boolean isDone() {
- return result != null || cancelled;
- }
-
- @Override
- public R get() throws InterruptedException, ExecutionException {
- st.waitForService(0);
- return tryGetResult();
- }
-
- @Override
- public R get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
- st.waitForService(TimeUnit.MILLISECONDS.convert(timeout, unit));
- if (result == null)
- throw new TimeoutException("No result after " + timeout + " " + unit);
- return tryGetResult();
- }
-
- protected R tryGetResult() throws ExecutionException, CancellationException {
- if (cancelled)
- throw new CancellationException();
- if (exception != null)
- throw new ExecutionException(exception);
- if (result == null)// this should not happen
- try {
- throw new IllegalStateException("No result available");
- } catch (Exception e) {
- exception = e;
- throw new ExecutionException(e);
- }
- return result;
- }
-
-}