// AVOID CONVERSIONS: FASTER!
fieldValue = iRecord.rawField(p.getName());
if (p.isNotNull() && fieldValue == null)
// NULLITY
throw new OValidationException("The field '" + p.getFullName() + "' cannot be null, record: " + iRecord);
if (fieldValue != null && p.getRegexp() != null) {
// REGEXP
if (!fieldValue.toString().matches(p.getRegexp()))
throw new OValidationException("The field '" + p.getFullName() + "' does not match the regular expression '"
+ p.getRegexp() + "'. Field value is: " + fieldValue + ", record: " + iRecord);
}
} else {
if (p.isMandatory())
throw new OValidationException("The field '" + p.getFullName() + "' is mandatory, but not found on record: " + iRecord);
fieldValue = null;
}
final OType type = p.getType();
if (fieldValue != null && type != null) {
// CHECK TYPE
switch (type) {
case LINK:
validateLink(p, fieldValue);
break;
case LINKLIST:
if (!(fieldValue instanceof List))
throw new OValidationException("The field '" + p.getFullName()
+ "' has been declared as LINKLIST but an incompatible type is used. Value: " + fieldValue);
validateLinkCollection(p, (Collection<Object>) fieldValue);
break;
case LINKSET:
if (!(fieldValue instanceof Set))
throw new OValidationException("The field '" + p.getFullName()
+ "' has been declared as LINKSET but an incompatible type is used. Value: " + fieldValue);
validateLinkCollection(p, (Collection<Object>) fieldValue);
break;
case LINKMAP:
if (!(fieldValue instanceof Map))
throw new OValidationException("The field '" + p.getFullName()
+ "' has been declared as LINKMAP but an incompatible type is used. Value: " + fieldValue);
validateLinkCollection(p, ((Map<?, Object>) fieldValue).values());
break;
case EMBEDDED:
validateEmbedded(p, fieldValue);
break;
case EMBEDDEDLIST:
if (!(fieldValue instanceof List))
throw new OValidationException("The field '" + p.getFullName()
+ "' has been declared as EMBEDDEDLIST but an incompatible type is used. Value: " + fieldValue);
if (p.getLinkedClass() != null) {
for (Object item : ((List<?>) fieldValue))
validateEmbedded(p, item);
} else if (p.getLinkedType() != null) {
for (Object item : ((List<?>) fieldValue))
validateType(p, item);
}
break;
case EMBEDDEDSET:
if (!(fieldValue instanceof Set))
throw new OValidationException("The field '" + p.getFullName()
+ "' has been declared as EMBEDDEDSET but an incompatible type is used. Value: " + fieldValue);
if (p.getLinkedClass() != null) {
for (Object item : ((Set<?>) fieldValue))
validateEmbedded(p, item);
} else if (p.getLinkedType() != null) {
for (Object item : ((Set<?>) fieldValue))
validateType(p, item);
}
break;
case EMBEDDEDMAP:
if (!(fieldValue instanceof Map))
throw new OValidationException("The field '" + p.getFullName()
+ "' has been declared as EMBEDDEDMAP but an incompatible type is used. Value: " + fieldValue);
if (p.getLinkedClass() != null) {
for (Entry<?, ?> entry : ((Map<?, ?>) fieldValue).entrySet())
validateEmbedded(p, entry.getValue());
} else if (p.getLinkedType() != null) {
for (Entry<?, ?> entry : ((Map<?, ?>) fieldValue).entrySet())
validateType(p, entry.getValue());
}
break;
}
}
if (p.getMin() != null) {
// MIN
final String min = p.getMin();
if (p.getType().equals(OType.STRING) && (fieldValue != null && ((String) fieldValue).length() < Integer.parseInt(min)))
throw new OValidationException("The field '" + p.getFullName() + "' contains fewer characters than " + min + " requested");
else if (p.getType().equals(OType.BINARY) && (fieldValue != null && ((byte[]) fieldValue).length < Integer.parseInt(min)))
throw new OValidationException("The field '" + p.getFullName() + "' contains fewer bytes than " + min + " requested");
else if (p.getType().equals(OType.INTEGER) && (fieldValue != null && type.asInt(fieldValue) < Integer.parseInt(min)))
throw new OValidationException("The field '" + p.getFullName() + "' is less than " + min);
else if (p.getType().equals(OType.LONG) && (fieldValue != null && type.asLong(fieldValue) < Long.parseLong(min)))
throw new OValidationException("The field '" + p.getFullName() + "' is less than " + min);
else if (p.getType().equals(OType.FLOAT) && (fieldValue != null && type.asFloat(fieldValue) < Float.parseFloat(min)))
throw new OValidationException("The field '" + p.getFullName() + "' is less than " + min);
else if (p.getType().equals(OType.DOUBLE) && (fieldValue != null && type.asDouble(fieldValue) < Double.parseDouble(min)))
throw new OValidationException("The field '" + p.getFullName() + "' is less than " + min);
else if (p.getType().equals(OType.DATE)) {
try {
if (fieldValue != null
&& ((Date) fieldValue).before(iRecord.getDatabaseInternal().getStorage().getConfiguration().getDateFormatInstance()
.parse(min)))
throw new OValidationException("The field '" + p.getFullName() + "' contains the date " + fieldValue
+ " which precedes the first acceptable date (" + min + ")");
} catch (ParseException e) {
}
} else if (p.getType().equals(OType.DATETIME)) {
try {
if (fieldValue != null
&& ((Date) fieldValue).before(iRecord.getDatabaseInternal().getStorage().getConfiguration()
.getDateTimeFormatInstance().parse(min)))
throw new OValidationException("The field '" + p.getFullName() + "' contains the datetime " + fieldValue
+ " which precedes the first acceptable datetime (" + min + ")");
} catch (ParseException e) {
}
} else if ((p.getType().equals(OType.EMBEDDEDLIST) || p.getType().equals(OType.EMBEDDEDSET)
|| p.getType().equals(OType.LINKLIST) || p.getType().equals(OType.LINKSET))
&& (fieldValue != null && ((Collection<?>) fieldValue).size() < Integer.parseInt(min)))
throw new OValidationException("The field '" + p.getFullName() + "' contains fewer items than " + min + " requested");
}
if (p.getMax() != null) {
// MAX
final String max = p.getMax();
if (p.getType().equals(OType.STRING) && (fieldValue != null && ((String) fieldValue).length() > Integer.parseInt(max)))
throw new OValidationException("The field '" + p.getFullName() + "' contains more characters than " + max + " requested");
else if (p.getType().equals(OType.BINARY) && (fieldValue != null && ((byte[]) fieldValue).length > Integer.parseInt(max)))
throw new OValidationException("The field '" + p.getFullName() + "' contains more bytes than " + max + " requested");
else if (p.getType().equals(OType.INTEGER) && (fieldValue != null && type.asInt(fieldValue) > Integer.parseInt(max)))
throw new OValidationException("The field '" + p.getFullName() + "' is greater than " + max);
else if (p.getType().equals(OType.LONG) && (fieldValue != null && type.asLong(fieldValue) > Long.parseLong(max)))
throw new OValidationException("The field '" + p.getFullName() + "' is greater than " + max);
else if (p.getType().equals(OType.FLOAT) && (fieldValue != null && type.asFloat(fieldValue) > Float.parseFloat(max)))
throw new OValidationException("The field '" + p.getFullName() + "' is greater than " + max);
else if (p.getType().equals(OType.DOUBLE) && (fieldValue != null && type.asDouble(fieldValue) > Double.parseDouble(max)))
throw new OValidationException("The field '" + p.getFullName() + "' is greater than " + max);
else if (p.getType().equals(OType.DATE)) {
try {
if (fieldValue != null
&& ((Date) fieldValue).before(iRecord.getDatabaseInternal().getStorage().getConfiguration().getDateFormatInstance()
.parse(max)))
throw new OValidationException("The field '" + p.getFullName() + "' contains the date " + fieldValue
+ " which is after the last acceptable date (" + max + ")");
} catch (ParseException e) {
}
} else if (p.getType().equals(OType.DATETIME)) {
try {
if (fieldValue != null
&& ((Date) fieldValue).before(iRecord.getDatabaseInternal().getStorage().getConfiguration()
.getDateTimeFormatInstance().parse(max)))
throw new OValidationException("The field '" + p.getFullName() + "' contains the datetime " + fieldValue
+ " which is after the last acceptable datetime (" + max + ")");
} catch (ParseException e) {
}
} else if ((p.getType().equals(OType.EMBEDDEDLIST) || p.getType().equals(OType.EMBEDDEDSET)
|| p.getType().equals(OType.LINKLIST) || p.getType().equals(OType.LINKSET))
&& (fieldValue != null && ((Collection<?>) fieldValue).size() > Integer.parseInt(max)))
throw new OValidationException("The field '" + p.getFullName() + "' contains more items than " + max + " requested");
}
if (p.isReadonly() && iRecord instanceof ODocument && !iRecord.getRecordVersion().isTombstone()) {
for (String f : ((ODocument) iRecord).getDirtyFields())
if (f.equals(p.getName())) {
// check if the field is actually changed by equal.
// this is due to a limitation in the merge algorithm used server side marking all non simple fields as dirty
Object orgVal = ((ODocument) iRecord).getOriginalValue(f);
boolean simple = fieldValue != null ? OType.isSimpleType(fieldValue) : OType.isSimpleType(orgVal);
if ((simple) || (fieldValue != null && orgVal == null) || (fieldValue == null && orgVal != null)
|| (fieldValue != null && !fieldValue.equals(orgVal)))
throw new OValidationException("The field '" + p.getFullName()
+ "' is immutable and cannot be altered. Field value is: " + ((ODocument) iRecord).field(f));
}
}
}