use of cern.modesti.point.Point in project modesti by jlsalmon.
the class Constraints method validateUniqueConstraint.
/**
* Unique constraints apply to the entire request. For example, a constraint
* with two members means that the result of the concatenation of the values
* of those members must be unique for all points.
*/
private static boolean validateUniqueConstraint(Constraint constraint, Request request, Category category) {
boolean valid = true;
List<String> concatenatedValues = new ArrayList<>();
// Build a new array containing the concatenation of the values of all constraint members
for (Point point : request.getNonEmptyPoints()) {
String concatenatedValue = "";
boolean atLeastOneNullMember = false;
for (String member : constraint.getMembers()) {
Object value = point.getValueByPropertyName(member);
if (value != null && (value instanceof String && !((String) value).isEmpty())) {
concatenatedValue += value.toString();
} else {
atLeastOneNullMember = true;
}
}
if (atLeastOneNullMember) {
concatenatedValue = "";
}
concatenatedValues.add(concatenatedValue);
}
for (Point point : request.getNonEmptyPoints()) {
String value = concatenatedValues.get(request.getPoints().indexOf(point));
if (value != null && !value.isEmpty() && concatenatedValues.indexOf(value) != concatenatedValues.lastIndexOf(value)) {
point.setValid(false);
valid = false;
// TODO: set category to invalid
// point.properties.valid = category.valid = valid = false;
List<String> fieldNames = category.getFieldNames(constraint.getMembers());
if (constraint.getMembers().size() == 1) {
point.addErrorMessage(category.getId(), constraint.getMembers().get(0), "'" + fieldNames.get(0) + "' must be unique for all points. Check for duplications.");
} else {
point.addErrorMessage(category.getId(), "", "" + String.join(", ", fieldNames) + "' must be unique for all points. Check for duplications.");
}
}
}
return valid;
}
use of cern.modesti.point.Point in project modesti by jlsalmon.
the class RequestDifferTest method createRequest.
private Request createRequest(int numPoints, int numProperties) {
Request request = new RequestImpl();
request.setType(RequestType.UPDATE);
request.setDescription("Test description");
request.setDomain("Unit Test");
ArrayList<Point> points = new ArrayList<>();
for (int i = 1; i <= numPoints; i++) {
Point p = createPoint(i, numProperties);
points.add(p);
}
request.setPoints(points);
return request;
}
use of cern.modesti.point.Point in project modesti by jlsalmon.
the class CoreValidationService method validatePoints.
private boolean validatePoints(Request request, List<Category> categories) {
boolean valid = true;
for (Point point : request.getNonEmptyPoints()) {
for (Category category : categories) {
for (Field field : category.getFields()) {
Object value = point.getValueByPropertyName(field.getPropertyName());
// Check for invalid fields
if (!isValidValue(value, point, field)) {
point.setValid(false);
valid = false;
point.addErrorMessage(category.getId(), field.getId(), "Value '" + value + "' is not a legal option for field '" + field.getName() + "'. Please select a value from the list.");
}
// Validate unique fields
if (field.getUnique() != null) {
Constraint constraint = new Constraint("unique", Collections.singletonList(field.getId()), null);
if (!Constraints.validate(constraint, request, category)) {
valid = false;
}
}
// Required fields (can be simple boolean or condition list)
boolean required = false;
if (field.getRequired() instanceof Boolean && (Boolean) field.getRequired()) {
required = true;
} else if (field.getRequired() != null) {
required = Conditionals.evaluate(field.getRequired(), point, request);
}
if (required) {
if (value == null || value.equals("")) {
point.setValid(false);
valid = false;
point.addErrorMessage(category.getId(), field.getId(), "'" + field.getName() + "' is mandatory");
}
}
// Min length
if (field.getMinLength() != null) {
if (value != null && value.toString().length() < field.getMinLength()) {
point.setValid(false);
valid = false;
point.addErrorMessage(category.getId(), field.getId(), "'" + field.getName() + "' must be at least " + field.getMinLength() + " characters in length");
}
}
// Max length
if (field.getMaxLength() != null) {
if (value != null && value.toString().length() > field.getMaxLength()) {
point.setValid(false);
valid = false;
point.addErrorMessage(category.getId(), field.getId(), "'" + field.getName() + "' must not exceed " + field.getMaxLength() + " characters in length");
}
}
// Numeric fields
if (field.getType().equals("numeric")) {
if (value != null && !value.toString().isEmpty() && !NumberUtils.isNumber(value.toString())) {
point.setValid(false);
valid = false;
point.addErrorMessage(category.getId(), field.getId(), "Value for '" + field.getName() + "' must be numeric");
}
}
}
}
}
return valid;
}
use of cern.modesti.point.Point in project modesti by jlsalmon.
the class CoreValidationService method validateRequest.
public boolean validateRequest(Request request) {
try {
if (RequestType.DELETE.equals(request.getType())) {
// Delete requests should not be validated
return true;
}
boolean valid = true;
Schema schema = schemaRepository.findOne(request.getDomain());
// Reset all points and clear any error messages.
for (Point point : request.getPoints()) {
point.setValid(true);
point.setErrors(new ArrayList<>());
}
if (environment.getProperty("modesti.disableValidator", Boolean.class, false) || request.isSkipCoreValidation()) {
log.info("core validations disabled");
} else {
// Concatenate all categories and datasources
List<Category> categories = new ArrayList<>(schema.getCategories());
categories.addAll(schema.getDatasources());
// Validate the mutually exclusive column group specifications.
if (!validateMutualExclusions(request, categories)) {
valid = false;
}
// column groups and mutually inclusive fields.
if (!validateConstraints(request, categories)) {
valid = false;
}
// values, min/max length, valid values etc.
if (!validatePoints(request, categories)) {
valid = false;
}
}
request.setValid(valid);
requestService.save(request);
if (!valid) {
log.info(format("request #%s failed validation, not invoking custom validator", request.getRequestId()));
return false;
}
log.info(format("request #%s is valid, invoking custom validator", request.getRequestId()));
RequestProvider plugin = requestProviderRegistry.getPluginFor(request);
RequestValidator validator = getPluginRequestValidator(plugin.getMetadata().getId());
if (validator == null) {
log.info(format("custom validator not provided for request #%s", request.getRequestId()));
return true;
}
valid = validator.validateRequest(request, schema);
request.setValid(valid);
requestService.save(request);
return valid;
} catch (RuntimeException e) {
request.setValid(false);
requestService.save(request);
log.info(format("Unexpected error during validation phase for request #%s '%s'", request.getRequestId(), e.toString()), e);
return false;
}
}
use of cern.modesti.point.Point in project modesti by jlsalmon.
the class CoreValidationService method validateMutualExclusions.
private boolean validateMutualExclusions(Request request, List<Category> categories) {
boolean valid = true;
for (Category category : categories) {
if (category.getExcludes() == null) {
continue;
}
for (String exclude : category.getExcludes()) {
// Get the excluded category
for (Category cat : categories) {
if (cat.getId().equals(exclude)) {
Category excludedCategory = cat;
// so, say something like "Fields in the "Alarms" group cannot be used if fields in the "Commands" group have been specified.".
for (Point point : request.getNonEmptyPoints()) {
List<Field> emptyFields = point.getEmptyFields(category.getFields());
// If at least one of the fields of this category are filled, then we must check the excluded category.
if (emptyFields.size() != category.getFields().size()) {
emptyFields = point.getEmptyFields(excludedCategory.getFields());
if (emptyFields.size() != excludedCategory.getFields().size()) {
point.setValid(false);
valid = false;
point.addErrorMessage(category.getId(), "", "Fields in the '" + category.getName() + "' group cannot be used if fields in the '" + excludedCategory.getName() + "' group have been specified.");
}
}
}
}
}
}
}
return valid;
}
Aggregations