aboutsummaryrefslogtreecommitdiffstats
path: root/bundle-plugin/src
diff options
context:
space:
mode:
authorgjoranv <gv@yahooinc.com>2023-05-19 17:21:04 +0200
committergjoranv <gv@yahooinc.com>2023-05-23 01:34:20 +0200
commit8e40763559f4d32d51a65f5f53d8334299420969 (patch)
treeca863bb50931284c34107110258f9e5f26e94ce9 /bundle-plugin/src
parentbebeaa9ef2df005a1abd088e0375c4dc869e2986 (diff)
Process @PublicApi annotation and collect annotated packages.
Diffstat (limited to 'bundle-plugin/src')
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassVisitor.java8
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/ClassFileMetaData.java16
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageInfo.java22
-rw-r--r--bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java44
-rw-r--r--bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassTest.java18
-rw-r--r--bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/sampleclasses/package-info.java2
6 files changed, 77 insertions, 33 deletions
diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassVisitor.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassVisitor.java
index 46a35b07ea7..e57af606b3a 100644
--- a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassVisitor.java
+++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassVisitor.java
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.plugin.classanalysis;
+import com.yahoo.api.annotations.PublicApi;
import com.yahoo.osgi.annotation.ExportPackage;
import com.yahoo.osgi.annotation.Version;
import org.apache.maven.artifact.versioning.ArtifactVersion;
@@ -28,6 +29,7 @@ class AnalyzeClassVisitor extends ClassVisitor implements ImportCollector {
private String name = null;
private final Set<String> imports = new HashSet<>();
private Optional<ExportPackageAnnotation> exportPackageAnnotation = Optional.empty();
+ private boolean isPublicApi = false;
private final Optional<ArtifactVersion> defaultExportPackageVersion;
@@ -159,6 +161,9 @@ class AnalyzeClassVisitor extends ClassVisitor implements ImportCollector {
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (ExportPackage.class.getName().equals(Type.getType(desc).getClassName())) {
return visitExportPackage();
+ } if (PublicApi.class.getName().equals(Type.getType(desc).getClassName())) {
+ isPublicApi = true;
+ return null;
} else {
if (visible) {
addImportWithTypeDesc(desc);
@@ -169,7 +174,8 @@ class AnalyzeClassVisitor extends ClassVisitor implements ImportCollector {
ClassFileMetaData result() {
assert (!imports.contains("int"));
- return new ClassFileMetaData(name, imports, exportPackageAnnotation);
+ var packageInfo = new PackageInfo(Packages.packageName(name), exportPackageAnnotation, isPublicApi);
+ return new ClassFileMetaData(name, imports, packageInfo);
}
}
diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/ClassFileMetaData.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/ClassFileMetaData.java
index 5601430a27f..7e2f59c1e4d 100644
--- a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/ClassFileMetaData.java
+++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/ClassFileMetaData.java
@@ -14,12 +14,12 @@ public class ClassFileMetaData {
private final String name;
private final Set<String> referencedClasses;
- private final Optional<ExportPackageAnnotation> exportPackage;
+ private final PackageInfo packageInfo;
- public ClassFileMetaData(String name, Set<String> referencedClasses, Optional<ExportPackageAnnotation> exportPackage) {
+ public ClassFileMetaData(String name, Set<String> referencedClasses, PackageInfo packageInfo) {
this.name = name;
this.referencedClasses = referencedClasses;
- this.exportPackage = exportPackage;
+ this.packageInfo = packageInfo;
}
public String getName() {
@@ -30,8 +30,16 @@ public class ClassFileMetaData {
return referencedClasses;
}
+ public PackageInfo packageInfo() {
+ return packageInfo;
+ }
+
public Optional<ExportPackageAnnotation> getExportPackage() {
- return exportPackage;
+ return packageInfo.exportPackage();
+ }
+
+ public boolean isPublicApi() {
+ return packageInfo.isPublicApi();
}
}
diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageInfo.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageInfo.java
new file mode 100644
index 00000000000..491f6d2a743
--- /dev/null
+++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageInfo.java
@@ -0,0 +1,22 @@
+package com.yahoo.container.plugin.classanalysis;
+
+import java.util.Optional;
+
+/**
+ * The package
+ *
+ * @author gjoranv
+ */
+record PackageInfo(String name, Optional<ExportPackageAnnotation> exportPackage, boolean isPublicApi) {
+
+ PackageInfo {
+ if (exportPackage.isEmpty() && isPublicApi) {
+ throw new IllegalArgumentException("Package %s is declared PublicApi, but is not exported.".formatted(name));
+ }
+ }
+
+ PackageInfo hasExportPackageOrElse(PackageInfo other) {
+ return exportPackage().isPresent() ? this : other;
+ }
+
+}
diff --git a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java
index 03398307e03..6e8fc89c605 100644
--- a/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java
+++ b/bundle-plugin/src/main/java/com/yahoo/container/plugin/classanalysis/PackageTally.java
@@ -17,16 +17,17 @@ import java.util.stream.Collectors;
* @author ollivir
*/
public class PackageTally {
- private final Map<String, Optional<ExportPackageAnnotation>> definedPackagesMap;
+
+ private final Map<String, PackageInfo> definedPackages;
private final Set<String> referencedPackagesUnfiltered;
- PackageTally(Map<String, Optional<ExportPackageAnnotation>> definedPackagesMap, Set<String> referencedPackagesUnfiltered) {
- this.definedPackagesMap = definedPackagesMap;
+ PackageTally(Map<String, PackageInfo> definedPackages, Set<String> referencedPackagesUnfiltered) {
+ this.definedPackages = definedPackages;
this.referencedPackagesUnfiltered = referencedPackagesUnfiltered;
}
public Set<String> definedPackages() {
- return definedPackagesMap.keySet();
+ return definedPackages.keySet();
}
public Set<String> referencedPackages() {
@@ -35,8 +36,8 @@ public class PackageTally {
public Map<String, ExportPackageAnnotation> exportedPackages() {
Map<String, ExportPackageAnnotation> ret = new HashMap<>();
- definedPackagesMap.forEach((pkg, annotation) -> {
- annotation.ifPresent(a -> ret.put(pkg, a));
+ definedPackages.forEach((pkg, pkgInfo) -> {
+ pkgInfo.exportPackage().ifPresent(a -> ret.put(pkg, a));
});
return ret;
}
@@ -58,36 +59,37 @@ public class PackageTally {
* Represents the classes for two package tallies that are deployed as a single unit.
* <p>
* ExportPackageAnnotations from this has precedence over the other.
+ * TODO: try using Map.merge (as in the functions below). Can't see how Maps.combine is any different.
*/
public PackageTally combine(PackageTally other) {
- Map<String, Optional<ExportPackageAnnotation>> map = Maps.combine(this.definedPackagesMap, other.definedPackagesMap,
- (l, r) -> l.isPresent() ? l : r);
+ var definedPkgs = Maps.combine(this.definedPackages, other.definedPackages, PackageInfo::hasExportPackageOrElse);
Set<String> referencedPkgs = new HashSet<>(this.referencedPackagesUnfiltered);
referencedPkgs.addAll(other.referencedPackagesUnfiltered);
- return new PackageTally(map, referencedPkgs);
+ return new PackageTally(definedPkgs, referencedPkgs);
}
public static PackageTally combine(Collection<PackageTally> packageTallies) {
- Map<String, Optional<ExportPackageAnnotation>> map = new HashMap<>();
+ var definedPkgs = new HashMap<String, PackageInfo>();
Set<String> referencedPkgs = new HashSet<>();
- for (PackageTally pt : packageTallies) {
- pt.definedPackagesMap.forEach((k, v) -> map.merge(k, v, (l, r) -> l.isPresent() ? l : r));
- referencedPkgs.addAll(pt.referencedPackagesUnfiltered);
+ for (PackageTally tally : packageTallies) {
+ tally.definedPackages.forEach((pkg, info) -> definedPkgs.merge(pkg, info, PackageInfo::hasExportPackageOrElse));
+ referencedPkgs.addAll(tally.referencedPackagesUnfiltered);
}
- return new PackageTally(map, referencedPkgs);
+ return new PackageTally(definedPkgs, referencedPkgs);
}
public static PackageTally fromAnalyzedClassFiles(Collection<ClassFileMetaData> analyzedClassFiles) {
- Map<String, Optional<ExportPackageAnnotation>> map = new HashMap<>();
- Set<String> referencedPkgs = new HashSet<>();
+ var definedPkgs = new HashMap<String, PackageInfo>();
+ var referencedPkgs = new HashSet<String>();
- for (ClassFileMetaData metaData : analyzedClassFiles) {
- String packageName = Packages.packageName(metaData.getName());
- map.merge(packageName, metaData.getExportPackage(), (l, r) -> l.isPresent() ? l : r);
- metaData.getReferencedClasses().forEach(className -> referencedPkgs.add(Packages.packageName(className)));
+ for (ClassFileMetaData classData : analyzedClassFiles) {
+ var pkgName = classData.packageInfo().name();
+ definedPkgs.merge(pkgName, classData.packageInfo(), PackageInfo::hasExportPackageOrElse);
+ classData.getReferencedClasses().forEach(className -> referencedPkgs.add(Packages.packageName(className)));
}
- return new PackageTally(map, referencedPkgs);
+ return new PackageTally(definedPkgs, referencedPkgs);
}
+
}
diff --git a/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassTest.java b/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassTest.java
index 9a7aade7ffb..11fe4a14d74 100644
--- a/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassTest.java
+++ b/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/AnalyzeClassTest.java
@@ -3,28 +3,27 @@ package com.yahoo.container.plugin.classanalysis;
import com.yahoo.container.plugin.classanalysis.sampleclasses.Base;
import com.yahoo.container.plugin.classanalysis.sampleclasses.ClassAnnotation;
-import com.yahoo.container.plugin.classanalysis.sampleclasses.InvisibleAnnotation;
import com.yahoo.container.plugin.classanalysis.sampleclasses.Derived;
import com.yahoo.container.plugin.classanalysis.sampleclasses.DummyAnnotation;
-import com.yahoo.container.plugin.classanalysis.sampleclasses.InvisibleDummyAnnotation;
import com.yahoo.container.plugin.classanalysis.sampleclasses.Fields;
import com.yahoo.container.plugin.classanalysis.sampleclasses.Interface1;
import com.yahoo.container.plugin.classanalysis.sampleclasses.Interface2;
-import com.yahoo.container.plugin.classanalysis.sampleclasses.RecordWithOverride;
-import com.yahoo.container.plugin.classanalysis.sampleclasses.SwitchStatement;
+import com.yahoo.container.plugin.classanalysis.sampleclasses.InvisibleAnnotation;
+import com.yahoo.container.plugin.classanalysis.sampleclasses.InvisibleDummyAnnotation;
import com.yahoo.container.plugin.classanalysis.sampleclasses.MethodAnnotation;
import com.yahoo.container.plugin.classanalysis.sampleclasses.MethodInvocation;
+import com.yahoo.container.plugin.classanalysis.sampleclasses.RecordWithOverride;
+import com.yahoo.container.plugin.classanalysis.sampleclasses.SwitchStatement;
import com.yahoo.osgi.annotation.ExportPackage;
import com.yahoo.osgi.annotation.Version;
import org.junit.jupiter.api.Test;
import javax.security.auth.login.LoginException;
-import java.awt.Image;
+import java.awt.*;
import java.awt.image.ImagingOpException;
import java.awt.image.Kernel;
import java.util.List;
import java.util.Optional;
-import java.util.Set;
import static com.yahoo.container.plugin.classanalysis.TestUtilities.analyzeClass;
import static com.yahoo.container.plugin.classanalysis.TestUtilities.classFile;
@@ -133,7 +132,12 @@ public class AnalyzeClassTest {
@Test
void export_annotations_are_processed() {
assertEquals(Optional.of(new ExportPackageAnnotation(3, 1, 4, "TEST_QUALIFIER-2")),
- Analyze.analyzeClass(classFile("com.yahoo.container.plugin.classanalysis.sampleclasses.package-info")).getExportPackage());
+ Analyze.analyzeClass(classFile("com.yahoo.container.plugin.classanalysis.sampleclasses.package-info")).getExportPackage());
+ }
+
+ @Test
+ void publicApi_annotations_are_processed() {
+ assertTrue(Analyze.analyzeClass(classFile("com.yahoo.container.plugin.classanalysis.sampleclasses.package-info")).isPublicApi());
}
@Test
diff --git a/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/sampleclasses/package-info.java b/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/sampleclasses/package-info.java
index d0d1db97c26..5f69032db17 100644
--- a/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/sampleclasses/package-info.java
+++ b/bundle-plugin/src/test/java/com/yahoo/container/plugin/classanalysis/sampleclasses/package-info.java
@@ -1,6 +1,8 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
@ExportPackage(version = @Version(major = 3, minor = 1, micro = 4, qualifier = "TEST_QUALIFIER-2"))
+@PublicApi
package com.yahoo.container.plugin.classanalysis.sampleclasses;
+import com.yahoo.api.annotations.PublicApi;
import com.yahoo.osgi.annotation.ExportPackage;
import com.yahoo.osgi.annotation.Version;