• Intro Headers Instructions Macros Commands
Fork me on GitHub
    • Getting Started
      • How to install bnd
      • Guided Tour
      • Guided Tour Workspace & Projects
      • FAQ - Frequently Asked Questions
    • Concepts and Practices
      • Introduction
      • Concepts
      • Best practices
    • Build and Development
      • Project Setup
      • Generating JARs
      • Versioning
      • Baselining
      • Service Components
      • Metatype
      • Contracts
      • Bundle Annotations
      • Accessor Properties
      • SPI Annotations
    • Dependency and Launching
      • Resolving Dependencies
      • Launching
      • Startlevels
    • Testing
      • Testing
      • Testing with Launchpad
    • Packaging and Distribution
      • Packaging Applications
      • JPMS Libraries
      • Wrapping Libraries to OSGi Bundles
    • Documentation and Tools
      • Generating Documentation
      • Commands
      • For Developers
      • Templates for Workspaces
      • Tips for Windows users
      • Tools bound to bnd
    • Reference Material
      • Reference
      • Headers
      • Instruction Reference
      • Instruction Index
      • Macro Reference
      • Macro Index
      • Plugins
      • External Plugins
    • Configuration and Troubleshooting
      • Settings
      • Errors
      • Warnings
  • Provide-Capability ::= capability (',' capability )*
    Header

    Specifies that a bundle provides a set of Capabilities,

    		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);
    	}
    }
    
Search
    • Home