Skip to content
Snippets Groups Projects

feat: Create pagination annotation

6 unresolved threads
Files
2
@@ -6,12 +6,14 @@
@@ -6,12 +6,14 @@
* which is available at https://www.eclipse.org/legal/epl-2.0/
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
*
* Author: Martin Lowe <martin.lowe@eclipse-foundation.org>
* Author: Martin Lowe <martin.lowe@eclipse-foundation.org>
 
* Zachary Sabourin <zachary.sabourin@eclipse-foundation.org>
*
*
* SPDX-License-Identifier: EPL-2.0
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
**********************************************************************/
package org.eclipsefoundation.core.response;
package org.eclipsefoundation.core.response;
import java.io.IOException;
import java.io.IOException;
 
import java.lang.reflect.Method;
import java.util.List;
import java.util.List;
import java.util.Set;
import java.util.Set;
import java.util.TreeSet;
import java.util.TreeSet;
@@ -23,6 +25,7 @@ import javax.servlet.http.HttpServletResponse;
@@ -23,6 +25,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.ContainerResponseFilter;
 
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriBuilder;
@@ -39,11 +42,13 @@ import org.slf4j.Logger;
@@ -39,11 +42,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.LoggerFactory;
/**
/**
* Adds pagination and Link headers to the response by slicing the response entity if its a list entity. This will not
* Adds pagination and Link headers to the response by slicing the response
 
* entity if its a list entity. This will not
* dig into complex entities to avoid false positives.
* dig into complex entities to avoid false positives.
*
*
* @author Martin Lowe
* @author Martin Lowe
*/
*/
 
@Provider
@Provider
@Priority(5)
@Priority(5)
public class PaginatedResultsFilter implements ContainerResponseFilter {
public class PaginatedResultsFilter implements ContainerResponseFilter {
@@ -69,12 +74,19 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
@@ -69,12 +74,19 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
@Context
@Context
HttpServletResponse response;
HttpServletResponse response;
 
@Context
 
ResourceInfo resourceInfo;
@Override
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
throws IOException {
if (enablePagination.get()) {
 
Method method = resourceInfo.getResourceMethod();
 
Pagination annotation = method.getAnnotation(Pagination.class);
 
 
if ((annotation == null || annotation.value()) && enablePagination.get()) {
Object entity = responseContext.getEntity();
Object entity = responseContext.getEntity();
 
// only try and paginate if there are multiple entities
// only try and paginate if there are multiple entities
if (entity instanceof Set) {
if (entity instanceof Set) {
paginateResults(responseContext,
paginateResults(responseContext,
@@ -108,10 +120,11 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
@@ -108,10 +120,11 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
}
}
/**
/**
* Gets a header value if available, checking first the servlet response then the mutable response wrapper.
* Gets a header value if available, checking first the servlet response then
 
* the mutable response wrapper.
*
*
* @param responseContext the mutable response wrapper
* @param responseContext the mutable response wrapper
* @param headerName the header to retrieve
* @param headerName the header to retrieve
* @return the header value if set, null otherwise.
* @return the header value if set, null otherwise.
*/
*/
private String getResponseHeader(ContainerResponseContext responseContext, String headerName) {
private String getResponseHeader(ContainerResponseContext responseContext, String headerName) {
@@ -142,10 +155,13 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
@@ -142,10 +155,13 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
}
}
/**
/**
* Gets the current requested page, rounding down to max if larger than the max page number, and up if below 1.
* Gets the current requested page, rounding down to max if larger than the max
 
* page number, and up if below 1.
*
*
* @param listEntity list entity used to determine the number of pages present for current call.
* @param listEntity list entity used to determine the number of pages present
* @return the current page number if set, the last page if greater, or 1 if not set or negative.
* for current call.
 
* @return the current page number if set, the last page if greater, or 1 if not
 
* set or negative.
*/
*/
private int getRequestedPage(int maxSize, int pageSize) {
private int getRequestedPage(int maxSize, int pageSize) {
MultivaluedMap<String, String> params = getUriInfo().getQueryParameters();
MultivaluedMap<String, String> params = getUriInfo().getQueryParameters();
@@ -167,7 +183,8 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
@@ -167,7 +183,8 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
}
}
/**
/**
* Allows for external bindings to affect the current page size, defaulting to the internal set configuration.
* Allows for external bindings to affect the current page size, defaulting to
 
* the internal set configuration.
*
*
* @param responseContext
* @param responseContext
* @return
* @return
@@ -185,7 +202,8 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
@@ -185,7 +202,8 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
}
}
/**
/**
* Returns the max page size as defined by internal metrics (ignoring pagesize params).
* Returns the max page size as defined by internal metrics (ignoring pagesize
 
* params).
*
*
* @return the internal max page size.
* @return the internal max page size.
*/
*/
@@ -201,11 +219,12 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
@@ -201,11 +219,12 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
}
}
/**
/**
* Builds an href for a paginated link using the BaseUri UriBuilder from the UriInfo object, replacing just the page
* Builds an href for a paginated link using the BaseUri UriBuilder from the
 
* UriInfo object, replacing just the page
* query parameter.
* query parameter.
*
*
* @param builder base URI builder from the UriInfo object.
* @param builder base URI builder from the UriInfo object.
* @param page the page to link to in the returned link
* @param page the page to link to in the returned link
* @return fully qualified HREF for the paginated results
* @return fully qualified HREF for the paginated results
*/
*/
private String buildHref(UriBuilder builder, int page) {
private String buildHref(UriBuilder builder, int page) {
@@ -219,9 +238,10 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
@@ -219,9 +238,10 @@ public class PaginatedResultsFilter implements ContainerResponseFilter {
* Gets an int bound by the size of a list.
* Gets an int bound by the size of a list.
*
*
* @param list the list to bind the number by
* @param list the list to bind the number by
* @param num the number to check for exceeding bounds.
* @param num the number to check for exceeding bounds.
* @return the passed number if its within the size of the given array, 0 if the number is negative, and the array
* @return the passed number if its within the size of the given array, 0 if the
* size if greater than the maximum bounds.
* number is negative, and the array
 
* size if greater than the maximum bounds.
*/
*/
private int getArrayLimitedNumber(List<?> list, int num) {
private int getArrayLimitedNumber(List<?> list, int num) {
return Math.min(list.size(), Math.max(0, num));
return Math.min(list.size(), Math.max(0, num));
Loading