package com.narrowtux.fmm.model;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatchedVersion {
public enum Operator {
GREATER_THAN(">"),
GREATER_THAN_OR_EQUALS(">="),
EQUALS("=="),
LESS_THAN("<"),
LESS_THAN_OR_EQUALS("<=");
private String value;
Operator(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static Operator ofValue(String value) {
for (Operator op : values()) {
if (op.getValue().equals(value)) {
return op;
}
}
return null;
}
}
private Integer major, minor, build;
private Operator operator;
public MatchedVersion(Integer major, Integer minor, Integer build, Operator operator) {
this.major = major;
this.minor = minor;
this.build = build;
this.operator = operator;
}
public Integer getMajor() {
return major;
}
public Integer getMinor() {
return minor;
}
public Integer getBuild() {
return build;
}
public Operator getOperator() {
return operator;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(operator.getValue());
builder.append(' ');
if (major != null) {
builder.append(major);
} else {
builder.append("?");
}
if (minor != null) {
builder.append(".");
builder.append(minor);
} else {
builder.append(".?");
}
if (build != null) {
builder.append(".");
builder.append(build);
} else {
builder.append(".?");
}
return builder.toString();
}
public boolean matches(Version version) {
Integer major = this.major, minor = this.minor, build = this.build;
if (null == major) {
major = fillInt(operator);
}
if (null == minor) {
minor = fillInt(operator);
}
if (null == build) {
build = fillInt(operator);
}
switch (operator) {
case EQUALS:
if (null == major || major == version.getMajor()) {
if (null == minor || minor == version.getMinor()) {
if (null == build || build == version.getBuild()) {
return true;
}
}
}
return false;
case GREATER_THAN:
if (version.getBuild() > build) {
if (version.getMinor() >= minor) {
return version.getMajor() >= major;
}
} else {
if (version.getMinor() > minor) {
return version.getMajor() >= major;
}
}
return version.getMajor() > major;
case GREATER_THAN_OR_EQUALS:
return version.getMajor() >= major && version.getMinor() >= minor && version.getBuild() >= build;
case LESS_THAN:
if (version.getMajor() < major) {
return true;
} else if (minor != null && version.getMajor() == major) {
if (version.getMinor() < minor) {
return true;
} else if (build != null && version.getMinor() == minor) {
return version.getBuild() < build;
}
}
return false;
case LESS_THAN_OR_EQUALS:
return version.getMajor() <= major && version.getMinor() <= minor && version.getBuild() <= build;
default:
throw new IllegalStateException("Unsupported operator");
}
}
private static Pattern MATCHED_VERSION_PATTERN = Pattern.compile("([<>=]+)\\s?([0-9\\.]+)");
public static MatchedVersion valueOf(String value) {
Matcher matcher = MATCHED_VERSION_PATTERN.matcher(value);
if (matcher.matches()) {
Operator op = Operator.ofValue(matcher.group(1));
if (op == null) {
System.out.println("Invalid operator '" + matcher.group(1) + "'");
return null;
}
String v = matcher.group(2);
Integer major = null, minor = null, build = null;
String vs[] = v.split("\\.");
if (vs.length >= 1) {
major = Integer.valueOf(vs[0]);
}
if (vs.length >= 2) {
minor = Integer.valueOf(vs[1]);
}
if (vs.length >= 3) {
build = Integer.valueOf(vs[2]);
}
return new MatchedVersion(major, minor, build, op);
}
return null;
}
private static Integer fillInt(Operator operator) {
switch (operator) {
case GREATER_THAN_OR_EQUALS:
case GREATER_THAN:
return -1;
case EQUALS:
return null; // equals to anything
case LESS_THAN:
return null;
case LESS_THAN_OR_EQUALS:
return Integer.MAX_VALUE;
default:
throw new IllegalStateException();
}
}
}