Represents an artifact version with all segments more major or equal to a given segment - * held in place. It can be thought of as an artifact having +∞ as its upper bound - * on all segments less major than the held segment.
- *When compared with another artifact versions, this results with the other object + *
Represents an immutable artifact version with all segments major to the given segment + * held in place. It can be thought of as an artifact having +∞ as its upper bound + * on all segments minor to the held segment.
+ *For example:
+ *A {@link BoundArtifactVersion} of {@code [1.2.3-2, INCREMENTAL]} can be seen as {@code 1.2.+∞} + * and will be greater than all versions matching the {@code 1.2.*} pattern.
+ *A {@link BoundArtifactVersion} of {@code [1.2.3-2, SUBINCREMENTAL]} will be greater + * * than all versions matching the {@code 1.2.3-2.*} pattern.
+ *When compared to another artifact versions, this results with the other object * with the segment versions up to the held segment being equal, * always comparing lower than this object.
*This is particularly helpful for -SNAPSHOT and other versions with qualifiers, which * are lower than version 0 in the Maven versioning system.
*/ -public class BoundArtifactVersion extends DefaultArtifactVersion { +public class BoundArtifactVersion implements ArtifactVersion { /** * Most major segment that can change, i.e. not held in place. * All segments that are more major than this one are held in place. */ private final Segment segment; - private final BoundComparableVersion comparator; + private final ArtifactVersion comparable; /** - * Constructs the instance + * Constructs the instance given the version in a text format. + * @param artifactVersion version in a text format + * @param segment most major segment that can change, i.e. not held in place + */ + public BoundArtifactVersion(String artifactVersion, Segment segment) { + this.segment = segment; + StringBuilder versionBuilder = new StringBuilder(); + String[] segments = tokens(artifactVersion); + for (int segNr = 0; + segNr <= segments.length || segNr <= Segment.SUBINCREMENTAL.value(); + segNr++, versionBuilder.append(".")) { + if (segNr < segment.value()) { + versionBuilder.append(segNr < segments.length ? integerItemOrZero(segments[segNr]) : "0"); + } else { + versionBuilder.append(Integer.MAX_VALUE); + } + } + versionBuilder.append(Integer.MAX_VALUE); + comparable = DefaultArtifactVersionCache.of(versionBuilder.toString()); + } + + /** + * Constructs the instance given a {@link ArtifactVersion instance} * @param artifactVersion artifact version containing the segment version values * @param segment most major segment that can change, i.e. not held in place */ public BoundArtifactVersion(ArtifactVersion artifactVersion, Segment segment) { - super(artifactVersion.toString()); - this.segment = segment; - this.comparator = new BoundComparableVersion(this); + this(artifactVersion.toString(), segment); + } + + /** + * Splits the given version string into tokens, splitting them on the {@code .} or {@code -} characters + * as well as on letter/digit boundaries. + * @param version version string + * @return tokens of the parsed version string + */ + private static String[] tokens(String version) { + if (version == null) { + return new String[0]; + } + List