com.dimajix.shaded.everit.schema.ObjectSchemaValidatingVisitor Maven / Gradle / Ivy
package com.dimajix.shaded.everit.schema;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static com.dimajix.shaded.everit.schema.loader.OrgJsonUtil.getNames;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.dimajix.shaded.everit.schema.regexp.Regexp;
import com.dimajix.shaded.json.JSONObject;
class ObjectSchemaValidatingVisitor extends Visitor {
private final Object subject;
private JSONObject objSubject;
private ObjectSchema schema;
private int objectSize;
private final ValidatingVisitor owner;
public ObjectSchemaValidatingVisitor(Object subject, ValidatingVisitor owner) {
this.subject = requireNonNull(subject, "subject cannot be null");
this.owner = requireNonNull(owner, "owner cannot be null");
}
@Override void visitObjectSchema(ObjectSchema objectSchema) {
if (owner.passesTypeCheck(JSONObject.class, objectSchema.requiresObject(), objectSchema.isNullable())) {
objSubject = (JSONObject) subject;
objectSize = objSubject.length();
this.schema = objectSchema;
Object failureState = owner.getFailureState();
Set objSubjectKeys = null;
if (objectSchema.hasDefaultProperty()) {
objSubjectKeys = new HashSet<>(objSubject.keySet());
}
super.visitObjectSchema(objectSchema);
if (owner.isFailureStateChanged(failureState) && objectSchema.hasDefaultProperty()) {
objSubject.keySet().retainAll(objSubjectKeys);
}
}
}
@Override void visitRequiredPropertyName(String requiredPropName) {
if (!objSubject.has(requiredPropName)) {
owner.failure(format("required key [%s] not found", requiredPropName), "required");
}
}
@Override void visitPropertyNameSchema(Schema propertyNameSchema) {
if (propertyNameSchema != null) {
String[] names = getNames(objSubject);
if (names == null || names.length == 0) {
return;
}
for (String name : names) {
ValidationException failure = owner.getFailureOfSchema(propertyNameSchema, name);
if (failure != null) {
owner.failure(failure.prepend(name));
}
}
}
}
@Override void visitMinProperties(Integer minProperties) {
if (minProperties != null && objectSize < minProperties.intValue()) {
owner.failure(format("minimum size: [%d], found: [%d]", minProperties, objectSize), "minProperties");
}
}
@Override void visitMaxProperties(Integer maxProperties) {
if (maxProperties != null && objectSize > maxProperties.intValue()) {
owner.failure(format("maximum size: [%d], found: [%d]", maxProperties, objectSize), "maxProperties");
}
}
@Override void visitPropertyDependencies(String ifPresent, Set allMustBePresent) {
if (objSubject.has(ifPresent)) {
for (String mustBePresent : allMustBePresent) {
if (!objSubject.has(mustBePresent)) {
owner.failure(format("property [%s] is required", mustBePresent), "dependencies");
}
}
}
}
@Override void visitAdditionalProperties(boolean permitsAdditionalProperties) {
if (!permitsAdditionalProperties) {
List additionalProperties = getAdditionalProperties();
if (null == additionalProperties || additionalProperties.isEmpty()) {
return;
}
for (String additionalProperty : additionalProperties) {
owner.failure(format("extraneous key [%s] is not permitted", additionalProperty), "additionalProperties");
}
}
}
@Override void visitSchemaOfAdditionalProperties(Schema schemaOfAdditionalProperties) {
if (schemaOfAdditionalProperties != null) {
List additionalPropNames = getAdditionalProperties();
for (String propName : additionalPropNames) {
Object propVal = objSubject.get(propName);
ValidationException failure = owner.getFailureOfSchema(schemaOfAdditionalProperties, propVal);
if (failure != null) {
owner.failure(failure.prepend(propName, schema));
}
}
}
}
private List getAdditionalProperties() {
String[] names = getNames(objSubject);
if (names == null) {
return new ArrayList<>();
} else {
List namesList = new ArrayList<>();
for (String name : names) {
if (!schema.getPropertySchemas().containsKey(name) && !matchesAnyPattern(name)) {
namesList.add(name);
}
}
return namesList;
}
}
private boolean matchesAnyPattern(String key) {
for (Regexp pattern : schema.getRegexpPatternProperties().keySet()) {
if (!pattern.patternMatchingFailure(key).isPresent()) {
return true;
}
}
return false;
}
@Override void visitPatternPropertySchema(Regexp propertyNamePattern, Schema schema) {
String[] propNames = getNames(objSubject);
if (propNames == null || propNames.length == 0) {
return;
}
for (String propName : propNames) {
if (!propertyNamePattern.patternMatchingFailure(propName).isPresent()) {
ValidationException failure = owner.getFailureOfSchema(schema, objSubject.get(propName));
if (failure != null) {
owner.failure(failure.prepend(propName));
}
}
}
}
@Override void visitSchemaDependency(String propName, Schema schema) {
if (objSubject.has(propName)) {
ValidationException failure = owner.getFailureOfSchema(schema, objSubject);
if (failure != null) {
owner.failure(failure);
}
}
}
@Override void visitPropertySchema(String properyName, Schema schema) {
if (objSubject.has(properyName)) {
ValidationException failure = owner.getFailureOfSchema(schema, objSubject.get(properyName));
if (failure != null) {
owner.failure(failure.prepend(properyName));
}
} else if (schema.hasDefaultValue()) {
objSubject.put(properyName, schema.getDefaultValue());
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy