net.sf.jsqlparser.util.validation.validator.AbstractValidator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsqlparser Show documentation
Show all versions of jsqlparser Show documentation
JSqlParser parses an SQL statement and translate it into a hierarchy of Java classes.
The generated hierarchy can be navigated using the Visitor Pattern.
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2020 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.util.validation.validator;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
import net.sf.jsqlparser.parser.feature.Feature;
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.util.validation.ValidationCapability;
import net.sf.jsqlparser.util.validation.ValidationContext;
import net.sf.jsqlparser.util.validation.ValidationException;
import net.sf.jsqlparser.util.validation.Validator;
import net.sf.jsqlparser.util.validation.feature.FeatureContext;
import net.sf.jsqlparser.util.validation.feature.FeatureSetValidation;
import net.sf.jsqlparser.util.validation.metadata.DatabaseMetaDataValidation;
import net.sf.jsqlparser.util.validation.metadata.MetadataContext;
import net.sf.jsqlparser.util.validation.metadata.Named;
import net.sf.jsqlparser.util.validation.metadata.NamedObject;
/**
* A abstract base for a Validation
*
* @param the type of statement this DeParser supports
* @author gitmotte
*/
public abstract class AbstractValidator implements Validator {
private ValidationContext context = new ValidationContext();
private Map> errors = new HashMap<>();
private Map>, AbstractValidator>> validatorForwards = new HashMap<>();
public > T getValidator(Class type) {
return type.cast(validatorForwards.computeIfAbsent(type, this::newObject));
}
private > E newObject(Class type) {
try {
E e = type.cast(type.getConstructor().newInstance());
e.setContext(context());
return e;
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
throw new IllegalStateException("Type " + type + " cannot be constructed by empty constructor!");
}
}
protected Consumer getMessageConsumer(ValidationCapability c) {
return s -> putError(c, s);
}
protected ValidationContext context() {
return context(true);
}
protected ValidationContext context(boolean reInit) {
return context.reinit(reInit);
}
/**
* adds an error for this {@link ValidationCapability}
*
* @param capability
* @param error
*/
protected void putError(ValidationCapability capability, ValidationException error) {
errors.computeIfAbsent(capability, k -> new HashSet<>()).add(error);
}
@Override
public final Map> getValidationErrors() {
Map> map = new HashMap<>();
map.putAll(errors);
for (AbstractValidator> v : validatorForwards.values()) {
for (Entry> e : v.getValidationErrors().entrySet()) {
Set set = map.get(e.getKey());
if (set == null) {
map.put(e.getKey(), e.getValue());
} else {
set.addAll(e.getValue());
}
}
}
return map;
}
public Collection getCapabilities() {
return context().getCapabilities();
}
@Override
public final void setContext(ValidationContext context) {
this.context = context;
}
protected void validateOptional(E element, Consumer elementConsumer) {
if (element != null) {
elementConsumer.accept(element);
}
}
protected > void validateOptionalList(
List elementList, Supplier validatorSupplier, BiConsumer elementConsumer) {
if (isNotEmpty(elementList)) {
V validator = validatorSupplier.get();
elementList.forEach(e -> elementConsumer.accept(e, validator));
}
}
/**
* a multi-expression in clause: {@code ((a, b), (c, d))}
*/
protected void validateOptionalMultiExpressionList(MultiExpressionList multiExprList) {
if (multiExprList != null) {
ExpressionValidator v = getValidator(ExpressionValidator.class);
multiExprList.getExpressionLists().stream().map(ExpressionList::getExpressions).flatMap(List::stream)
.forEach(e -> e.accept(v));
}
}
protected void validateOptionalExpression(Expression expression) {
validateOptional(expression, e -> e.accept(getValidator(ExpressionValidator.class)));
}
protected void validateOptionalExpression(Expression expression, ExpressionValidator v) {
validateOptional(expression, e -> e.accept(v));
}
protected void validateOptionalExpressions(List extends Expression> expressions) {
validateOptionalList(expressions, () -> getValidator(ExpressionValidator.class), (o, v) -> o.accept(v));
}
protected void validateOptionalFromItems(FromItem... fromItems) {
validateOptionalFromItems(Arrays.asList(fromItems));
}
protected void validateOptionalFromItems(List extends FromItem> fromItems) {
validateOptionalList(fromItems, () -> getValidator(SelectValidator.class),
this::validateOptionalFromItem);
}
protected void validateOptionalOrderByElements(List orderByElements) {
validateOptionalList(orderByElements, () -> getValidator(OrderByValidator.class), (o, v) -> o.accept(v));
}
protected void validateOptionalFromItem(FromItem fromItem) {
validateOptional(fromItem, i -> i.accept(getValidator(SelectValidator.class)));
}
protected void validateOptionalFromItem(FromItem fromItem, SelectValidator v) {
validateOptional(fromItem, i -> i.accept(v));
}
protected void validateOptionalItemsList(ItemsList itemsList) {
validateOptional(itemsList, i -> i.accept(getValidator(ItemsListValidator.class)));
}
/**
* Iterates through all {@link ValidationCapability} and validates the feature
* with {@link #validateFeature(ValidationCapability, Feature)}
*
* @param feature
*/
protected void validateFeature(Feature feature) {
for (ValidationCapability c : getCapabilities()) {
validateFeature(c, feature);
}
}
/**
* Iterates through all {@link ValidationCapability} and validates
*
* - the name with
* {@link #validateName(ValidationCapability, NamedObject, String)}
* - the feature with
* {@link #validateFeature(ValidationCapability, Feature)}
*
*
* @param feature
* @param namedObject
* @param fqn
*/
protected void validateFeatureAndName(Feature feature, NamedObject namedObject, String fqn) {
validateFeatureAndNameWithAlias(feature, namedObject, fqn, null);
}
/**
* Iterates through all {@link ValidationCapability} and validates
*
* - the name with
* {@link #validateName(ValidationCapability, NamedObject, String)}
* - the feature with
* {@link #validateFeature(ValidationCapability, Feature)}
*
*
* @param feature
* @param namedObject
* @param fqn
* @param alias
*/
protected void validateFeatureAndNameWithAlias(Feature feature, NamedObject namedObject, String fqn, String alias) {
for (ValidationCapability c : getCapabilities()) {
validateFeature(c, feature);
validateNameWithAlias(c, namedObject, fqn, alias, true);
}
}
/**
* Iterates through all {@link ValidationCapability} and validates for the name
* with {@link #validateName(ValidationCapability, NamedObject, String)}
*
* @param namedObject
* @param fqn
*/
protected void validateName(NamedObject namedObject, String fqn) {
validateNameWithAlias(namedObject, fqn, null);
}
/**
* Iterates through all {@link ValidationCapability} and validates for the name
* with {@link #validateName(ValidationCapability, NamedObject, String)}
*
* @param namedObject
* @param fqn
* @param alias
*/
protected void validateNameWithAlias(NamedObject namedObject, String fqn, String alias) {
for (ValidationCapability c : getCapabilities()) {
validateNameWithAlias(c, namedObject, fqn, alias, true);
}
}
/**
* Validates the feature if given {@link ValidationCapability} is a
* {@link FeatureSetValidation} and condition is true
*
* @param capability
* @param condition
* @param feature
*/
protected void validateFeature(ValidationCapability capability, boolean condition, Feature feature) {
if (condition) {
validateFeature(capability, feature);
}
}
/**
* validates for the feature if given elements is not empty - see
* {@link #isNotEmpty(Collection)}
*
* @param capability
* @param elements
* @param feature
*/
protected void validateOptionalFeature(ValidationCapability capability, List> elements, Feature feature) {
validateFeature(capability, isNotEmpty(elements), feature);
}
/**
* Validates for the feature if given element is not null
*
* @param capability
* @param element
* @param feature
*/
protected void validateOptionalFeature(ValidationCapability capability, Object element, Feature feature) {
validateFeature(capability, element != null, feature);
}
/**
* Validates if given {@link ValidationCapability} is a
* {@link FeatureSetValidation}
*
* @param capability
* @param feature
*/
protected void validateFeature(ValidationCapability capability, Feature feature) {
if (capability instanceof FeatureSetValidation) {
capability.validate(context().put(FeatureContext.feature, feature),
getMessageConsumer(capability));
}
}
/**
* Validates if given {@link ValidationCapability} is a
* {@link DatabaseMetaDataValidation}
*
* @param capability
* @param namedObject
* @param fqn
* @param alias
*/
protected void validateNameWithAlias(ValidationCapability capability, NamedObject namedObject, String fqn, String alias) {
validateNameWithAlias(capability, namedObject, fqn, alias, true);
}
/**
* @param capability
* @param namedObject
* @param fqn
*/
protected void validateName(ValidationCapability capability, NamedObject namedObject, String fqn) {
validateNameWithAlias(capability, namedObject, fqn, null, true);
}
/**
* Validates if given {@link ValidationCapability} is a
* {@link DatabaseMetaDataValidation}
*
* @param capability
* @param namedObject
* @param fqn
* @param alias
* @param exists - true
, check for existence,
* false
, check for non-existence
*/
protected void validateNameWithAlias(ValidationCapability capability, NamedObject namedObject, String fqn, String alias,
boolean exists,
NamedObject... parents) {
if (capability instanceof DatabaseMetaDataValidation) {
capability.validate(context()
.put(MetadataContext.named,
new Named(namedObject, fqn).setAlias(alias).setParents(Arrays.asList(parents))) //
.put(MetadataContext.exists, exists),
getMessageConsumer(capability));
}
}
/**
* @param capability
* @param namedObject
* @param fqn
* @param exists
* @param parents
*/
protected void validateName(ValidationCapability capability, NamedObject namedObject, String fqn, boolean exists,
NamedObject... parents) {
validateNameWithAlias(capability, namedObject, fqn, null, exists, parents);
}
/**
* @param capability
* @param name
*/
protected void validateOptionalColumnName(ValidationCapability capability, String name) {
validateOptionalName(capability, NamedObject.column, name, null, true);
}
/**
* @param capability
* @param name
* @param alias
*/
protected void validateOptionalColumnNameWithAlias(ValidationCapability capability, String name, String alias) {
validateOptionalName(capability, NamedObject.column, name, alias, true);
}
/**
* @param capability
* @param columnNames
* @param parents
*/
protected void validateOptionalColumnNames(ValidationCapability capability, List columnNames,
NamedObject... parents) {
validateOptionalColumnNames(capability, columnNames, true, parents);
}
/**
* @param capability
* @param columnNames
* @param exists
* @param parents
*/
protected void validateOptionalColumnNames(ValidationCapability capability, List columnNames,
boolean exists,
NamedObject... parents) {
if (columnNames != null) {
columnNames.forEach(n -> validateOptionalName(capability, NamedObject.column, n, null, exists, parents));
}
}
/**
* @param capability
* @param namedObject
* @param name
* @param alias
* @param parents
*/
protected void validateOptionalNameWithAlias(ValidationCapability capability, NamedObject namedObject, String name,
String alias,
NamedObject... parents) {
validateOptionalName(capability, namedObject, name, alias, true, parents);
}
/**
* @param capability
* @param namedObject
* @param name
* @param parents
*/
protected void validateOptionalName(ValidationCapability capability, NamedObject namedObject, String name,
NamedObject... parents) {
validateOptionalNameWithAlias(capability, namedObject, name, (String) null, parents);
}
/**
* @param capability
* @param namedObject
* @param name
* @param alias
* @param exists
* @param parents
*/
protected void validateOptionalName(ValidationCapability capability, NamedObject namedObject, String name,
String alias,
boolean exists,
NamedObject... parents) {
if (name != null) {
validateNameWithAlias(capability, namedObject, name, alias, exists, parents);
}
}
protected boolean isNotEmpty(Collection> c) {
return c != null && !c.isEmpty();
}
protected boolean isNotEmpty(String c) {
return c != null && !c.isEmpty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy