001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.kernel.repository; 018 019 import java.util.StringTokenizer; 020 import java.io.Serializable; 021 022 /** 023 * Default implementation of artifact versioning. 024 * 025 * @author <a href="mailto:brett@apache.org">Brett Porter</a> 026 * @version $Id: Version.java 476049 2006-11-17 04:35:17Z kevan $ 027 */ 028 // This code was lifted from Apache Maven 029 public class Version implements Comparable, Serializable { 030 // Geronimo adds Serial UID because we serialize versions into config.ser 031 private static final long serialVersionUID = 7941704456058067109L; 032 033 private Integer majorVersion; 034 035 private Integer minorVersion; 036 037 private Integer incrementalVersion; 038 039 private Integer buildNumber; 040 041 private String qualifier; 042 043 public Version(String version) { 044 parseVersion(version); 045 } 046 047 public int compareTo(Object o) { 048 Version otherVersion = (Version) o; 049 050 int result = compareIntegers(majorVersion, otherVersion.majorVersion); 051 if (result == 0) { 052 result = compareIntegers(minorVersion, otherVersion.minorVersion); 053 } 054 if (result == 0) { 055 result = compareIntegers(incrementalVersion, otherVersion.incrementalVersion); 056 } 057 if (result == 0) { 058 if (buildNumber != null || otherVersion.buildNumber != null) { 059 result = compareIntegers(buildNumber, otherVersion.buildNumber); 060 } else if (qualifier != null) { 061 if (otherVersion.qualifier != null) { 062 if (qualifier.length() > otherVersion.qualifier.length() && 063 qualifier.startsWith(otherVersion.qualifier)) { 064 // here, the longer one that otherwise match is considered older 065 result = -1; 066 } else if (qualifier.length() < otherVersion.qualifier.length() && 067 otherVersion.qualifier.startsWith(qualifier)) { 068 // here, the longer one that otherwise match is considered older 069 result = 1; 070 } else { 071 result = qualifier.compareTo(otherVersion.qualifier); 072 } 073 } else { 074 // otherVersion has no qualifier but we do - that's newer 075 result = -1; 076 } 077 } else if (otherVersion.qualifier != null) { 078 // otherVersion has a qualifier but we don't, we're newer 079 result = 1; 080 } 081 } 082 return result; 083 } 084 085 private int compareIntegers(Integer i1, Integer i2) { 086 // treat null as 0 in comparison 087 if (i1 == null ? i2 == null : i1.equals(i2)) { 088 return 0; 089 } else if (i1 == null) { 090 return -i2.intValue(); 091 } else if (i2 == null) { 092 return i1.intValue(); 093 } else { 094 return i1.intValue() - i2.intValue(); 095 } 096 } 097 098 public int getMajorVersion() { 099 return majorVersion != null ? majorVersion.intValue() : 0; 100 } 101 102 public int getMinorVersion() { 103 return minorVersion != null ? minorVersion.intValue() : 0; 104 } 105 106 public int getIncrementalVersion() { 107 return incrementalVersion != null ? incrementalVersion.intValue() : 0; 108 } 109 110 public int getBuildNumber() { 111 return buildNumber != null ? buildNumber.intValue() : 0; 112 } 113 114 public String getQualifier() { 115 return qualifier; 116 } 117 118 public final void parseVersion(String version) { 119 int index = version.indexOf("-"); 120 121 String part1; 122 String part2 = null; 123 124 if (index < 0) { 125 part1 = version; 126 } else { 127 part1 = version.substring(0, index); 128 part2 = version.substring(index + 1); 129 } 130 131 if (part2 != null) { 132 try { 133 if (part2.length() == 1 || !part2.startsWith("0")) { 134 buildNumber = Integer.valueOf(part2); 135 } else { 136 qualifier = part2; 137 } 138 } 139 catch (NumberFormatException e) { 140 qualifier = part2; 141 } 142 } 143 144 if (part1.indexOf(".") < 0 && !part1.startsWith("0")) { 145 try { 146 majorVersion = Integer.valueOf(part1); 147 } 148 catch (NumberFormatException e) { 149 // qualifier is the whole version, including "-" 150 qualifier = version; 151 buildNumber = null; 152 } 153 } else { 154 boolean fallback = false; 155 StringTokenizer tok = new StringTokenizer(part1, "."); 156 try { 157 majorVersion = getNextIntegerToken(tok); 158 if (tok.hasMoreTokens()) { 159 minorVersion = getNextIntegerToken(tok); 160 } 161 if (tok.hasMoreTokens()) { 162 incrementalVersion = getNextIntegerToken(tok); 163 } 164 if (tok.hasMoreTokens()) { 165 fallback = true; 166 } 167 } 168 catch (NumberFormatException e) { 169 fallback = true; 170 } 171 172 if (fallback) { 173 // qualifier is the whole version, including "-" 174 qualifier = version; 175 majorVersion = null; 176 minorVersion = null; 177 incrementalVersion = null; 178 } 179 } 180 } 181 182 private static Integer getNextIntegerToken(StringTokenizer tok) { 183 String s = tok.nextToken(); 184 if (s.length() > 1 && s.startsWith("0")) { 185 throw new NumberFormatException("Number part has a leading 0: '" + s + "'"); 186 } 187 return Integer.valueOf(s); 188 } 189 190 public String toString() { 191 StringBuffer buf = new StringBuffer(); 192 if (majorVersion != null) { 193 buf.append(majorVersion); 194 } 195 if (minorVersion != null) { 196 buf.append("."); 197 buf.append(minorVersion); 198 } 199 if (incrementalVersion != null) { 200 buf.append("."); 201 buf.append(incrementalVersion); 202 } 203 if (buildNumber != null) { 204 buf.append("-"); 205 buf.append(buildNumber); 206 } else if (qualifier != null) { 207 if (buf.length() > 0) { 208 buf.append("-"); 209 } 210 buf.append(qualifier); 211 } 212 return buf.toString(); 213 } 214 215 public boolean equals(Object other) { 216 if (this == other) { 217 return true; 218 } 219 if (other == null || this.getClass() != other.getClass()) { 220 return false; 221 } 222 Version v = (Version) other; 223 if (majorVersion == null? v.majorVersion != null: !majorVersion.equals(v.majorVersion)) { 224 return false; 225 } 226 if (minorVersion == null? v.minorVersion != null: !minorVersion.equals(v.minorVersion)) { 227 return false; 228 } 229 if (incrementalVersion == null? v.incrementalVersion != null: !incrementalVersion.equals(v.incrementalVersion)) { 230 return false; 231 } 232 if (buildNumber == null? v.buildNumber != null: !buildNumber.equals(v.buildNumber)) { 233 return false; 234 } 235 return qualifier == null ? v.qualifier == null : qualifier.equals(v.qualifier); 236 } 237 238 public int hashCode() { 239 int hashCode = 0; 240 if (majorVersion != null) { 241 hashCode = majorVersion.intValue(); 242 } 243 if (minorVersion != null) { 244 hashCode = 37 * hashCode + minorVersion.intValue(); 245 } 246 if (incrementalVersion != null) { 247 hashCode = 37 * hashCode + incrementalVersion.intValue(); 248 } 249 if (buildNumber != null) { 250 hashCode = 37 * hashCode + buildNumber.intValue(); 251 } 252 if (qualifier != null) { 253 hashCode = 37 * hashCode + qualifier.hashCode(); 254 } 255 return hashCode; 256 } 257 }