
com.github.mhewedy.expressions.ExpressionsPredicateBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-data-jpa-mongodb-expressions Show documentation
Show all versions of spring-data-jpa-mongodb-expressions Show documentation
Spring Data JPA Mongodb Expressions
package com.github.mhewedy.expressions;
import org.springframework.util.Assert;
import jakarta.persistence.criteria.*;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.ManagedType;
import jakarta.persistence.metamodel.PluralAttribute;
import jakarta.persistence.metamodel.SingularAttribute;
import java.time.*;
import java.time.chrono.HijrahDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static com.github.mhewedy.expressions.Expression.*;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import static jakarta.persistence.metamodel.Attribute.PersistentAttributeType;
class ExpressionsPredicateBuilder {
static Predicate getPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb, Expressions expressions) {
Assert.notNull(expressions, "expressions must not be null!");
List predicates = getPredicates(query, cb,
root,
root.getModel(),
expressions.getExpressions());
if (predicates.isEmpty()) {
return cb.isTrue(cb.literal(true));
}
if (predicates.size() == 1) {
return predicates.iterator().next();
}
Predicate[] array = predicates.toArray(new Predicate[0]);
return cb.and(array);
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static List getPredicates(CriteriaQuery> query, CriteriaBuilder cb,
Path> from, ManagedType> type,
List expressions) {
List predicates = new ArrayList<>();
for (Expression expression : expressions) {
if (expression instanceof SingularExpression) {
SingularExpression singularExpression = (SingularExpression) expression;
final String field = extractField(singularExpression.field);
Attribute, ?> attribute = getAttribute(type, field);
if (attribute.isAssociation()) {
if (attribute instanceof PluralAttribute) {
query.distinct(true);
}
final String subField = extractSubField(singularExpression.field);
if (!subField.isEmpty()) {
final SingularExpression subExpression =
new SingularExpression(subField, singularExpression.operator, singularExpression.value);
predicates.addAll(
getPredicates(query, cb,
reuseOrCreateJoin((From, ?>) from, attribute, field),
extractSubFieldType(attribute),
singletonList(subExpression)
)
);
continue;
}
}
Path exprPath = from.get((SingularAttribute) attribute);
if (PersistentAttributeType.EMBEDDED == attribute.getPersistentAttributeType()) {
final String subField = extractSubField(singularExpression.field);
attribute = extractSubFieldType(attribute).getAttribute(subField);
exprPath = exprPath.get((SingularAttribute) attribute);
}
Object attributeValue = convertValueToAttributeType(singularExpression.value, attribute.getJavaType());
Predicate predicate;
switch (singularExpression.operator) {
// equality
case $eq:
if (attributeValue == null) {
predicate = cb.isNull(exprPath);
} else {
predicate = cb.equal(exprPath, attributeValue);
}
break;
case $ieq:
predicate = cb.equal(cb.lower(exprPath), ((String) attributeValue).toLowerCase());
break;
case $ne:
if (attributeValue == null) {
predicate = cb.isNotNull(exprPath);
} else {
predicate = cb.notEqual(exprPath, attributeValue);
}
break;
// comparison
case $gt:
if (Number.class.isAssignableFrom(attribute.getJavaType())) {
predicate = cb.gt(exprPath, (Number) attributeValue);
} else if (Comparable.class.isAssignableFrom(attribute.getJavaType())) {
predicate = cb.greaterThan(exprPath, (Comparable) attributeValue);
} else {
throw new IllegalArgumentException("field should be Number or Comparable: " +
singularExpression);
}
break;
case $gte:
if (Number.class.isAssignableFrom(attribute.getJavaType())) {
predicate = cb.ge(exprPath, (Number) attributeValue);
} else if (Comparable.class.isAssignableFrom(attribute.getJavaType())) {
predicate = cb.greaterThanOrEqualTo(exprPath, (Comparable) attributeValue);
} else {
throw new IllegalArgumentException("field should be Number or Comparable: " +
singularExpression);
}
break;
case $lt:
if (Number.class.isAssignableFrom(attribute.getJavaType())) {
predicate = cb.lt(exprPath, (Number) attributeValue);
} else if (Comparable.class.isAssignableFrom(attribute.getJavaType())) {
predicate = cb.lessThan(exprPath, (Comparable) attributeValue);
} else {
throw new IllegalArgumentException("field should be Number or Comparable: " +
singularExpression);
}
break;
case $lte:
if (Number.class.isAssignableFrom(attribute.getJavaType())) {
predicate = cb.le(exprPath, (Number) attributeValue);
} else if (Comparable.class.isAssignableFrom(attribute.getJavaType())) {
predicate = cb.lessThanOrEqualTo(exprPath, (Comparable) attributeValue);
} else {
throw new IllegalArgumentException("field should be Number or Comparable: " +
singularExpression);
}
break;
// like
case $start:
predicate = cb.like(exprPath.as(String.class), attributeValue + "%");
break;
case $end:
predicate = cb.like(exprPath.as(String.class), "%" + attributeValue);
break;
case $contains:
predicate = cb.like(exprPath.as(String.class), "%" + attributeValue + "%");
break;
case $istart:
predicate = cb.like(cb.lower(exprPath.as(String.class)), attributeValue.toString().toLowerCase() + "%");
break;
case $iend:
predicate = cb.like(cb.lower(exprPath.as(String.class)), "%" + attributeValue.toString().toLowerCase());
break;
case $icontains:
predicate = cb.like(cb.lower(exprPath.as(String.class)), "%" + attributeValue.toString().toLowerCase() + "%");
break;
default:
throw new IllegalStateException("Unexpected value: " + singularExpression);
}
predicates.add(predicate);
} else if (expression instanceof ListExpression) {
ListExpression listExpression = (ListExpression) expression;
final String field = extractField(listExpression.field);
Attribute, ?> attribute = getAttribute(type, field);
if (attribute.isAssociation()) {
if (attribute instanceof PluralAttribute) {
query.distinct(true);
}
final String subField = extractSubField(listExpression.field);
if (!subField.isEmpty()) {
final ListExpression subExpression =
new ListExpression(subField, listExpression.operator, listExpression.values);
predicates.addAll(
getPredicates(query, cb,
reuseOrCreateJoin((From, ?>) from, attribute, field),
extractSubFieldType(attribute),
singletonList(subExpression)
)
);
continue;
}
}
Path exprPath = from.get((SingularAttribute) attribute);
if (PersistentAttributeType.EMBEDDED == attribute.getPersistentAttributeType()) {
final String subField = extractSubField(listExpression.field);
attribute = extractSubFieldType(attribute).getAttribute(subField);
exprPath = exprPath.get((SingularAttribute) attribute);
}
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy