use of com.blazebit.persistence.DefaultKeyset in project blaze-persistence by Blazebit.
the class KeysetPageableHandlerMethodArgumentResolver method resolveArgument.
@Override
public Mono<Object> resolveArgument(MethodParameter methodParameter, BindingContext bindingContext, ServerWebExchange serverWebExchange) {
assertPageableUniqueness(methodParameter);
Pageable defaultOrFallback = getDefaultFromAnnotationOrFallback(methodParameter);
String pageString = serverWebExchange.getRequest().getQueryParams().getFirst(getParameterNameToUse(getPageParameterName(), methodParameter));
String offsetString = serverWebExchange.getRequest().getQueryParams().getFirst(getParameterNameToUse(getOffsetParameterName(), methodParameter));
String pageSizeString = serverWebExchange.getRequest().getQueryParams().getFirst(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 = (org.springframework.data.domain.Sort) sortResolver.resolveArgument(methodParameter, bindingContext, serverWebExchange).block();
// 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 = serverWebExchange.getRequest().getQueryParams().getFirst(previousOffsetName);
String previousPageName = getParameterName(keysetConfig.previousPageName(), getParameterNameToUse(getPreviousPageParameterName(), methodParameter));
String previousPageString = serverWebExchange.getRequest().getQueryParams().getFirst(previousPageName);
if (StringUtils.hasText(previousOffsetString) || StringUtils.hasText(previousPageString)) {
String previousPageSizeName = getParameterName(keysetConfig.previousPageSizeName(), getParameterNameToUse(getPreviousSizeParameterName(), methodParameter));
String previousPageSizeString = serverWebExchange.getRequest().getQueryParams().getFirst(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 = serverWebExchange.getRequest().getQueryParams().getFirst(lowestName);
String highestName = getParameterName(keysetConfig.highestName(), getParameterNameToUse(getHighestParameterName(), methodParameter));
String highestString = serverWebExchange.getRequest().getQueryParams().getFirst(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 Mono.just(new KeysetPageRequest(keysetPage, sort, offset, pageSize));
}
use of com.blazebit.persistence.DefaultKeyset in project blaze-persistence by Blazebit.
the class GraphQLEntityViewSupport method extractKeysetPage.
/**
* Extracts the {@link KeysetPage} from the page size and offset,
* as well as deserializing before or after cursors.
*
* @param first The GraphQL relay first parameter
* @param last The GraphQL relay last parameter
* @param beforeCursor The GraphQL relay before cursor
* @param afterCursor The GraphQL relay after cursor
* @return the {@link KeysetPage} or <code>null</code>
*/
public KeysetPage extractKeysetPage(Integer first, Integer last, String beforeCursor, String afterCursor) {
if (first == null && last == null && beforeCursor == null && afterCursor == null) {
return null;
} else {
KeysetPage keysetPage;
if (beforeCursor != null) {
if (afterCursor != null) {
throw new RuntimeException("Can't provide both beforeCursor and afterCursor!");
}
GraphQLCursor cursor = deserialize(beforeCursor);
keysetPage = new DefaultKeysetPage(cursor.getOffset(), cursor.getPageSize(), new DefaultKeyset(cursor.getTuple()), null);
} else if (afterCursor != null) {
if (last != null) {
// Using an after cursor with last does not make sense, so skip using the cursor
// The only problem with that is, that the cursor could refer to the last element
// If that is the case, we would still get a result, which is IMO an edge case and can be ignored
keysetPage = new DefaultKeysetPage(0, last, new DefaultKeyset(null), null);
} else {
GraphQLCursor cursor = deserialize(afterCursor);
keysetPage = new DefaultKeysetPage(cursor.getOffset(), cursor.getPageSize(), null, new DefaultKeyset(cursor.getTuple()));
}
} else if (first != null) {
keysetPage = new DefaultKeysetPage(0, first, null, null);
} else {
// Keyset with empty tuple is a special case for traversing the result list in reverse order
keysetPage = new DefaultKeysetPage(0, last, new DefaultKeyset(null), null);
}
return keysetPage;
}
}
use of com.blazebit.persistence.DefaultKeyset in project blaze-persistence by Blazebit.
the class LazyKeysetLink method initialize.
@Override
public void initialize(List<OrderByExpression> orderByExpressions) {
Serializable[] tuple = new Serializable[orderByExpressions.size()];
for (int i = 0; i < tuple.length; i++) {
String expressionString = orderByExpressions.get(0).getExpression().toString();
Object value = keysetValues.get(expressionString);
if (value == null) {
if (!keysetValues.containsKey(expressionString)) {
throw new IllegalArgumentException("The keyset provided [" + keysetValues + "] does not contain an entry for the order by expression: " + expressionString);
}
tuple[i] = null;
} else {
if (!(value instanceof Serializable)) {
throw new IllegalArgumentException("The keyset value [" + value + "] provided for the order by expression [" + expressionString + "] is not an instance of java.io.Serializable!");
}
tuple[i] = (Serializable) value;
}
}
keyset = new DefaultKeyset(tuple);
validate(keyset, orderByExpressions);
}
use of com.blazebit.persistence.DefaultKeyset in project blaze-persistence by Blazebit.
the class KeysetPageableParamConverter method fromString.
@Override
public Pageable fromString(String value) {
MultivaluedMap<String, String> queryParameters = requestUriInfo.getQueryParameters();
Pageable defaultOrFallback = pageableConfiguration.getFallbackPageable();
String offsetString = queryParameters.getFirst(pageableConfiguration.getPrefix() + pageableConfiguration.getOffsetParameterName());
String pageString = queryParameters.getFirst(pageableConfiguration.getPrefix() + pageableConfiguration.getPageParameterName());
String pageSizeString = queryParameters.getFirst(pageableConfiguration.getPrefix() + pageableConfiguration.getSizeParameterName());
boolean pageAndSizeGiven = (!StringUtils.isEmpty(pageString) || !StringUtils.isEmpty(offsetString)) && !StringUtils.isEmpty(pageSizeString);
if (!pageAndSizeGiven && defaultOrFallback == null) {
return null;
}
int maxPageSize = pageableConfiguration.getMaxPageSize();
int pageSize = !StringUtils.isEmpty(pageSizeString) ? parseAndApplyBoundaries(pageSizeString, maxPageSize, false) : defaultOrFallback.getPageSize();
// Limit lower bound
pageSize = pageSize < 1 ? defaultOrFallback.getPageSize() : pageSize;
// Limit upper bound
pageSize = pageSize > maxPageSize ? maxPageSize : pageSize;
int offset;
if (!StringUtils.isEmpty(offsetString)) {
offset = parseAndApplyBoundaries(pageString, Integer.MAX_VALUE, false);
} else if (!StringUtils.isEmpty(pageString)) {
offset = pageSize * parseAndApplyBoundaries(pageString, Integer.MAX_VALUE, true);
} else {
offset = pageSize * defaultOrFallback.getPageNumber();
}
Sort sort = resolveSort(queryParameters.get(pageableConfiguration.getSortParameterName()));
// Default if necessary and default configured
sort = sort == null && defaultOrFallback != null ? defaultOrFallback.getSort() : sort;
KeysetPage keysetPage = null;
Iterator<Sort.Order> iterator;
if (keysetClass != null) {
if (sort != null && (iterator = sort.iterator()).hasNext()) {
String previousOffsetString = queryParameters.getFirst(keysetPageableConfiguration.getPrefix() + keysetPageableConfiguration.getPreviousOffsetParameterName());
String previousPageString = queryParameters.getFirst(keysetPageableConfiguration.getPrefix() + keysetPageableConfiguration.getPreviousPageParameterName());
if (!StringUtils.isEmpty(previousOffsetString) || !StringUtils.isEmpty(previousPageString)) {
String previousPageSizeString = queryParameters.getFirst(keysetPageableConfiguration.getPrefix() + keysetPageableConfiguration.getPreviousSizeParameterName());
int previousPageSize = StringUtils.isEmpty(previousPageSizeString) ? pageSize : parseAndApplyBoundaries(previousPageSizeString, maxPageSize, false);
int previousOffset;
if (!StringUtils.isEmpty(previousOffsetString)) {
previousOffset = parseAndApplyBoundaries(previousOffsetString, Integer.MAX_VALUE, false);
} else {
int previousPage = parseAndApplyBoundaries(previousPageString, Integer.MAX_VALUE, true);
previousOffset = previousPage * previousPageSize;
}
String lowestString = queryParameters.getFirst(keysetPageableConfiguration.getPrefix() + keysetPageableConfiguration.getLowestParameterName());
String highestString = queryParameters.getFirst(keysetPageableConfiguration.getPrefix() + keysetPageableConfiguration.getHighestParameterName());
if (!StringUtils.isEmpty(lowestString) && !StringUtils.isEmpty(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()) {
Sort.Order o = iterator.next();
JsonNode low = lowestObject;
JsonNode high = highestObject;
String[] propertyParts = o.getPath().split("\\.");
Class<? extends Serializable> propertyType = getPropertyType(keysetClass, o.getPath());
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);
}
return new PageRequest(sort, offset, pageSize);
}
use of com.blazebit.persistence.DefaultKeyset 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