All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.redhat.lightblue.crud.ConstraintValidator Maven / Gradle / Ivy
/*
Copyright 2013 Red Hat, Inc. and/or its affiliates.
This file is part of lightblue.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
package com.redhat.lightblue.crud;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.redhat.lightblue.util.JsonDoc;
import com.redhat.lightblue.util.Registry;
import com.redhat.lightblue.util.Path;
import com.redhat.lightblue.util.Error;
import com.redhat.lightblue.util.KeyValueCursor;
import com.redhat.lightblue.metadata.EntityMetadata;
import com.redhat.lightblue.metadata.FieldTreeNode;
import com.redhat.lightblue.metadata.FieldConstraint;
import com.redhat.lightblue.metadata.EntityConstraint;
import com.redhat.lightblue.metadata.Field;
import com.redhat.lightblue.metadata.FieldCursor;
public class ConstraintValidator {
private static final Logger LOGGER = LoggerFactory.getLogger(ConstraintValidator.class);
private final Registry fRegistry;
private final Registry eRegistry;
private final EntityMetadata md;
private final Map> docErrors = new HashMap<>();
private final List errors = new ArrayList<>();
private List extends JsonDoc> currentDocList;
private JsonDoc currentDoc;
private FieldTreeNode currentFieldNode;
private Path currentFieldPath;
private FieldConstraint currentFieldConstraint;
private EntityConstraint currentEntityConstraint;
protected ConstraintValidator(Registry r,
Registry e,
EntityMetadata md) {
this.fRegistry = r;
this.eRegistry = e;
this.md = md;
}
public void clearErrors() {
docErrors.clear();
errors.clear();
}
public List extends JsonDoc> getCurrentDocList() {
return currentDocList;
}
public JsonDoc getCurrentDoc() {
return currentDoc;
}
public FieldTreeNode getCurrentFieldMetadata() {
return currentFieldNode;
}
public Path getCurrentFieldPath() {
return currentFieldPath;
}
public FieldConstraint getCurrentFieldConstraint() {
return currentFieldConstraint;
}
public EntityConstraint getCurrentEntityConstraint() {
return currentEntityConstraint;
}
public Map> getDocErrors() {
return docErrors;
}
public void addDocError(Error err) {
getDocError().add(err);
}
public void addDocErrors(List list) {
getDocError().addAll(list);
}
private List getDocError() {
if (currentDoc == null) {
throw new IllegalStateException();
}
List list = docErrors.get(currentDoc);
if (list == null) {
list = new ArrayList<>();
docErrors.put(currentDoc, list);
}
return list;
}
public void addError(Error err) {
errors.add(err);
}
public List getErrors() {
return errors;
}
public boolean hasErrors() {
return !errors.isEmpty()
|| !docErrors.isEmpty();
}
public void validateDocs(List extends JsonDoc> docList) {
currentDocList = docList;
currentDoc = null;
LOGGER.debug("validateDocs() enter with {} docs", docList.size());
Error.push("validateDocs");
try {
for (JsonDoc doc : docList) {
validateDoc(doc);
}
} catch (Error e) {
// rethrow lightblue error
throw e;
} catch (Exception e) {
// throw new Error (preserves current error context)
LOGGER.error(e.getMessage(), e);
throw Error.get(CrudConstants.ERR_CRUD, e.getMessage());
} finally {
Error.pop();
}
LOGGER.debug("validateDocs() complete");
}
public void validateDoc(JsonDoc doc) {
currentDoc = doc;
Error.push("validateDoc");
LOGGER.debug("validateDoc() enter with entity {}", md.getName());
try {
currentFieldConstraint = null;
currentFieldNode = null;
currentFieldPath = null;
Path currentValuePath = null;
JsonNode currentValue = null;
checkEntityConstraints(doc);
currentEntityConstraint = null;
checkConstraints(doc, currentValuePath, currentValue);
} catch (Error e) {
// rethrow lightblue error
throw e;
} catch (Exception e) {
// throw new Error (preserves current error context)
LOGGER.error(e.getMessage(), e);
throw Error.get(CrudConstants.ERR_CRUD, e.getMessage());
} finally {
Error.pop();
}
currentDoc = null;
currentFieldConstraint = null;
currentFieldNode = null;
currentFieldPath = null;
LOGGER.debug("validateDoc() complete");
}
private void checkEntityConstraints(JsonDoc doc) {
LOGGER.debug("checking entity constraints");
for (EntityConstraint x : md.getConstraints()) {
currentEntityConstraint = x;
String constraintType = currentEntityConstraint.getType();
LOGGER.debug("checking entity constraint " + constraintType);
Error.push(constraintType);
try {
EntityConstraintChecker checker = eRegistry.find(constraintType);
if (checker == null) {
throw Error.get(CrudConstants.ERR_NO_CONSTRAINT);
}
checker.checkConstraint(this, currentEntityConstraint, doc);
} catch (Error e) {
// rethrow lightblue error
throw e;
} catch (Exception e) {
// throw new Error (preserves current error context)
LOGGER.error(e.getMessage(), e);
throw Error.get(CrudConstants.ERR_CRUD, e.getMessage());
} finally {
Error.pop();
}
}
}
private void checkConstraints(JsonDoc doc, Path currentValuePath, JsonNode currentValue) {
LOGGER.debug("checking field constraints");
FieldCursor cursor = md.getFieldCursor();
while (cursor.next()) {
currentFieldNode = cursor.getCurrentNode();
currentFieldPath = cursor.getCurrentPath();
LOGGER.debug("checking field {}", currentFieldPath);
Error.push(currentFieldPath.toString());
try {
List constraints = null;
if (currentFieldNode instanceof Field) {
constraints = ((Field) currentFieldNode).getConstraints();
}
if (constraints != null && !constraints.isEmpty()) {
checkFieldConstraints(doc, constraints, currentValuePath, currentValue);
}
} catch (Error e) {
// rethrow lightblue error
throw e;
} catch (Exception e) {
// throw new Error (preserves current error context)
LOGGER.error(e.getMessage(), e);
throw Error.get(CrudConstants.ERR_CRUD, e.getMessage());
} finally {
Error.pop();
}
}
}
private void checkFieldConstraints(JsonDoc doc, List constraints, Path currentValuePath, JsonNode currentValue) {
for (FieldConstraint x : constraints) {
currentFieldConstraint = x;
String constraintType = currentFieldConstraint.getType();
LOGGER.debug("checking constraint " + constraintType);
Error.push(constraintType);
try {
FieldConstraintChecker checker = fRegistry.find(constraintType);
if (checker == null) {
throw Error.get(CrudConstants.ERR_NO_CONSTRAINT);
}
if (checker instanceof FieldConstraintDocChecker) {
// Constraint needs to be checked once for the doc
checkFieldContraints(doc, (FieldConstraintDocChecker) checker);
} else if (checker instanceof FieldConstraintValueChecker) {
// Constraint needs to be checked for all the values in the doc
checkValueContraints(doc, (FieldConstraintChecker) checker, currentValuePath, currentValue);
}
} catch (Error e) {
// rethrow lightblue error
throw e;
} catch (Exception e) {
// throw new Error (preserves current error context)
LOGGER.error(e.getMessage(), e);
throw Error.get(CrudConstants.ERR_CRUD, e.getMessage());
} finally {
Error.pop();
}
}
}
private void checkFieldContraints(JsonDoc doc, FieldConstraintDocChecker checker) {
((FieldConstraintDocChecker) checker).checkConstraint(this,
currentFieldNode,
currentFieldPath,
currentFieldConstraint,
doc);
}
private void checkValueContraints(JsonDoc doc, FieldConstraintChecker checker, Path currentValuePath, JsonNode currentValue) {
KeyValueCursor fieldValues = doc.getAllNodes(currentFieldPath);
while (fieldValues.hasNext()) {
fieldValues.next();
currentValuePath = fieldValues.getCurrentKey();
currentValue = fieldValues.getCurrentValue();
Error.push(currentValuePath.toString());
try {
((FieldConstraintValueChecker) checker).checkConstraint(this,
currentFieldNode,
currentFieldPath,
currentFieldConstraint,
currentValuePath,
doc,
currentValue);
} catch (Error e) {
// rethrow lightblue error
throw e;
} catch (Exception e) {
// throw new Error (preserves current error context)
LOGGER.error(e.getMessage(), e);
throw Error.get(CrudConstants.ERR_CRUD, e.getMessage());
} finally {
Error.pop();
}
}
}
public EntityMetadata getEntityMetadata() {
return md;
}
}