Skip to content

Commit

Permalink
bundle annotations: Replace use of enum types
Browse files Browse the repository at this point in the history
Using enum types in the CLASS retention bundle annotations is causing
issues for those using the annotations. Various tools, such as javadoc,
attempt to reify the elements in the annotations and since the
osgi.annotation jar is generally a scope=provided dependency, the enum
types are not available to downstream users of the jars using the
OSGi annotations and so tools generates an annoying warning.

See quarkusio/quarkus#19970 and
eclipse/microprofile-config#716.

To address this, we support the use of enum values or string values
as the annotation element value. This will support the OSGi change in
osgi/osgi#404

We seamlessly handle old and new annotations
using the old enum values or the new string values. So moving to using
the updated OSGi annotations will also require moving to use Bnd with
this fix.

Signed-off-by: BJ Hargrave <[email protected]>
  • Loading branch information
bjhargrave committed Feb 7, 2022
1 parent 70df4e1 commit e9fdaf1
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import org.osgi.annotation.bundle.Attribute;
import org.osgi.annotation.bundle.Directive;
import org.osgi.annotation.bundle.Requirement;
import org.osgi.annotation.bundle.Requirement.Resolution;
import org.osgi.resource.Namespace;

@Custom(name = "bar", resolution = Resolution.OPTIONAL)
@Custom(name = "bar", resolution = Namespace.RESOLUTION_OPTIONAL)
public class ResolutionDirectiveOverride {}

@Requirement(namespace = "foo")
Expand All @@ -14,5 +14,5 @@ public class ResolutionDirectiveOverride {}
String name();

@Directive
Resolution resolution() default Resolution.MANDATORY;
String resolution() default Namespace.RESOLUTION_MANDATORY;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import org.osgi.annotation.bundle.Attribute;
import org.osgi.annotation.bundle.Directive;
import org.osgi.annotation.bundle.Requirement;
import org.osgi.annotation.bundle.Requirement.Cardinality;
import org.osgi.resource.Namespace;

@Custom(name = "bar", cardinality = Cardinality.MULTIPLE)
@Custom(name = "bar", cardinality = Namespace.CARDINALITY_MULTIPLE)
public class CardinalityDirectiveOverride {}

@Requirement(namespace = "foo")
Expand All @@ -14,5 +14,5 @@ public class CardinalityDirectiveOverride {}
String name();

@Directive
Cardinality cardinality() default Cardinality.SINGLE;
String cardinality() default Namespace.CARDINALITY_SINGLE;
}
4 changes: 3 additions & 1 deletion biz.aQute.bndlib/src/aQute/bnd/osgi/Analyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
Expand Down Expand Up @@ -841,7 +842,8 @@ public void annotation(Annotation a) {

Object substitution = a.get("substitution");
if (substitution != null) {
switch (substitution.toString()) {
switch (substitution.toString()
.toUpperCase(Locale.ROOT)) {
case "CONSUMER" :
info.put(PROVIDE_DIRECTIVE, "false");
break;
Expand Down
59 changes: 49 additions & 10 deletions biz.aQute.bndlib/src/aQute/bnd/osgi/AnnotationHeaders.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
Expand All @@ -18,6 +19,7 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.osgi.resource.Namespace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -34,6 +36,7 @@
import aQute.bnd.bundle.annotations.Headers;
import aQute.bnd.bundle.annotations.Requirement;
import aQute.bnd.bundle.annotations.Requirements;
import aQute.bnd.exceptions.Exceptions;
import aQute.bnd.header.Attrs;
import aQute.bnd.header.OSGiHeader;
import aQute.bnd.header.Parameters;
Expand All @@ -42,13 +45,12 @@
import aQute.bnd.osgi.Descriptors.PackageRef;
import aQute.bnd.osgi.Descriptors.TypeRef;
import aQute.bnd.stream.MapStream;
import aQute.bnd.unmodifiable.Sets;
import aQute.bnd.version.Version;
import aQute.bnd.version.VersionRange;
import aQute.lib.collections.MultiMap;
import aQute.lib.converter.Converter;
import aQute.bnd.exceptions.Exceptions;
import aQute.lib.strings.Strings;
import aQute.bnd.unmodifiable.Sets;

/**
* This class parses the 'header annotations'. Header annotations are
Expand Down Expand Up @@ -740,23 +742,60 @@ private void doRequirement(Annotation a, Requirement annotation) throws Exceptio
"The Requirement annotation with namespace %s applied to class %s has invalid filter information.",
annotation.namespace(), current.getFQN());
}
req.append(";filter:='")
req.append(';')
.append(Namespace.REQUIREMENT_FILTER_DIRECTIVE)
.append(':')
.append('=')
.append('\'')
.append(filter)
.append('\'');
}

if (a.containsKey("resolution")) {
req.append(";resolution:=")
.append(annotation.resolution());
Object resolution = a.get("resolution");
if (resolution != null) {
String value = resolution.toString()
.toLowerCase(Locale.ROOT);
switch (value) {
case Namespace.RESOLUTION_MANDATORY :
case Namespace.RESOLUTION_OPTIONAL :
req.append(';')
.append(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE)
.append(':')
.append('=')
.append(value);
break;
default :
analyzer.error("Requirement annotation in %s has invalid resolution value: %s", current,
resolution);
break;
}
}

if (a.containsKey("cardinality")) {
req.append(";cardinality:=")
.append(annotation.cardinality());
Object cardinality = a.get("cardinality");
if (cardinality != null) {
String value = cardinality.toString()
.toLowerCase(Locale.ROOT);
switch (value) {
case Namespace.CARDINALITY_SINGLE :
case Namespace.CARDINALITY_MULTIPLE :
req.append(';')
.append(Namespace.REQUIREMENT_CARDINALITY_DIRECTIVE)
.append(':')
.append('=')
.append(value);
break;
default :
analyzer.error("Requirement annotation in %s has invalid cardinality value: %s", current,
cardinality);
break;
}
}

if (a.containsKey("effective")) {
req.append(";effective:=");
req.append(';')
.append(Namespace.REQUIREMENT_EFFECTIVE_DIRECTIVE)
.append(':')
.append('=');
escape(req, annotation.effective());
}

Expand Down

0 comments on commit e9fdaf1

Please sign in to comment.