
io.github.perplexhub.rsql.RSQLJPASupport Maven / Gradle / Ivy
package io.github.perplexhub.rsql;
import java.util.*;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import cz.jirutka.rsql.parser.RSQLParser;
import cz.jirutka.rsql.parser.ast.ComparisonOperator;
import cz.jirutka.rsql.parser.ast.Node;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@SuppressWarnings({ "serial" })
public class RSQLJPASupport extends RSQLCommonSupport {
public RSQLJPASupport() {
super();
}
public RSQLJPASupport(Map entityManagerMap) {
super(entityManagerMap);
}
public static Specification rsql(final String rsqlQuery) {
return toSpecification(rsqlQuery, false, null);
}
public static Specification rsql(final String rsqlQuery, final boolean distinct) {
return toSpecification(rsqlQuery, distinct, null);
}
public static Specification rsql(final String rsqlQuery, final Map propertyPathMapper) {
return toSpecification(rsqlQuery, false, propertyPathMapper);
}
public static Specification rsql(final String rsqlQuery, final boolean distinct, final Map propertyPathMapper) {
return toSpecification(rsqlQuery, distinct, propertyPathMapper);
}
public static Specification rsql(final String rsqlQuery, final List> customPredicates) {
return toSpecification(rsqlQuery, customPredicates);
}
public static Specification toSpecification(final String rsqlQuery) {
return toSpecification(rsqlQuery, false, null);
}
public static Specification toSpecification(final String rsqlQuery, final Map propertyPathMapper) {
return toSpecification(rsqlQuery, false, propertyPathMapper);
}
public static Specification toSpecification(final String rsqlQuery, final boolean distinct) {
return toSpecification(rsqlQuery, distinct, null);
}
public static Specification toSpecification(final String rsqlQuery, final boolean distinct, final Map propertyPathMapper) {
return toSpecification(rsqlQuery, distinct, propertyPathMapper, null);
}
public static Specification toSpecification(final String rsqlQuery, final List> customPredicates) {
return toSpecification(rsqlQuery, false, null, customPredicates);
}
public static Specification toSpecification(final String rsqlQuery, final boolean distinct, final Map propertyPathMapper, final List> customPredicates) {
log.debug("toSpecification({},distinct:{},propertyPathMapper:{})", rsqlQuery, distinct, propertyPathMapper);
return new Specification() {
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) {
query.distinct(distinct);
if (StringUtils.hasText(rsqlQuery)) {
Set supportedOperators = RSQLOperators.supportedOperators();
if (customPredicates != null) {
supportedOperators.addAll(customPredicates.stream().map(RSQLCustomPredicate::getOperator).filter(Objects::nonNull).collect(Collectors.toSet()));
}
Node rsql = new RSQLParser(supportedOperators).parse(rsqlQuery);
return rsql.accept(new RSQLJPAPredicateConverter(cb, propertyPathMapper, customPredicates), root);
} else
return null;
}
};
}
/**
* Returns a single entity matching the given {@link Specification} or {@link Optional#empty()} if none found.
*
* @param jpaSpecificationExecutor JPA repository
* @param rsqlQuery can be {@literal null}.
* @return never {@literal null}.
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one entity found.
*/
public static Optional> findOne(JpaSpecificationExecutor> jpaSpecificationExecutor, @Nullable String rsqlQuery) {
return jpaSpecificationExecutor.findOne(toSpecification(rsqlQuery));
}
/**
* Returns all entities matching the given {@link Specification}.
*
* @param jpaSpecificationExecutor JPA repository
* @param rsqlQuery can be {@literal null}.
* @return never {@literal null}.
*/
public static List> findAll(JpaSpecificationExecutor> jpaSpecificationExecutor, @Nullable String rsqlQuery) {
return jpaSpecificationExecutor.findAll(toSpecification(rsqlQuery));
}
/**
* Returns a {@link Page} of entities matching the given {@link Specification}.
*
* @param jpaSpecificationExecutor JPA repository
* @param rsqlQuery can be {@literal null}.
* @param pageable must not be {@literal null}.
* @return never {@literal null}.
*/
public static Page> findAll(JpaSpecificationExecutor> jpaSpecificationExecutor, @Nullable String rsqlQuery, Pageable pageable) {
return jpaSpecificationExecutor.findAll(toSpecification(rsqlQuery), pageable);
}
/**
* Returns all entities matching the given {@link Specification} and {@link Sort}.
*
* @param jpaSpecificationExecutor JPA repository
* @param rsqlQuery can be {@literal null}.
* @param sort must not be {@literal null}.
* @return never {@literal null}.
*/
public static List> findAll(JpaSpecificationExecutor> jpaSpecificationExecutor, @Nullable String rsqlQuery, Sort sort) {
return jpaSpecificationExecutor.findAll(toSpecification(rsqlQuery), sort);
}
/**
* Returns all entities matching the given {@link Specification} and {@link Sort}.
*
* @param jpaSpecificationExecutor JPA repository
* @param rsqlQuery can be {@literal null}.
* @param sort can be {@literal null}, comma delimited.
* @return never {@literal null}.
*/
public static List> findAll(JpaSpecificationExecutor> jpaSpecificationExecutor, @Nullable String rsqlQuery, @Nullable String sort) {
return StringUtils.hasText(sort)
? jpaSpecificationExecutor.findAll(toSpecification(rsqlQuery), Sort.by(Direction.ASC, StringUtils.commaDelimitedListToStringArray(sort)))
: jpaSpecificationExecutor.findAll(toSpecification(rsqlQuery));
}
/**
* Returns the number of instances that the given {@link Specification} will return.
*
* @param jpaSpecificationExecutor JPA repository
* @param rsqlQuery the {@link Specification} to count instances for. Can be {@literal null}.
* @return the number of instances.
*/
public static long count(JpaSpecificationExecutor> jpaSpecificationExecutor, @Nullable String rsqlQuery) {
return jpaSpecificationExecutor.count(toSpecification(rsqlQuery));
}
protected String getVersion() {
try {
Properties prop = new Properties();
prop.load(getClass().getResourceAsStream("/META-INF/maven/io.github.perplexhub/rsql-jpa/pom.properties"));
String version = prop.getProperty("version");
return StringUtils.hasText(version) ? "[" + version + "] " : "";
} catch (Exception e) {
return "";
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy