Support installation by reference for equinox
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / init / a2 / FsA2Source.java
index 949dbdf81dec07b0753b2009c753a2fc02c2564f..d4aa863869aa682f3aec5c92e80e8212d8042f2c 100644 (file)
@@ -1,12 +1,15 @@
 package org.argeo.init.a2;
 
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
 
 import org.argeo.init.osgi.OsgiBootUtils;
 import org.osgi.framework.Version;
@@ -14,27 +17,73 @@ import org.osgi.framework.Version;
 /** A file system {@link AbstractProvisioningSource} in A2 format. */
 public class FsA2Source extends AbstractProvisioningSource implements A2Source {
        private final Path base;
+       private final Map<String, String> xOr;
 
-       public FsA2Source(Path base) {
-               super();
+//     public FsA2Source(Path base) {
+//             this(base, new HashMap<>());
+//     }
+
+       public FsA2Source(Path base, Map<String, String> xOr, boolean useReference) {
+               super(useReference);
                this.base = base;
+               this.xOr = new HashMap<>(xOr);
        }
 
        void load() throws IOException {
+               SortedMap<Path, A2Contribution> contributions = new TreeMap<>();
+
                DirectoryStream<Path> contributionPaths = Files.newDirectoryStream(base);
-               SortedSet<A2Contribution> contributions = new TreeSet<>();
                contributions: for (Path contributionPath : contributionPaths) {
                        if (Files.isDirectory(contributionPath)) {
                                String contributionId = contributionPath.getFileName().toString();
                                if (A2Contribution.BOOT.equals(contributionId))// skip boot
                                        continue contributions;
-                               A2Contribution contribution = getOrAddContribution(contributionId);
-                               contributions.add(contribution);
+                               if (contributionId.contains(".")) {
+                                       A2Contribution contribution = getOrAddContribution(contributionId);
+                                       contributions.put(contributionPath, contribution);
+                               } else {// variants
+                                       Path variantPath = null;
+                                       // is it an explicit variant?
+                                       String variant = xOr.get(contributionPath.getFileName().toString());
+                                       if (variant != null) {
+                                               variantPath = contributionPath.resolve(variant);
+                                       }
+
+                                       // is there a default variant?
+                                       if (variantPath == null) {
+                                               Path defaultPath = contributionPath.resolve(A2Contribution.DEFAULT);
+                                               if (Files.exists(defaultPath)) {
+                                                       variantPath = defaultPath;
+                                               }
+                                       }
+
+                                       if (variantPath == null)
+                                               continue contributions;
+
+                                       // a variant was found, let's collect its contributions (also common ones in its
+                                       // parent)
+                                       for (Path variantContributionPath : Files.newDirectoryStream(variantPath.getParent())) {
+                                               String variantContributionId = variantContributionPath.getFileName().toString();
+                                               if (variantContributionId.contains(".")) {
+                                                       A2Contribution contribution = getOrAddContribution(variantContributionId);
+                                                       contributions.put(variantContributionPath, contribution);
+                                               }
+                                       }
+                                       for (Path variantContributionPath : Files.newDirectoryStream(variantPath)) {
+                                               String variantContributionId = variantContributionPath.getFileName().toString();
+                                               if (variantContributionId.contains(".")) {
+                                                       A2Contribution contribution = getOrAddContribution(variantContributionId);
+                                                       contributions.put(variantContributionPath, contribution);
+                                               }
+                                       }
+                               }
                        }
                }
 
-               for (A2Contribution contribution : contributions) {
-                       DirectoryStream<Path> modulePaths = Files.newDirectoryStream(base.resolve(contribution.getId()));
+               for (Path contributionPath : contributions.keySet()) {
+                       String contributionId = contributionPath.getFileName().toString();
+                       A2Contribution contribution = getOrAddContribution(contributionId);
+                       DirectoryStream<Path> modulePaths = Files.newDirectoryStream(contributionPath);
                        modules: for (Path modulePath : modulePaths) {
                                if (!Files.isDirectory(modulePath)) {
                                        // OsgiBootUtils.debug("Registering " + modulePath);
@@ -43,27 +92,18 @@ public class FsA2Source extends AbstractProvisioningSource implements A2Source {
                                        String ext = moduleFileName.substring(lastDot + 1);
                                        if (!"jar".equals(ext))
                                                continue modules;
-                                       String moduleName = moduleFileName.substring(0, lastDot);
-                                       if (moduleName.endsWith("-SNAPSHOT"))
-                                               moduleName = moduleName.substring(0, moduleName.length() - "-SNAPSHOT".length());
-                                       int lastDash = moduleName.lastIndexOf('-');
-                                       String versionStr = moduleName.substring(lastDash + 1);
-                                       String componentName = moduleName.substring(0, lastDash);
-                                       // if(versionStr.endsWith("-SNAPSHOT")) {
-                                       // versionStr = readVersionFromModule(modulePath);
-                                       // }
                                        Version version;
-                                       try {
+                                       // TODO optimise? check attributes?
+                                       String[] nameVersion = readNameVersionFromModule(modulePath);
+                                       String componentName = nameVersion[0];
+                                       String versionStr = nameVersion[1];
+                                       if (versionStr != null) {
                                                version = new Version(versionStr);
-                                       } catch (Exception e) {
-                                               versionStr = readVersionFromModule(modulePath);
-                                               if (versionStr != null) {
-                                                       version = new Version(versionStr);
-                                               } else {
-                                                       OsgiBootUtils.debug("Ignore " + modulePath + " (" + e.getMessage() + ")");
-                                                       continue modules;
-                                               }
+                                       } else {
+                                               OsgiBootUtils.debug("Ignore " + modulePath + " since version cannot be found");
+                                               continue modules;
                                        }
+//                                     }
                                        A2Component component = contribution.getOrAddComponent(componentName);
                                        A2Module module = component.getOrAddModule(version, modulePath);
                                        if (OsgiBootUtils.isDebug())
@@ -74,15 +114,33 @@ public class FsA2Source extends AbstractProvisioningSource implements A2Source {
 
        }
 
-       public static void main(String[] args) {
+       @Override
+       public URI getUri() {
+               URI baseUri = base.toUri();
                try {
-                       FsA2Source context = new FsA2Source(Paths.get(
-                                       "/home/mbaudier/dev/git/apache2/argeo-commons/dist/argeo-node/target/argeo-node-2.1.77-SNAPSHOT/share/osgi"));
-                       context.load();
-                       context.asTree();
-               } catch (Exception e) {
-                       e.printStackTrace();
+                       if (baseUri.getScheme().equals("file")) {
+                               return new URI(SCHEME_A2, null, base.toString(), null);
+                       } else {
+                               throw new UnsupportedOperationException("Unsupported scheme " + baseUri.getScheme());
+                       }
+               } catch (URISyntaxException e) {
+                       throw new IllegalStateException("Cannot build URI from " + baseUri, e);
                }
        }
 
+//     public static void main(String[] args) {
+//             if (args.length == 0)
+//                     throw new IllegalArgumentException("Usage: <path to A2 base>");
+//             try {
+//                     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();
+//                     context.asTree();
+//             } catch (Exception e) {
+//                     e.printStackTrace();
+//             }
+//     }
+
 }