708 Features Specification

708.1 Introduction

OSGi has become a platform capable of running large applications for a variety of purposes, including rich client applications, server-side systems and cloud and container based architectures. As these applications are generally based on many bundles, describing each bundle individually in an application definition becomes unwieldy once the number of bundles reaches a certain level.

When developing large scale applications it is often the case that few people know the role of every single bundle or configuration item in the application. To keep the architecture understandable a grouping mechanism is needed that allows for the representation of parts of the application into larger entities that keep reasoning about the system manageable. In such a domain members of teams spread across an organization will need to be able to both develop new parts for the application as well as make tweaks or enhancements to parts developed by others such as adding configuration and resources or changing one or more bundles relevant to their part of the application.

The higher level constructs that define the application should be reusable in different contexts, for example if one team has developed a component to handle job processing, different applications should be able to use it, and if needed tune its configuration or other aspects so that it works in each setting without having to know each and every detail that the job processing component is built up from.

Applications are often associated with additional resources or metadata, for example database scripts or custom artifacts. By including these with the application definition, all the related entities are encapsulated in a single artifact.

By combining various applications or subsystems together, systems are composed of existing, reusable building blocks, where all these blocks can work together. Architects of these systems need to think about components without having to dive into the individual implementation details of each subcomponent. The Features defined in this specification can be used to model such applications. Features contain the definition of an application or component and can be composed into larger systems.

708.1.1 Essentials

  • Declarative - Features are declarative and can be mapped to different implementations.

  • Extensible - Features are extensible with custom content to facilitate all information related to a Feature to be co-located.

  • Human Readable - No special software is needed to read or author Features.

  • Machine Readable - Features can easily be processed by tools.

708.1.2 Entities

The following entities are used in this specification:

  • Feature - A Feature contains a number of entities that, when provided to a launcher can be turned into an executable system. Features can also be building blocks which are assembled into larger systems.

  • Bundles - A Feature can contain one ore more bundles.

  • Capabilities and Requirements - A Feature can declare additional capabilities and requirements.

  • Configuration - A Feature can contain configurations for the Configuration Admin service.

  • Extension - A Feature can contain a number of extensions with custom content.

  • Launcher - A launcher can turn one or more Features into an executable system.

  • Processor - A Feature processor can read Features and perform a processing operation on them, such as validation, transformation or generation of new entities based on the Features.

  • Properties - Framework properties can be specified in a Feature.

Figure 708.1 Features Entity overview

Features Entity overview

708.2 Feature

Features are defined by declaring JSON documents or by using the Feature API. Each Feature has a unique ID which includes a version. It can hold a number of entities, including a list of bundles, configurations, capabilities, requirements and others. Features are extensible, that is a Feature can also hold any number of custom entities which are related to the Feature.

Features may have dependencies on other Features. Features inherit the capabilities and requirements from all bundles listed in the Feature, and can also have additional capabilities and requirements declared on the Feature level.

Once created, a Feature is immutable. Its definition cannot be modified. However another Feature with a different identity can be created which is based on a given Feature using the prototype mechanism.

Additionally it’s possible to record caching related information in a Feature through transient extensions, however this cached content is not significant for the definition of the Feature or part of its identity.

708.2.1 Identifiers

Identifiers used throughout this specification are defined using the Maven Identifier model. They are composed of the following parts:

  • Group ID

  • Artifact ID

  • Version

  • Type (optional)

  • Classifier (optional)

For more information see [3] Apache Maven Pom Reference. The format used to specify identifiers is as follows:

group-id ':' artifact-id [ ':' type [ ':' classifier ] ] ':' version

708.2.2 Feature Identifier

Each Feature has a unique identifier. Apart from providing a persistent handle to the Feature it also provides enough information to find the Feature in an artifact repository. This identifier is defined using the format described in Identifiers. As Features are immutable, a given Feature identifier always refers to the same Feature. ### Mention the Maven artifact packaging type: osgifeature

708.2.3 Attributes

A Feature can have the following attributes:

Table 708.1 Feature Attributes

Attribute Data Type Kind Description
name String Optional The short descriptive name of the Feature.
description String Optional A longer description of the Feature.
isComplete boolean Optional, defaults to false Completeness of the Feature. A Feature is complete when it has no external dependencies.
isFinal boolean Optional, defaults to false If the Feature is final. A final Feature cannot be used as a prototype for another Feature.
license String Optional The license of the Feature.
vendor String Optional The vendor of the Feature.

An initial Feature without content can be declared as follows:

{
  "id": "org.acme:acmeapp:1.0.0",

  "name": "The ACME app",
  "description": 
    "This is the main ACME app, from where all functionality can be reached."

  /*
    Additional Feature entities here
    ...
  */
}

708.2.4 Using the Feature API

Features can also be created, read and written using the Feature API. The Feature API uses the builder pattern to create most entities used in Features.

A builder is used to create a single entity and cannot be re-used to create a second one. Builders are obtained from the BuilderFactory

BuilderFactory factory = // ... from Service Registry ...

FeatureBuilder builder = factory.newFeatureBuilder(
  new ID("org.acme", "acmeapp", "1.0.0"));
builder.setName("The ACME app");
builder.setDescription("This is the main ACME app, "
  + "from where all functionality can be reached.");

Feature f = builder.build();

708.3 Comments

Comments in the form of [2] JSMin (The JavaScript Minifier) comments are supported, that is, any text on the same line after // is ignored and any text between /* */ is ignored.

708.4 Bundles

Features often list a number of bundles that implement the functionality provided by the Feature. Bundles are listed by referencing them in the bundles array so that they can be resolved from a repository. Bundles can have metadata associated with them, such as the relative start order of the bundle in the Feature. Custom metadata can also be provided. A single Feature can provide multiple versions of the same bundle, if desired.

Bundles are referenced using the identifier format described in Identifiers. This means that Bundles are referenced using their Maven coordinates. The bundles array can either contain String values referencing the bundles directly by their identifier, or JSON objects which can contain the bundle IDs with additional metadata.

The following example shows a simple Feature describing a small application with its dependencies:

{
  "id": "org.acme:acmeapp:1.0.1",
    
  "name": "The Acme Application",
  "license": "https://opensource.org/licenses/Apache-2.0",
  "isComplete": true,

  "bundles": [
    "org.osgi:org.osgi.util.function:1.1.0",
    "org.osgi:org.osgi.util.promise:1.1.1",
    {
      "id": "org.apache.commons:commons-email:1.5",

      // This attribute is used by custom tooling to 
      // find the associated javadoc
      "org.acme.javadoc.link": 
        "https://commons.apache.org/proper/commons-email/javadocs/api-1.5"
    },
    "com.acme:acmelib:1.7.2"      
  ]
   
  /* 
    Additional Feature entities here 
    ...
  */
}

708.4.1 Bundle Metadata

Arbitrary key-value pairs can be associated with bundle entries to store custom metadata alongside the bundle references. Reverse DNS naming should be used with the keys to avoid name clashes when metadata is provided by multiple entities.

Bundle metadata supports String keys and String values.

708.4.2 Using the Feature API

A Feature with Bundles can be created using the Feature API as follows:

BuilderFactory factory = // ... from Service Registry ...

FeatureBuilder builder = factory.newFeatureBuilder(
    new ID("org.acme", "acmeapp", "1.0.1"));
builder.setName("The Acme Application");
builder.setLicense("https://opensource.org/licenses/Apache-2.0");
builder.setComplete(true);

FeatureBundle b1 = factory.newBundleBuilder(
    ID.fromMavenID("org.osgi:org.osgi.util.function:1.1.0"))
  .build();

FeatureBundle b2 = factory.newBundleBuilder(
    ID.fromMavenID("org.osgi:org.osgi.util.promise:1.1.1"))
  .build();

FeatureBundle b3 = factory.newBundleBuilder(
    ID.fromMavenID("org.apache.commons:commons-email:1.1.5"))
  .addMetadata("org.acme.javadoc.link",
    "https://commons.apache.org/proper/commons-email/javadocs/api-1.5")
  .build();

FeatureBundle b4 = factory.newBundleBuilder(
    ID.fromMavenID("com.acme:acmelib:1.7.2"))
  .build();

builder.addBundles(b1, b2, b3, b4);

Feature f = builder.build();

708.5 Configurations

Features support configuration using the OSGi Configurator syntax, see Configurator Specification. This can be specified with the configurations key in the Feature. A Launcher can apply these configurations to the Configuration Admin service when starting the system.

It is an error to define the same PID (or Factory PID) twice in a single Feature.

Example:

{
    "id": "org.acme:acmeapp:osgifeature:configs:1.0.0",
    "configurations": {
        "org.apache.felix.http": {
            "org.osgi.service.http.port": 8080,
            "org.osgi.service.http.port.secure": 8443
        }
    }    
}

708.6 Framework Properties

When a Feature is launched in an OSGi framework it may be necessary to specify Framework properties. These can be provided in the Framework Properties section of the Feature. The Launcher must be able to satisfy the specified properties. If it cannot ensure that these are present in the running Framework the launcher must fail.

### TODO to specify failure behavior in all sections.

Example:

{
  "id": "org.acme:acmeapp:osgifeature:fw-props:2.0.0",
  "framework-properties": {
    "org.osgi.framework.system.packages.extra": 
      "javax.activation;version=\"1.1.1\"",
    "org.osgi.framework.bootdelegation": "javax.activation"
  }
}

708.7 Variables

Configurations and Framework Properties support late binding of values. This enables setting these items through a Launcher, for example to specify a database user name, server port number or other information that may be variable between runtimes.

Variables are declared in the variables section of the Feature and they can have a default value specified. The default can be of type String, number or boolean. Variables can also be declared to not have a default, which means that they must be provided with a value through the Launcher. This is done by specifying null as the default in the variable declaration.

Example:

{
    "id": "org.acme:acmeapp:osgifeature:configs:1.1.0",
    "variables": {
        "http.port": 8080,
        "db.username": "scott",
        "db.password": null
    },
    "configurations": {
        "org.acme.server.http": {
            "org.osgi.service.http.port:Integer": "${http.port}"
        },
        "org.acme.db": {
            "username": "${db.username}-user",
            "password": "${db.password}"
        }
    }    
}

Variables are referenced with the curly brace placeholder syntax: ${ variable-name } in the configuration value or framework property value section. To support conversion of variables to non-string types the configurator syntax specifying the datatype with the configuration key can be used, as in the above example.

Multiple variables can be referenced for a single configuration or framework property value and variables can be combined with text. Variable substitution is applied recursively, that is if the value of a variable is again a variable it must be substituted. If no variable exist with the given name, then the ${ variable-name } must be retained in the value.

708.8 Capabilities & Requirements

Features inherit all capabilities and requirements from their bundles. Additional capabilities and requirements can be added to the Feature directly.

For example, a Feature can declare a set of bundles and configurations which together may provide an osgi.implementation capability, meaning that sum of these provide the implementation of a specification. Any kind of capability can be declared to be provided by the Feature. These capabilities can be used as part of the resolution process when a number of Features are resolved together.

Additional requirements can mean that a Feature is only complete, when these requirements are also satisfied, in addition to the requirements provided in the bundles that are part of the Feature.

Example:

{
  "id": "org.acme:acmeapp:osgifeature:capreq:1.0.0",
  
  // Requirements over and above the requirements in the bundles 
  // referenced by the Feature.
  "requirements": [
    {
      "namespace": "osgi.contract",
      "directives": {
        "filter": "(&(osgi.contract=JavaServlet)(version=3.1))"
      }
    }
  ],

  // Capabilities over and above the capabilities provided by the 
  // bundles referenced by the Feature.
  "capabilities": [
    {
      "namespace": "osgi.service",
      "attributes": {
        "objectClass:List<String>": 
          "org.osgi.service.http.runtime.HttpServiceRuntime"
      }
    }
  ]
}

708.9 Extensions

Features can be extended with custom content. This makes it possible to keep entities and information relating to the Feature together with the rest of the Feature.

Custom content is provided through Feature extensions, and can be in one of the following formats:

  • Text - A text extension contains a block of text.

  • JSON - A JSON extension contains embedded custom JSON content.

  • Artifacts - A list of custom artifacts associated with the Feature.

Extensions can have a variety of consumers. For example they can be handled by a Feature Launcher or by an external tool which can process the extension at any point of the Feature life cycle.

Extensions can be marked as one of the following three kinds:

  • Mandatory - The entity processing this Feature must know how to handle this extension.

  • Optional - This extension is optional. If the entity processing the Feature cannot handle it, the extension can be skipped or ignored. This is the default.

  • Transient - This extension contains transient information which can be used to optimize the processing of the Feature. It is not part of the Feature definition.

Extensions are specified as JSON objects under the extensions key in the Feature. A Feature can contain any number of extensions, as long as the extension keys are unique. It is recommended to use reverse DNS naming for extension keys to avoid name clashing of multiple extensions in a single Feature. Extensions names without DNS prefix are reserved for OSGi use.

708.9.1 Text Extensions

Text extensions support the addition of custom text content to the Feature. The text is provided as a JSON string value or as a JSON array of strings. ### update the API to report text as an array

Example:

{
    "id": "org.acme:acmeapp:2.0.0",
    
    "name": "The Acme Application",
    "license": "https://opensource.org/licenses/Apache-2.0",
    "isComplete": true,

    "bundles": [
        "org.osgi:org.osgi.util.function:1.1.0",
        "org.osgi:org.osgi.util.promise:1.1.1",
        "com.acme:acmelib:2.0.0"      
    ],
    
    "extensions": {
        "org.acme.mydoc": {
            "type": "text",
            "text": [
                "This application provides the main acme ",
                "functionality."
            ]
        }
    }
}

708.9.2 JSON Extensions

Custom JSON content can be added to Features by using a JSON extension. The content can either be a JSON object or a JSON array.

The following example extension declares under which execution environment the Feature is complete, using a custom JSON object.

{
    "id": "org.acme:acmeapp:2.1.0",
    
    "name": "The Acme Application",
    "license": "https://opensource.org/licenses/Apache-2.0",
    "isComplete": true,

    "bundles": [
        "org.osgi:org.osgi.util.function:1.1.0",
        "org.osgi:org.osgi.util.promise:1.1.1",
        "com.acme:acmelib:2.0.0"      
    ],
    
    "extensions": {
        "execution-environment": {
            "type": "json",
            "json": {
                "environment-capabilities":
                    ["osgi.ee; filter:=\"(&(osgi.ee=JavaSE)(version=11))\""], 
                "framework": "org.osgi:core:6.0.0",
                "provided-features": ["org.acme:platform:1.1"]
            }
        }
    }
}

708.9.3 Artifact list Extension

Custom extensions can be used to associate artifacts that are not listed as bundles with the Feature.

For example, database definition resources can be listed as artifacts in a Feature. In the following example, the extension org.acme.ddlfiles lists Database Definition Resources which must be handled by the launcher agent, that is, the database must be configured when the application is run:

{
    "id": "org.acme:acmeapp:2.2.0",
    
    "name": "The Acme Application",
    "license": "https://opensource.org/licenses/Apache-2.0",
    "isComplete": true,

    "bundles": [
        "org.osgi:org.osgi.util.function:1.1.0",
        "org.osgi:org.osgi.util.promise:1.1.1",
        "com.acme:acmelib:2.0.0"      
    ],
    
    "extensions": {
        "org.acme.ddlfiles": {
            "kind": "mandatory",
            "type": "artifacts",
            "artifacts": ["org.acme:appddl:1.2.1"]
        }
    }
}

### Do we want to support metadata for artifacts?

708.10 Merging Features

...

708.11 Security

...

708.12 JSON Schema

...

708.13 org.osgi.util.feature

Version 1.0

Converter Package Version 1.0.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. This package has two types of users: the consumers that use the API in this package and the providers that implement the API in this package.

Example import for consumers using the API in this package:

Import-Package: org.osgi.util.feature; version="[1.0,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.util.feature; version="[1.0,1.1)"

708.13.1 Summary

708.13.2 public interface BuilderFactory

The Builder Factory can be used to obtain builders for the various entities.

Consumers of this API must not implement this type

708.13.2.1 public FeatureBundleBuilder newBundleBuilder(ID id)

The artifact ID for the bundle object being built.

Obtain a new builder for Bundle objects.

The builder.

708.13.2.2 public FeatureConfigurationBuilder newConfigurationBuilder(String pid)

The persistent ID for the Configuration being built.

Obtain a new builder for Configuration objects.

The builder.

708.13.2.3 public FeatureConfigurationBuilder newConfigurationBuilder(String factoryPid, String name)

The factory persistent ID for the Configuration being built.

The name of the configuration being built. The PID for the configuration will be the factoryPid + '~' + name

Obtain a new builder for Factory Configuration objects.

The builder.

708.13.2.4 public FeatureExtensionBuilder newExtensionBuilder(String name, FeatureExtension.Type type, FeatureExtension.Kind kind)

The extension name.

The type of extension: JSON, Text or Artifacts.

The kind of extension: Mandatory, Optional or Transient.

Obtain a new builder for Feature objects.

The builder.

708.13.2.5 public FeatureBuilder newFeatureBuilder(ID id)

The artifact ID for the feature object being built.

Obtain a new builder for Feature objects.

The builder.

708.13.2.6 public MergeContextBuilder newMergeContextBuilder()

Obtain a new builder for MergeContext objects.

The builder.

708.13.3 public interface ConflictResolver<T, R>

The type of entity this conflict resolver is used for.

The type of the result of the resolution.

Interface implemented by a callback that can resolve merge conflicts.

Thread-safe

708.13.3.1 public R resolve(Feature f1, T o1, Feature f2, T o2)

The first feature model.

The first conflicting object.

The second feature model

The second conflicting object.

Resolve this conflict between o1 and o2.

The resolution of the conflict.

708.13.4 public interface Feature
extends FeatureArtifact

The Feature Model Feature.

Thread-safe

Consumers of this API must not implement this type

708.13.4.1 public List<FeatureBundle> getBundles()

Get the bundles.

The bundles.

708.13.4.2 public Map<String, FeatureConfiguration> getConfigurations()

Get the configurations.

The configurations.

708.13.4.3 public String getDescription()

Get the description.

The description.

708.13.4.4 public Map<String, FeatureExtension> getExtensions()

Get the extensions.

The extensions.

708.13.4.5 public String getLicense()

Get the license.

The license.

708.13.4.6 public String getName()

Get the name.

The name.

708.13.4.7 public Map<String, String> getVariables()

Get the variables.

The variables.

708.13.4.8 public String getVendor()

Get the vendor.

The vendor.

708.13.4.9 public boolean isComplete()

Get whether the feature is complete or not.

Completeness value.

708.13.4.10 public boolean isFinal()

Get whether the feature is final or not.

Final value.

708.13.5 public interface FeatureArtifact

An Artifact is an entity with an ID.

Consumers of this API must not implement this type

708.13.5.1 public ID getID()

Get the artifact's ID.

The ID of this artifact.

708.13.6 public interface FeatureBuilder

A builder for Feature Models.

Not Thread-safe

Consumers of this API must not implement this type

708.13.6.1 public FeatureBuilder addBundles(FeatureBundle... bundles)

The Bundles to add.

Add Bundles to the Feature.

This builder.

708.13.6.2 public FeatureBuilder addConfigurations(FeatureConfiguration... configs)

The Configurations to add.

Add Configurations to the Feature.

This builder.

708.13.6.3 public FeatureBuilder addExtensions(FeatureExtension... extensions)

The Extensions to add.

Add Extensions to the Feature

This builder.

708.13.6.4 public FeatureBuilder addVariable(String key, String defaultValue)

The key.

The default value.

Add a variable to the Feature. If a variable with the specified key already exists it is replaced with this one.

This builder.

708.13.6.5 public FeatureBuilder addVariables(Map<String, String> variables)

to be added.

Add a map of variables to the Feature

This builder.

708.13.6.6 public Feature build()

Build the Feature. Can only be called once on a builder. After calling this method the current builder instance cannot be used any more.

The Feature.

708.13.6.7 public FeatureBuilder setComplete(boolean complete)

If the feature is complete.

Set the Feature Complete flag.

This builder.

708.13.6.8 public FeatureBuilder setDescription(String description)

The description.

Set the Feature Description.

This builder.

708.13.6.9 public FeatureBuilder setFinal(boolean isFinal)

If the feature is final.

Set the Feature is Final flag.

This builder.

708.13.6.10 public FeatureBuilder setLicense(String license)

The License.

Set the License.

This builder.

708.13.6.11 public FeatureBuilder setName(String name)

The Name.

Set the Feature Name.

This builder.

708.13.6.12 public FeatureBuilder setVendor(String vendor)

The Vendor.

Set the Vendor.

This builder.

708.13.7 public interface FeatureBundle
extends FeatureArtifact

A Bundle which is part of a feature.

Thread-safe

Consumers of this API must not implement this type

708.13.7.1 public Map<String, Object> getMetadata()

Get the metadata for this bundle.

The metadata.

708.13.8 public interface FeatureBundleBuilder

A builder for Feature Model FeatureBundle objects.

Not Thread-safe

Consumers of this API must not implement this type

708.13.8.1 public FeatureBundleBuilder addMetadata(String key, Object value)

Metadata key.

Metadata value.

Add metadata for this Bundle.

This builder.

708.13.8.2 public FeatureBundleBuilder addMetadata(Map<String, Object> md)

The map with metadata.

Add metadata for this Bundle by providing a map. All metadata in the map is added to any previously provided metadata.

This builder.

708.13.8.3 public FeatureBundle build()

Build the Bundle object. Can only be called once on a builder. After calling this method the current builder instance cannot be used any more.

The Bundle.

708.13.9 public interface FeatureConfiguration

Represents an OSGi Configuration in the Feature Model.

Thread-safe

Consumers of this API must not implement this type

708.13.9.1 public String getFactoryPid()

Get the Factory PID from the configuration, if any.

The Factory PID, or null if there is none.

708.13.9.2 public String getPid()

Get the PID from the configuration.

The PID.

708.13.9.3 public Map<String, Object> getValues()

Get the configuration key-value map.

The key-value map.

708.13.10 public interface FeatureConfigurationBuilder

A builder for Feature Model FeatureConfiguration objects.

Not Thread-safe

Consumers of this API must not implement this type

708.13.10.1 public FeatureConfigurationBuilder addValue(String key, Object value)

The configuration key.

The configuration value. Acceptable data types are: TODO list

Add a configuration value for this Configuration object. If a value with the same key was previously provided the previous value is overwritten.

This builder.

708.13.10.2 public FeatureConfigurationBuilder addValues(Map<String, Object> cfg)

Add a map of configuration values for this Configuration object. All values will be added to any previously provided configuration values.

This builder.

708.13.10.3 public FeatureConfiguration build()

Build the Configuration object. Can only be called once on a builder. After calling this method the current builder instance cannot be used any more.

The Configuration.

708.13.11 public interface FeatureExtension

A Feature Model Extension. Extensions can contain either Text, JSON or a list of Artifacts.

Extensions are of one of the following kinds:

  • Mandatory: this extension must be processed by the runtime

  • Optional: this extension does not have to be processed by the runtime

  • Transient: this extension contains transient information such as caching data that is for optimization purposes. It may be changed or removed and is not part of the feature's identity.

Thread-safe

Consumers of this API must not implement this type

708.13.11.1 public List<ID> getArtifacts()

Get the Artifacts from this extension.

The Artifacts, or null if this is not an Artifacts extension.

708.13.11.2 public String getJSON()

Get the JSON from this extension.

The JSON, or null if this is not a JSON extension.

708.13.11.3 public FeatureExtension.Kind getKind()

Get the extension kind.

The kind.

708.13.11.4 public String getName()

Get the extension name.

The name.

708.13.11.5 public String getText()

Get the Text from this extension.

The Text, or null if this is not a Text extension.

708.13.11.6 public FeatureExtension.Type getType()

Get the extension type.

The type.

708.13.12 enum FeatureExtension.Kind

The kind of extension: optional, mandatory or transient.

708.13.12.1 MANDATORY

A mandatory extension must be processed.

708.13.12.2 OPTIONAL

An optional extension can be ignored if no processor is found.

708.13.12.3 TRANSIENT

A transient extension contains computed information which can be used as a cache to speed up operation.

708.13.12.4 public static FeatureExtension.Kind valueOf(String name)

708.13.12.5 public static FeatureExtension.Kind[] values()

708.13.13 enum FeatureExtension.Type

The type of extension

708.13.13.1 JSON

A JSON extension.

708.13.13.2 TEXT

A plain text extension.

708.13.13.3 ARTIFACTS

An extension that is a list of artifact identifiers.

708.13.13.4 public static FeatureExtension.Type valueOf(String name)

708.13.13.5 public static FeatureExtension.Type[] values()

708.13.14 public interface FeatureExtensionBuilder

A builder for Feature Model FeatureExtension objects.

Not Thread-safe

Consumers of this API must not implement this type

708.13.14.1 public FeatureExtensionBuilder addArtifact(ID aid)

The ArtifactID of the artifact to add.

Add an Artifact to the extension. Can only be called for extensions of type FeatureExtension.Type.ARTIFACTS.

This builder.

708.13.14.2 public FeatureExtensionBuilder addArtifact(String groupId, String artifactId, String version)

The Group ID of the artifact to add.

The Artifact ID of the artifact to add.

The Version of the artifact to add.

Add an Artifact to the extension. Can only be called for extensions of type FeatureExtension.Type.ARTIFACTS.

This builder.

708.13.14.3 public FeatureExtensionBuilder addArtifact(String groupId, String artifactId, String version, String at, String classifier)

The Group ID of the artifact to add.

The Artifact ID of the artifact to add.

The Version of the artifact to add.

The type indicator of the artifact to add.

The classifier of the artifact to add.

Add an Artifact to the extension. Can only be called for extensions of type FeatureExtension.Type.ARTIFACTS.

This builder.

708.13.14.4 public FeatureExtensionBuilder addText(String text)

The text to be added.

Add text to the extension. Can only be called for extensions of type FeatureExtension.Type.TEXT.

This builder.

708.13.14.5 public FeatureExtension build()

Build the Extension. Can only be called once on a builder. After calling this method the current builder instance cannot be used any more.

The Extension.

708.13.14.6 public FeatureExtensionBuilder setJSON(String json)

The JSON to be added.

Add JSON in String form to the extension. Can only be called for extensions of type FeatureExtension.Type.JSON.

This builder.

708.13.15 public class Features

The Features class is the primary entry point for interacting with the feature model.

Thread-safe

Consumers of this API must not implement this type

708.13.15.1 public Features()

708.13.15.2 public static BuilderFactory getBuilderFactory()

Get a factory which can be used to build feature model entities.

A builder factory.

708.13.15.3 public static Feature mergeFeatures(ID targetID, Feature f1, Feature f2, MergeContext ctx)

The ID of the new feature.

The first feature

The second feature

The merge context to use for the merge operation.

Merge two features into a new feature.

The merged feature.

708.13.15.4 public static Feature readFeature(Reader jsonReader) throws IOException

A Reader to the JSON input

Read a Feature from JSON

The Feature represented by the JSON

IOException– When reading fails

708.13.15.5 public static void writeFeature(Feature feature, Writer jsonWriter) throws IOException

the Feature to write.

A Writer to which the Feature should be written.

Write a Feature Model to JSON

IOException– When writing fails.

708.13.16 public class ID

ID used to denote an artifact. This could be a feature model, a bundle which is part of the feature model or some other artifact.

Artifact IDs follow the Maven convention of having:

  • A group ID

  • An artifact ID

  • A version

  • A type identifier (optional)

  • A classifier (optional)

Thread-safe

Consumers of this API must not implement this type

708.13.16.1 public ID(String groupId, String artifactId, String version)

The group ID.

The artifact ID.

The version.

Construct an Artifact ID

708.13.16.2 public ID(String groupId, String artifactId, String version, String type, String classifier)

The group ID.

The artifact ID.

The version.

The type identifier.

The classifier.

Construct an Artifact ID

708.13.16.3 public boolean equals(Object obj)

708.13.16.4 public static ID fromMavenID(String mavenID)

Construct an Artifact ID from a Maven ID. Maven IDs have the following syntax:

group-id ':' artifact-id [ ':' [type] [ ':' classifier ] ] ':' version

The ID

708.13.16.5 public String getArtifactId()

Get the artifact ID.

The artifact ID.

708.13.16.6 public String getClassifier()

Get the classifier.

The classifier.

708.13.16.7 public String getGroupId()

Get the group ID.

The group ID.

708.13.16.8 public String getType()

Get the type identifier.

The type identifier.

708.13.16.9 public String getVersion()

Get the version.

The version.

708.13.16.10 public int hashCode()

708.13.16.11 public String toString()

708.13.17 public interface MergeContext

Context provided by the caller for the merge operation.

Consumers of this API must not implement this type

708.13.17.1 public List<FeatureBundle> handleBundleConflict(Feature f1, FeatureBundle b1, Feature f2, FeatureBundle b2)

The first feature.

The first bundle.

The second feature.

The second bundle.

If two merged features both contain the same bundle, same group ID and artifact ID but different version, this method is called to resolve what to do.

Return a list of bundles that should be used in this case. This could be one or both of the provided bundles, or a different bundle altogether.

708.13.17.2 public FeatureConfiguration handleConfigurationConflict(Feature f1, FeatureConfiguration c1, Feature f2, FeatureConfiguration c2)

The first feature.

The first configuration.

The second feature.

The second configuration.

If two merged features both contain the same configuration PID, this method is called to perform the merge operation.

The merged configuration to use.

708.13.17.3 public FeatureExtension handleExtensionConflict(Feature f1, FeatureExtension e1, Feature f2, FeatureExtension e2)

The first feature.

The first extension.

The second feature.

The second extension.

If two merged features both contain an extension with the same IF, this method is called to perform the merge operation.

The merged extension.

708.13.18 public interface MergeContextBuilder

A builder for MergeContext objects.

Not Thread-safe

Consumers of this API must not implement this type

708.13.18.1 public MergeContext build()

Build the Merge Context. Can only be called once on a builder. After calling this method the current builder instance cannot be used any more.

The Merge Context.

708.13.18.2 public MergeContextBuilder bundleConflictHandler(ConflictResolver<FeatureBundle, List<FeatureBundle>> bh)

The Conflict Resolver.

Set the Bundle Conflict Resolver.

This builder.

708.13.18.3 public MergeContextBuilder configConflictHandler(ConflictResolver<FeatureConfiguration, FeatureConfiguration> ch)

The Conflict Resolver.

Set the Configuration Conflict Resolver.

This builder.

708.13.18.4 public MergeContextBuilder extensionConflictHandler(ConflictResolver<FeatureExtension, FeatureExtension> eh)

The Conflict Resolver.

Set the Extension Conflict Resolver.

This builder.

708.14 References

[1]JSON (JavaScript Object Notation) https://www.json.org

[2]JSMin (The JavaScript Minifier) https://www.crockford.com/javascript/jsmin.html

[3]Apache Maven Pom Reference https://maven.apache.org/pom.html