blob: 47052445b6b53c9e24a34eda05cde752d945e9cc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 23.04.2012 Aaron Digulla.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Aaron Digulla - initial API and implementation and/or initial documentation
*******************************************************************************/
package m4e.p2;
class Version implements Comparable<Version> {
final static int BIT_WIDTH = 20
final static int BIT_MASK = ( 1 << BIT_WIDTH ) - 1
final boolean blank
final long version
int len
final String qualifier
Version( String pattern ) {
if( pattern ) {
def parts = pattern.split( '\\.', 4 )
long major = Long.parseLong( parts[0] )
long minor = 0
long service = 0
len = parts.length
check( pattern, 'major', major )
if( len > 1 ) {
minor = Long.parseLong( parts[1] )
check( pattern, 'minor', minor )
if( len > 2 ) {
service = Long.parseLong( parts[2] )
check( pattern, 'service', service )
if( len > 3 ) {
qualifier = parts[3]
}
}
}
version = ( ( ( major << BIT_WIDTH ) + minor ) << BIT_WIDTH ) + service
blank = false
assert pattern == toString()
} else {
blank = true
}
}
void check( String version, String field, long value ) {
if( value < 0 ) {
throw new VersionException( version, "${field} must be > 0: ${value}" )
}
if( value > BIT_MASK ) {
throw new VersionException( version, "${field} must be < ${BIT_MASK}: ${value}" )
}
}
boolean equals( Object o ) {
if( this == o ) {
return true
}
if( !( o instanceof Version ) ) {
return false
}
Version other = o
if( blank != other.blank ) {
return false
}
if( version != other.version ) {
return false
}
if( qualifier != other.qualifier ) {
return false
}
return true
}
int hashCode() {
if( blank ) {
return 0
}
return 1311 * version + ( qualifier ? qualifier.hashCode() : 0 )
}
int getMajor() {
return version >>> (2*BIT_WIDTH)
}
int getMinor() {
return ( version >>> BIT_WIDTH ) & BIT_MASK
}
int getService() {
return version & BIT_MASK
}
String toString() {
if( blank ) {
return ''
}
def buffer = prepareVersionBuffer()
if( qualifier ) {
buffer.append( '.' ).append( qualifier )
}
return buffer.toString()
}
String shortVersion() {
if( blank ) {
return ''
}
return prepareVersionBuffer().toString()
}
private StringBuilder prepareVersionBuffer() {
StringBuilder buffer = new StringBuilder()
buffer.append( major )
if( len > 1 ) {
buffer.append( '.' ).append( minor )
}
if( len > 2 ) {
buffer.append( '.' ).append( service )
}
return buffer
}
public int compareTo( Version o ) {
if( blank ) {
return o.blank ? 0 : -1
} else if( o.blank ) {
return 1
}
int d = Long.signum( version - o.version )
if( d == 0 ) {
if( qualifier ) {
if( o.qualifier ) {
d = qualifier.compareTo( o.qualifier )
} else {
d = 1
}
} else {
d = o.qualifier ? -1 : 0
}
}
return d;
}
Version next() {
return new Version( "${major}.${minor}.${service+1}" )
}
Version stripQualifier() {
return new Version( "${major}.${minor}.${service}" )
}
}
class VersionException extends RuntimeException {
String version
VersionException( String version, String message ) {
super( "Error parsing version '${version}': ${message}" )
this.version = version
}
}