A2 variants supported
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / init / a2 / ProvisioningManager.java
index 6012c34ee6d20afc9fc954cbe5a4005890c912c4..6d842650c2620fd2d26249bf69d7d741a37aa3fd 100644 (file)
@@ -1,15 +1,21 @@
 package org.argeo.init.a2;
 
 import java.io.File;
+import java.io.UnsupportedEncodingException;
 import java.net.URI;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -55,6 +61,17 @@ public class ProvisioningManager {
        public void registerSource(String uri) {
                try {
                        URI u = new URI(uri);
+
+                       // XOR
+                       Map<String, List<String>> properties = queryToMap(u);
+                       Map<String, String> xOr = new HashMap<>();
+                       for (String key : properties.keySet()) {
+                               List<String> lst = properties.get(key);
+                               if (lst.size() != 1)
+                                       throw new IllegalArgumentException("Invalid XOR definitions in " + uri);
+                               xOr.put(key, lst.get(0));
+                       }
+
                        if (A2Source.SCHEME_A2.equals(u.getScheme())) {
                                if (u.getHost() == null || "".equals(u.getHost())) {
                                        String baseStr = u.getPath();
@@ -63,7 +80,7 @@ public class ProvisioningManager {
                                        }
                                        Path base = Paths.get(baseStr);
                                        if (Files.exists(base)) {
-                                               FsA2Source source = new FsA2Source(base);
+                                               FsA2Source source = new FsA2Source(base, xOr);
                                                source.load();
                                                addSource(source);
                                                OsgiBootUtils.info("Registered " + uri + " as source");
@@ -172,25 +189,70 @@ public class ProvisioningManager {
                return updatedBundles;
        }
 
+       private static Map<String, List<String>> queryToMap(URI uri) {
+               return queryToMap(uri.getQuery());
+       }
+
+       private static Map<String, List<String>> queryToMap(String queryPart) {
+               try {
+                       final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
+                       if (queryPart == null)
+                               return query_pairs;
+                       final String[] pairs = queryPart.split("&");
+                       for (String pair : pairs) {
+                               final int idx = pair.indexOf("=");
+                               final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8.name())
+                                               : pair;
+                               if (!query_pairs.containsKey(key)) {
+                                       query_pairs.put(key, new LinkedList<String>());
+                               }
+                               final String value = idx > 0 && pair.length() > idx + 1
+                                               ? URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8.name())
+                                               : null;
+                               query_pairs.get(key).add(value);
+                       }
+                       return query_pairs;
+               } catch (UnsupportedEncodingException e) {
+                       throw new IllegalArgumentException("Cannot convert " + queryPart + " to map", e);
+               }
+       }
+
        public static void main(String[] args) {
+               if (args.length == 0)
+                       throw new IllegalArgumentException("Usage: <path to A2 base>");
                Map<String, String> configuration = new HashMap<>();
                configuration.put("osgi.console", "2323");
+               configuration.put("org.osgi.framework.bootdelegation",
+                               "com.sun.jndi.ldap,com.sun.jndi.ldap.sasl,com.sun.security.jgss,com.sun.jndi.dns,com.sun.nio.file,com.sun.nio.sctp,sun.nio.cs");
                Framework framework = OsgiBootUtils.launch(configuration);
                try {
                        ProvisioningManager pm = new ProvisioningManager(framework.getBundleContext());
-                       FsA2Source context = new FsA2Source(Paths.get(
-                                       "/home/mbaudier/dev/git/apache2/argeo-commons/dist/argeo-node/target/argeo-node-2.1.74-SNAPSHOT/argeo-node/share/osgi"));
+                       Map<String, String> xOr = new HashMap<>();
+                       xOr.put("osgi", "equinox");
+                       xOr.put("swt", "rap");
+                       FsA2Source context = new FsA2Source(Paths.get(args[0]), xOr);
                        context.load();
+                       pm.addSource(context);
                        if (framework.getBundleContext().getBundles().length == 1) {// initial
                                pm.install(null);
                        } else {
                                pm.update();
                        }
+
+                       Thread.sleep(2000);
+
+                       Bundle[] bundles = framework.getBundleContext().getBundles();
+                       Arrays.sort(bundles, (b1, b2) -> b1.getSymbolicName().compareTo(b2.getSymbolicName()));
+                       for (Bundle b : bundles)
+                               if (b.getState() == Bundle.RESOLVED || b.getState() == Bundle.STARTING || b.getState() == Bundle.ACTIVE)
+                                       System.out.println(b.getSymbolicName() + " " + b.getVersion());
+                               else
+                                       System.err.println(b.getSymbolicName() + " " + b.getVersion() + " (" + b.getState() + ")");
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
                        try {
-                               // framework.stop();
+                               framework.stop();
                        } catch (Exception e) {
                                e.printStackTrace();
                        }