[New] Rewrote the Paging class to use offset/limit
Also returns next, previous and last offsets. Added helper method to create a REST Response from a page in ResponseUtil
This commit is contained in:
parent
ba476b2f68
commit
992f3966dc
|
@ -22,4 +22,14 @@ public class StrolchRestfulConstants {
|
|||
|
||||
public static final String STROLCH_CERTIFICATE = "strolch.certificate"; //$NON-NLS-1$
|
||||
public static final String STROLCH_AUTHORIZATION = "strolch.authorization"; //$NON-NLS-1$
|
||||
|
||||
public static final String MSG = "msg";
|
||||
public static final String DATA = "data";
|
||||
public static final String LAST_OFFSET = "lastOffset";
|
||||
public static final String NEXT_OFFSET = "nextOffset";
|
||||
public static final String PREVIOUS_OFFSET = "previousOffset";
|
||||
public static final String SIZE = "size";
|
||||
public static final String OFFSET = "offset";
|
||||
public static final String LIMIT = "limit";
|
||||
|
||||
}
|
||||
|
|
|
@ -225,23 +225,25 @@ public class ModelQuery {
|
|||
StrolchElementVisitor<T, JsonObject> toJsonVisitor) {
|
||||
|
||||
// paging
|
||||
Paging<T> paging = Paging.asPage(elements, queryData.getPageSize(), queryData.getPage());
|
||||
Paging<T> paging = Paging.asPage(elements, queryData.getOffset(), queryData.getLimit());
|
||||
|
||||
// get page
|
||||
List<T> page = paging.getPage();
|
||||
|
||||
JsonObject root = new JsonObject();
|
||||
root.addProperty("msg", "-");
|
||||
root.addProperty("draw", queryData.getDraw());
|
||||
root.addProperty("limit", paging.getLimit());
|
||||
root.addProperty("offset", paging.getOffset());
|
||||
root.addProperty("size", paging.getSize());
|
||||
root.addProperty("previousOffset", paging.getPreviousOffset());
|
||||
root.addProperty("nextOffset", paging.getNextOffset());
|
||||
root.addProperty("lastOffset", paging.getLastOffset());
|
||||
|
||||
root.addProperty("dataSetSize", dataSetSize);
|
||||
root.addProperty("nrOfElements", paging.getNrOfElements());
|
||||
|
||||
if (StringHelper.isNotEmpty(queryData.getOrderBy()))
|
||||
root.addProperty("sortBy", queryData.getOrderBy());
|
||||
root.addProperty("ascending", queryData.isAscending());
|
||||
root.addProperty("nrOfPages", paging.getNrOfPages());
|
||||
root.addProperty("pageSize", paging.getPageSize());
|
||||
root.addProperty("page", paging.getPageToReturn());
|
||||
|
||||
// add items
|
||||
JsonArray data = new JsonArray();
|
||||
|
|
|
@ -7,14 +7,11 @@ public class QueryData {
|
|||
@QueryParam("realmName")
|
||||
private String realmName;
|
||||
|
||||
@QueryParam("draw")
|
||||
private int draw;
|
||||
@QueryParam("offset")
|
||||
private int offset;
|
||||
|
||||
@QueryParam("pageSize")
|
||||
private int pageSize;
|
||||
|
||||
@QueryParam("page")
|
||||
private int page;
|
||||
@QueryParam("limit")
|
||||
private int limit;
|
||||
|
||||
@QueryParam("query")
|
||||
private String query;
|
||||
|
@ -33,14 +30,6 @@ public class QueryData {
|
|||
this.realmName = realmName;
|
||||
}
|
||||
|
||||
public int getDraw() {
|
||||
return this.draw;
|
||||
}
|
||||
|
||||
public void setDraw(int draw) {
|
||||
this.draw = draw;
|
||||
}
|
||||
|
||||
public String getOrderBy() {
|
||||
return this.orderBy;
|
||||
}
|
||||
|
@ -57,20 +46,20 @@ public class QueryData {
|
|||
this.ascending = ascending;
|
||||
}
|
||||
|
||||
public int getPageSize() {
|
||||
return this.pageSize;
|
||||
public int getOffset() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
public void setPageSize(int pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return this.page;
|
||||
public int getLimit() {
|
||||
return this.limit;
|
||||
}
|
||||
|
||||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public String getQuery() {
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
package li.strolch.rest.helper;
|
||||
|
||||
import static li.strolch.rest.StrolchRestfulConstants.DATA;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.LAST_OFFSET;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.LIMIT;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.MSG;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.NEXT_OFFSET;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.OFFSET;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.PREVIOUS_OFFSET;
|
||||
import static li.strolch.rest.StrolchRestfulConstants.SIZE;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import li.strolch.utils.collections.Paging;
|
||||
import li.strolch.utils.helper.ExceptionHelper;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
|
||||
|
@ -15,8 +28,6 @@ import li.strolch.utils.helper.StringHelper;
|
|||
*/
|
||||
public class ResponseUtil {
|
||||
|
||||
public static final String MSG = "msg";
|
||||
|
||||
public static Response toResponse() {
|
||||
JsonObject response = new JsonObject();
|
||||
response.addProperty(MSG, StringHelper.DASH);
|
||||
|
@ -64,4 +75,30 @@ public class ResponseUtil {
|
|||
|
||||
return Response.serverError().entity(json).type(MediaType.APPLICATION_JSON).build();
|
||||
}
|
||||
|
||||
public static Response toResponse(Paging<JsonObject> paging) {
|
||||
JsonObject response = new JsonObject();
|
||||
|
||||
response.addProperty(MSG, StringHelper.DASH);
|
||||
|
||||
response.addProperty(LIMIT, paging.getLimit());
|
||||
response.addProperty(OFFSET, paging.getOffset());
|
||||
response.addProperty(SIZE, paging.getSize());
|
||||
response.addProperty(PREVIOUS_OFFSET, paging.getPreviousOffset());
|
||||
response.addProperty(NEXT_OFFSET, paging.getNextOffset());
|
||||
response.addProperty(LAST_OFFSET, paging.getLastOffset());
|
||||
|
||||
List<JsonObject> page = paging.getPage();
|
||||
JsonArray data = new JsonArray();
|
||||
for (JsonObject jsonObject : page) {
|
||||
JsonObject element = jsonObject;
|
||||
data.add(element);
|
||||
}
|
||||
response.add(DATA, data);
|
||||
|
||||
String json = new Gson().toJson(response);
|
||||
|
||||
return Response.ok(json, MediaType.APPLICATION_JSON).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ package li.strolch.utils.collections;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Paging helper creating windows on result list of queries. The input is the original complete list, and with the help
|
||||
* of an offset and a limit, a page/window can be fetched.
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*
|
||||
* @param <T>
|
||||
|
@ -25,108 +28,138 @@ import java.util.List;
|
|||
*/
|
||||
public class Paging<T> {
|
||||
|
||||
private int pageSize;
|
||||
private int pageToReturn;
|
||||
private int nrOfPages;
|
||||
private int nrOfElements;
|
||||
private int limit;
|
||||
private int offset;
|
||||
private int size;
|
||||
|
||||
private List<T> input;
|
||||
private List<T> page;
|
||||
|
||||
private Paging(int pageSize, int indexOfPageToReturn) {
|
||||
this.pageSize = pageSize;
|
||||
this.pageToReturn = indexOfPageToReturn;
|
||||
private int nextOffset;
|
||||
private int previousOffset;
|
||||
private int firstOffset;
|
||||
private int lastOffset;
|
||||
|
||||
private Paging() {
|
||||
// empty constructor
|
||||
}
|
||||
|
||||
public int getPageSize() {
|
||||
return this.pageSize;
|
||||
/**
|
||||
* @return the max number of elements to be returned in the page/window
|
||||
*/
|
||||
public int getLimit() {
|
||||
return this.limit;
|
||||
}
|
||||
|
||||
public void setPageSize(int pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
/**
|
||||
* @return the offset in the input list for the page/window
|
||||
*/
|
||||
public int getOffset() {
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
public int getPageToReturn() {
|
||||
return this.pageToReturn;
|
||||
/**
|
||||
* @return the next offset, i.e. offset + limit
|
||||
*/
|
||||
public int getNextOffset() {
|
||||
return this.nextOffset;
|
||||
}
|
||||
|
||||
public void setPageToReturn(int pageToReturn) {
|
||||
this.pageToReturn = pageToReturn;
|
||||
/**
|
||||
* @return the previous offset, i.e. offset - limit
|
||||
*/
|
||||
public int getPreviousOffset() {
|
||||
return this.previousOffset;
|
||||
}
|
||||
|
||||
public int getNrOfPages() {
|
||||
return this.nrOfPages;
|
||||
/**
|
||||
* @return 0, as the first offset is the first element in the input list
|
||||
*/
|
||||
public int getFirstOffset() {
|
||||
return this.firstOffset;
|
||||
}
|
||||
|
||||
public void setNrOfPages(int nrOfPages) {
|
||||
this.nrOfPages = nrOfPages;
|
||||
/**
|
||||
* @return the last possible offset given the offset, limit and input size
|
||||
*/
|
||||
public int getLastOffset() {
|
||||
return this.lastOffset;
|
||||
}
|
||||
|
||||
public int getNrOfElements() {
|
||||
return this.nrOfElements;
|
||||
}
|
||||
|
||||
public void setNrOfElements(int nrOfElements) {
|
||||
this.nrOfElements = nrOfElements;
|
||||
/**
|
||||
* @return the size of the input list
|
||||
*/
|
||||
public int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the input
|
||||
*/
|
||||
public List<T> getInput() {
|
||||
return this.input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current page/window
|
||||
*/
|
||||
public List<T> getPage() {
|
||||
return this.page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a sub list of the given list by creating defining start and end from the requested page of the form
|
||||
* Creates a sub list of the input list with the given limit and offset
|
||||
*
|
||||
* @param list
|
||||
* the list to paginate
|
||||
* @param pageSize
|
||||
* The number of items to return in each page
|
||||
* @param page
|
||||
* the page to return - start index is 1
|
||||
*
|
||||
* the list to paginate / create a window for
|
||||
* @param offset
|
||||
* where to start the sub list
|
||||
* @param limit
|
||||
* The number of items to return in each page/window
|
||||
* @return a {@link Paging} instance from which the selected page (list) can be retrieved
|
||||
*
|
||||
* @param <T>
|
||||
* the type of element in the list
|
||||
*/
|
||||
public static <T> Paging<T> asPage(List<T> list, int pageSize, int page) {
|
||||
public static <T> Paging<T> asPage(List<T> list, int offset, int limit) {
|
||||
|
||||
Paging<T> paging = new Paging<>(pageSize, page);
|
||||
paging.nrOfElements = list.size();
|
||||
Paging<T> paging = new Paging<>();
|
||||
paging.firstOffset = 0;
|
||||
paging.limit = limit;
|
||||
paging.offset = offset;
|
||||
|
||||
paging.size = list.size();
|
||||
paging.input = list;
|
||||
|
||||
paging.firstOffset = 0;
|
||||
|
||||
if (paging.limit <= 0 || paging.offset < 0) {
|
||||
paging.offset = 0;
|
||||
paging.limit = list.size();
|
||||
|
||||
if (paging.pageSize <= 0 || paging.pageToReturn <= 0) {
|
||||
paging.nrOfPages = 0;
|
||||
paging.pageSize = list.size();
|
||||
paging.pageToReturn = 0;
|
||||
paging.input = list;
|
||||
paging.page = list;
|
||||
|
||||
paging.nextOffset = 0;
|
||||
paging.lastOffset = 0;
|
||||
paging.previousOffset = 0;
|
||||
|
||||
return paging;
|
||||
}
|
||||
|
||||
int size = list.size();
|
||||
paging.page = list.subList(offset, Math.min(paging.size, offset + limit));
|
||||
|
||||
// calculate maximum number of pages
|
||||
paging.nrOfPages = size / paging.pageSize;
|
||||
if (size % paging.pageSize != 0)
|
||||
paging.nrOfPages++;
|
||||
if (limit == 1) {
|
||||
|
||||
// and from this validate requested page
|
||||
paging.pageToReturn = Math.min(paging.pageToReturn, paging.nrOfPages);
|
||||
paging.nextOffset = Math.min(paging.size - 1, offset + 1);
|
||||
paging.previousOffset = Math.max(0, offset - 1);
|
||||
paging.lastOffset = paging.size - 1;
|
||||
|
||||
// now we can calculate the start and end of the page
|
||||
int start = Math.max(0, paging.pageSize * paging.pageToReturn - paging.pageSize);
|
||||
int end = Math.min(size, paging.pageSize * paging.pageToReturn);
|
||||
} else {
|
||||
|
||||
// and return the list
|
||||
paging.page = list.subList(start, end);
|
||||
|
||||
// fix page size
|
||||
if (paging.page.size() < paging.pageSize)
|
||||
paging.pageSize = paging.page.size();
|
||||
paging.nextOffset = Math.min(paging.size - 1, limit + offset);
|
||||
paging.previousOffset = Math.max(0, offset - limit);
|
||||
paging.lastOffset = offset + ((paging.size - offset) - ((paging.size - offset) % limit));
|
||||
}
|
||||
|
||||
return paging;
|
||||
}
|
||||
|
|
|
@ -22,59 +22,153 @@ import java.util.List;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import li.strolch.utils.collections.Paging;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class PagingTest {
|
||||
|
||||
private List<String> getInputList() {
|
||||
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f", "g");
|
||||
return list;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnAll() {
|
||||
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
|
||||
List<String> list = getInputList();
|
||||
List<String> page = Paging.asPage(list, -1, -1).getPage();
|
||||
assertEquals(list, page);
|
||||
page = Paging.asPage(list, 0, 0).getPage();
|
||||
assertEquals(list, page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnFirstPage1() {
|
||||
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
|
||||
List<String> page = Paging.asPage(list, 1, 1).getPage();
|
||||
List<String> list = getInputList();
|
||||
List<String> page = Paging.asPage(list, 0, 1).getPage();
|
||||
assertEquals(Arrays.asList("a"), page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnFirstPage2() {
|
||||
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
|
||||
List<String> page = Paging.asPage(list, 2, 1).getPage();
|
||||
List<String> list = getInputList();
|
||||
List<String> page = Paging.asPage(list, 0, 2).getPage();
|
||||
assertEquals(Arrays.asList("a", "b"), page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnSecondPage1() {
|
||||
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
|
||||
List<String> page = Paging.asPage(list, 1, 2).getPage();
|
||||
List<String> list = getInputList();
|
||||
List<String> page = Paging.asPage(list, 1, 1).getPage();
|
||||
assertEquals(Arrays.asList("b"), page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnSecondPage2() {
|
||||
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
|
||||
List<String> list = getInputList();
|
||||
List<String> page = Paging.asPage(list, 2, 2).getPage();
|
||||
assertEquals(Arrays.asList("c", "d"), page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLastPage1() {
|
||||
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
|
||||
List<String> page = Paging.asPage(list, 1, 6).getPage();
|
||||
List<String> list = getInputList();
|
||||
List<String> page = Paging.asPage(list, 5, 1).getPage();
|
||||
assertEquals(Arrays.asList("f"), page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLastPage2() {
|
||||
List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f");
|
||||
List<String> page = Paging.asPage(list, 2, 3).getPage();
|
||||
List<String> list = getInputList();
|
||||
List<String> page = Paging.asPage(list, 4, 2).getPage();
|
||||
assertEquals(Arrays.asList("e", "f"), page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLastPage3() {
|
||||
List<String> list = getInputList();
|
||||
|
||||
Paging<String> paging = Paging.asPage(list, 0, 2);
|
||||
List<String> page = paging.getPage();
|
||||
assertEquals(Arrays.asList("a", "b"), page);
|
||||
assertEquals(0, paging.getFirstOffset());
|
||||
assertEquals(2, paging.getNextOffset());
|
||||
assertEquals(6, paging.getLastOffset());
|
||||
|
||||
paging = Paging.asPage(list, paging.getLastOffset(), 2);
|
||||
page = paging.getPage();
|
||||
assertEquals(Arrays.asList("g"), page);
|
||||
assertEquals(0, paging.getFirstOffset());
|
||||
assertEquals(6, paging.getNextOffset());
|
||||
assertEquals(6, paging.getLastOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLastPage4() {
|
||||
List<String> list = getInputList();
|
||||
|
||||
Paging<String> paging = Paging.asPage(list, 0, 1);
|
||||
List<String> page = paging.getPage();
|
||||
assertEquals(Arrays.asList("a"), page);
|
||||
|
||||
paging = Paging.asPage(list, paging.getLastOffset(), 1);
|
||||
page = paging.getPage();
|
||||
assertEquals(Arrays.asList("g"), page);
|
||||
assertEquals(0, paging.getFirstOffset());
|
||||
assertEquals(6, paging.getNextOffset());
|
||||
assertEquals(6, paging.getLastOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLastPage5() {
|
||||
List<String> list = getInputList();
|
||||
|
||||
Paging<String> paging = Paging.asPage(list, 0, 3);
|
||||
List<String> page = paging.getPage();
|
||||
assertEquals(Arrays.asList("a", "b", "c"), page);
|
||||
assertEquals(0, paging.getFirstOffset());
|
||||
assertEquals(3, paging.getNextOffset());
|
||||
assertEquals(6, paging.getLastOffset());
|
||||
|
||||
page = Paging.asPage(list, paging.getNextOffset(), paging.getLimit()).getPage();
|
||||
assertEquals(Arrays.asList("d", "e", "f"), page);
|
||||
|
||||
page = Paging.asPage(list, paging.getLastOffset(), paging.getLimit()).getPage();
|
||||
assertEquals(Arrays.asList("g"), page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLastPage6() {
|
||||
List<String> list = getInputList();
|
||||
|
||||
Paging<String> paging = Paging.asPage(list, 1, 1);
|
||||
List<String> page = paging.getPage();
|
||||
assertEquals(Arrays.asList("b"), page);
|
||||
|
||||
page = Paging.asPage(list, paging.getPreviousOffset(), paging.getLimit()).getPage();
|
||||
assertEquals(Arrays.asList("a"), page);
|
||||
|
||||
page = Paging.asPage(list, paging.getNextOffset(), paging.getLimit()).getPage();
|
||||
assertEquals(Arrays.asList("c"), page);
|
||||
|
||||
page = Paging.asPage(list, paging.getLastOffset(), paging.getLimit()).getPage();
|
||||
assertEquals(Arrays.asList("g"), page);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnLastPage7() {
|
||||
List<String> list = getInputList();
|
||||
|
||||
Paging<String> paging = Paging.asPage(list, 2, 2);
|
||||
List<String> page = paging.getPage();
|
||||
assertEquals(Arrays.asList("c", "d"), page);
|
||||
|
||||
page = Paging.asPage(list, paging.getPreviousOffset(), paging.getLimit()).getPage();
|
||||
assertEquals(Arrays.asList("a", "b"), page);
|
||||
|
||||
page = Paging.asPage(list, paging.getNextOffset(), paging.getLimit()).getPage();
|
||||
assertEquals(Arrays.asList("e", "f"), page);
|
||||
|
||||
page = Paging.asPage(list, paging.getLastOffset(), paging.getLimit()).getPage();
|
||||
assertEquals(Arrays.asList("g"), page);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue