This project has retired. For details please refer to its
Attic page.
VersionComparator xref
1 package org.apache.archiva.common.utils;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.lang.ArrayUtils;
23 import org.apache.commons.lang.StringUtils;
24 import org.apache.commons.lang.math.NumberUtils;
25
26 import java.util.ArrayList;
27 import java.util.Comparator;
28 import java.util.List;
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 public class VersionComparator
55 implements Comparator<String>
56 {
57 private static final Comparator<String> INSTANCE = new VersionComparator();
58
59 private final List<String> specialWords;
60
61 public VersionComparator()
62 {
63 specialWords = new ArrayList<>( 23 );
64
65
66 specialWords.add( "final" );
67 specialWords.add( "release" );
68 specialWords.add( "current" );
69 specialWords.add( "latest" );
70 specialWords.add( "g" );
71 specialWords.add( "gold" );
72 specialWords.add( "fcs" );
73
74
75 specialWords.add( "a" );
76 specialWords.add( "alpha" );
77 specialWords.add( "b" );
78 specialWords.add( "beta" );
79 specialWords.add( "pre" );
80 specialWords.add( "rc" );
81 specialWords.add( "m" );
82 specialWords.add( "milestone" );
83
84
85 specialWords.add( "dev" );
86 specialWords.add( "test" );
87 specialWords.add( "debug" );
88 specialWords.add( "unofficial" );
89 specialWords.add( "nightly" );
90 specialWords.add( "incubating" );
91 specialWords.add( "incubator" );
92 specialWords.add( "snapshot" );
93 }
94
95 public static Comparator<String> getInstance()
96 {
97 return INSTANCE;
98 }
99
100 @Override
101 public int compare( String o1, String o2 )
102 {
103 if ( o1 == null && o2 == null )
104 {
105 return 0;
106 }
107
108 if ( o1 == null )
109 {
110 return 1;
111 }
112
113 if ( o2 == null )
114 {
115 return -1;
116 }
117
118 String[] parts1 = toParts( o1 );
119 String[] parts2 = toParts( o2 );
120
121 int diff;
122 int partLen = Math.max( parts1.length, parts2.length );
123 for ( int i = 0; i < partLen; i++ )
124 {
125 diff = comparePart( safePart( parts1, i ), safePart( parts2, i ) );
126 if ( diff != 0 )
127 {
128 return diff;
129 }
130 }
131
132 diff = parts2.length - parts1.length;
133
134 if ( diff != 0 )
135 {
136 return diff;
137 }
138
139 return o1.compareToIgnoreCase( o2 );
140 }
141
142 private String safePart( String[] parts, int idx )
143 {
144 if ( idx < parts.length )
145 {
146 return parts[idx];
147 }
148
149 return "0";
150 }
151
152 private int comparePart( String s1, String s2 )
153 {
154 boolean is1Num = NumberUtils.isNumber( s1 );
155 boolean is2Num = NumberUtils.isNumber( s2 );
156
157
158 if ( is1Num && is2Num )
159 {
160 int i1 = NumberUtils.toInt( s1 );
161 int i2 = NumberUtils.toInt( s2 );
162
163 return i1 - i2;
164 }
165
166
167 if ( !is1Num && !is2Num )
168 {
169 int idx1 = specialWords.indexOf( s1.toLowerCase() );
170 int idx2 = specialWords.indexOf( s2.toLowerCase() );
171
172
173
174 if ( idx1 >= 0 && idx2 >= 0 )
175 {
176 return idx1 - idx2;
177 }
178 }
179
180
181 if ( !is1Num && is2Num )
182 {
183 return -1;
184 }
185
186
187 if ( is1Num && !is2Num )
188 {
189 return 1;
190 }
191
192
193 return s1.compareToIgnoreCase( s2 );
194 }
195
196 public static String[] toParts( String version )
197 {
198 if ( StringUtils.isBlank( version ) )
199 {
200 return ArrayUtils.EMPTY_STRING_ARRAY;
201 }
202
203 int modeOther = 0;
204 int modeDigit = 1;
205 int modeText = 2;
206
207 List<String> parts = new ArrayList<>();
208 int len = version.length();
209 int i = 0;
210 int start = 0;
211 int mode = modeOther;
212
213 while ( i < len )
214 {
215 char c = version.charAt( i );
216
217 if ( Character.isDigit( c ) )
218 {
219 if ( mode != modeDigit )
220 {
221 if ( mode != modeOther )
222 {
223 parts.add( version.substring( start, i ) );
224 }
225 mode = modeDigit;
226 start = i;
227 }
228 }
229 else if ( Character.isLetter( c ) )
230 {
231 if ( mode != modeText )
232 {
233 if ( mode != modeOther )
234 {
235 parts.add( version.substring( start, i ) );
236 }
237 mode = modeText;
238 start = i;
239 }
240 }
241 else
242 {
243
244 if ( mode != modeOther )
245 {
246 parts.add( version.substring( start, i ) );
247 mode = modeOther;
248 }
249 }
250
251 i++;
252 }
253
254
255 if ( mode != modeOther )
256 {
257 parts.add( version.substring( start, i ) );
258 }
259
260 return parts.toArray( new String[parts.size()] );
261 }
262 }