/**
* Copyright (C) 2013 - 2015 the enviroCar community
*
* This file is part of the enviroCar app.
*
* The enviroCar app is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The enviroCar app is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the enviroCar app. If not, see http://www.gnu.org/licenses/.
*/
package org.envirocar.core.util;
/**
* This class represents a range of version numbers following
* semantic versioning ("major.minor.bugfix") pattern.
*
* @author matthes rieke
*
*/
public class VersionRange {
private Version minimum;
private Version maximum;
private boolean minimumIncluded;
private boolean maximumIncluded;
private VersionRange(Version min, Version max,
boolean minInclude, boolean maxInclude) {
this.minimum = min;
this.maximum = max;
this.minimumIncluded = minInclude;
this.maximumIncluded = maxInclude;
}
/**
* Parses a Version range string (e.g. "[0.2, 12.3.2)")
* into its object representation.
*
* @param ver the range string
* @return the instance object
*/
public static VersionRange fromString(String ver) {
boolean minInclude = includeToBoolean(ver.charAt(0));
boolean maxInclude = includeToBoolean(ver.charAt(ver.length()-1));
String[] split = ver.trim().substring(1, ver.length()-1).split(",");
if (split.length != 2) throw new IllegalArgumentException("Invalid version count.");
return new VersionRange(Version.fromString(split[0]), Version.fromString(split[1]),
minInclude, maxInclude);
}
private static boolean includeToBoolean(char c) {
if (c == '(' || c == ')') {
return false;
}
if (c == '[' || c == ']') {
return true;
}
throw new IllegalArgumentException("Invalid surronding character of range: "+c);
}
/**
* @return the maximum version of this range
*/
public Version getMaximum() {
return this.maximum;
}
/**
* @return the minimum version of this range
*/
public Version getMinimum() {
return this.minimum;
}
/**
* @return true if the maximum is included within this range ('<=')
*/
public boolean isMaximumIncluded() {
return this.maximumIncluded;
}
/**
* @return true if the minimum is included within this range ('>=')
*/
public boolean isMinimumIncluded() {
return this.minimumIncluded;
}
/**
* @param v the version to check
* @return true if the provided version is within this range
*/
public boolean isInRange(Version v) {
if (v.compareTo(this.minimum) == 0 && minimumIncluded) {
return true;
}
if (v.compareTo(this.maximum) == 0 && maximumIncluded) {
return true;
}
if (v.compareTo(this.minimum) > 0 && v.compareTo(this.maximum) < 0) {
return true;
}
return false;
}
/**
* A class representing a Version following the semantic
* versioning pattern ("major.minor.bugfix").
*
* @author matthes rieke
*
*/
public static class Version implements Comparable<Version> {
private int major;
private int minor;
private int fix;
private boolean snapshot;
private Version(int ma, int mi, int fi) {
this(ma, mi, fi, false);
}
private Version(int ma, int mi, int fi, boolean snap) {
this.major = ma;
this.minor = mi;
this.fix = fi;
this.snapshot = snap;
}
/**
* Takes a String (e.g. "0.3.1") and creates a corresponding
* object.
*
* @param ver the version as a string
* @return the version instance
*/
public static Version fromString(String ver) {
String[] split = ver.split("\\.");
int ma = 0;
if (split.length > 0) {
ma = Integer.parseInt(split[0].trim());
}
int mi = 0;
if (split.length > 1) {
mi = Integer.parseInt(split[1].trim());
}
int fi = 0;
boolean snap = false;
if (split.length > 2) {
if (split[2].contains("-")) {
fi = Integer.parseInt(split[2].substring(0, split[2].indexOf("-")).trim());
snap = true;
}
else {
fi = Integer.parseInt(split[2].trim());
}
}
return new Version(ma, mi, fi, snap);
}
public int getMajor() {
return major;
}
public int getMinor() {
return minor;
}
public int getFix() {
return fix;
}
public boolean isSnapshot() {
return snapshot;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.major);
sb.append(".");
sb.append(this.minor);
sb.append(".");
sb.append(this.fix);
if (this.snapshot) {
sb.append("-SNAPSHOT");
}
return sb.toString();
}
@Override
public int compareTo(Version that) {
if (this.major == that.major && this.minor == that.minor
&& this.fix == that.fix) {
return 0;
}
if (this.major > that.major) {
return 1;
}
if (this.major == that.major && this.minor > that.minor) {
return 1;
}
if (this.major == that.major && this.minor == that.minor && this.fix > that.fix) {
return 1;
}
return -1;
}
@Override
public boolean equals(Object o) {
if (o == null || o.getClass() != this.getClass()) {
return false;
}
Version that = (Version) o;
return this.major == that.major && this.minor == that.minor &&
this.fix == that.fix && this.snapshot == that.snapshot;
}
@Override
public int hashCode() {
return this.major*1000 + this.minor*100 + this.fix*10;
}
}
}