View Javadoc

1   /*
2    * Copyright 2001-2005 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.geronimo.kernel.repository;
17  
18  import java.util.StringTokenizer;
19  import java.io.Serializable;
20  
21  /**
22   * Default implementation of artifact versioning.
23   *
24   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
25   * @version $Id: Version.java 410741 2006-06-01 04:35:48Z jsisson $
26   */
27  // This code was lifted from Apache Maven
28  public class Version implements Comparable, Serializable {
29      // Geronimo adds Serial UID because we serialize versions into config.ser
30      private static final long serialVersionUID = 7941704456058067109L;
31  
32      private Integer majorVersion;
33  
34      private Integer minorVersion;
35  
36      private Integer incrementalVersion;
37  
38      private Integer buildNumber;
39  
40      private String qualifier;
41  
42      public Version(String version) {
43          parseVersion(version);
44      }
45  
46      public int compareTo(Object o) {
47          Version otherVersion = (Version) o;
48  
49          int result = compareIntegers(majorVersion, otherVersion.majorVersion);
50          if (result == 0) {
51              result = compareIntegers(minorVersion, otherVersion.minorVersion);
52          }
53          if (result == 0) {
54              result = compareIntegers(incrementalVersion, otherVersion.incrementalVersion);
55          }
56          if (result == 0) {
57              if (buildNumber != null || otherVersion.buildNumber != null) {
58                  result = compareIntegers(buildNumber, otherVersion.buildNumber);
59              } else if (qualifier != null) {
60                  if (otherVersion.qualifier != null) {
61                      if (qualifier.length() > otherVersion.qualifier.length() &&
62                              qualifier.startsWith(otherVersion.qualifier)) {
63                          // here, the longer one that otherwise match is considered older
64                          result = -1;
65                      } else if (qualifier.length() < otherVersion.qualifier.length() &&
66                              otherVersion.qualifier.startsWith(qualifier)) {
67                          // here, the longer one that otherwise match is considered older
68                          result = 1;
69                      } else {
70                          result = qualifier.compareTo(otherVersion.qualifier);
71                      }
72                  } else {
73                      // otherVersion has no qualifier but we do - that's newer
74                      result = -1;
75                  }
76              } else if (otherVersion.qualifier != null) {
77                  // otherVersion has a qualifier but we don't, we're newer
78                  result = 1;
79              }
80          }
81          return result;
82      }
83  
84      private int compareIntegers(Integer i1, Integer i2) {
85          // treat null as 0 in comparison
86          if (i1 == null ? i2 == null : i1.equals(i2)) {
87              return 0;
88          } else if (i1 == null) {
89              return -i2.intValue();
90          } else if (i2 == null) {
91              return i1.intValue();
92          } else {
93              return i1.intValue() - i2.intValue();
94          }
95      }
96  
97      public int getMajorVersion() {
98          return majorVersion != null ? majorVersion.intValue() : 0;
99      }
100 
101     public int getMinorVersion() {
102         return minorVersion != null ? minorVersion.intValue() : 0;
103     }
104 
105     public int getIncrementalVersion() {
106         return incrementalVersion != null ? incrementalVersion.intValue() : 0;
107     }
108 
109     public int getBuildNumber() {
110         return buildNumber != null ? buildNumber.intValue() : 0;
111     }
112 
113     public String getQualifier() {
114         return qualifier;
115     }
116 
117     public final void parseVersion(String version) {
118         int index = version.indexOf("-");
119 
120         String part1;
121         String part2 = null;
122 
123         if (index < 0) {
124             part1 = version;
125         } else {
126             part1 = version.substring(0, index);
127             part2 = version.substring(index + 1);
128         }
129 
130         if (part2 != null) {
131             try {
132                 if (part2.length() == 1 || !part2.startsWith("0")) {
133                     buildNumber = Integer.valueOf(part2);
134                 } else {
135                     qualifier = part2;
136                 }
137             }
138             catch (NumberFormatException e) {
139                 qualifier = part2;
140             }
141         }
142 
143         if (part1.indexOf(".") < 0 && !part1.startsWith("0")) {
144             try {
145                 majorVersion = Integer.valueOf(part1);
146             }
147             catch (NumberFormatException e) {
148                 // qualifier is the whole version, including "-"
149                 qualifier = version;
150                 buildNumber = null;
151             }
152         } else {
153             boolean fallback = false;
154             StringTokenizer tok = new StringTokenizer(part1, ".");
155             try {
156                 majorVersion = getNextIntegerToken(tok);
157                 if (tok.hasMoreTokens()) {
158                     minorVersion = getNextIntegerToken(tok);
159                 }
160                 if (tok.hasMoreTokens()) {
161                     incrementalVersion = getNextIntegerToken(tok);
162                 }
163                 if (tok.hasMoreTokens()) {
164                     fallback = true;
165                 }
166             }
167             catch (NumberFormatException e) {
168                 fallback = true;
169             }
170 
171             if (fallback) {
172                 // qualifier is the whole version, including "-"
173                 qualifier = version;
174                 majorVersion = null;
175                 minorVersion = null;
176                 incrementalVersion = null;
177             }
178         }
179     }
180 
181     private static Integer getNextIntegerToken(StringTokenizer tok) {
182         String s = tok.nextToken();
183         if (s.length() > 1 && s.startsWith("0")) {
184             throw new NumberFormatException("Number part has a leading 0: '" + s + "'");
185         }
186         return Integer.valueOf(s);
187     }
188 
189     public String toString() {
190         StringBuffer buf = new StringBuffer();
191         if (majorVersion != null) {
192             buf.append(majorVersion);
193         }
194         if (minorVersion != null) {
195             buf.append(".");
196             buf.append(minorVersion);
197         }
198         if (incrementalVersion != null) {
199             buf.append(".");
200             buf.append(incrementalVersion);
201         }
202         if (buildNumber != null) {
203             buf.append("-");
204             buf.append(buildNumber);
205         } else if (qualifier != null) {
206             if (buf.length() > 0) {
207                 buf.append("-");
208             }
209             buf.append(qualifier);
210         }
211         return buf.toString();
212     }
213 
214     public boolean equals(Object other) {
215         if (this == other) {
216             return true;
217         }
218         if (other == null || this.getClass() != other.getClass()) {
219             return false;
220         }
221         Version v = (Version) other;
222         if (majorVersion == null? v.majorVersion != null: !majorVersion.equals(v.majorVersion)) {
223             return false;
224         }
225         if (minorVersion == null? v.minorVersion != null: !minorVersion.equals(v.minorVersion)) {
226             return false;
227         }
228         if (incrementalVersion == null? v.incrementalVersion != null: !incrementalVersion.equals(v.incrementalVersion)) {
229             return false;
230         }
231         if (buildNumber == null? v.buildNumber != null: !buildNumber.equals(v.buildNumber)) {
232             return false;
233         }
234         return qualifier == null ? v.qualifier == null : qualifier.equals(v.qualifier);
235     }
236 
237     public int hashCode() {
238         int hashCode = 0;
239         if (majorVersion != null) {
240             hashCode = majorVersion.intValue();
241         }
242         if (minorVersion != null) {
243             hashCode = 37 * hashCode + minorVersion.intValue();
244         }
245         if (incrementalVersion != null) {
246             hashCode = 37 * hashCode + incrementalVersion.intValue();
247         }
248         if (buildNumber != null) {
249             hashCode = 37 * hashCode + buildNumber.intValue();
250         }
251         if (qualifier != null) {
252             hashCode = 37 * hashCode + qualifier.hashCode();
253         }
254         return hashCode;
255     }
256 }