/** A provisioning source in A2 format. */
public interface A2Source extends ProvisioningSource {
+ /** Use standard a2 protocol, installing from source URL. */
final static String SCHEME_A2 = "a2";
+ /**
+ * Use equinox-specific reference: installation, which does not copy the bundle
+ * content.
+ */
+ final static String SCHEME_A2_REFERENCE = "a2+reference";
final static String DEFAULT_A2_URI = SCHEME_A2 + ":///";
+ final static String DEFAULT_A2_REFERENCE_URI = SCHEME_A2_REFERENCE + ":///";
URI getUri();
}
public abstract class AbstractProvisioningSource implements ProvisioningSource {
protected final Map<String, A2Contribution> contributions = Collections.synchronizedSortedMap(new TreeMap<>());
+ private final boolean useReference;
+
+ public AbstractProvisioningSource(boolean useReference) {
+ this.useReference = useReference;
+ }
+
public Iterable<A2Contribution> listContributions(Object filter) {
return contributions.values();
}
@Override
public Bundle install(BundleContext bc, A2Module module) {
try {
- Path tempJar = null;
- if (module.getLocator() instanceof Path && Files.isDirectory((Path) module.getLocator()))
- tempJar = toTempJar((Path) module.getLocator());
- Bundle bundle;
- try (InputStream in = newInputStream(tempJar != null ? tempJar : module.getLocator())) {
- bundle = bc.installBundle(module.getBranch().getCoordinates(), in);
+ Object locator = module.getLocator();
+ if (useReference && locator instanceof Path locatorPath) {
+ String referenceUrl = "reference:file:" + locatorPath.toString();
+ Bundle bundle = bc.installBundle(referenceUrl);
+ return bundle;
+ } else {
+
+ Path tempJar = null;
+ if (locator instanceof Path && Files.isDirectory((Path) locator))
+ tempJar = toTempJar((Path) locator);
+ Bundle bundle;
+ try (InputStream in = newInputStream(tempJar != null ? tempJar : locator)) {
+ bundle = bc.installBundle(module.getBranch().getCoordinates(), in);
+ }
+
+ if (tempJar != null)
+ Files.deleteIfExists(tempJar);
+ return bundle;
}
- if (tempJar != null)
- Files.deleteIfExists(tempJar);
- return bundle;
} catch (BundleException | IOException e) {
throw new A2Exception("Cannot install module " + module, e);
}
@Override
public void update(Bundle bundle, A2Module module) {
try {
- Path tempJar = null;
- if (module.getLocator() instanceof Path && Files.isDirectory((Path) module.getLocator()))
- tempJar = toTempJar((Path) module.getLocator());
- try (InputStream in = newInputStream(tempJar != null ? tempJar : module.getLocator())) {
- bundle.update(in);
+ Object locator = module.getLocator();
+ if (useReference && locator instanceof Path) {
+ try (InputStream in = newInputStream(locator)) {
+ bundle.update(in);
+ }
+ } else {
+ Path tempJar = null;
+ if (locator instanceof Path && Files.isDirectory((Path) locator))
+ tempJar = toTempJar((Path) locator);
+ try (InputStream in = newInputStream(tempJar != null ? tempJar : locator)) {
+ bundle.update(in);
+ }
+ if (tempJar != null)
+ Files.deleteIfExists(tempJar);
}
- if (tempJar != null)
- Files.deleteIfExists(tempJar);
} catch (BundleException | IOException e) {
throw new A2Exception("Cannot update module " + module, e);
}
import org.osgi.framework.Version;
/**
- * A provisioning source based on the linear classpath with which the JCM has
+ * A provisioning source based on the linear classpath with which the JVM has
* been started.
*/
public class ClasspathSource extends AbstractProvisioningSource {
+
+ public ClasspathSource() {
+ super(true);
+ }
+
void load() throws IOException {
A2Contribution classpathContribution = getOrAddContribution( A2Contribution.CLASSPATH);
List<String> classpath = Arrays.asList(System.getProperty("java.class.path").split(File.pathSeparator));
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
/** A file system {@link AbstractProvisioningSource} in A2 format. */
public class FsA2Source extends AbstractProvisioningSource implements A2Source {
private final Path base;
- private Map<String, String> xOr;
+ private final Map<String, String> xOr;
- public FsA2Source(Path base) {
- this(base, new HashMap<>());
- }
+// public FsA2Source(Path base) {
+// this(base, new HashMap<>());
+// }
- public FsA2Source(Path base, Map<String, String> xOr) {
+ public FsA2Source(Path base, Map<String, String> xOr, boolean useReference) {
+ super(useReference);
this.base = base;
- this.xOr = xOr;
+ this.xOr = new HashMap<>(xOr);
}
void load() throws IOException {
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 {
-// version = new Version(versionStr);
-// } catch (Exception e) {
+ // TODO optimise? check attributes?
String[] nameVersion = readNameVersionFromModule(modulePath);
String componentName = nameVersion[0];
String versionStr = nameVersion[1];
}
}
- 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();
- }
- }
+// 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();
+// }
+// }
}
private final Path base;
public FsM2Source(Path base) {
- super();
+ super(false);
this.base = base;
}
private final BundleContext bc;
public OsgiContext(BundleContext bc) {
- super();
+ super(false);
this.bc = bc;
}
public OsgiContext() {
+ super(false);
Bundle bundle = FrameworkUtil.getBundle(OsgiContext.class);
if (bundle == null)
throw new IllegalArgumentException(
package org.argeo.init.a2;
+import static org.argeo.init.a2.A2Source.SCHEME_A2;
+import static org.argeo.init.a2.A2Source.SCHEME_A2_REFERENCE;
+
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URI;
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 org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
-import org.osgi.framework.launch.Framework;
import org.osgi.framework.wiring.FrameworkWiring;
/** Loads provisioning sources into an OSGi context. */
xOr.put(key, lst.get(0));
}
- if (A2Source.SCHEME_A2.equals(u.getScheme())) {
+ if (SCHEME_A2.equals(u.getScheme()) || SCHEME_A2_REFERENCE.equals(u.getScheme())) {
if (u.getHost() == null || "".equals(u.getHost())) {
String baseStr = u.getPath();
if (File.separatorChar == '\\') {// MS Windows
}
Path base = Paths.get(baseStr);
if (Files.exists(base)) {
- FsA2Source source = new FsA2Source(base, xOr);
+ FsA2Source source = new FsA2Source(base, xOr, SCHEME_A2_REFERENCE.equals(u.getScheme()));
source.load();
addSource(source);
OsgiBootUtils.info("Registered " + uri + " as source");
+ } else {
+ OsgiBootUtils.debug("Source " + base + " does not exist, ignoring.");
}
+ } else {
+ throw new UnsupportedOperationException(
+ "Remote installation is not yet supported, cannot add source " + u);
}
+ } else {
+ throw new IllegalArgumentException("Unkown scheme: for source " + u);
}
} catch (Exception e) {
throw new A2Exception("Cannot add source " + uri, 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());
- 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();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
+// 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());
+// 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();
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// }
+// }
}
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 if (source.trim().equals(A2Source.DEFAULT_A2_REFERENCE_URI)) {
+ if (Files.exists(homePath))
+ provisioningManager.registerSource(A2Source.SCHEME_A2_REFERENCE + "://" + homePath.toString()
+ + "/.local/share/a2" + queryPart);
+ provisioningManager
+ .registerSource(A2Source.SCHEME_A2_REFERENCE + ":///usr/local/share/a2" + queryPart);
+ provisioningManager.registerSource(A2Source.SCHEME_A2_REFERENCE + ":///usr/share/a2" + queryPart);
} else {
provisioningManager.registerSource(source + queryPart);
}