Provide-Capability ::= capability (‘,’ capability )*
Description: Parameters capabilities = new Parameters(annotationHeaders.getHeader(PROVIDE_CAPABILITY)); /* * Provide-Capability header */ private void doProvideCapability(ProvideCapability annotation) { StringBuilder sb = new StringBuilder(annotation.ns()); if (annotation.name() != null) sb.append(";").append(annotation.ns()).append("='").append(annotation.name()).append("'"); if (annotation.uses() != null) sb.append(";").append("uses:='").append(Strings.join(",", annotation.uses())).append("'"); if (annotation.mandatory() != null) sb.append(";").append("mandatory:='").append(Strings.join(",", annotation.mandatory())).append("'"); if (annotation.version() != null) sb.append(";").append("version:Version='").append(annotation.version()).append("'"); if (annotation.value() != null) sb.append(";").append(annotation.value()); if (annotation.effective() != null) sb.append(";effective:='").append(annotation.effective()).append("'");
Date: 2019-10-12T20:06:21-04:00

- # Provide-Capability ::= capability (',' capability )*

      		Parameters capabilities = new Parameters(annotationHeaders.getHeader(PROVIDE_CAPABILITY));

      	/*
       * Provide-Capability header
       */
      private void doProvideCapability(ProvideCapability annotation) {
      	StringBuilder sb = new StringBuilder(annotation.ns());
      	if (annotation.name() != null)
      		sb.append(";").append(annotation.ns()).append("='").append(annotation.name()).append("'");
      	if (annotation.uses() != null)
      		sb.append(";").append("uses:='").append(Strings.join(",", annotation.uses())).append("'");
      	if (annotation.mandatory() != null)
      		sb.append(";").append("mandatory:='").append(Strings.join(",", annotation.mandatory())).append("'");
      	if (annotation.version() != null)
      		sb.append(";").append("version:Version='").append(annotation.version()).append("'");
      	if (annotation.value() != null)
      		sb.append(";").append(annotation.value());
      	if (annotation.effective() != null)
      		sb.append(";effective:='").append(annotation.effective()).append("'");

      	add(Constants.PROVIDE_CAPABILITY, sb.toString());
      }

      		package aQute.bnd.annotation.headers;

      	import java.lang.annotation.*;

      	/**
      	 * Define a Provide Capability clause in the manifest.
      	 * <p>
      	 * Since this annotation can only be applied once, it is possible to create an annotation
      	 * that models a specific capability. For example:
      	 * <pre>
      	 * interface Webserver {
      	 * 		@ProvideCapability(ns="osgi.extender", name="aQute.webserver", version = "${@version}")
      	 * 	 	@interface Provide {}
      	 *
      	 * 		@RequireCapability(ns="osgi.extender", filter="(&(osgi.extender=aQute.webserver)${frange;${@version}})")
      	 * 	 	@interface Require {}
      	 * }
      	 *
      	 * Webserver.@Provide
      	 * public class MyWebserver {
      	 * }
      	 * </pre>
      	 *
      	 */
      	@Retention(RetentionPolicy.CLASS)
      	@Target({
      			ElementType.ANNOTATION_TYPE, ElementType.TYPE
      	})
      	public @interface ProvideCapability {
      		/**
      		 * Appended at the end of the clause (after a ';'). Can be used to add
      		 * additional attributes and directives.
      		 */
      		String value() default "";

      		/**
      		 * The capability namespace. For example: {@code osgi.contract}.
      		 */
      		String ns();

      		/**
      		 * The name of the capability. If this is set, a property will be added as
      		 * {ns}={name}. This is the custom pattern for OSGi namespaces. Leaving this
      		 * unfilled, requires the {@link #value()} to be used to specify the name of
      		 * the capability, if needed. For example {@code aQute.sse}.
      		 */
      		String name() default "";

      		/**
      		 * The version of the capability. This must be a valid OSGi version.
      		 */
      		String version() default "";

      		/**
      		 * Effective time. Specifies the time a capability is available, either
      		 * resolve (default) or another name. The OSGi framework resolver only
      		 * considers Capabilities without an effective directive or
      		 * effective:=resolve. Capabilities with other values for the effective
      		 * directive can be considered by an external agent.
      		 */
      		String effective() default "resolve";

      		/**
      		 * The uses directive lists package names that are used by this Capability.
      		 * This information is intended to be used for <em>uses constraints</em>,
      		 */
      		String[] uses() default {};

      		/**
      		 * Mandatory attributes. Forces the resolver to only satisfy filters that
      		 * refer to all listed attributes.
      		 */
      		String[] mandatory() default {};
      	}

      				verifyDirectives(Constants.PROVIDE_CAPABILITY, "effective:|uses:", null, null);

      		private void verifyCapabilities() {
      	Parameters map = parseHeader(manifest.getMainAttributes().getValue(Constants.PROVIDE_CAPABILITY));
      	for (String key : map.keySet()) {
      		Attrs attrs = map.get(key);
      		verify(attrs, "cardinality:", CARDINALITY_PATTERN, false, "Requirement %s cardinality not correct", key);
      		verify(attrs, "resolution:", RESOLUTION_PATTERN, false, "Requirement %s resolution not correct", key);

      		if (key.equals("osgi.extender")) {
      			verify(attrs, "osgi.extender", SYMBOLICNAME, true,
      					"Extender %s must always have the osgi.extender attribute set", key);
      			verify(attrs, "version", VERSION, true, "Extender %s must always have a version", key);
      		} else if (key.equals("osgi.serviceloader")) {
      			verify(attrs, "register:", PACKAGEPATTERN, false,
      					"Service Loader extender register: directive not a fully qualified Java name");
      		} else if (key.equals("osgi.contract")) {
      			verify(attrs, "osgi.contract", SYMBOLICNAME, true,
      					"Contracts %s must always have the osgi.contract attribute set", key);

      		} else if (key.equals("osgi.service")) {
      			verify(attrs, "objectClass", MULTIPACKAGEPATTERN, true,
      					"osgi.service %s must have the objectClass attribute set", key);

      		} else if (key.equals("osgi.ee")) {
      			// TODO
      		} else if (key.startsWith("osgi.wiring.") || key.startsWith("osgi.identity")) {
      			error("osgi.wiring.* namespaces must not be specified with generic requirements/capabilities");
      		}

      		verifyAttrs(attrs);

      		if (attrs.containsKey("filter:"))
      			error("filter: directive is intended for Requirements, not Capability %s", key);
      		if (attrs.containsKey("cardinality:"))
      			error("cardinality: directive is intended for Requirements, not Capability %s", key);
      		if (attrs.containsKey("resolution:"))
      			error("resolution: directive is intended for Requirements, not Capability %s", key);
      	}
      }