Improve nested OSGi runtimes
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / init / osgi / OsgiRuntimeContext.java
index 2e8c1042ca7d20e21d749fecd7eb418833f9f07b..3d4b9768c34c33d75e0519a3f2b376b4ed5fe4ee 100644 (file)
@@ -4,15 +4,19 @@ import java.io.Serializable;
 import java.lang.System.Logger;
 import java.lang.System.Logger.Level;
 import java.lang.System.LoggerFinder;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Hashtable;
+import java.util.List;
 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 java.util.function.Supplier;
 
+import org.argeo.api.init.InitConstants;
 import org.argeo.api.init.RuntimeContext;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
@@ -28,20 +32,42 @@ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable {
        private final static long STOP_FOR_UPDATE_TIMEOUT = 60 * 1000;
        private final static long CLOSE_TIMEOUT = 60 * 1000;
 
-       // private final static String SYMBOLIC_NAME_FELIX_SCR = "org.apache.felix.scr";
-
-       private ConnectFrameworkFactory frameworkFactory;
+       private final ConnectFrameworkFactory frameworkFactory;
        private Map<String, String> config;
        private Framework framework;
-//     private OsgiBoot osgiBoot;
+
+       // Nested runtimes
+//     private final BundleContext foreignBundleContext;
+       // private final List<String> foreignCategories;
+
+       private final ForeignModuleConnector moduleConnector;
 
        /**
         * Constructor to use when the runtime context will create the OSGi
         * {@link Framework}.
         */
        public OsgiRuntimeContext(ConnectFrameworkFactory frameworkFactory, Map<String, String> config) {
+               this(frameworkFactory, config, null, null);
+       }
+
+       /**
+        * Constructor to use when the runtime context will create the OSGi
+        * {@link Framework} and will potentially have a parent runtime.
+        */
+       OsgiRuntimeContext(ConnectFrameworkFactory frameworkFactory, Map<String, String> config,
+                       BundleContext foreignBundleContext, List<String> foreignCategories) {
                this.frameworkFactory = frameworkFactory;
                this.config = config;
+               if (foreignCategories != null) {
+//             String parentCategories = config.get(InitConstants.PROP_ARGEO_OSGI_PARENT_CATEGORIES);
+//             if (parentCategories != null) {
+//                     Objects.requireNonNull(foreignBundleContext, "Foreign bundle context");
+//                     List<String> foreignCategories = Arrays.asList(parentCategories.trim().split(","));
+//                     foreignCategories.removeIf((s) -> "".equals(s));
+                       this.moduleConnector = new ForeignModuleConnector(foreignBundleContext, foreignCategories);
+               } else {
+                       this.moduleConnector = null;
+               }
        }
 
        /**
@@ -49,6 +75,9 @@ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable {
         * means.
         */
        OsgiRuntimeContext(BundleContext bundleContext) {
+               this.frameworkFactory = null;
+               // TODO try nesting within Eclipse PDE
+               this.moduleConnector = null;
                start(bundleContext);
        }
 
@@ -63,7 +92,7 @@ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable {
 //                     if (opt.isEmpty())
 //                             throw new IllegalStateException("Cannot find OSGi framework");
 //                     framework = opt.get().newFramework(config);
-                       framework = frameworkFactory.newFramework(config, null);
+                       framework = frameworkFactory.newFramework(config, moduleConnector);
                }
 
                try {
@@ -101,6 +130,8 @@ public class OsgiRuntimeContext implements RuntimeContext, AutoCloseable {
                OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
                String frameworkUuuid = bundleContext.getProperty(Constants.FRAMEWORK_UUID);
 
+//             osgiBoot.bootstrap();
+
                // separate thread in order to improve logging
                Thread osgiBootThread = new Thread("OSGi boot framework " + frameworkUuuid) {
                        @Override