X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.init%2Fsrc%2Forg%2Fargeo%2Finit%2Fosgi%2FOsgiRuntimeContext.java;h=186577b4dba40dda3ee7169b0d2bb4c863489c10;hb=9fd6762a7ac6bb5102dcd2c5a3bc876aa5c942c4;hp=91756e32b6759921484c0c1bf6b937408ccd4ab7;hpb=b7d8618ce593bbeca7e311d32a4d98988e27f877;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java b/org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java index 91756e32b..186577b4d 100644 --- a/org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java +++ b/org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java @@ -1,24 +1,46 @@ package org.argeo.init.osgi; +import java.lang.System.LoggerFinder; +import java.util.Collections; +import java.util.Hashtable; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.ServiceLoader; +import java.util.concurrent.Flow; +import java.util.function.Consumer; import org.argeo.init.RuntimeContext; +import org.argeo.init.logging.ThinLoggerFinder; +import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; +import org.osgi.framework.Constants; import org.osgi.framework.launch.Framework; import org.osgi.framework.launch.FrameworkFactory; -public class OsgiRuntimeContext implements RuntimeContext { +/** An OSGi runtime context. */ +public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable { private Map config; private Framework framework; private OsgiBoot osgiBoot; + /** + * Constructor to use when the runtime context will create the OSGi + * {@link Framework}. + */ public OsgiRuntimeContext(Map config) { this.config = config; } + /** + * Constructor to use when the OSGi {@link Framework} has been created by other + * means. + */ + OsgiRuntimeContext(BundleContext bundleContext) { + start(bundleContext); + } + @Override public void run() { ServiceLoader sl = ServiceLoader.load(FrameworkFactory.class); @@ -29,24 +51,78 @@ public class OsgiRuntimeContext implements RuntimeContext { try { framework.start(); BundleContext bundleContext = framework.getBundleContext(); - osgiBoot = new OsgiBoot(bundleContext); - osgiBoot.bootstrap(); + start(bundleContext); } catch (BundleException e) { throw new IllegalStateException("Cannot start OSGi framework", e); } } + public void start(BundleContext bundleContext) { + // preferences +// SystemRootPreferences systemRootPreferences = ThinPreferencesFactory.getInstance().getSystemRootPreferences(); +// bundleContext.registerService(AbstractPreferences.class, systemRootPreferences, new Hashtable<>()); + + // Make sure LoggerFinder has been searched for, since it is lazily loaded + LoggerFinder.getLoggerFinder(); + + // logging + bundleContext.registerService(Consumer.class, ThinLoggerFinder.getConfigurationConsumer(), + new Hashtable<>(Collections.singletonMap(Constants.SERVICE_PID, "argeo.logging.configuration"))); + bundleContext.registerService(Flow.Publisher.class, ThinLoggerFinder.getLogEntryPublisher(), + new Hashtable<>(Collections.singletonMap(Constants.SERVICE_PID, "argeo.logging.publisher"))); + + osgiBoot = new OsgiBoot(bundleContext); + osgiBoot.bootstrap(config); + + } + + public void update() { + Objects.requireNonNull(osgiBoot); + osgiBoot.update(); + } + + public void stop(BundleContext bundleContext) { +// if (loggingConfigurationSr != null) +// try { +// loggingConfigurationSr.unregister(); +// } catch (Exception e) { +// // silent +// } +// if (logEntryPublisherSr != null) +// try { +// logEntryPublisherSr.unregister(); +// } catch (Exception e) { +// // silent +// } + } + @Override public void waitForStop(long timeout) throws InterruptedException { if (framework == null) throw new IllegalStateException("Framework is not initialised"); + framework.waitForStop(timeout); } - @Override public void close() throws Exception { + // TODO make shutdown of dynamic service more robust + Bundle scrBundle = osgiBoot.getBundlesBySymbolicName().get("org.apache.felix.scr"); + if (scrBundle != null) { + scrBundle.stop(); + while (!(scrBundle.getState() <= Bundle.RESOLVED)) { + Thread.sleep(500); + } + Thread.sleep(1000); + } + + stop(framework.getBundleContext()); if (framework != null) framework.stop(); + + } + + public Framework getFramework() { + return framework; } }