001 package org.apache.maven.artifact.versioning; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.util.StringTokenizer; 023 024 /** 025 * Default implementation of artifact versioning. 026 * 027 * @author <a href="mailto:brett@apache.org">Brett Porter</a> 028 */ 029 public class DefaultArtifactVersion 030 implements ArtifactVersion 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 private ComparableVersion comparable; 043 044 public DefaultArtifactVersion( String version ) 045 { 046 parseVersion( version ); 047 } 048 049 @Override 050 public int hashCode() 051 { 052 return 11 + comparable.hashCode(); 053 } 054 055 @Override 056 public boolean equals( Object other ) 057 { 058 if ( this == other ) 059 { 060 return true; 061 } 062 063 if ( !( other instanceof ArtifactVersion ) ) 064 { 065 return false; 066 } 067 068 return compareTo( (ArtifactVersion) other ) == 0; 069 } 070 071 public int compareTo( ArtifactVersion otherVersion ) 072 { 073 if ( otherVersion instanceof DefaultArtifactVersion ) 074 { 075 return this.comparable.compareTo( ( (DefaultArtifactVersion) otherVersion).comparable ); 076 } 077 else 078 { 079 return compareTo( new DefaultArtifactVersion( otherVersion.toString() ) ); 080 } 081 } 082 083 public int getMajorVersion() 084 { 085 return majorVersion != null ? majorVersion : 0; 086 } 087 088 public int getMinorVersion() 089 { 090 return minorVersion != null ? minorVersion : 0; 091 } 092 093 public int getIncrementalVersion() 094 { 095 return incrementalVersion != null ? incrementalVersion : 0; 096 } 097 098 public int getBuildNumber() 099 { 100 return buildNumber != null ? buildNumber : 0; 101 } 102 103 public String getQualifier() 104 { 105 return qualifier; 106 } 107 108 public final void parseVersion( String version ) 109 { 110 comparable = new ComparableVersion( version ); 111 112 int index = version.indexOf( "-" ); 113 114 String part1; 115 String part2 = null; 116 117 if ( index < 0 ) 118 { 119 part1 = version; 120 } 121 else 122 { 123 part1 = version.substring( 0, index ); 124 part2 = version.substring( index + 1 ); 125 } 126 127 if ( part2 != null ) 128 { 129 try 130 { 131 if ( ( part2.length() == 1 ) || !part2.startsWith( "0" ) ) 132 { 133 buildNumber = Integer.valueOf( part2 ); 134 } 135 else 136 { 137 qualifier = part2; 138 } 139 } 140 catch ( NumberFormatException e ) 141 { 142 qualifier = part2; 143 } 144 } 145 146 if ( ( part1.indexOf( "." ) < 0 ) && !part1.startsWith( "0" ) ) 147 { 148 try 149 { 150 majorVersion = Integer.valueOf( part1 ); 151 } 152 catch ( NumberFormatException e ) 153 { 154 // qualifier is the whole version, including "-" 155 qualifier = version; 156 buildNumber = null; 157 } 158 } 159 else 160 { 161 boolean fallback = false; 162 163 StringTokenizer tok = new StringTokenizer( part1, "." ); 164 try 165 { 166 majorVersion = getNextIntegerToken( tok ); 167 if ( tok.hasMoreTokens() ) 168 { 169 minorVersion = getNextIntegerToken( tok ); 170 } 171 if ( tok.hasMoreTokens() ) 172 { 173 incrementalVersion = getNextIntegerToken( tok ); 174 } 175 if ( tok.hasMoreTokens() ) 176 { 177 fallback = true; 178 } 179 180 // string tokenzier won't detect these and ignores them 181 if ( part1.indexOf( ".." ) >= 0 || part1.startsWith( "." ) || part1.endsWith( "." ) ) 182 { 183 fallback = true; 184 } 185 } 186 catch ( NumberFormatException e ) 187 { 188 fallback = true; 189 } 190 191 if ( fallback ) 192 { 193 // qualifier is the whole version, including "-" 194 qualifier = version; 195 majorVersion = null; 196 minorVersion = null; 197 incrementalVersion = null; 198 buildNumber = null; 199 } 200 } 201 } 202 203 private static Integer getNextIntegerToken( StringTokenizer tok ) 204 { 205 String s = tok.nextToken(); 206 if ( ( s.length() > 1 ) && s.startsWith( "0" ) ) 207 { 208 throw new NumberFormatException( "Number part has a leading 0: '" + s + "'" ); 209 } 210 return Integer.valueOf( s ); 211 } 212 213 @Override 214 public String toString() 215 { 216 StringBuilder buf = new StringBuilder(); 217 if ( majorVersion != null ) 218 { 219 buf.append( majorVersion ); 220 } 221 if ( minorVersion != null ) 222 { 223 buf.append( "." ); 224 buf.append( minorVersion ); 225 } 226 if ( incrementalVersion != null ) 227 { 228 buf.append( "." ); 229 buf.append( incrementalVersion ); 230 } 231 if ( buildNumber != null ) 232 { 233 buf.append( "-" ); 234 buf.append( buildNumber ); 235 } 236 else if ( qualifier != null ) 237 { 238 if ( buf.length() > 0 ) 239 { 240 buf.append( "-" ); 241 } 242 buf.append( qualifier ); 243 } 244 return buf.toString(); 245 } 246 }