summaryrefslogtreecommitdiffstats
path: root/bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java
diff options
context:
space:
mode:
Diffstat (limited to 'bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java')
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java97
1 files changed, 97 insertions, 0 deletions
diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java
new file mode 100644
index 00000000000..b58248ec4a6
--- /dev/null
+++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/osgi/ImportPackages.java
@@ -0,0 +1,97 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.plugin.osgi;
+
+import com.google.common.collect.Sets;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Tony Vaagenes
+ * @author ollivir
+ */
+public class ImportPackages {
+ public static final int INFINITE_VERSION = 99999;
+ private static final String GUAVA_BASE_PACKAGE = "com.google.common";
+
+ public static class Import {
+ private final String packageName;
+ private final List<Integer> versionNumber;
+
+ public Import(String packageName, Optional<String> version) {
+ this.packageName = packageName;
+ this.versionNumber = new ArrayList<>();
+
+ if (version.isPresent()) {
+ try {
+ Arrays.stream(version.get().split("\\.")).map(Integer::parseInt).limit(3).forEach(this.versionNumber::add);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(
+ String.format("Invalid version number '%s' for package '%s'.", version.get(), packageName), e);
+ }
+ }
+ }
+
+ public Optional<Integer> majorVersion() {
+ if (versionNumber.size() >= 1) {
+ return Optional.of(versionNumber.get(0));
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ public String packageName() {
+ return packageName;
+ }
+
+ public String version() {
+ return versionNumber.stream().map(Object::toString).collect(Collectors.joining("."));
+ }
+
+ // TODO: Detecting guava packages should be based on Bundle-SymbolicName, not package name.
+ public Optional<String> importVersionRange() {
+ if (versionNumber.isEmpty()) {
+ return Optional.empty();
+ } else {
+ int upperLimit = isGuavaPackage() ? INFINITE_VERSION // guava increases major version for each release
+ : versionNumber.get(0) + 1;
+ return Optional.of(String.format("[%s,%d)", version(), upperLimit));
+ }
+ }
+
+ public boolean isGuavaPackage() {
+ return packageName.equals(GUAVA_BASE_PACKAGE) || packageName.startsWith(GUAVA_BASE_PACKAGE + ".");
+ }
+
+ public String asOsgiImport() {
+ return packageName + importVersionRange().map(version -> ";version=\"" + version + '"').orElse("");
+ }
+ }
+
+ public static Map<String, Import> calculateImports(Set<String> referencedPackages, Set<String> implementedPackages,
+ Map<String, ExportPackages.Export> exportedPackages) {
+ Map<String, Import> ret = new HashMap<>();
+ for (String undefinedPackage : Sets.difference(referencedPackages, implementedPackages)) {
+ ExportPackages.Export export = exportedPackages.get(undefinedPackage);
+ if (export != null) {
+ ret.put(undefinedPackage, new Import(undefinedPackage, version(export)));
+ }
+ }
+ return ret;
+ }
+
+ private static Optional<String> version(ExportPackages.Export export) {
+ for (ExportPackages.Parameter param : export.getParameters()) {
+ if ("version".equals(param.getName())) {
+ return Optional.of(param.getValue());
+ }
+ }
+ return Optional.empty();
+ }
+}