package com.jetdrone.vertx.yoke.util.validation;
import com.jetdrone.vertx.yoke.core.YokeException;
import com.jetdrone.vertx.yoke.core.impl.ThreadLocalUTCDateFormat;
import com.jetdrone.vertx.yoke.json.JsonSchema;
import com.jetdrone.vertx.yoke.json.JsonSchemaResolver;
import com.jetdrone.vertx.yoke.middleware.YokeRequest;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Pattern;
public final class That {
private static final Pattern DATETIME = Pattern.compile("^\\d{4}-(?:0[0-9]|1[0-2])-[0-9]{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$");
private static final Pattern DATE = Pattern.compile("^\\d{4}-(?:0[0-9]|1[0-2])-[0-9]{2}$");
private static final Pattern TIME = Pattern.compile("^\\d{2}:\\d{2}:\\d{2}$");
private static final Pattern EMAIL = Pattern.compile("^(?:[\\w!#\\$%&'\\*\\+\\-/=\\?\\^`\\{\\|\\}~]+\\.)*[\\w!#\\$%&'\\*\\+\\-/=\\?\\^`\\{\\|\\}~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-](?!\\.)){0,61}[a-zA-Z0-9]?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\\[(?:(?:[01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.){3}(?:[01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\]))$");
private static final Pattern IPADDRESS = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
private static final Pattern IPV6ADDRESS = Pattern.compile("^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$");
private static final Pattern URI = Pattern.compile("^[a-zA-Z][a-zA-Z0-9+-.]*:[^\\s]*$");
private static final Pattern HOSTNAME = Pattern.compile("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\\-]*[A-Za-z0-9])$");
private static final Pattern ALPHA = Pattern.compile("^[a-zA-Z]+$");
private static final Pattern ALPHANUMERIC = Pattern.compile("^[a-zA-Z0-9]+$");
private static final Map<String, Object> EMPTY_MAP = Collections.emptyMap();
private static final JsonObject EMPTY = new JsonObject(EMPTY_MAP);
private static final SimpleNumberComparator NUMBERCOMPARATOR = new SimpleNumberComparator();
private static final ThreadLocalUTCDateFormat DATEFORMAT = new ThreadLocalUTCDateFormat();
private static class SimpleNumberComparator implements Comparator<Number>, Serializable {
private static final long serialVersionUID = 1l;
@Override
public int compare(Number o1, Number o2) {
if (o1 instanceof Short && o2 instanceof Short) {
return ((Short) o1).compareTo((Short) o2);
} else if (o1 instanceof Long && o2 instanceof Long) {
return ((Long) o1).compareTo((Long) o2);
} else if (o1 instanceof Integer && o2 instanceof Integer) {
return ((Integer) o1).compareTo((Integer) o2);
} else if (o1 instanceof Float && o2 instanceof Float) {
return ((Float) o1).compareTo((Float) o2);
} else if (o1 instanceof Double && o2 instanceof Double) {
return ((Double) o1).compareTo((Double) o2);
} else if (o1 instanceof Byte && o2 instanceof Byte) {
return ((Byte) o1).compareTo((Byte) o2);
} else if (o1 instanceof BigInteger && o2 instanceof BigInteger) {
return ((BigInteger) o1).compareTo((BigInteger) o2);
} else if (o1 instanceof BigDecimal && o2 instanceof BigDecimal) {
return ((BigDecimal) o1).compareTo((BigDecimal) o2);
} else {
throw new NumberFormatException();
}
}
}
private final int type;
private final String path;
public That(String path) {
int sep = path.indexOf(":");
String type;
// defaults to param
if (sep == -1) {
type = "param";
this.path = path;
} else {
type = path.substring(0, sep);
this.path = path.substring(sep + 1);
}
switch (type) {
case "param":
this.type = 0;
break;
case "form":
this.type = 1;
break;
case "body":
this.type = 2;
break;
case "context":
this.type = 3;
break;
case "header":
this.type = 4;
break;
default:
throw new RuntimeException("Unknown type: " + type);
}
}
private Object get(final YokeRequest request) throws YokeException {
switch (type) {
case 0:
return request.getParam(isOptional() ? this.path.substring(1) : this.path);
case 1:
return request.getFormAttribute(path);
case 2:
if (!request.hasBody()) {
throw new YokeException(400, "No Body");
}
Object obj = request.body();
if (!(obj instanceof JsonObject)) {
throw new YokeException(400, "Body is not JSON");
}
JsonObject json = (JsonObject) obj;
String[] keys = path.split("\\.");
for (int i = 0; i < keys.length - 1; i++) {
boolean optional = keys[i].charAt(0) == '?';
if (json == null) {
if (optional) {
json = EMPTY;
} else {
throw new YokeException(400, "Parameter '" + keys[i] + "' is not present or is null");
}
}
json = json.getJsonObject(optional ? keys[i].substring(1) : keys[i]);
}
boolean optional = keys[keys.length - 1].charAt(0) == '?';
if (json == null) {
if (optional) {
json = EMPTY;
} else {
throw new YokeException(400, "Parameter '" + keys[keys.length - 1] + "' is not present or is null");
}
}
return json.getValue(optional ? keys[keys.length - 1].substring(1) : keys[keys.length - 1]);
case 3:
return request.get(path);
case 4:
return request.getHeader(path);
default:
throw new YokeException(400, "Unknown source " + type);
}
}
private boolean isOptional() {
return path.charAt(0) == '?' || path.contains(".?");
}
public Assertion is(final Type type) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
if (optional || type == Type.Null) {
return;
}
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
switch (type) {
case Any:
return;
// base json types
case JsonObject:
if (field instanceof JsonObject || field instanceof Map) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case JsonArray:
if (field instanceof JsonArray || field instanceof List) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case String:
if (field instanceof String) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Number:
if (field instanceof Number) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Boolean:
if (field instanceof Boolean) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
// specific types
case Integer:
if (field instanceof Integer) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Long:
if (field instanceof Long) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Double:
if (field instanceof Double) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
// json schema validations
case DateTime:
if (field instanceof CharSequence && DATETIME.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Date:
if (field instanceof CharSequence && DATE.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Time:
if (field instanceof CharSequence && TIME.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Email:
if (field instanceof CharSequence && EMAIL.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case IPAddress:
if (field instanceof CharSequence && IPADDRESS.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case IPV6Address:
if (field instanceof CharSequence && IPV6ADDRESS.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case URI:
if (field instanceof CharSequence && URI.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Hostname:
if (field instanceof CharSequence && HOSTNAME.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Alpha:
if (field instanceof CharSequence && ALPHA.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
case Alphanumeric:
if (field instanceof CharSequence && ALPHANUMERIC.matcher((CharSequence) field).matches()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is not " + type.name());
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion exists() {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
}
};
}
public Assertion between(final Number min, final Number max) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
int len = ((String) field).length();
if (len >= min.intValue() && len <= max.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside the range [" + min + ":" + max + "] be NULL");
}
if (field instanceof Number) {
if (NUMBERCOMPARATOR.compare((Number) field, min) >= 0 && NUMBERCOMPARATOR.compare((Number) field, max) <= 0) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside the range [" + min + ":" + max + "] be NULL");
}
if (field instanceof List) {
int len = ((List) field).size();
if (len >= min.intValue() && len <= max.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside the range [" + min + ":" + max + "] be NULL");
}
if (field instanceof JsonArray) {
int len = ((JsonArray) field).size();
if (len >= min.intValue() && len <= max.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside the range [" + min + ":" + max + "] be NULL");
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion between(final Date min, final Date max) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
if (DATETIME.matcher((CharSequence) field).matches()) {
long millis;
try {
millis = DATEFORMAT.parse((String) field).getTime();
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (millis >= min.getTime() && millis <= max.getTime()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside the range [" + min + ":" + max + "] be NULL");
}
if (DATE.matcher((CharSequence) field).matches()) {
long millis;
try {
millis = DATEFORMAT.parse(field + "T00:00:00Z").getTime();
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (millis >= min.getTime() && millis <= max.getTime()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside the range [" + min + ":" + max + "] be NULL");
}
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion lessThan(final Number max) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
int len = ((String) field).length();
if (len < max.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside greater than [" + max + "] be NULL");
}
if (field instanceof Number) {
if (NUMBERCOMPARATOR.compare((Number) field, max) < 0) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside greater than [" + max + "] be NULL");
}
if (field instanceof List) {
int len = ((List) field).size();
if (len < max.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside greater than [" + max + "] be NULL");
}
if (field instanceof JsonArray) {
int len = ((JsonArray) field).size();
if (len < max.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is outside greater than [" + max + "] be NULL");
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion greaterThan(final Number min) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
int len = ((String) field).length();
if (len > min.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is less than [" + min + "] be NULL");
}
if (field instanceof Number) {
if (NUMBERCOMPARATOR.compare((Number) field, min) > 0) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is less than [" + min + "] be NULL");
}
if (field instanceof List) {
int len = ((List) field).size();
if (len > min.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is less than [" + min + "] be NULL");
}
if (field instanceof JsonArray) {
int len = ((JsonArray) field).size();
if (len > min.intValue()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is less than [" + min + "] be NULL");
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion before(final Date max) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
if (DATETIME.matcher((CharSequence) field).matches()) {
long millis;
try {
millis = DATEFORMAT.parse((String) field).getTime();
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (millis < max.getTime()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is after [" + max + "] be NULL");
}
if (DATE.matcher((CharSequence) field).matches()) {
long millis;
try {
millis = DATEFORMAT.parse(field + "T00:00:00Z").getTime();
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (millis < max.getTime()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is after [" + max + "] be NULL");
}
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion after(final Date min) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
if (DATETIME.matcher((CharSequence) field).matches()) {
long millis;
try {
millis = DATEFORMAT.parse((String) field).getTime();
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (millis > min.getTime()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is before [" + min + "] be NULL");
}
if (DATE.matcher((CharSequence) field).matches()) {
long millis;
try {
millis = DATEFORMAT.parse(field + "T00:00:00Z").getTime();
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (millis > min.getTime()) {
return;
}
throw new YokeException(errorCode, "'" + path + "' is before [" + min + "] be NULL");
}
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion equals(final String value) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
if (value.equals(field)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
}
};
}
public Assertion equals(final Number value) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof Number) {
if (value.equals(field)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
}
};
}
public Assertion equals(final Date value) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
if (DATETIME.matcher((CharSequence) field).matches()) {
Date date;
try {
date = DATEFORMAT.parse((String) field);
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (value.equals(date)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
if (DATE.matcher((CharSequence) field).matches()) {
Date date;
try {
date = DATEFORMAT.parse(field + "T00:00:00Z");
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (value.equals(date)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion equals(final Boolean value) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof Boolean) {
if (value.equals(field)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
}
};
}
public Assertion notEquals(final String value) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
if (!value.equals(field)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
}
};
}
public Assertion notEquals(final Number value) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof Number) {
if (!value.equals(field)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
}
};
}
public Assertion notEquals(final Date value) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof String) {
if (DATETIME.matcher((CharSequence) field).matches()) {
Date date;
try {
date = DATEFORMAT.parse((String) field);
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (!value.equals(date)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
if (DATE.matcher((CharSequence) field).matches()) {
Date date;
try {
date = DATEFORMAT.parse(field + "T00:00:00Z");
} catch (ParseException e) {
throw new YokeException(errorCode, "Failed to validate", e);
}
if (!value.equals(date)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
}
// unknown
throw new YokeException(errorCode, "Failed to validate");
}
};
}
public Assertion notEquals(final Boolean value) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
throw new YokeException(errorCode, "'" + path + "' cannot be NULL");
}
if (field instanceof Boolean) {
if (!value.equals(field)) {
return;
}
throw new YokeException(errorCode, "'" + path + "' does not equal [" + value + "] be NULL");
}
}
};
}
public Assertion conformsTo(final JsonSchemaResolver.Schema schema) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
throw new YokeException(errorCode, "'" + field + "' cannot be NULL");
}
if (JsonSchema.conformsSchema(field, schema)) {
return;
}
throw new YokeException(errorCode, "'" + field + "' does not conforms to schema");
}
};
}
public Assertion conformsTo(final String schemaRef) {
return new Assertion() {
@Override
public void ok(final YokeRequest request) throws YokeException {
final Object field = get(request);
final boolean optional = isOptional();
// null is handled as a special case
if (field == null) {
throw new YokeException(errorCode, "'" + field + "' cannot be NULL");
}
if (JsonSchema.conformsSchema(field, schemaRef)) {
return;
}
throw new YokeException(errorCode, "'" + field + "' does not conforms to schema");
}
};
}
}