Add support for plugable QL for EntityManager (#2698)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -31,7 +31,6 @@ import java.util.Objects;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.ql.Node.Comparison.Operator;
|
||||
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParser;
|
||||
|
||||
/**
|
||||
* Provides entity matcher that matches an entity object against a filter (a {@link Node} or an RSQL string).
|
||||
@@ -44,14 +43,10 @@ public class EntityMatcher {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
public static EntityMatcher forNode(final Node root) {
|
||||
public static EntityMatcher of(final Node root) {
|
||||
return new EntityMatcher(root);
|
||||
}
|
||||
|
||||
public static EntityMatcher forRsql(final String rsql) {
|
||||
return forNode(RsqlParser.parse(rsql));
|
||||
}
|
||||
|
||||
public <T> boolean match(final T t) {
|
||||
return match(t, root);
|
||||
}
|
||||
|
||||
@@ -149,8 +149,7 @@ public class QLSupport {
|
||||
* given {@code fieldNameProvider}
|
||||
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
|
||||
*/
|
||||
public <A extends Enum<A> & QueryField, T> Specification<T> buildSpec(
|
||||
final String query, final Class<A> queryFieldType) {
|
||||
public <A extends Enum<A> & QueryField, T> Specification<T> buildSpec(final String query, final Class<A> queryFieldType) {
|
||||
if (specBuilder == SpecBuilder.G3) {
|
||||
return new SpecificationBuilder<T>(!caseInsensitiveDB && ignoreCase, database)
|
||||
.specification(parser.parse(caseInsensitiveDB || ignoreCase ? query.toLowerCase() : query, queryFieldType));
|
||||
@@ -159,6 +158,10 @@ public class QLSupport {
|
||||
}
|
||||
}
|
||||
|
||||
public <A extends Enum<A> & QueryField> EntityMatcher entityMatcher(final String query, final Class<A> queryFieldType) {
|
||||
return EntityMatcher.of(parser.parse(caseInsensitiveDB || ignoreCase ? query.toLowerCase() : query, queryFieldType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the query string
|
||||
*
|
||||
@@ -168,7 +171,7 @@ public class QLSupport {
|
||||
* @throws QueryException if query is invalid
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public <A extends Enum<A> & QueryField> void validateQuery(final String query, final Class<A> queryFieldType, final Class<?> jpaType) {
|
||||
public <A extends Enum<A> & QueryField> void validate(final String query, final Class<A> queryFieldType, final Class<?> jpaType) {
|
||||
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
||||
final CriteriaQuery<?> criteriaQuery = criteriaBuilder.createQuery(jpaType);
|
||||
buildSpec(query, queryFieldType).toPredicate(criteriaQuery.from((Class) jpaType), criteriaQuery, criteriaBuilder);
|
||||
|
||||
@@ -50,14 +50,14 @@ public class SpecificationBuilderLegacy<A extends Enum<A> & QueryField, T> {
|
||||
|
||||
public Specification<T> specification(final String rsql) {
|
||||
return (root, query, cb) -> {
|
||||
final QLSupport rsqlUtility = QLSupport.getInstance();
|
||||
final QLSupport qlSupport = QLSupport.getInstance();
|
||||
|
||||
final Node rootNode = parseRsql(rsql, rsqlUtility);
|
||||
final Node rootNode = parseRsql(rsql, qlSupport);
|
||||
query.distinct(true);
|
||||
|
||||
final boolean ensureIgnoreCase = !rsqlUtility.isCaseInsensitiveDB() && rsqlUtility.isIgnoreCase();
|
||||
final boolean ensureIgnoreCase = !qlSupport.isCaseInsensitiveDB() && qlSupport.isIgnoreCase();
|
||||
final RSQLVisitor<List<Predicate>, String> jpqQueryRSQLVisitor =
|
||||
rsqlUtility.getSpecBuilder() == LEGACY_G1
|
||||
qlSupport.getSpecBuilder() == LEGACY_G1
|
||||
? new JpaQueryRsqlVisitor<>(root, cb, rsqlQueryFieldType, virtualPropertyReplacer, database, query, ensureIgnoreCase)
|
||||
: new JpaQueryRsqlVisitorG2<>(rsqlQueryFieldType, root, query, cb, database, virtualPropertyReplacer, ensureIgnoreCase);
|
||||
final List<Predicate> accept = rootNode.accept(jpqQueryRSQLVisitor);
|
||||
|
||||
@@ -553,7 +553,7 @@ class SpecificationBuilderTest {
|
||||
|
||||
private List<Root> filter(final String rsql) {
|
||||
// reference / auto filter (using elements and reflection)
|
||||
final EntityMatcher matcher = EntityMatcher.forRsql(rsql);
|
||||
final EntityMatcher matcher = EntityMatcher.of(RsqlParser.parse(rsql));
|
||||
final List<Root> refResult = StreamSupport.stream(rootRepository.findAll().spliterator(), false).filter(matcher::match).toList();
|
||||
final List<Root> result = rootRepository.findAll(getSpecification(rsql));
|
||||
// auto check with reference result
|
||||
|
||||
Reference in New Issue
Block a user