all: osgi jni move-rap
$(MAKE) -f Makefile-rcp.mk
-move-rap: osgi
- mkdir -p $(A2_OUTPUT)/$(A2_CATEGORY).eclipse.rap
- mv -v $(A2_OUTPUT)/$(A2_CATEGORY)/*.rap.$(MAJOR).$(MINOR).jar $(A2_OUTPUT)/$(A2_CATEGORY).eclipse.rap
+move-swt: osgi
+ mkdir -p $(A2_OUTPUT)/swt/$(A2_CATEGORY)
+ mv -v $(A2_OUTPUT)/$(A2_CATEGORY)/org.argeo.swt.minidesktop.$(MAJOR).$(MINOR).jar $(A2_OUTPUT)/swt/$(A2_CATEGORY)
+ mv -v $(A2_OUTPUT)/$(A2_CATEGORY)/org.argeo.cms.swt.$(MAJOR).$(MINOR).jar $(A2_OUTPUT)/swt/$(A2_CATEGORY)
+ mv -v $(A2_OUTPUT)/$(A2_CATEGORY)/org.argeo.cms.e4.$(MAJOR).$(MINOR).jar $(A2_OUTPUT)/swt/$(A2_CATEGORY)
+
+move-rap: move-swt
+ mkdir -p $(A2_OUTPUT)/swt/rap/$(A2_CATEGORY)
+ mv -v $(A2_OUTPUT)/$(A2_CATEGORY)/*.rap.$(MAJOR).$(MINOR).jar $(A2_OUTPUT)/swt/rap/$(A2_CATEGORY)
+ mv -v $(A2_OUTPUT)/$(A2_CATEGORY)/*.rap.cli.$(MAJOR).$(MINOR).jar $(A2_OUTPUT)/swt/rap/$(A2_CATEGORY)
touch $(BUILD_BASE)/*.rap/bnd.bnd
A2_CATEGORY = org.argeo.cms
org.argeo.tp \
org.argeo.tp.apache \
org.argeo.tp.jetty \
-org.argeo.tp.eclipse \
osgi/api/org.argeo.tp.osgi \
+osgi/equinox/org.argeo.tp.eclipse \
swt/rap/org.argeo.tp.swt \
swt/rap/org.argeo.tp.swt.workbench \
org.argeo.tp.jcr
include sdk.mk
.PHONY: clean all osgi
-all: osgi
+all: osgi move-rcp
-A2_CATEGORY = org.argeo.cms.eclipse.rcp
+move-rcp: osgi
+ mkdir -p $(A2_OUTPUT)/swt/rcp/$(A2_CATEGORY)
+ mv -v $(A2_OUTPUT)/$(A2_CATEGORY)/*.rcp.$(MAJOR).$(MINOR).jar $(A2_OUTPUT)/swt/rcp/$(A2_CATEGORY)
+ mv -v $(A2_OUTPUT)/$(A2_CATEGORY)/*.rcp.cli.$(MAJOR).$(MINOR).jar $(A2_OUTPUT)/swt/rcp/$(A2_CATEGORY)
+ touch $(BUILD_BASE)/*.rcp/bnd.bnd
+
+A2_CATEGORY = org.argeo.cms
BUNDLES = \
swt/rcp/org.argeo.swt.specific.rcp \
final static String RUNTIME = "runtime";
final static String CLASSPATH = "classpath";
+ final static String DEFAULT = "default";
+
private final ProvisioningSource source;
private final String id;
}
+ protected String[] readNameVersionFromModule(Path modulePath) {
+ Manifest manifest;
+ if (Files.isDirectory(modulePath)) {
+ manifest = findManifest(modulePath);
+ } else {
+ try (JarInputStream in = new JarInputStream(newInputStream(modulePath))) {
+ manifest = in.getManifest();
+ } catch (IOException e) {
+ throw new A2Exception("Cannot read manifest from " + modulePath, e);
+ }
+ }
+ String versionStr = manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+ String symbolicName = manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+ int semiColIndex = symbolicName.indexOf(';');
+ if (semiColIndex >= 0)
+ symbolicName = symbolicName.substring(0, semiColIndex);
+ return new String[] { symbolicName, versionStr };
+ }
+
protected String readVersionFromModule(Path modulePath) {
Manifest manifest;
if (Files.isDirectory(modulePath)) {
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;
/** A file system {@link AbstractProvisioningSource} in A2 format. */
public class FsA2Source extends AbstractProvisioningSource implements A2Source {
private final Path base;
+ private Map<String, String> xOr;
public FsA2Source(Path base) {
+ this(base, new HashMap<>());
+ }
+
+ public FsA2Source(Path base, Map<String, String> xOr) {
this.base = base;
+ this.xOr = 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);
// try {
// version = new Version(versionStr);
// } catch (Exception e) {
- String versionStr = readVersionFromModule(modulePath);
- String componentName = readSymbolicNameFromModule(modulePath);
+ String[] nameVersion = readNameVersionFromModule(modulePath);
+ String componentName = nameVersion[0];
+ String versionStr = nameVersion[1];
if (versionStr != null) {
version = new Version(versionStr);
} else {
}
public static void main(String[] args) {
+ if (args.length == 0)
+ throw new IllegalArgumentException("Usage: <path to A2 base>");
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"));
+ 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) {
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;
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();
}
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");
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();
}
} else {
for (String source : sources.split(",")) {
if (source.trim().equals(A2Source.DEFAULT_A2_URI)) {
+ int qmIndex = source.lastIndexOf('?');
+ String queryPart = "";
+ if (qmIndex >= 0) {
+ queryPart = source.substring(qmIndex);
+ }
if (Files.exists(homePath))
- provisioningManager
- .registerSource(A2Source.SCHEME_A2 + "://" + homePath.toString() + "/.local/share/a2");
- provisioningManager.registerSource(A2Source.SCHEME_A2 + ":///usr/local/share/a2");
- provisioningManager.registerSource(A2Source.SCHEME_A2 + ":///usr/share/a2");
+ provisioningManager.registerSource(
+ A2Source.SCHEME_A2 + "://" + homePath.toString() + "/.local/share/a2" + queryPart);
+ provisioningManager.registerSource(A2Source.SCHEME_A2 + ":///usr/local/share/a2" + queryPart);
+ provisioningManager.registerSource(A2Source.SCHEME_A2 + ":///usr/share/a2" + queryPart);
} else {
provisioningManager.registerSource(source);
}