• Intro Headers Instructions Macros Commands
  • Fork me on GitHub
    • Introduction
    • How to install bnd
    • Guided Tour
    • Guided Tour Workspace & Projects
    • Concepts
    • Best practices
    • Build
    • Project Setup
    • Generating JARs
    • Versioning
    • Baselining
    • Service Components
    • Metatype
    • Contracts
    • Bundle Annotations
    • Accessor Properties
    • SPI Annotations
    • Resolving Dependencies
    • Launching
    • Startlevels
    • Testing
    • Testing with Launchpad
    • Packaging Applications
    • JPMS Libraries
    • Wrapping Libraries to OSGi Bundles
    • Generating Documentation
    • Commands
    • For Developers
    • Tips for Windows users
    • Tools bound to bnd
    • Headers
    • Instruction Reference
    • Instruction Index
    • Macro Reference
    • Macro Index
    • Plugins
    • External Plugins
    • Settings
    • Errors
    • Warnings
    • Frequently Asked Questions
  • 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);
    	}
    }
    
    • GitHub