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 }