/
BoundArtifactVersion.java
130 lines (108 loc) · 4.6 KB
/
BoundArtifactVersion.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package org.codehaus.mojo.versions.ordering;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.codehaus.mojo.versions.api.Segment;
import static org.codehaus.mojo.versions.ordering.ComparableVersion.IntegerItem.ZERO;
/**
* <p>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.</p>
* <p>When compared with 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.</p>
* <p>This is particularly helpful for -SNAPSHOT and other versions with qualifiers, which
* are lower than version 0 in the Maven versioning system.</p>
*/
public class BoundArtifactVersion extends DefaultArtifactVersion {
/**
* 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;
/**
* Constructs the instance
* @param artifactVersion artifact version containing the segment version values
* @param segment most major segment that can change, i.e. <em>not</em> held in place
*/
public BoundArtifactVersion(ArtifactVersion artifactVersion, Segment segment) {
super(artifactVersion.toString());
this.segment = segment;
this.comparator = new BoundComparableVersion(this);
}
/**
* Returns the most major segment that can change.
* All segments that are more major than this one are held in place.
* @return segment that can change
*/
public Segment getSegment() {
return segment;
}
@Override
public int compareTo(ArtifactVersion other) {
if (other == null) {
return -1;
}
return comparator.compareTo(ComparableVersion.of(other.toString()));
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof BoundArtifactVersion)) {
return false;
}
BoundArtifactVersion that = (BoundArtifactVersion) o;
return new EqualsBuilder()
.appendSuper(super.equals(o))
.append(getSegment(), that.getSegment())
.append(comparator, that.comparator)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.appendSuper(super.hashCode())
.append(getSegment())
.append(comparator)
.toHashCode();
}
protected static class BoundComparableVersion extends ComparableVersion {
private BoundArtifactVersion artifactVersion;
protected BoundComparableVersion(BoundArtifactVersion artifactVersion) {
super(artifactVersion.toString());
this.artifactVersion = artifactVersion;
}
@Override
public int compareTo(ComparableVersion o) {
// all segments more or equally major than artifactVersion.segment can change
return compareTo(
((List<Item>) items).iterator(),
((Iterable<Item>) o.items).iterator(),
artifactVersion.segment.value());
}
private int compareTo(Iterator<Item> left, Iterator<Item> right, int comparisonsLeft) {
if (comparisonsLeft <= 0) {
// always greater than the other version if all more major segments are equal
return 1;
}
int result = left.hasNext() && right.hasNext()
? integerItemOrZero(left.next()).compareTo(right.next())
: left.hasNext() || right.hasNext() ? compareToZero(left, right) : 1;
return result != 0 ? result : compareTo(left, right, comparisonsLeft - 1);
}
private static int compareToZero(Iterator<Item> left, Iterator<Item> right) {
return left.hasNext()
? integerItemOrZero(left.next()).compareTo(ZERO)
: -right.next().compareTo(ZERO);
}
private static Item integerItemOrZero(Item item) {
return item instanceof IntegerItem ? item : ZERO;
}
}
}