001 /* 002 * Copyright 2001-2005 The Apache Software Foundation. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.apache.geronimo.kernel.repository; 017 018 import java.util.StringTokenizer; 019 import java.io.Serializable; 020 021 /** 022 * Default implementation of artifact versioning. 023 * 024 * @author <a href="mailto:brett@apache.org">Brett Porter</a> 025 * @version $Id: Version.java 410741 2006-06-01 04:35:48Z jsisson $ 026 */ 027 // This code was lifted from Apache Maven 028 public class Version implements Comparable, Serializable { 029 // Geronimo adds Serial UID because we serialize versions into config.ser 030 private static final long serialVersionUID = 7941704456058067109L; 031 032 private Integer majorVersion; 033 034 private Integer minorVersion; 035 036 private Integer incrementalVersion; 037 038 private Integer buildNumber; 039 040 private String qualifier; 041 042 public Version(String version) { 043 parseVersion(version); 044 } 045 046 public int compareTo(Object o) { 047 Version otherVersion = (Version) o; 048 049 int result = compareIntegers(majorVersion, otherVersion.majorVersion); 050 if (result == 0) { 051 result = compareIntegers(minorVersion, otherVersion.minorVersion); 052 } 053 if (result == 0) { 054 result = compareIntegers(incrementalVersion, otherVersion.incrementalVersion); 055 } 056 if (result == 0) { 057 if (buildNumber != null || otherVersion.buildNumber != null) { 058 result = compareIntegers(buildNumber, otherVersion.buildNumber); 059 } else if (qualifier != null) { 060 if (otherVersion.qualifier != null) { 061 if (qualifier.length() > otherVersion.qualifier.length() && 062 qualifier.startsWith(otherVersion.qualifier)) { 063 // here, the longer one that otherwise match is considered older 064 result = -1; 065 } else if (qualifier.length() < otherVersion.qualifier.length() && 066 otherVersion.qualifier.startsWith(qualifier)) { 067 // here, the longer one that otherwise match is considered older 068 result = 1; 069 } else { 070 result = qualifier.compareTo(otherVersion.qualifier); 071 } 072 } else { 073 // otherVersion has no qualifier but we do - that's newer 074 result = -1; 075 } 076 } else if (otherVersion.qualifier != null) { 077 // otherVersion has a qualifier but we don't, we're newer 078 result = 1; 079 } 080 } 081 return result; 082 } 083 084 private int compareIntegers(Integer i1, Integer i2) { 085 // treat null as 0 in comparison 086 if (i1 == null ? i2 == null : i1.equals(i2)) { 087 return 0; 088 } else if (i1 == null) { 089 return -i2.intValue(); 090 } else if (i2 == null) { 091 return i1.intValue(); 092 } else { 093 return i1.intValue() - i2.intValue(); 094 } 095 } 096 097 public int getMajorVersion() { 098 return majorVersion != null ? majorVersion.intValue() : 0; 099 } 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 }