package org.argeo.osgi.boot.a2;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.Collections;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.jar.JarInputStream;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-
-import org.argeo.osgi.boot.OsgiBootException;
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;
/** Where components are retrieved from. */
-abstract class ProvisioningSource {
- final Map<String, A2Contribution> contributions = Collections.synchronizedSortedMap(new TreeMap<>());
-
- A2Contribution getOrAddContribution(String contributionId) {
- if (contributions.containsKey(contributionId))
- return contributions.get(contributionId);
- else
- return new A2Contribution(this, contributionId);
- }
-
- void asTree(String prefix, StringBuffer buf) {
- if (prefix == null)
- prefix = "";
- for (String contributionId : contributions.keySet()) {
- buf.append(prefix);
- buf.append(contributionId);
- buf.append('\n');
- A2Contribution contribution = contributions.get(contributionId);
- contribution.asTree(prefix + " ", buf);
- }
- }
-
- void asTree() {
- StringBuffer buf = new StringBuffer();
- asTree("", buf);
- System.out.println(buf);
- }
-
- A2Component findComponent(String componentId) {
- SortedMap<A2Contribution, A2Component> res = new TreeMap<>();
- for (A2Contribution contribution : contributions.values()) {
- components: for (String componentIdKey : contribution.components.keySet()) {
- if (componentId.equals(componentIdKey)) {
- res.put(contribution, contribution.components.get(componentIdKey));
- break components;
- }
- }
- }
- if (res.size() == 0)
- return null;
- // TODO explicit contribution priorities
- return res.get(res.lastKey());
-
- }
-
- A2Branch findBranch(String componentId, Version version) {
- A2Component component = findComponent(componentId);
- if (component == null)
- return null;
- String branchId = version.getMajor() + "." + version.getMinor();
- if (!component.branches.containsKey(branchId))
- return null;
- return component.branches.get(branchId);
- }
-
- protected String readVersionFromModule(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 OsgiBootException("Cannot read manifest from " + modulePath, e);
- }
- }
- String versionStr = manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
- return versionStr;
- }
-
- protected String readSymbolicNameFromModule(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 OsgiBootException("Cannot read manifest from " + modulePath, e);
- }
- }
- String symbolicName = manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
- int semiColIndex = symbolicName.indexOf(';');
- if (semiColIndex >= 0)
- symbolicName = symbolicName.substring(0, semiColIndex);
- return symbolicName;
- }
-
- private static Manifest findManifest(Path currentPath) {
- Path metaInfPath = currentPath.resolve("META-INF");
- if (Files.exists(metaInfPath) && Files.isDirectory(metaInfPath)) {
- Path manifestPath = metaInfPath.resolve("MANIFEST.MF");
- try {
- try (InputStream in = Files.newInputStream(manifestPath)) {
- Manifest manifest = new Manifest(in);
- return manifest;
- }
- } catch (IOException e) {
- throw new OsgiBootException("Cannot read manifest from " + manifestPath, e);
- }
- } else {
- Path parentPath = currentPath.getParent();
- if (parentPath == null)
- throw new OsgiBootException("MANIFEST.MF file not found.");
- return findManifest(currentPath.getParent());
- }
- }
-
- public Bundle install(BundleContext bc, A2Module module) throws IOException, BundleException {
- 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);
- }
- if (tempJar != null)
- Files.deleteIfExists(tempJar);
- return bundle;
- }
+public interface ProvisioningSource {
+ /** List all contributions of this source. */
+ Iterable<A2Contribution> listContributions(Object filter);
- public void update(Bundle bundle, A2Module module) throws IOException, BundleException {
- 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);
- }
- if (tempJar != null)
- Files.deleteIfExists(tempJar);
- }
+ /** Install a module in the OSGi runtime. */
+ Bundle install(BundleContext bc, A2Module module);
- static Path toTempJar(Path dir) {
- try {
- Manifest manifest = findManifest(dir);
- Path jarPath = Files.createTempFile("a2Source", ".jar");
- try (JarOutputStream zos = new JarOutputStream(new FileOutputStream(jarPath.toFile()), manifest)) {
- Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- Path relPath = dir.relativize(file);
- // skip MANIFEST from folder
- if (relPath.toString().contentEquals("META-INF/MANIFEST.MF"))
- return FileVisitResult.CONTINUE;
- zos.putNextEntry(new ZipEntry(relPath.toString()));
- Files.copy(file, zos);
- zos.closeEntry();
- return FileVisitResult.CONTINUE;
- }
- });
- }
- return jarPath;
- } catch (IOException e) {
- throw new OsgiBootException("Cannot install OSGi bundle from " + dir, e);
- }
+ /** Update a module in the OSGi runtime. */
+ void update(Bundle bundle, A2Module module);
- }
+ /** Finds the {@link A2Branch} related to this component and version. */
+ A2Branch findBranch(String componentId, Version version);
- private InputStream newInputStream(Object locator) throws IOException {
- if (locator instanceof Path) {
- return Files.newInputStream((Path) locator);
- } else if (locator instanceof URL) {
- return ((URL) locator).openStream();
- } else {
- throw new IllegalArgumentException("Unsupported module locator type " + locator.getClass());
- }
- }
}