1 | |
package org.apache.maven.shared.release.versions; |
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
import org.apache.maven.artifact.Artifact; |
23 | |
import org.apache.maven.artifact.ArtifactUtils; |
24 | |
import org.apache.maven.artifact.versioning.DefaultArtifactVersion; |
25 | |
import org.codehaus.plexus.util.StringUtils; |
26 | |
|
27 | |
import java.util.ArrayList; |
28 | |
import java.util.Arrays; |
29 | |
import java.util.List; |
30 | |
import java.util.Locale; |
31 | |
import java.util.regex.Matcher; |
32 | |
import java.util.regex.Pattern; |
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 | 124 | public class DefaultVersionInfo |
60 | |
implements VersionInfo |
61 | |
{ |
62 | |
private final String strVersion; |
63 | |
|
64 | |
private final List<String> digits; |
65 | |
|
66 | |
private String annotation; |
67 | |
|
68 | |
private String annotationRevision; |
69 | |
|
70 | |
private final String buildSpecifier; |
71 | |
|
72 | |
private String annotationSeparator; |
73 | |
|
74 | |
private String annotationRevSeparator; |
75 | |
|
76 | |
private final String buildSeparator; |
77 | |
|
78 | |
private static final int DIGITS_INDEX = 1; |
79 | |
|
80 | |
private static final int ANNOTATION_SEPARATOR_INDEX = 2; |
81 | |
|
82 | |
private static final int ANNOTATION_INDEX = 3; |
83 | |
|
84 | |
private static final int ANNOTATION_REV_SEPARATOR_INDEX = 4; |
85 | |
|
86 | |
private static final int ANNOTATION_REVISION_INDEX = 5; |
87 | |
|
88 | |
private static final int BUILD_SEPARATOR_INDEX = 6; |
89 | |
|
90 | |
private static final int BUILD_SPECIFIER_INDEX = 7; |
91 | |
|
92 | |
private static final String SNAPSHOT_IDENTIFIER = "SNAPSHOT"; |
93 | |
|
94 | |
private static final String DIGIT_SEPARATOR_STRING = "."; |
95 | |
|
96 | 2 | public static final Pattern STANDARD_PATTERN = Pattern.compile( |
97 | |
"^((?:\\d+\\.)*\\d+)" |
98 | |
+ "([-_])?" |
99 | |
+ "([a-zA-Z]*)" |
100 | |
+ "([-_])?" |
101 | |
+ "(\\d*)" |
102 | |
+ "(?:([-_])?(.*?))?$" ); |
103 | |
|
104 | |
|
105 | |
|
106 | |
|
107 | |
|
108 | |
|
109 | |
|
110 | |
|
111 | |
|
112 | 2 | public static final Pattern ALTERNATE_PATTERN = Pattern.compile( |
113 | |
"^(SNAPSHOT|[a-zA-Z]+[_-]SNAPSHOT)" |
114 | |
); |
115 | |
|
116 | |
|
117 | |
|
118 | |
|
119 | |
|
120 | |
|
121 | |
public DefaultVersionInfo( String version ) |
122 | |
throws VersionParseException |
123 | 444 | { |
124 | 444 | strVersion = version; |
125 | |
|
126 | |
|
127 | 444 | Matcher matcher = ALTERNATE_PATTERN.matcher( strVersion ); |
128 | |
|
129 | 444 | if ( matcher.matches() ) |
130 | |
{ |
131 | 14 | annotation = null; |
132 | 14 | digits = null; |
133 | 14 | buildSpecifier = version; |
134 | 14 | buildSeparator = null; |
135 | 14 | return; |
136 | |
} |
137 | |
|
138 | 430 | Matcher m = STANDARD_PATTERN.matcher( strVersion ); |
139 | 430 | if ( m.matches() ) |
140 | |
{ |
141 | 420 | digits = parseDigits( m.group( DIGITS_INDEX ) ); |
142 | 420 | if ( !SNAPSHOT_IDENTIFIER.equals( m.group( ANNOTATION_INDEX ) ) ) |
143 | |
{ |
144 | 370 | annotationSeparator = m.group( ANNOTATION_SEPARATOR_INDEX ); |
145 | 370 | annotation = nullIfEmpty( m.group( ANNOTATION_INDEX ) ); |
146 | |
|
147 | 370 | if ( StringUtils.isNotEmpty( m.group( ANNOTATION_REV_SEPARATOR_INDEX ) ) |
148 | |
&& StringUtils.isEmpty( m.group( ANNOTATION_REVISION_INDEX ) ) ) |
149 | |
{ |
150 | |
|
151 | 4 | buildSeparator = m.group( ANNOTATION_REV_SEPARATOR_INDEX ); |
152 | 4 | buildSpecifier = nullIfEmpty( m.group( BUILD_SPECIFIER_INDEX ) ); |
153 | |
} |
154 | |
else |
155 | |
{ |
156 | 366 | annotationRevSeparator = m.group( ANNOTATION_REV_SEPARATOR_INDEX ); |
157 | 366 | annotationRevision = nullIfEmpty( m.group( ANNOTATION_REVISION_INDEX ) ); |
158 | |
|
159 | 366 | buildSeparator = m.group( BUILD_SEPARATOR_INDEX ); |
160 | 366 | buildSpecifier = nullIfEmpty( m.group( BUILD_SPECIFIER_INDEX ) ); |
161 | |
} |
162 | |
} |
163 | |
else |
164 | |
{ |
165 | |
|
166 | 50 | buildSeparator = m.group( ANNOTATION_SEPARATOR_INDEX ); |
167 | 50 | buildSpecifier = nullIfEmpty( m.group( ANNOTATION_INDEX ) ); |
168 | |
} |
169 | |
} |
170 | |
else |
171 | |
{ |
172 | 10 | throw new VersionParseException( "Unable to parse the version string: \"" + version + "\"" ); |
173 | |
} |
174 | 420 | } |
175 | |
|
176 | |
public DefaultVersionInfo( List<String> digits, String annotation, String annotationRevision, String buildSpecifier, |
177 | |
String annotationSeparator, String annotationRevSeparator, String buildSeparator ) |
178 | 68 | { |
179 | 68 | this.digits = digits; |
180 | 68 | this.annotation = annotation; |
181 | 68 | this.annotationRevision = annotationRevision; |
182 | 68 | this.buildSpecifier = buildSpecifier; |
183 | 68 | this.annotationSeparator = annotationSeparator; |
184 | 68 | this.annotationRevSeparator = annotationRevSeparator; |
185 | 68 | this.buildSeparator = buildSeparator; |
186 | 68 | this.strVersion = getVersionString( this, buildSpecifier, buildSeparator ); |
187 | 68 | } |
188 | |
|
189 | |
public boolean isSnapshot() |
190 | |
{ |
191 | 14 | return ArtifactUtils.isSnapshot( strVersion ); |
192 | |
} |
193 | |
|
194 | |
public VersionInfo getNextVersion() |
195 | |
{ |
196 | 74 | DefaultVersionInfo version = null; |
197 | 74 | if ( digits != null ) |
198 | |
{ |
199 | 68 | List<String> digits = new ArrayList<String>( this.digits ); |
200 | 68 | String annotationRevision = this.annotationRevision; |
201 | 68 | if ( StringUtils.isNumeric( annotationRevision ) ) |
202 | |
{ |
203 | 12 | annotationRevision = incrementVersionString( annotationRevision ); |
204 | |
} |
205 | |
else |
206 | |
{ |
207 | 56 | digits.set( digits.size() - 1, incrementVersionString( (String) digits.get( digits.size() - 1 ) ) ); |
208 | |
} |
209 | |
|
210 | 68 | version = new DefaultVersionInfo( digits, annotation, annotationRevision, buildSpecifier, |
211 | |
annotationSeparator, annotationRevSeparator, buildSeparator ); |
212 | |
} |
213 | 74 | return version; |
214 | |
} |
215 | |
|
216 | |
|
217 | |
|
218 | |
|
219 | |
|
220 | |
|
221 | |
|
222 | |
|
223 | |
|
224 | |
public int compareTo( VersionInfo obj ) |
225 | |
{ |
226 | 128 | DefaultVersionInfo that = (DefaultVersionInfo) obj; |
227 | |
|
228 | |
int result; |
229 | |
|
230 | 128 | if ( strVersion.startsWith( that.strVersion ) && !strVersion.equals( that.strVersion ) |
231 | |
&& strVersion.charAt( that.strVersion.length() ) != '-' ) |
232 | |
{ |
233 | 2 | result = 1; |
234 | |
} |
235 | 126 | else if ( that.strVersion.startsWith( strVersion ) && !strVersion.equals( that.strVersion ) |
236 | |
&& that.strVersion.charAt( strVersion.length() ) != '-' ) |
237 | |
{ |
238 | 2 | result = -1; |
239 | |
} |
240 | |
else |
241 | |
{ |
242 | |
|
243 | |
|
244 | 124 | String thisVersion = strVersion.toUpperCase( Locale.ENGLISH ).toLowerCase( Locale.ENGLISH ); |
245 | 124 | String thatVersion = that.strVersion.toUpperCase( Locale.ENGLISH ).toLowerCase( Locale.ENGLISH ); |
246 | |
|
247 | 124 | result = new DefaultArtifactVersion( thisVersion ).compareTo( new DefaultArtifactVersion( thatVersion ) ); |
248 | |
} |
249 | 128 | return result; |
250 | |
} |
251 | |
|
252 | |
public boolean equals( Object obj ) |
253 | |
{ |
254 | 4 | if ( !( obj instanceof DefaultVersionInfo ) ) |
255 | |
{ |
256 | 0 | return false; |
257 | |
} |
258 | |
|
259 | 4 | return compareTo( (VersionInfo) obj ) == 0; |
260 | |
} |
261 | |
|
262 | |
|
263 | |
|
264 | |
|
265 | |
|
266 | |
|
267 | |
|
268 | |
protected String incrementVersionString( String s ) |
269 | |
{ |
270 | 68 | int n = Integer.valueOf( s ).intValue() + 1; |
271 | 68 | String value = String.valueOf( n ); |
272 | 68 | if ( value.length() < s.length() ) |
273 | |
{ |
274 | |
|
275 | 10 | value = StringUtils.leftPad( value, s.length(), "0" ); |
276 | |
} |
277 | 68 | return value; |
278 | |
} |
279 | |
|
280 | |
public String getSnapshotVersionString() |
281 | |
{ |
282 | 38 | if ( strVersion.equals( Artifact.SNAPSHOT_VERSION ) ) |
283 | |
{ |
284 | 2 | return strVersion; |
285 | |
} |
286 | |
|
287 | 36 | String baseVersion = getReleaseVersionString(); |
288 | |
|
289 | 36 | if ( baseVersion.length() > 0 ) |
290 | |
{ |
291 | 36 | baseVersion += "-"; |
292 | |
} |
293 | |
|
294 | 36 | return baseVersion + Artifact.SNAPSHOT_VERSION; |
295 | |
} |
296 | |
|
297 | |
public String getReleaseVersionString() |
298 | |
{ |
299 | 100 | String baseVersion = strVersion; |
300 | |
|
301 | 100 | Matcher m = Artifact.VERSION_FILE_PATTERN.matcher( baseVersion ); |
302 | 100 | if ( m.matches() ) |
303 | |
{ |
304 | 4 | baseVersion = m.group( 1 ); |
305 | |
} |
306 | |
|
307 | 96 | else if ( StringUtils.right( baseVersion, 9 ).equalsIgnoreCase( "-" + Artifact.SNAPSHOT_VERSION ) ) |
308 | |
{ |
309 | 54 | baseVersion = baseVersion.substring( 0, baseVersion.length() - Artifact.SNAPSHOT_VERSION.length() - 1 ); |
310 | |
} |
311 | 42 | else if ( baseVersion.equals( Artifact.SNAPSHOT_VERSION ) ) |
312 | |
{ |
313 | 4 | baseVersion = "1.0"; |
314 | |
} |
315 | 100 | return baseVersion; |
316 | |
} |
317 | |
|
318 | |
public String toString() |
319 | |
{ |
320 | 144 | return strVersion; |
321 | |
} |
322 | |
|
323 | |
protected static String getVersionString( DefaultVersionInfo info, String buildSpecifier, String buildSeparator ) |
324 | |
{ |
325 | 68 | StringBuilder sb = new StringBuilder(); |
326 | |
|
327 | 68 | if ( info.digits != null ) |
328 | |
{ |
329 | 68 | sb.append( joinDigitString( info.digits ) ); |
330 | |
} |
331 | |
|
332 | 68 | if ( StringUtils.isNotEmpty( info.annotation ) ) |
333 | |
{ |
334 | 16 | sb.append( StringUtils.defaultString( info.annotationSeparator ) ); |
335 | 16 | sb.append( info.annotation ); |
336 | |
} |
337 | |
|
338 | 68 | if ( StringUtils.isNotEmpty( info.annotationRevision ) ) |
339 | |
{ |
340 | 12 | if ( StringUtils.isEmpty( info.annotation ) ) |
341 | |
{ |
342 | 0 | sb.append( StringUtils.defaultString( info.annotationSeparator ) ); |
343 | |
} |
344 | |
else |
345 | |
{ |
346 | 12 | sb.append( StringUtils.defaultString( info.annotationRevSeparator ) ); |
347 | |
} |
348 | 12 | sb.append( info.annotationRevision ); |
349 | |
} |
350 | |
|
351 | 68 | if ( StringUtils.isNotEmpty( buildSpecifier ) ) |
352 | |
{ |
353 | 22 | sb.append( StringUtils.defaultString( buildSeparator ) ); |
354 | 22 | sb.append( buildSpecifier ); |
355 | |
} |
356 | |
|
357 | 68 | return sb.toString(); |
358 | |
} |
359 | |
|
360 | |
|
361 | |
|
362 | |
|
363 | |
|
364 | |
|
365 | |
protected static String joinDigitString( List<String> digits ) |
366 | |
{ |
367 | 130 | return digits != null ? StringUtils.join( digits.iterator(), DIGIT_SEPARATOR_STRING ) : null; |
368 | |
} |
369 | |
|
370 | |
|
371 | |
|
372 | |
|
373 | |
|
374 | |
|
375 | |
|
376 | |
private List<String> parseDigits( String strDigits ) |
377 | |
{ |
378 | 420 | return Arrays.asList( StringUtils.split( strDigits, DIGIT_SEPARATOR_STRING ) ); |
379 | |
} |
380 | |
|
381 | |
|
382 | |
|
383 | |
|
384 | |
|
385 | |
private static String nullIfEmpty( String s ) |
386 | |
{ |
387 | 1156 | return StringUtils.isEmpty( s ) ? null : s; |
388 | |
} |
389 | |
|
390 | |
public List<String> getDigits() |
391 | |
{ |
392 | 62 | return digits; |
393 | |
} |
394 | |
|
395 | |
public String getAnnotation() |
396 | |
{ |
397 | 62 | return annotation; |
398 | |
} |
399 | |
|
400 | |
public String getAnnotationRevision() |
401 | |
{ |
402 | 62 | return annotationRevision; |
403 | |
} |
404 | |
|
405 | |
public String getBuildSpecifier() |
406 | |
{ |
407 | 62 | return buildSpecifier; |
408 | |
} |
409 | |
|
410 | |
} |