package com.g414.haildb;
import java.math.BigInteger;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class Validation {
private static final Map<ColumnType, Validator<Object>> validators;
static {
Map<ColumnType, Validator<Object>> newValidators = new HashMap<ColumnType, Validator<Object>>();
newValidators.put(ColumnType.VARCHAR, new Validator<Object>() {
public boolean isValid(ColumnDef columnDef, Object obj) {
if (isBadNull(columnDef, obj)) {
return false;
} else if (obj == null) {
return true;
}
if (!(obj instanceof String)) {
return false;
}
String target = (String) obj;
if (target != null && isBadLength(columnDef, target.length())) {
return false;
}
return true;
};
});
newValidators.put(ColumnType.CHAR, newValidators
.get(ColumnType.VARCHAR));
newValidators.put(ColumnType.BINARY, new Validator<Object>() {
public boolean isValid(ColumnDef columnDef, Object obj) {
if (isBadNull(columnDef, obj)) {
return false;
} else if (obj == null) {
return true;
}
byte[] target = (byte[]) obj;
if (!(obj instanceof byte[])) {
return false;
}
if (target != null && isBadLength(columnDef, target.length)) {
return false;
}
return true;
};
});
newValidators.put(ColumnType.VARBINARY, newValidators
.get(ColumnType.BINARY));
newValidators
.put(ColumnType.BLOB, newValidators.get(ColumnType.BINARY));
newValidators.put(ColumnType.INT, new Validator<Object>() {
public boolean isValid(ColumnDef columnDef, Object obj) {
if (isBadNull(columnDef, obj)) {
return false;
} else if (obj == null) {
return true;
}
if (!(obj instanceof Number)) {
return false;
}
Number target = (Number) obj;
if (!(target instanceof Byte) && !(target instanceof Short)
&& !(target instanceof Integer)
&& !(target instanceof Long)
&& !(target instanceof BigInteger)) {
return false;
}
boolean isUnsigned = columnDef.is(ColumnAttribute.UNSIGNED);
int signed = isUnsigned ? 0 : 1;
int posBits = (8 * columnDef.getLength()) - signed;
if (target instanceof BigInteger) {
BigInteger hiLimit = BigInteger.ONE.shiftLeft(posBits);
BigInteger loLimit = isUnsigned ? BigInteger.ZERO
: ((BigInteger) hiLimit).negate().subtract(
BigInteger.ONE);
if (((BigInteger) target).compareTo(loLimit) < 0
|| ((BigInteger) target).compareTo(hiLimit) > 0) {
return false;
}
} else {
long hiLimit = Long.MAX_VALUE >> (63 - posBits);
long loLimit = isUnsigned ? 0 : -((Long) hiLimit) - 1;
long compare = target.longValue();
if ((compare < loLimit) || (compare > hiLimit)) {
return false;
}
}
return true;
}
});
validators = Collections.unmodifiableMap(newValidators);
}
public static boolean isValid(ColumnDef def, Object value) {
return validators.containsKey(def.getType())
&& validators.get(def.getType()).isValid(def, value);
}
private static boolean isBadNull(ColumnDef columnDef, Object target) {
return columnDef.is(ColumnAttribute.NOT_NULL) && (target == null);
}
private static boolean isBadLength(ColumnDef columnDef, int length) {
return columnDef.getLength() < length
&& !columnDef.getType().equals(ColumnType.BLOB);
}
private interface Validator<T> {
public boolean isValid(ColumnDef columnDef, T target);
}
}