]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/osgi/util/OnServiceRegistration.java
Mini desktop graalvm packaging.
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / osgi / util / OnServiceRegistration.java
1 package org.argeo.osgi.util;
2
3 import java.util.concurrent.CancellationException;
4 import java.util.concurrent.ExecutionException;
5 import java.util.concurrent.Future;
6 import java.util.concurrent.TimeUnit;
7 import java.util.concurrent.TimeoutException;
8 import java.util.function.Function;
9
10 import org.osgi.framework.BundleContext;
11 import org.osgi.framework.FrameworkUtil;
12 import org.osgi.framework.ServiceReference;
13 import org.osgi.util.tracker.ServiceTracker;
14
15 public class OnServiceRegistration<R> implements Future<R> {
16 private BundleContext ownBundleContext = FrameworkUtil.getBundle(OnServiceRegistration.class).getBundleContext();
17
18 private ServiceTracker<?, ?> st;
19
20 private R result;
21 private boolean cancelled = false;
22 private Throwable exception;
23
24 public <T> OnServiceRegistration(Class<T> clss, Function<T, R> function) {
25 this(null, clss, function);
26 }
27
28 public <T> OnServiceRegistration(BundleContext bundleContext, Class<T> clss, Function<T, R> function) {
29 st = new ServiceTracker<T, T>(bundleContext != null ? bundleContext : ownBundleContext, clss, null) {
30
31 @Override
32 public T addingService(ServiceReference<T> reference) {
33 T service = super.addingService(reference);
34 try {
35 if (result != null)// we only want the first one
36 return service;
37 result = function.apply(service);
38 return service;
39 } catch (Exception e) {
40 exception = e;
41 return service;
42 } finally {
43 close();
44 }
45 }
46 };
47 st.open(bundleContext == null);
48 }
49
50 @Override
51 public boolean cancel(boolean mayInterruptIfRunning) {
52 if (result != null || exception != null || cancelled)
53 return false;
54 st.close();
55 cancelled = true;
56 return true;
57 }
58
59 @Override
60 public boolean isCancelled() {
61 return cancelled;
62 }
63
64 @Override
65 public boolean isDone() {
66 return result != null || cancelled;
67 }
68
69 @Override
70 public R get() throws InterruptedException, ExecutionException {
71 st.waitForService(0);
72 return tryGetResult();
73 }
74
75 @Override
76 public R get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
77 st.waitForService(TimeUnit.MILLISECONDS.convert(timeout, unit));
78 if (result == null)
79 throw new TimeoutException("No result after " + timeout + " " + unit);
80 return tryGetResult();
81 }
82
83 protected R tryGetResult() throws ExecutionException, CancellationException {
84 if (cancelled)
85 throw new CancellationException();
86 if (exception != null)
87 throw new ExecutionException(exception);
88 if (result == null)// this should not happen
89 try {
90 throw new IllegalStateException("No result available");
91 } catch (Exception e) {
92 exception = e;
93 throw new ExecutionException(e);
94 }
95 return result;
96 }
97
98 }