5.4 Specifying automatic version expansion of imported packages based on a pattern

When you use the Import-Template template header to augment package imports that Bundlor generates in the manifest file, you use the version directive to specify a version or version range of the imported package.

Import-Template: 
 com.springsource.kernel*;version="[1.2.0, 2.0.0)"
 org.apache.commons.logging;version="[1.1.1, 2.0.0)"

The preceding example specifies that Bundlor should version the com.springsource.* packages at [2.5.4.A, 3.0.0) and the org.apache.commons.logging package at [1.1.1, 2.0.0) in the generated manifest file. This works just fine for many use cases, but sometimes the use of literal versions in this manner can be restrictive.

In order to make the manifest template more dynamic and useful, you can specify that Bundlor automatically expand the package version into a version range using an expansion pattern of your choosing. The pattern uses as a base a property placeholder that you define (as described in Section 5.3, “Specifying property placeholders”) and set to a valid OSGI version number. Then, based on the expansion pattern you specify, Bundlor generates a version range using the 4 parts of an OSGI version: major, minor, micro, and qualifier.

The way to tell Bundlor to automatically expand a package import version is to specify the property placeholder to the right of the version directive of the package in the Import-Template header, and then within the property placeholder, specify the pattern for both sides of the version range. The following manifest template snippet shows how to use this feature; the example is described in detail after the table.

Import-Template: 
 com.springsource.kernel.*;version="${com.springsource.kernel:[=.=.=.=, +1.0.0)}",
 org.apache.commons.logging.*;version="${org.apache.commons.logging:[=.=.=.=, =.=.+1)}"

The following table lists the symbols you can use in the expansion pattern.

Table 5.2. Expansion Pattern Symbols

SymbolDescriptionLocation Allowed
=Use the same value from the variable. Valid only in the first three segments (major, minor, micro) of the version pattern.
[+/-]n Adjust the value from the variable by this amount. For example, +1 means to add 1 to the value from the variable. Valid only in the first three segments (major, minor, micro) of the version pattern.
-n Substitute this value for the one in the variable. Typically you only use this for putting in a 0. Valid only in the first three segments (major, minor, micro) of the version pattern.
Any legal qualifier valueSubstitute this value for the one in the variable.Valid only in the fourth (qualifier) segment of the version pattern.

Based on the descriptions of the symbols, we can now understand how the examples above work. First assume that you have set the property ${com.springsource.kernel} to the value 1.2.0. Based on the expansion pattern, Bundlor sets the version range of the imported com.springsource.kernel.* packages to [1.2.0, 2.0.0). The pattern in this case first specifies that the beginning of the version range stay exactly the same as the value of the property. The pattern then specifies that at the end of the version range, the major part of the version should be one integer larger than what the property is originally set to (1); the pattern then specifies that the minor and micro segments of the version both be set to 0.

Similarly, assume that you set the ${org.apache.commons.logging} property to 1.4.0. Bundlor generates a version range of [1.4.0, 1.4.1). Again, the beginning of the range is exactly the same as the property value. The pattern specifies that, in the end of the range, only the micro segment of the version increase by one; the major and minor segments stay the same.

5.4.1 Re-using version patterns

If you use the same version expansion pattern for several imports, you can name the pattern using the Version-Patterns header in the manifest template, and then use this name in the particular import of Import-Template.

Use the form pattern.name;pattern="pattern" to specify a named pattern, where pattern.name is the name of the pattern and pattern is the pattern, such as [=.=.=.=, +1.0.0).

Version-Patterns:
 apache;pattern="[=.=.=.=, +1.0.0)",
 hibernate;pattern="[=.=.=.=, =.=.+1)"

The preceding example shows two named patterns: apache and hibernate. The apache pattern specifies a version range from the one provided in the property up to but not including the next major version. The hibernate pattern specifies a version range of the one provided up to but not including the next micro version.

To use a named pattern, simply substitute it in the Import-Template header in the place where you would put the in-line pattern.

Import-Template:
 org.apache.commons.codec.*;version="${org.apache.commons.codec:apache}",
 org.apache.commons.logging.*;version="${org.apache.commons.logging:apache}",
 org.hibernate.*;version="${org.hibernate:hibernate}"
 org.myorg.*;version="${org.myorg:(=.=.=.=, =.+1.0.=]}"

In the example, the apache named pattern is used twice, for the two org.apache imports, and the hibernate pattern is used once. Also note that you can also include an import whose version is specified with an in-line pattern. The in-line pattern shows a more unusual usage. It will create a version range from, but not including, the provided version up to and including the next minor version with the same qualifier.