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 package info.magnolia.module.model;
35
36 import java.util.regex.Pattern;
37
38
39
40
41
42 public class Version {
43 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Version.class);
44
45 public static final Version UNDEFINED_FROM = new UndefinedEarlierVersion();
46 public static final Version UNDEFINED_TO = new UndefinedLaterVersion();
47 public static final Version UNDEFINED_DEVELOPMENT_VERSION = new UndefinedDevelopmentVersion();
48
49 private static final Pattern classifierValidation = Pattern.compile("[A-Za-z0-9-_]+");
50 private final short major;
51 private final short minor;
52 private final short patch;
53 private final String classifier;
54
55
56
57
58 protected Version(int major, int minor, int patch) {
59 this.major = (short) major;
60 this.minor = (short) minor;
61 this.patch = (short) patch;
62 this.classifier = null;
63 }
64
65 private Version(String versionStr) {
66 final String numbers;
67 final int classifierIdx = versionStr.indexOf('-');
68 if (classifierIdx > 0) {
69 classifier = versionStr.substring(classifierIdx + 1);
70 if (!classifierValidation.matcher(classifier).matches()) {
71 throw new IllegalArgumentException("Invalid classifier: \"" + classifier + "\" in version \"" + versionStr + "\"");
72 }
73 numbers = versionStr.substring(0, classifierIdx);
74 } else {
75 classifier = null;
76 numbers = versionStr;
77 }
78
79 final String[] strings = numbers.split("\\.", -1);
80 if (strings.length > 0) {
81 major = getShortFor("major revision", versionStr, strings[0]);
82 } else {
83 major = getShortFor("major revision", versionStr, versionStr);
84 }
85 if (strings.length > 1) {
86 minor = getShortFor("minor revision", versionStr, strings[1]);
87 } else {
88 minor = 0;
89 }
90 if (strings.length > 2) {
91 patch = getShortFor("patch revision", versionStr, strings[2]);
92 } else {
93 patch = 0;
94 }
95 }
96
97
98
99
100
101
102
103
104
105 public static Version parseVersion(String versionStr) {
106
107 versionStr = versionStr.trim();
108
109 log.debug("parsing version [{}]", versionStr);
110
111 if (UndefinedDevelopmentVersion.isDevelopmentVersion(versionStr)) {
112
113 return UNDEFINED_DEVELOPMENT_VERSION;
114 }
115
116 return new Version(versionStr);
117 }
118
119 public static Version parseVersion(int major, int minor, int patch) {
120 return new Version(major, minor, patch);
121 }
122
123
124
125
126
127 public boolean isEquivalent(final Version other) {
128 if (other == UNDEFINED_DEVELOPMENT_VERSION) {
129 return true;
130 }
131 return this.getMajor() == other.getMajor() &&
132 this.getMinor() == other.getMinor() &&
133 this.getPatch() == other.getPatch();
134 }
135
136 public boolean isStrictlyAfter(final Version other) {
137 if (isEquivalent(other)) {
138 return false;
139 }
140 if (this.getMajor() != other.getMajor()) {
141 return this.getMajor() > other.getMajor();
142 }
143 if (this.getMinor() != other.getMinor()) {
144 return this.getMinor() > other.getMinor();
145 }
146 if (this.getPatch() != other.getPatch()) {
147 return this.getPatch() > other.getPatch();
148 }
149 return false;
150 }
151
152 public boolean isBeforeOrEquivalent(final Version other) {
153 return !isStrictlyAfter(other);
154 }
155
156 public short getMajor() {
157 return major;
158 }
159
160 public short getMinor() {
161 return minor;
162 }
163
164 public short getPatch() {
165 return patch;
166 }
167
168 public String getClassifier() {
169 return classifier;
170 }
171
172 @Override
173 public String toString() {
174 return major + "." + minor + "." + patch + (classifier != null ? "-" + classifier : "");
175 }
176
177 private short getShortFor(String message, String versionStr, String input) {
178 try {
179 return Short.parseShort(input);
180 } catch (NumberFormatException e) {
181 throw new RuntimeException("Invalid " + message + ": \"" + input + "\" in version \"" + versionStr + "\"");
182 }
183 }
184
185 private static final class UndefinedLaterVersion extends Version {
186 public UndefinedLaterVersion() {
187 super(Short.MAX_VALUE, Short.MAX_VALUE, Short.MAX_VALUE);
188 }
189
190 @Override
191 public String toString() {
192 return "*";
193 }
194 }
195
196 private static final class UndefinedEarlierVersion extends Version {
197 public UndefinedEarlierVersion() {
198 super(Short.MIN_VALUE, Short.MIN_VALUE, Short.MIN_VALUE);
199 }
200
201 @Override
202 public String toString() {
203 return "*";
204 }
205 }
206
207
208
209
210
211 static final class UndefinedDevelopmentVersion extends Version {
212
213 @Deprecated
214 static final String KEY = "${project.version}";
215
216 public UndefinedDevelopmentVersion() {
217 super(0, 0, 0);
218 }
219
220 @Override
221 public boolean isEquivalent(Version other) {
222 return true;
223 }
224
225 @Override
226 public String toString() {
227 return KEY;
228 }
229
230 public static boolean isDevelopmentVersion(String version) {
231 return version != null && version.startsWith("${");
232 }
233
234 }
235
236
237 @Override
238 public boolean equals(Object o) {
239 if (this == o) {
240 return true;
241 }
242 if (o == null || getClass() != o.getClass()) {
243 return false;
244 }
245
246 Version/../../../info/magnolia/module/model/Version.html#Version">Version version = (Version) o;
247
248 if (major != version.major) {
249 return false;
250 }
251 if (minor != version.minor) {
252 return false;
253 }
254 if (patch != version.patch) {
255 return false;
256 }
257 if (classifier != null ? !classifier.equals(version.classifier) : version.classifier != null) {
258 return false;
259 }
260
261 return true;
262 }
263
264 @Override
265 public int hashCode() {
266 int result;
267 result = major;
268 result = 31 * result + minor;
269 result = 31 * result + patch;
270 result = 31 * result + (classifier != null ? classifier.hashCode() : 0);
271 return result;
272 }
273 }