001package 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 022import java.util.StringTokenizer; 023import java.util.regex.Pattern; 024 025/** 026 * Default implementation of artifact versioning. 027 * 028 * @author <a href="mailto:brett@apache.org">Brett Porter</a> 029 */ 030public class DefaultArtifactVersion 031 implements ArtifactVersion 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 private ComparableVersion comparable; 044 045 public DefaultArtifactVersion( String version ) 046 { 047 parseVersion( version ); 048 } 049 050 @Override 051 public int hashCode() 052 { 053 return 11 + comparable.hashCode(); 054 } 055 056 @Override 057 public boolean equals( Object other ) 058 { 059 if ( this == other ) 060 { 061 return true; 062 } 063 064 if ( !( other instanceof ArtifactVersion ) ) 065 { 066 return false; 067 } 068 069 return compareTo( (ArtifactVersion) other ) == 0; 070 } 071 072 public int compareTo( ArtifactVersion otherVersion ) 073 { 074 if ( otherVersion instanceof DefaultArtifactVersion ) 075 { 076 return this.comparable.compareTo( ( (DefaultArtifactVersion) otherVersion ).comparable ); 077 } 078 else 079 { 080 return compareTo( new DefaultArtifactVersion( otherVersion.toString() ) ); 081 } 082 } 083 084 public int getMajorVersion() 085 { 086 return majorVersion != null ? majorVersion : 0; 087 } 088 089 public int getMinorVersion() 090 { 091 return minorVersion != null ? minorVersion : 0; 092 } 093 094 public int getIncrementalVersion() 095 { 096 return incrementalVersion != null ? incrementalVersion : 0; 097 } 098 099 public int getBuildNumber() 100 { 101 return buildNumber != null ? buildNumber : 0; 102 } 103 104 public String getQualifier() 105 { 106 return qualifier; 107 } 108 109 public final void parseVersion( String version ) 110 { 111 comparable = new ComparableVersion( version ); 112 113 int index = version.indexOf( "-" ); 114 115 String part1; 116 String part2 = null; 117 118 if ( index < 0 ) 119 { 120 part1 = version; 121 } 122 else 123 { 124 part1 = version.substring( 0, index ); 125 part2 = version.substring( index + 1 ); 126 } 127 128 if ( part2 != null ) 129 { 130 try 131 { 132 if ( ( part2.length() == 1 ) || !part2.startsWith( "0" ) ) 133 { 134 buildNumber = Integer.valueOf( part2 ); 135 } 136 else 137 { 138 qualifier = part2; 139 } 140 } 141 catch ( NumberFormatException e ) 142 { 143 qualifier = part2; 144 } 145 } 146 147 if ( ( !part1.contains( "." ) ) && !part1.startsWith( "0" ) ) 148 { 149 try 150 { 151 majorVersion = Integer.valueOf( part1 ); 152 } 153 catch ( NumberFormatException e ) 154 { 155 // qualifier is the whole version, including "-" 156 qualifier = version; 157 buildNumber = null; 158 } 159 } 160 else 161 { 162 boolean fallback = false; 163 164 StringTokenizer tok = new StringTokenizer( part1, "." ); 165 try 166 { 167 majorVersion = getNextIntegerToken( tok ); 168 if ( tok.hasMoreTokens() ) 169 { 170 minorVersion = getNextIntegerToken( tok ); 171 } 172 if ( tok.hasMoreTokens() ) 173 { 174 incrementalVersion = getNextIntegerToken( tok ); 175 } 176 if ( tok.hasMoreTokens() ) 177 { 178 qualifier = tok.nextToken(); 179 fallback = Pattern.compile( "\\d+" ).matcher( qualifier ).matches(); 180 } 181 182 // string tokenzier won't detect these and ignores them 183 if ( part1.contains( ".." ) || part1.startsWith( "." ) || part1.endsWith( "." ) ) 184 { 185 fallback = true; 186 } 187 } 188 catch ( NumberFormatException e ) 189 { 190 fallback = true; 191 } 192 193 if ( fallback ) 194 { 195 // qualifier is the whole version, including "-" 196 qualifier = version; 197 majorVersion = null; 198 minorVersion = null; 199 incrementalVersion = null; 200 buildNumber = null; 201 } 202 } 203 } 204 205 private static Integer getNextIntegerToken( StringTokenizer tok ) 206 { 207 String s = tok.nextToken(); 208 if ( ( s.length() > 1 ) && s.startsWith( "0" ) ) 209 { 210 throw new NumberFormatException( "Number part has a leading 0: '" + s + "'" ); 211 } 212 return Integer.valueOf( s ); 213 } 214 215 @Override 216 public String toString() 217 { 218 return comparable.toString(); 219 } 220}