VariVersion.java
package eu.javaexperience.version;
import java.util.Arrays;
import java.util.Comparator;
import eu.javaexperience.asserts.AssertArgument;
import eu.javaexperience.parse.ParsePrimitive;
import eu.javaexperience.reflect.Mirror;
import eu.javaexperience.text.StringTools;
public class VariVersion implements Version
{
protected final int[] version;
public VariVersion(int[] ver)
{
this.version = ver;
}
public static VariVersion parse(String str)
{
String[] vers = str.split("\\.");
int[] a = new int[vers.length];
int ep = 0;
for(int i=0;i < vers.length;++i)
{
String s = StringTools.passOnlyNumbers(vers[i]);
int val = ParsePrimitive.tryParseInt(s, -1);
if(val >= 0)
{
a[ep++] = val;
}
}
return new VariVersion(cutTrailingZero(a, ep));
}
protected static int[] cutTrailingZero(int[] arr, int ep)
{
for(int i = ep-1;i >=0 ;--i)
{
if(0 == arr[i])
{
ep = i;
}
else
{
break;
}
}
if(arr.length == ep)
{
return arr;
}
else
{
return Arrays.copyOf(arr, ep);
}
}
@Override
public int hashCode()
{
int ret = 31;
for(int i=0;i<version.length;++i)
{
ret = 37 * ret + version[i];
}
return ret;
}
@Override
public boolean equals(Object o)
{
if(!(o instanceof VariVersion))
{
return false;
}
VariVersion v = (VariVersion) o;
if(version.length != v.version.length)
{
return false;
}
for(int i=0;i< version.length;++i)
{
if(version[i] != v.version[i])
{
return false;
}
}
return true;
}
public static final Comparator<Version> COMPARATOR = new VariVersion(Mirror.emptyIntArray);
@Override
public int compare(Version other_this, Version other_thanThis)
{
if(null == other_this && null == other_thanThis)
{
return 0;
}
if(null == other_thanThis)
{
return 1;
}
if(null == other_this)
{
return -1;
}
VariVersion _this = other_this.asVariVersion();
VariVersion thanThis = other_thanThis.asVariVersion();
int maxlen = Math.min(_this.version.length, thanThis.version.length);
for(int i=0;i<maxlen;++i)
{
if(_this.version[i] > thanThis.version[i])
{
return 1;
}
else if(_this.version[i] < thanThis.version[i])
{
return -1;
}
}
if(_this.version.length > thanThis.version.length)
{
return 1;
}
else if(_this.version.length < thanThis.version.length)
{
return -1;
}
//minden egyezik
return 0;
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("v");
for(int i=0;i<version.length;++i)
{
if(0 != i)
{
sb.append(".");
}
sb.append(version[i]);
}
return sb.toString();
}
@Override
public VariVersion asVariVersion()
{
return this;
}
@Override
public int compareTo(Version o)
{
return compare(this, o);
}
protected static void assertCmp(String a, String b, int mag)
{
VariVersion _a = parse(a);
VariVersion _b = parse(b);
int res = _a.compareTo(_b);
if(mag == res)
{
System.out.println("pass");
}
else
{
System.out.println("cmp fail: "+_a+" <> "+_b+" => "+res+", req: "+mag);
}
}
protected static void assertNewest(String a, String b, boolean a_newest)
{
if(a_newest != VariVersion.parse(a).isThisNewerThan(VariVersion.parse(b)))
{
throw new RuntimeException("fail");
}
}
public static void main(String[] args)
{
AssertArgument.assertEquals(parse("1.6.23.1.54.2.4").toString(), "v1.6.23.1.54.2.4", "a");
AssertArgument.assertEquals(parse("").toString(), "v", "b");
AssertArgument.assertEquals(parse("1.0.0.1").toString(), "v1.0.0.1", "c");
AssertArgument.assertEquals(parse("1.0.1.0.0").toString(), "v1.0.1", "d");
assertCmp("", "", 0);
assertCmp("1", "1", 0);
assertCmp("1.6.12", "1.6.12", 0);
assertCmp("1.6.0", "1.6", 0);
assertCmp("1", "2", -1);
assertCmp("1.2", "1.3", -1);
assertCmp("1.3", "1.2", 1);
assertCmp("1.6.11.5.4.3", "2.0.0.0.0", -1);
assertCmp("2.0.0.0.0", "1.6.11.5.4.3", 1);
assertNewest("", "", false);
assertNewest("1", "1", false);
assertNewest("1.6.12", "1.6.12", false);
assertNewest("1.6.0", "1.6", false);
assertNewest("1", "2", false);
assertNewest("1.2", "1.3", false);
assertNewest("1.3", "1.2", true);
assertNewest("1.6.11.5.4.3", "2.0.0.0.0", false);
assertNewest("2.0.0.0.0", "1.6.11.5.4.3",true);
System.out.println("all pass");
}
@Override
public boolean isThisNewerThan(Version thanThis)
{
int mag = this.compareTo(thanThis);
return mag > 0;
}
@Override
public int versionLevel(int n)
{
if(version.length <= n)
{
return 0;
}
return version[n];
}
@Override
public int getMajor()
{
return versionLevel(0);
}
@Override
public int getMinor()
{
return versionLevel(1);
}
@Override
public int getPatch()
{
return versionLevel(2);
}
@Override
public int getTweak()
{
return versionLevel(3);
}
/**
* Returns with this reference is version is valid or throws a {@link RuntimeException}
* */
@Override
public VariVersion assertValidVersion()
{
for(int i=0;i<version.length;++i)
{
if(version[i] < 0)
{
throw new RuntimeException("Invalid negative version: "+this);
}
}
return this;
}
@Override
public VariVersion withDifferentOf(int level, int diff)
{
if(0 == diff)
{
return this;
}
int ret[] = null;
if(version.length > level)
{
ret = Arrays.copyOf(version, version.length);
}
else
{
ret = Arrays.copyOf(version, level+1);
}
ret[level] += diff;
return new VariVersion(ret).assertValidVersion();
}
}