use of com.blazebit.persistence.spring.data.repository.KeysetPageable in project blaze-persistence by Blazebit.
the class AbstractEntityViewAwareRepository method getQuery.
protected <S extends E> TypedQuery<V> getQuery(Specification<S> spec, Class<S> domainClass, Pageable pageable, Sort sort) {
BlazeCriteriaQuery<S> cq = BlazeCriteria.get(cbf, domainClass);
Root<S> root = this.applySpecificationToCriteria(spec, domainClass, cq);
Class<V> entityViewClass = metadata == null || metadata.getEntityViewClass() == null ? this.entityViewClass : (Class<V>) metadata.getEntityViewClass();
if (sort != null && entityViewClass == null) {
cq.orderBy(QueryUtils.toOrders(sort, root, BlazeCriteria.get(cbf)));
}
CriteriaBuilder<S> cb = cq.createCriteriaBuilder(entityManager);
String[] fetches = EMPTY;
if (metadata != null && metadata.getEntityGraph() != null && (fetches = metadata.getEntityGraph().attributePaths()).length != 0) {
cb.fetch(fetches);
}
boolean withCountQuery = true;
boolean withKeysetExtraction = false;
boolean withExtractAllKeysets = false;
TypedQuery<V> query;
if (entityViewClass == null) {
if (pageable == null) {
query = (TypedQuery<V>) cb.getQuery();
} else {
PaginatedCriteriaBuilder<S> paginatedCriteriaBuilder;
if (pageable instanceof KeysetPageable) {
KeysetPageable keysetPageable = (KeysetPageable) pageable;
paginatedCriteriaBuilder = cb.page(keysetPageable.getKeysetPage(), getOffset(pageable), pageable.getPageSize());
withCountQuery = keysetPageable.isWithCountQuery();
withKeysetExtraction = true;
withExtractAllKeysets = keysetPageable.isWithExtractAllKeysets();
} else {
paginatedCriteriaBuilder = cb.page(getOffset(pageable), pageable.getPageSize());
}
if (withKeysetExtraction) {
paginatedCriteriaBuilder.withKeysetExtraction(true);
paginatedCriteriaBuilder.withExtractAllKeysets(withExtractAllKeysets);
}
paginatedCriteriaBuilder.withCountQuery(withCountQuery);
query = (TypedQuery<V>) paginatedCriteriaBuilder.getQuery();
}
} else {
if (pageable == null) {
EntityViewSetting<V, CriteriaBuilder<V>> setting = EntityViewSetting.create(entityViewClass);
CriteriaBuilder<V> fqb = evm.applySetting(setting, cb);
if (sort != null) {
EntityViewSortUtil.applySort(evm, entityViewClass, fqb, sort);
}
query = fqb.getQuery();
} else {
EntityViewSetting<V, PaginatedCriteriaBuilder<V>> setting = EntityViewSetting.create(entityViewClass, getOffset(pageable), pageable.getPageSize());
if (pageable instanceof KeysetPageable) {
KeysetPageable keysetPageable = (KeysetPageable) pageable;
setting.withKeysetPage(keysetPageable.getKeysetPage());
withCountQuery = keysetPageable.isWithCountQuery();
withKeysetExtraction = true;
withExtractAllKeysets = keysetPageable.isWithExtractAllKeysets();
}
PaginatedCriteriaBuilder<V> paginatedCriteriaBuilder = evm.applySetting(setting, cb);
if (withKeysetExtraction) {
paginatedCriteriaBuilder.withKeysetExtraction(true);
paginatedCriteriaBuilder.withExtractAllKeysets(withExtractAllKeysets);
}
paginatedCriteriaBuilder.withCountQuery(withCountQuery);
if (sort != null || (sort = pageable.getSort()) != null) {
EntityViewSortUtil.applySort(evm, entityViewClass, paginatedCriteriaBuilder, sort);
}
query = paginatedCriteriaBuilder.getQuery();
}
}
return this.applyRepositoryMethodMetadata(query, fetches.length == 0);
}
use of com.blazebit.persistence.spring.data.repository.KeysetPageable in project blaze-persistence by Blazebit.
the class KeysetPageableHandlerMethodArgumentResolver method resolveArgument.
@Override
public KeysetPageable resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
assertPageableUniqueness(methodParameter);
Pageable defaultOrFallback = getDefaultFromAnnotationOrFallback(methodParameter);
String pageString = webRequest.getParameter(getParameterNameToUse(getPageParameterName(), methodParameter));
String offsetString = webRequest.getParameter(getParameterNameToUse(getOffsetParameterName(), methodParameter));
String pageSizeString = webRequest.getParameter(getParameterNameToUse(getSizeParameterName(), methodParameter));
boolean pageAndSizeGiven = (StringUtils.hasText(pageString) || StringUtils.hasText(offsetString)) && StringUtils.hasText(pageSizeString);
if (!pageAndSizeGiven && defaultOrFallback == null) {
return null;
}
int pageSize = StringUtils.hasText(pageSizeString) ? parseAndApplyBoundaries(pageSizeString, getMaxPageSize(), false) : defaultOrFallback.getPageSize();
// Limit lower bound
pageSize = pageSize < 1 ? defaultOrFallback.getPageSize() : pageSize;
// Limit upper bound
pageSize = pageSize > getMaxPageSize() ? getMaxPageSize() : pageSize;
int offset;
if (StringUtils.hasText(offsetString)) {
offset = parseAndApplyBoundaries(offsetString, Integer.MAX_VALUE, false);
} else if (StringUtils.hasText(pageString)) {
offset = pageSize * parseAndApplyBoundaries(pageString, Integer.MAX_VALUE, true);
} else {
offset = pageSize * defaultOrFallback.getPageNumber();
}
org.springframework.data.domain.Sort sort = sortResolver.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
// Default if necessary and default configured
sort = sort == UNSORTED && defaultOrFallback != null ? defaultOrFallback.getSort() : sort;
KeysetPage keysetPage = null;
Iterator<org.springframework.data.domain.Sort.Order> iterator;
if (sort != null && (iterator = sort.iterator()).hasNext()) {
KeysetConfig keysetConfig = methodParameter.getParameterAnnotation(KeysetConfig.class);
Class<?> domainClass = keysetConfig.keysetClass();
if (domainClass == void.class) {
domainClass = keysetConfig.value();
}
if (domainClass == void.class) {
Method annotatedMethod = methodParameter.getMethod();
throw new IllegalStateException(String.format(INVALID_KEYSET_DOMAIN_CLASS, annotatedMethod));
}
String previousOffsetName = getParameterName(keysetConfig.previousOffsetName(), getParameterNameToUse(getPreviousOffsetParameterName(), methodParameter));
String previousOffsetString = webRequest.getParameter(previousOffsetName);
String previousPageName = getParameterName(keysetConfig.previousPageName(), getParameterNameToUse(getPreviousPageParameterName(), methodParameter));
String previousPageString = webRequest.getParameter(previousPageName);
if (StringUtils.hasText(previousOffsetString) || StringUtils.hasText(previousPageString)) {
String previousPageSizeName = getParameterName(keysetConfig.previousPageSizeName(), getParameterNameToUse(getPreviousSizeParameterName(), methodParameter));
String previousPageSizeString = webRequest.getParameter(previousPageSizeName);
int previousPageSize = StringUtils.hasText(previousPageSizeString) ? parseAndApplyBoundaries(previousPageSizeString, getMaxPageSize(), false) : pageSize;
int previousOffset;
if (StringUtils.hasText(previousOffsetString)) {
previousOffset = parseAndApplyBoundaries(previousOffsetString, Integer.MAX_VALUE, false);
} else {
int previousPage = parseAndApplyBoundaries(previousPageString, Integer.MAX_VALUE, true);
previousOffset = previousPage * previousPageSize;
}
String lowestName = getParameterName(keysetConfig.lowestName(), getParameterNameToUse(getLowestParameterName(), methodParameter));
String lowestString = webRequest.getParameter(lowestName);
String highestName = getParameterName(keysetConfig.highestName(), getParameterNameToUse(getHighestParameterName(), methodParameter));
String highestString = webRequest.getParameter(highestName);
if (StringUtils.hasText(lowestString) && StringUtils.hasText(highestString)) {
List<Serializable> lowest = new ArrayList<>();
List<Serializable> highest = new ArrayList<>();
JsonNode lowestObject;
JsonNode highestObject;
try {
lowestObject = mapper.readTree(lowestString);
} catch (IOException ex) {
throw new IllegalArgumentException("Invalid lowest object!", ex);
}
try {
highestObject = mapper.readTree(highestString);
} catch (IOException ex) {
throw new IllegalArgumentException("Invalid highest object!", ex);
}
while (iterator.hasNext()) {
org.springframework.data.domain.Sort.Order o = iterator.next();
JsonNode low = lowestObject;
JsonNode high = highestObject;
String[] propertyParts = o.getProperty().split("\\.");
Class<? extends Serializable> propertyType = getPropertyType(domainClass, o.getProperty());
for (int i = 0; i < propertyParts.length; i++) {
low = low == null ? null : low.get(propertyParts[i]);
high = high == null ? null : high.get(propertyParts[i]);
}
lowest.add(low == null ? null : convert(low, propertyType));
highest.add(high == null ? null : convert(high, propertyType));
}
keysetPage = new DefaultKeysetPage(previousOffset, previousPageSize, new DefaultKeyset(lowest.toArray(new Serializable[lowest.size()])), new DefaultKeyset(highest.toArray(new Serializable[highest.size()])));
}
}
}
return new KeysetPageRequest(keysetPage, sort, offset, pageSize);
}
Aggregations