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 java.util.Arrays;
23 import java.util.List;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26
27 import org.apache.maven.artifact.ArtifactUtils;
28 import org.apache.maven.artifact.versioning.ArtifactVersion;
29 import org.codehaus.plexus.util.StringUtils;
30
31 public class Version
32 implements Comparable<Version>
33 {
34 private final AetherVersion aetherVersion;
35
36 private final MavenArtifactVersion mavenArtifactVersion;
37
38 private final String strVersion;
39
40 private final List<String> digits;
41
42 private String annotation;
43
44 private String annotationRevision;
45
46 private final String buildSpecifier;
47
48 private String annotationSeparator;
49
50 private String annotationRevSeparator;
51
52 private final String buildSeparator;
53
54 private static final int DIGITS_INDEX = 1;
55
56 private static final int ANNOTATION_SEPARATOR_INDEX = 2;
57
58 private static final int ANNOTATION_INDEX = 3;
59
60 private static final int ANNOTATION_REV_SEPARATOR_INDEX = 4;
61
62 private static final int ANNOTATION_REVISION_INDEX = 5;
63
64 private static final int BUILD_SEPARATOR_INDEX = 6;
65
66 private static final int BUILD_SPECIFIER_INDEX = 7;
67
68 private static final String SNAPSHOT_IDENTIFIER = "SNAPSHOT";
69
70 private static final String DIGIT_SEPARATOR_STRING = ".";
71
72 public static final Pattern STANDARD_PATTERN = Pattern.compile( "^((?:\\d+\\.)*\\d+)"
73
74
75 + "([-_])?"
76 + "([a-zA-Z]*)"
77 + "([-_])?"
78 + "(\\d*)"
79 + "(?:([-_])?(.*?))?$" );
80
81
82
83
84
85 public static final Pattern ALTERNATE_PATTERN = Pattern.compile( "^(SNAPSHOT|[a-zA-Z]+[_-]SNAPSHOT)"
86
87
88
89
90
91
92
93 );
94
95 public Version( String version )
96 throws VersionParseException
97 {
98 this.strVersion = version;
99 this.aetherVersion = new AetherVersion( version );
100 this.mavenArtifactVersion = new MavenArtifactVersion( version );
101
102
103 Matcher matcher = ALTERNATE_PATTERN.matcher( strVersion );
104
105 if ( matcher.matches() )
106 {
107 annotation = null;
108 digits = null;
109 buildSpecifier = version;
110 buildSeparator = null;
111 return;
112 }
113
114 Matcher m = STANDARD_PATTERN.matcher( strVersion );
115 if ( m.matches() )
116 {
117 digits = parseDigits( m.group( DIGITS_INDEX ) );
118 if ( !SNAPSHOT_IDENTIFIER.equals( m.group( ANNOTATION_INDEX ) ) )
119 {
120 annotationSeparator = m.group( ANNOTATION_SEPARATOR_INDEX );
121 annotation = nullIfEmpty( m.group( ANNOTATION_INDEX ) );
122
123 if ( StringUtils.isNotEmpty( m.group( ANNOTATION_REV_SEPARATOR_INDEX ) )
124 && StringUtils.isEmpty( m.group( ANNOTATION_REVISION_INDEX ) ) )
125 {
126
127 buildSeparator = m.group( ANNOTATION_REV_SEPARATOR_INDEX );
128 buildSpecifier = nullIfEmpty( m.group( BUILD_SPECIFIER_INDEX ) );
129 }
130 else
131 {
132 annotationRevSeparator = m.group( ANNOTATION_REV_SEPARATOR_INDEX );
133 annotationRevision = nullIfEmpty( m.group( ANNOTATION_REVISION_INDEX ) );
134
135 buildSeparator = m.group( BUILD_SEPARATOR_INDEX );
136 buildSpecifier = nullIfEmpty( m.group( BUILD_SPECIFIER_INDEX ) );
137 }
138 }
139 else
140 {
141
142 buildSeparator = m.group( ANNOTATION_SEPARATOR_INDEX );
143 buildSpecifier = nullIfEmpty( m.group( ANNOTATION_INDEX ) );
144 }
145 }
146 else
147 {
148 throw new VersionParseException( "Unable to parse the version string: \"" + version + "\"" );
149 }
150 }
151
152 public boolean isSnapshot()
153 {
154 return ArtifactUtils.isSnapshot( strVersion );
155 }
156
157 public String toString()
158 {
159 return strVersion;
160 }
161
162 protected static String getVersionString( Version info, String buildSpecifier, String buildSeparator )
163 {
164 StringBuilder sb = new StringBuilder();
165
166 if ( info.digits != null )
167 {
168 sb.append( joinDigitString( info.digits ) );
169 }
170
171 if ( StringUtils.isNotEmpty( info.annotation ) )
172 {
173 sb.append( StringUtils.defaultString( info.annotationSeparator ) );
174 sb.append( info.annotation );
175 }
176
177 if ( StringUtils.isNotEmpty( info.annotationRevision ) )
178 {
179 if ( StringUtils.isEmpty( info.annotation ) )
180 {
181 sb.append( StringUtils.defaultString( info.annotationSeparator ) );
182 }
183 else
184 {
185 sb.append( StringUtils.defaultString( info.annotationRevSeparator ) );
186 }
187 sb.append( info.annotationRevision );
188 }
189
190 if ( StringUtils.isNotEmpty( buildSpecifier ) )
191 {
192 sb.append( StringUtils.defaultString( buildSeparator ) );
193 sb.append( buildSpecifier );
194 }
195
196 return sb.toString();
197 }
198
199
200
201
202
203
204 protected static String joinDigitString( List<String> digits )
205 {
206 return digits != null ? StringUtils.join( digits.iterator(), DIGIT_SEPARATOR_STRING ) : null;
207 }
208
209
210
211
212
213
214 private List<String> parseDigits( String strDigits )
215 {
216 return Arrays.asList( StringUtils.split( strDigits, DIGIT_SEPARATOR_STRING ) );
217 }
218
219 private static String nullIfEmpty( String s )
220 {
221 return StringUtils.isEmpty( s ) ? null : s;
222 }
223
224 public List<String> getDigits()
225 {
226 return digits;
227 }
228
229 public String getAnnotation()
230 {
231 return annotation;
232 }
233
234 public String getAnnotationRevSeparator()
235 {
236 return annotationRevSeparator;
237 }
238
239 public String getAnnotationRevision()
240 {
241 return annotationRevision;
242 }
243
244 public String getBuildSeparator()
245 {
246 return buildSeparator;
247 }
248
249 public String getBuildSpecifier()
250 {
251 return buildSpecifier;
252 }
253
254
255
256
257
258 public int compareTo( Version other )
259 throws VersionComparisonConflictException
260 {
261 int aetherComparisonResult = this.aetherVersion.compareTo( other.aetherVersion );
262 int mavenComparisonResult = this.mavenArtifactVersion.compareTo( other.mavenArtifactVersion );
263
264 if ( aetherComparisonResult < 0 && mavenComparisonResult < 0 )
265 {
266 return -1;
267 }
268 else if ( aetherComparisonResult == 0 && mavenComparisonResult == 0 )
269 {
270 return 0;
271 }
272 else if ( aetherComparisonResult > 0 && mavenComparisonResult > 0 )
273 {
274 return 1;
275 }
276 else
277 {
278 throw new VersionComparisonConflictException( this.strVersion, other.strVersion, aetherComparisonResult,
279 mavenComparisonResult );
280 }
281 }
282
283 }