Improve A2 provisioning framework.
[lgpl/argeo-commons.git] / org.argeo.osgi.boot / src / org / argeo / osgi / boot / a2 / ProvisioningManager.java
index e7a29707766df3d5ab1199e2d0bb0d48a6aa2175..c88af39d9d3bcb177fed1d8548f4ce3050e8b9d2 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.osgi.boot.a2;
 
-import java.io.InputStream;
+import java.io.File;
 import java.net.URI;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -13,18 +13,16 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.argeo.osgi.boot.OsgiBootException;
 import org.argeo.osgi.boot.OsgiBootUtils;
 import org.eclipse.osgi.launch.EquinoxFactory;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 import org.osgi.framework.launch.Framework;
-import org.osgi.framework.launch.FrameworkFactory;
 import org.osgi.framework.wiring.FrameworkWiring;
 
+/** Loads provisioning sources into an OSGi context. */
 public class ProvisioningManager {
        BundleContext bc;
        OsgiContext osgiContext;
@@ -36,13 +34,13 @@ public class ProvisioningManager {
                osgiContext.load();
        }
 
-       void addSource(ProvisioningSource context) {
-               sources.add(context);
+       protected void addSource(ProvisioningSource source) {
+               sources.add(source);
        }
 
-       void installWholeSource(ProvisioningSource context) {
+       void installWholeSource(ProvisioningSource source) {
                Set<Bundle> updatedBundles = new HashSet<>();
-               for (A2Contribution contribution : context.contributions.values()) {
+               for (A2Contribution contribution : source.listContributions(null)) {
                        for (A2Component component : contribution.components.values()) {
                                A2Module module = component.last().last();
                                Bundle bundle = installOrUpdate(module);
@@ -57,16 +55,20 @@ public class ProvisioningManager {
        public void registerSource(String uri) {
                try {
                        URI u = new URI(uri);
-                       if ("a2".equals(u.getScheme())) {
+                       if (A2Source.SCHEME_A2.equals(u.getScheme())) {
                                if (u.getHost() == null || "".equals(u.getHost())) {
-                                       Path base = Paths.get(u.getPath());
+                                       String baseStr = u.getPath();
+                                       if (File.separatorChar == '\\') {// MS Windows
+                                               baseStr = baseStr.substring(1).replace('/', File.separatorChar);
+                                       }
+                                       Path base = Paths.get(baseStr);
                                        FsA2Source source = new FsA2Source(base);
                                        source.load();
                                        addSource(source);
                                }
                        }
                } catch (Exception e) {
-                       throw new OsgiBootException("Cannot add source " + uri, e);
+                       throw new A2Exception("Cannot add source " + uri, e);
                }
        }
 
@@ -78,7 +80,10 @@ public class ProvisioningManager {
                                Path frameworkPath = Paths.get(frameworkLocationUri);
                                if (frameworkPath.getParent().getFileName().toString().equals(A2Contribution.BOOT)) {
                                        Path base = frameworkPath.getParent().getParent();
-                                       URI baseUri = new URI("a2", null, null, 0, base.toString(), null, null);
+                                       String baseStr = base.toString();
+                                       if (File.separatorChar == '\\')// MS Windows
+                                               baseStr = '/' + baseStr.replace(File.separatorChar, '/');
+                                       URI baseUri = new URI(A2Source.SCHEME_A2, null, null, 0, baseStr, null, null);
                                        registerSource(baseUri.toString());
                                        OsgiBootUtils.info("Registered " + baseUri + " as default source");
                                        return true;
@@ -98,15 +103,16 @@ public class ProvisioningManager {
                }
        }
 
-       /** @return the new/updated bundle, or null if nothign was done. */
-       Bundle installOrUpdate(A2Module module) {
+       /** @return the new/updated bundle, or null if nothing was done. */
+       protected Bundle installOrUpdate(A2Module module) {
                try {
                        ProvisioningSource moduleSource = module.getBranch().getComponent().getContribution().getSource();
                        Version moduleVersion = module.getVersion();
                        A2Branch osgiBranch = osgiContext.findBranch(module.getBranch().getComponent().getId(), moduleVersion);
                        if (osgiBranch == null) {
-                               Bundle bundle = bc.installBundle(module.getBranch().getCoordinates(),
-                                               moduleSource.newInputStream(module.getLocator()));
+//                             Bundle bundle = bc.installBundle(module.getBranch().getCoordinates(),
+//                                             moduleSource.newInputStream(module.getLocator()));
+                               Bundle bundle = moduleSource.install(bc, module);
                                if (OsgiBootUtils.isDebug())
                                        OsgiBootUtils.debug("Installed bundle " + bundle.getLocation() + " with version " + moduleVersion);
                                return bundle;
@@ -115,13 +121,14 @@ public class ProvisioningManager {
                                int compare = moduleVersion.compareTo(lastOsgiModule.getVersion());
                                if (compare > 0) {// update
                                        Bundle bundle = (Bundle) lastOsgiModule.getLocator();
-                                       bundle.update(moduleSource.newInputStream(module.getLocator()));
+//                                     bundle.update(moduleSource.newInputStream(module.getLocator()));
+                                       moduleSource.update(bundle, module);
                                        OsgiBootUtils.info("Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
                                        return bundle;
                                }
                        }
                } catch (Exception e) {
-                       OsgiBootUtils.error("Could not install module " + module, e);
+                       OsgiBootUtils.error("Could not install module " + module + ": " + e.getMessage(), e);
                }
                return null;
        }
@@ -140,8 +147,9 @@ public class ProvisioningManager {
                                Version moduleVersion = module.getVersion();
                                int compare = moduleVersion.compareTo(version);
                                if (compare > 0) {// update
-                                       try (InputStream in = source.newInputStream(module.getLocator())) {
-                                               bundle.update(in);
+                                       try {
+                                               source.update(bundle, module);
+//                                             bundle.update(in);
                                                String fragmentHost = bundle.getHeaders().get(Constants.FRAGMENT_HOST);
                                                if (fragmentHost != null)
                                                        fragmentsUpdated = true;
@@ -161,22 +169,10 @@ public class ProvisioningManager {
                return updatedBundles;
        }
 
-       private static Framework launch() {
-               // start OSGi
-               FrameworkFactory frameworkFactory = new EquinoxFactory();
+       public static void main(String[] args) {
                Map<String, String> configuration = new HashMap<>();
                configuration.put("osgi.console", "2323");
-               Framework framework = frameworkFactory.newFramework(configuration);
-               try {
-                       framework.start();
-               } catch (BundleException e) {
-                       throw new OsgiBootException("Cannot start OSGi framework", e);
-               }
-               return framework;
-       }
-
-       public static void main(String[] args) {
-               Framework framework = launch();
+               Framework framework = OsgiBootUtils.launch(new EquinoxFactory(), configuration);
                try {
                        ProvisioningManager pm = new ProvisioningManager(framework.getBundleContext());
                        FsA2Source context = new FsA2Source(Paths.get(