package org.argeo.osgi.util; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.ForkJoinPool; import org.argeo.util.register.Register; import org.argeo.util.register.Singleton; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; public class OsgiRegister implements Register { private final BundleContext bundleContext; private Executor executor; private CompletableFuture shutdownStarting = new CompletableFuture(); public OsgiRegister(BundleContext bundleContext) { this.bundleContext = bundleContext; // TODO experiment with dedicated executors this.executor = ForkJoinPool.commonPool(); } @Override public Singleton set(T obj, Class clss, Map attributes, Class... classes) { CompletableFuture> srf = new CompletableFuture>(); CompletableFuture postRegistration = CompletableFuture.supplyAsync(() -> { List lst = new ArrayList<>(); lst.add(clss.getName()); for (Class c : classes) { lst.add(c.getName()); } ServiceRegistration sr = bundleContext.registerService(lst.toArray(new String[lst.size()]), obj, new Hashtable(attributes)); srf.complete(sr); return obj; }, executor); Singleton singleton = new Singleton(clss, postRegistration); shutdownStarting. // thenCompose(singleton::prepareUnregistration). // thenRunAsync(() -> { try { srf.get().unregister(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } }, executor); return singleton; } public void shutdown() { shutdownStarting.complete(null); } }