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 package jnlp.sample.util;
38
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.List;
42
43
44
45
46
47
48
49 public class VersionID
50 implements Comparable
51 {
52 private String[] _tuple;
53
54 private boolean _usePrefixMatch;
55
56 private boolean _useGreaterThan;
57
58 private boolean _isCompound;
59
60 private VersionID _rest;
61
62
63
64
65 public VersionID( String str )
66 {
67 _usePrefixMatch = false;
68 _useGreaterThan = false;
69 _isCompound = false;
70 if ( str == null || str.length() == 0 )
71 {
72 _tuple = new String[0];
73 return;
74 }
75
76
77 int amp = str.indexOf( "&" );
78 if ( amp >= 0 )
79 {
80 _isCompound = true;
81 VersionID firstPart = new VersionID( str.substring( 0, amp ) );
82 _rest = new VersionID( str.substring( amp + 1 ) );
83 _tuple = firstPart._tuple;
84 _usePrefixMatch = firstPart._usePrefixMatch;
85 _useGreaterThan = firstPart._useGreaterThan;
86 }
87 else
88 {
89
90 if ( str.endsWith( "+" ) )
91 {
92 _useGreaterThan = true;
93 str = str.substring( 0, str.length() - 1 );
94 }
95 else if ( str.endsWith( "*" ) )
96 {
97 _usePrefixMatch = true;
98 str = str.substring( 0, str.length() - 1 );
99 }
100
101 List<String> list = new ArrayList<String>();
102 int start = 0;
103 for ( int i = 0; i < str.length(); i++ )
104 {
105
106 if ( ".-_".indexOf( str.charAt( i ) ) != -1 )
107 {
108 if ( start < i )
109 {
110 String value = str.substring( start, i );
111 list.add( value );
112 }
113 start = i + 1;
114 }
115 }
116 if ( start < str.length() )
117 {
118 list.add( str.substring( start, str.length() ) );
119 }
120 _tuple = new String[list.size()];
121 _tuple = list.toArray( _tuple );
122 }
123 }
124
125
126
127
128 public boolean isSimpleVersion()
129 {
130 return !_useGreaterThan && !_usePrefixMatch && !_isCompound;
131 }
132
133
134
135
136
137
138
139 public boolean match( VersionID vid )
140 {
141 if ( _isCompound )
142 {
143 if ( !_rest.match( vid ) )
144 {
145 return false;
146 }
147 }
148 return ( _usePrefixMatch )
149 ? this.isPrefixMatch( vid )
150 : ( _useGreaterThan ) ? vid.isGreaterThanOrEqual( this ) : matchTuple( vid );
151 }
152
153
154
155
156 public boolean equals( Object o )
157 {
158 if ( matchTuple( o ) )
159 {
160 VersionID ov = (VersionID) o;
161 if ( _rest == null || _rest.equals( ov._rest ) )
162 {
163 if ( ( _useGreaterThan == ov._useGreaterThan ) && ( _usePrefixMatch == ov._usePrefixMatch ) )
164 {
165 return true;
166 }
167 }
168 }
169 return false;
170 }
171
172
173
174
175 private boolean matchTuple( Object o )
176 {
177
178 if ( o == null || !( o instanceof VersionID ) )
179 {
180 return false;
181 }
182 VersionID vid = (VersionID) o;
183
184
185 String[] t1 = normalize( _tuple, vid._tuple.length );
186 String[] t2 = normalize( vid._tuple, _tuple.length );
187
188
189 for ( int i = 0; i < t1.length; i++ )
190 {
191 Object o1 = getValueAsObject( t1[i] );
192 Object o2 = getValueAsObject( t2[i] );
193 if ( !o1.equals( o2 ) )
194 {
195 return false;
196 }
197 }
198 return true;
199 }
200
201 private Object getValueAsObject( String value )
202 {
203 if ( value.length() > 0 && value.charAt( 0 ) != '-' )
204 {
205 try
206 {
207 return Integer.valueOf( value );
208 }
209 catch ( NumberFormatException nfe )
210 { }
211 }
212 return value;
213 }
214
215 public boolean isGreaterThan( VersionID vid )
216 {
217 return isGreaterThanOrEqualHelper( vid, false );
218 }
219
220 public boolean isGreaterThanOrEqual( VersionID vid )
221 {
222 return isGreaterThanOrEqualHelper( vid, true );
223 }
224
225
226
227
228 private boolean isGreaterThanOrEqualHelper( VersionID vid, boolean allowEqual )
229 {
230
231 if ( _isCompound )
232 {
233 if ( !_rest.isGreaterThanOrEqualHelper( vid, allowEqual ) )
234 {
235 return false;
236 }
237 }
238
239 String[] t1 = normalize( _tuple, vid._tuple.length );
240 String[] t2 = normalize( vid._tuple, _tuple.length );
241
242 for ( int i = 0; i < t1.length; i++ )
243 {
244
245 Object e1 = getValueAsObject( t1[i] );
246 Object e2 = getValueAsObject( t2[i] );
247 if ( e1.equals( e2 ) )
248 {
249
250 }
251 else
252 {
253 if ( e1 instanceof Integer && e2 instanceof Integer )
254 {
255 return (Integer) e1 > (Integer) e2;
256 }
257 else
258 {
259 String s1 = t1[i];
260 String s2 = t2[i];
261 return s1.compareTo( s2 ) > 0;
262 }
263
264 }
265 }
266
267 return allowEqual;
268 }
269
270
271
272
273 public boolean isPrefixMatch( VersionID vid )
274 {
275
276 if ( _isCompound )
277 {
278 if ( !_rest.isPrefixMatch( vid ) )
279 {
280 return false;
281 }
282 }
283
284 String[] t2 = normalize( vid._tuple, _tuple.length );
285
286 for ( int i = 0; i < _tuple.length; i++ )
287 {
288 Object e1 = _tuple[i];
289 Object e2 = t2[i];
290 if ( e1.equals( e2 ) )
291 {
292
293 }
294 else
295 {
296
297 return false;
298 }
299 }
300 return true;
301 }
302
303
304
305
306 private String[] normalize( String[] list, int minlength )
307 {
308 if ( list.length < minlength )
309 {
310
311 String[] newlist = new String[minlength];
312 System.arraycopy( list, 0, newlist, 0, list.length );
313 Arrays.fill( newlist, list.length, newlist.length, "0" );
314 return newlist;
315 }
316 else
317 {
318 return list;
319 }
320 }
321
322 public int compareTo( Object o )
323 {
324 if ( o == null || !( o instanceof VersionID ) )
325 {
326 return -1;
327 }
328 VersionID vid = (VersionID) o;
329 return equals( vid ) ? 0 : ( isGreaterThanOrEqual( vid ) ? 1 : -1 );
330 }
331
332
333
334
335 public String toString()
336 {
337 StringBuilder sb = new StringBuilder();
338 for ( int i = 0; i < _tuple.length - 1; i++ )
339 {
340 sb.append( _tuple[i] );
341 sb.append( '.' );
342 }
343 if ( _tuple.length > 0 )
344 {
345 sb.append( _tuple[_tuple.length - 1] );
346 }
347 if ( _usePrefixMatch )
348 {
349 sb.append( '+' );
350 }
351 return sb.toString();
352 }
353 }
354