com.ksoot.common.spring.boot.pagination.PaginatedResourceAssembler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-boot-commons Show documentation
Show all versions of spring-boot-commons Show documentation
Commons Spring boot components and Utilities
The newest version!
package com.ksoot.common.spring.boot.pagination;
import static org.springframework.web.util.UriComponentsBuilder.fromUri;
import java.util.List;
import java.util.function.Function;
import lombok.NonNull;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.data.web.HateoasPageableHandlerMethodArgumentResolver;
import org.springframework.hateoas.IanaLinkRelations;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkRelation;
import org.springframework.hateoas.UriTemplate;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponentsBuilder;
public class PaginatedResourceAssembler {
public static final String PAGE_MUST_NOT_BE_NULL = "Page must not be null!";
public static final String PAGE_CONTENT_MUST_NOT_BE_NULL = "Page Content must not be null!";
public static final String PAGEABLE_MUST_NOT_BE_NULL = "Pageable must not be null!";
public static final String PAGE_TRANSFORMER_MUST_NOT_BE_NULL =
"'pageTransformer' must not be null!";
private static final boolean FORCE_FIRST_AND_LAST_RELS = false;
@NonNull private static HateoasPageableHandlerMethodArgumentResolver pageableResolver;
public PaginatedResourceAssembler(
@Nullable final HateoasPageableHandlerMethodArgumentResolver resolver) {
PaginatedResourceAssembler.pageableResolver =
resolver == null ? new HateoasPageableHandlerMethodArgumentResolver() : resolver;
}
/**
* Use in case of non reactive web application, base URL can be automatically determined from
* ServletUriComponentsBuilder
*
* @param Class of the content of page
* @param content Page data
* @param pageRequest Requested Page
* @param totalRecords Total number of records
* @return PaginatedResource
*/
public static PaginatedResource assemble(
final List content, final Pageable pageRequest, final long totalRecords) {
return assemble(new PageImpl(content, pageRequest, totalRecords), getUriTemplate());
}
public static PaginatedResource assemble(
final List content,
final Pageable pageRequest,
final long totalRecords,
final Function, List> pageTransformer) {
final Page newPage =
PageableExecutionUtils.getPage(
pageTransformer.apply(content), pageRequest, () -> totalRecords);
return assemble(newPage, getUriTemplate());
}
/**
* Use in case of non reactive web application, base URL can be automatically determined from
* ServletUriComponentsBuilder
*
* @param Class of the content of page
* @param page Requested Page
* @return PaginatedResource
*/
public static PaginatedResource assemble(final Page page) {
Assert.notNull(page, PAGE_MUST_NOT_BE_NULL);
Assert.notNull(page.getContent(), PAGE_CONTENT_MUST_NOT_BE_NULL);
Assert.notNull(page.getPageable(), PAGEABLE_MUST_NOT_BE_NULL);
final PaginatedResource paginatedResource = new PaginatedResource<>(page);
addPaginationLinks(paginatedResource, page, getUriTemplate());
return paginatedResource;
}
public static PaginatedResource assemble(
final Page page, final Function, List> pageTransformer) {
Assert.notNull(page, PAGE_MUST_NOT_BE_NULL);
Assert.notNull(page.getContent(), PAGE_CONTENT_MUST_NOT_BE_NULL);
Assert.notNull(page.getPageable(), PAGEABLE_MUST_NOT_BE_NULL);
Assert.notNull(pageTransformer, PAGE_TRANSFORMER_MUST_NOT_BE_NULL);
final Page newPage =
PageableExecutionUtils.getPage(
pageTransformer.apply(page.getContent()), page.getPageable(), page::getTotalElements);
final PaginatedResource paginatedResource = new PaginatedResource<>(newPage);
addPaginationLinks(paginatedResource, newPage, getUriTemplate());
return paginatedResource;
}
private static PaginatedResource assemble(final Page page, final UriTemplate base) {
Assert.notNull(page, PAGE_MUST_NOT_BE_NULL);
Assert.notNull(page.getContent(), PAGE_CONTENT_MUST_NOT_BE_NULL);
Assert.notNull(page.getPageable(), PAGEABLE_MUST_NOT_BE_NULL);
final PaginatedResource paginatedResource = new PaginatedResource<>(page);
addPaginationLinks(paginatedResource, page, base);
return paginatedResource;
}
private static void addPaginationLinks(
final PaginatedResource paginatedResource, final Page page, final UriTemplate base) {
final boolean isNavigable = page.hasPrevious() || page.hasNext();
final Link selfLink = createLink(base, page.getPageable(), IanaLinkRelations.SELF);
paginatedResource.getMetadata().add(selfLink);
if (page.hasPrevious()) {
paginatedResource
.getMetadata()
.add(createLink(base, page.previousPageable(), IanaLinkRelations.PREV));
}
if (page.hasNext()) {
paginatedResource
.getMetadata()
.add(createLink(base, page.nextPageable(), IanaLinkRelations.NEXT));
}
if (isNavigable || FORCE_FIRST_AND_LAST_RELS) {
paginatedResource
.getMetadata()
.add(
createLink(
base,
PageRequest.of(0, page.getSize(), page.getSort()),
IanaLinkRelations.FIRST));
}
if (isNavigable || FORCE_FIRST_AND_LAST_RELS) {
final int lastIndex = page.getTotalPages() == 0 ? 0 : page.getTotalPages() - 1;
paginatedResource
.getMetadata()
.add(
createLink(
base,
PageRequest.of(lastIndex, page.getSize(), page.getSort()),
IanaLinkRelations.LAST));
}
}
private static Link createLink(
final UriTemplate base, final Pageable pageable, final LinkRelation relation) {
final UriComponentsBuilder builder = fromUri(base.expand());
pageableResolver.enhance(builder, null, pageable);
return Link.of(UriTemplate.of(builder.build().toString()), relation);
}
private static UriTemplate getUriTemplate() {
return UriTemplate.of(currentRequest());
}
// Work in case of Servlet web application, in case of Reactive web application throws
// NullPointerException
private static String currentRequest() {
return ServletUriComponentsBuilder.fromCurrentRequest().build().toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy