]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.init/src/org/argeo/init/osgi/OsgiRuntimeContext.java
Better integrate RCP build
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / init / osgi / OsgiRuntimeContext.java
1 package org.argeo.init.osgi;
2
3 import java.util.Collections;
4 import java.util.Hashtable;
5 import java.util.Map;
6 import java.util.Objects;
7 import java.util.Optional;
8 import java.util.ServiceLoader;
9 import java.util.concurrent.Flow;
10 import java.util.function.Consumer;
11
12 import org.argeo.init.RuntimeContext;
13 import org.argeo.init.logging.ThinLoggerFinder;
14 import org.osgi.framework.Bundle;
15 import org.osgi.framework.BundleContext;
16 import org.osgi.framework.BundleException;
17 import org.osgi.framework.Constants;
18 import org.osgi.framework.ServiceRegistration;
19 import org.osgi.framework.launch.Framework;
20 import org.osgi.framework.launch.FrameworkFactory;
21
22 /** An OSGi runtime context. */
23 public class OsgiRuntimeContext implements RuntimeContext {
24 private Map<String, String> config;
25 private Framework framework;
26 private OsgiBoot osgiBoot;
27
28 @SuppressWarnings("rawtypes")
29 private ServiceRegistration<Consumer> loggingConfigurationSr;
30 @SuppressWarnings("rawtypes")
31 private ServiceRegistration<Flow.Publisher> logEntryPublisherSr;
32
33 public OsgiRuntimeContext(Map<String, String> config) {
34 this.config = config;
35 }
36
37 public OsgiRuntimeContext(BundleContext bundleContext) {
38 start(bundleContext);
39 }
40
41 @Override
42 public void run() {
43 ServiceLoader<FrameworkFactory> sl = ServiceLoader.load(FrameworkFactory.class);
44 Optional<FrameworkFactory> opt = sl.findFirst();
45 if (opt.isEmpty())
46 throw new IllegalStateException("Cannot find OSGi framework");
47 framework = opt.get().newFramework(config);
48 try {
49 framework.start();
50 BundleContext bundleContext = framework.getBundleContext();
51 start(bundleContext);
52 } catch (BundleException e) {
53 throw new IllegalStateException("Cannot start OSGi framework", e);
54 }
55 }
56
57 public void start(BundleContext bundleContext) {
58 // logging
59 loggingConfigurationSr = bundleContext.registerService(Consumer.class,
60 ThinLoggerFinder.getConfigurationConsumer(),
61 new Hashtable<>(Collections.singletonMap(Constants.SERVICE_PID, "argeo.logging.configuration")));
62 logEntryPublisherSr = bundleContext.registerService(Flow.Publisher.class,
63 ThinLoggerFinder.getLogEntryPublisher(),
64 new Hashtable<>(Collections.singletonMap(Constants.SERVICE_PID, "argeo.logging.publisher")));
65
66 osgiBoot = new OsgiBoot(bundleContext);
67 osgiBoot.bootstrap();
68
69 }
70
71 public void update() {
72 Objects.requireNonNull(osgiBoot);
73 osgiBoot.update();
74 }
75
76 public void stop(BundleContext bundleContext) {
77 // if (loggingConfigurationSr != null)
78 // try {
79 // loggingConfigurationSr.unregister();
80 // } catch (Exception e) {
81 // // silent
82 // }
83 // if (logEntryPublisherSr != null)
84 // try {
85 // logEntryPublisherSr.unregister();
86 // } catch (Exception e) {
87 // // silent
88 // }
89 }
90
91 @Override
92 public void waitForStop(long timeout) throws InterruptedException {
93 if (framework == null)
94 throw new IllegalStateException("Framework is not initialised");
95
96 framework.waitForStop(timeout);
97 }
98
99 public void close() throws Exception {
100 // TODO make shutdown of dynamic service more robust
101 Bundle scrBundle = osgiBoot.getBundlesBySymbolicName().get("org.apache.felix.scr");
102 if (scrBundle != null) {
103 scrBundle.stop();
104 while (!(scrBundle.getState() <= Bundle.RESOLVED)) {
105 Thread.sleep(500);
106 }
107 Thread.sleep(1000);
108 }
109
110 stop(framework.getBundleContext());
111 if (framework != null)
112 framework.stop();
113
114 }
115
116 }