Provided intial OSGi support for WebJars#58
Conversation
| </developers> | ||
|
|
||
| <properties> | ||
| <bnd.bundle.version>3.3.1.2-SNAPSHOT</bnd.bundle.version> |
There was a problem hiding this comment.
I've tried to make bumping these easy by creating the unsnapshot plugin so I wonder if we can create a similar plugin that OSGI-ifies the version rather than having to edit it in multiple places.
There was a problem hiding this comment.
I've attached a piece of code that takes a maven version and tries to transform it into an OSGi version. In the worst case this will always return a version in the form 0.0.0.timestamp if the given maven version is completly malformed.
I have no experience with creating Maven plugins, so maybe you could just take this code an turn it into one?
public class OSGiVersion {
public static void main(String[] args) {
OSGiVersion osgiVersion = new OSGiVersion();
String s1 = "1.2.3.4-_asdfasdf&/"; // malformed qualifier
String s2 = ".asdf..33öjkhadsf"; // malformed segments and malformed qualifier
String s3 = "1.asdf.3.asd.asdf.sdf"; // malformed segment and malformed qualifier
String s4 = "1.2.3-beta1-2"; // everything ok
String s5 = ""; // malformed version
String s6 = "1.2-test"; // everything ok
String s7 = "1.2-SNAPSHOT"; // everything ok
System.out.println(osgiVersion.calculateVersion(s1));
System.out.println(osgiVersion.calculateVersion(s2));
System.out.println(osgiVersion.calculateVersion(s3));
System.out.println(osgiVersion.calculateVersion(s4));
System.out.println(osgiVersion.calculateVersion(s5));
System.out.println(osgiVersion.calculateVersion(s6));
System.out.println(osgiVersion.calculateVersion(s7));
}
/**
* @param mvnVersion
* @return a version that is compliant tothe description of OSGi versions by https://osgi.org/specification/osgi.core/7.0.0/framework.module.html#i2655136
*/
public String calculateVersion(String mvnVersion) {
// default OSGi version
String[] bndVersionSegments = {"0", "0", "0", Long.toString(System.currentTimeMillis())};
if(mvnVersion == null || mvnVersion.length() == 0) {
// malformed version -> error message?
System.err.println("Malformed version");
return toVersionString(bndVersionSegments);
}
// remove all whitespaces
mvnVersion = mvnVersion.replaceAll("\\s+", "");
// get all segments, but at most 4
String[] mvnVersionSegments = mvnVersion.split("\\.", 4);
for (int i = 0; i < mvnVersionSegments.length; i++) {
String mvnSegment = mvnVersionSegments[i];
String[] numberAndRest = getNumberAndRest(mvnSegment);
switch (numberAndRest.length) {
case 0:
// no leading number found in this segment
if(i == 3) {
// it's ok, because it is the qualifier, which doesn't need to start with a number
bndVersionSegments[3] = formatQualifier(mvnSegment);
} else {
// malformed segment -> error message?
System.err.println("Malformed segment");
}
break;
case 1:
// it's a number. This is always acceptable
bndVersionSegments[i] = numberAndRest[0];
break;
case 2:
// it's a number with something else as rest.
if(i == 3) {
// it's ok because it is the qualifier
bndVersionSegments[3] = formatQualifier(mvnSegment);
} else{
if(i == mvnVersionSegments.length - 1) {
// it's ok because it is the last segment of the maven version. The rest is used as qualifier
bndVersionSegments[i] = numberAndRest[0];
bndVersionSegments[3] = formatQualifier(numberAndRest[1]);
}
else {
// malformed segment -> error message?
System.err.println("Malformed segment");
}
}
break;
default:
// malformed return -> error message?
System.err.println("Malformed return value of getNumberAndRest()");
break;
}
}
return toVersionString(bndVersionSegments);
}
/**
*
* @param segment a String in the form of a leading number part and anything else as rest, e.g. 123 or 123asdf.
* @return a String array 'result' with length 0 if segment has no leading number, 1 if segment is a number (result[0] == segment), 2 if segment has a leading number and anything else as rest (result[0] == number, result[1] == rest)
*/
private String[] getNumberAndRest(String segment) {
String pattern = "(\\d+)(.*)";
if(segment.matches(pattern)) {
String number = segment.replaceAll(pattern, "$1");
String rest = segment.replaceAll(pattern, "$2");
if(rest.length() == 0) {
return new String[] {number};
}
return new String[]{number, rest};
} else {
return new String[0];
}
}
/**
* @param qualifier an arbitrary String
* @return a String that only contains a-z, A-z, 0-9, -, _
*/
private String formatQualifier(String qualifier) {
String wellFormedQualifier = qualifier.replaceAll("[^\\w_\\-]", "");
if(wellFormedQualifier.length() != qualifier.length()) {
// warning?
System.err.println("Malformed qualifier");
}
return wellFormedQualifier;
}
/**
* @return the values of the array with dots in between as one String
*/
private String toVersionString(String[] segments) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < segments.length; i++) {
String segment = segments[i];
sb.append(segment);
if(i != segments.length - 1) {
sb.append(".");
}
}
return sb.toString();
}
}There was a problem hiding this comment.
@jamesward is there anything else you need for this plugin?
There was a problem hiding this comment.
I've created a repo for the plugin:
https://github.com/jamesward/osgi-version-maven-plugin
But the output isn't quite what I'd expect. For example:
https://github.com/jamesward/osgi-version-maven-plugin/blob/master/src/test/java/com/jamesward/osgiversion/UnsnapshotMojoTest.java#L32
The output of that one is 1.2.3.-beta1-.2 (the dashes are preserved. Anyhow, let's collaborate over on that repo and get it fixed up and released.
There was a problem hiding this comment.
The "-beta1-.2" part is regarded as the qualifier part of the OSGi version, which may contain dashes, but if those are not important, then I can alter the code to remove them. In OSGi they have no effect on the resolver, I think.
There was a problem hiding this comment.
I think it'd look better without the dashes in the qualifier, at least without leading and trailing dashes. Want to send a PR?
I've added the bnd-maven-plugin to generate the necessary Manifest content, like
WebJars-Resource can be used in an OSGi environment to find WebJar bundles with a
BundleTrackerand register their resources at aHttpService.Require-Capability is redeclaring the dependencies that are also used by maven, but in a format that the OSGi resolver can use to automatically resolve those dependencies.
The Bundle-Version has to be set manually if the
${project.version}is not OSGi compatible, e.g. a version like this: 1.2.3-2-SNAPSHOT. Bnd would ignore the "-2-" part and create the version like this: 1.2.3.SNAPSHOT, where probably something like 1.2.3.2-SNAPSHOT would be preferred. Therefore I had to create a new propertybnd.bundle.versionthat is set to 1.2.3.2-SNAPSHOT to achieve this.