/******************************************************************************* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. ******************************************************************************/ package org.apache.olingo.odata2.jpa.processor.core.access.data; import java.util.ArrayList; import java.util.List; import javax.persistence.Query; import org.apache.olingo.odata2.jpa.processor.api.access.JPAPaging; public class JPAPage implements JPAPaging { private int pageSize; private int startPage; private int nextPage; private List<Object> pagedEntries; protected JPAPage(final int startPage, final int nextPage, final List<Object> pagedEntities, final int pageSize) { this.pageSize = pageSize; this.startPage = startPage; this.nextPage = nextPage; pagedEntries = pagedEntities; } @Override public int getPageSize() { return pageSize; } @Override public List<Object> getPagedEntities() { return pagedEntries; } @Override public int getNextPage() { return nextPage; } @Override public int getStartPage() { return startPage; } public static class JPAPageBuilder { private int pageSize; private int startPage; private int nextPage; private int top = -1; private int skip; private int skipToken; private Query query; private List<Object> entities; private List<Object> pagedEntities; private static class TopSkip { public int top; public int skip; } public JPAPageBuilder() {} public JPAPageBuilder pageSize(final int pageSize) { this.pageSize = pageSize; return this; } public JPAPageBuilder query(final Query query) { this.query = query; return this; } public JPAPage build() { if (entities != null) { return buildFromEntities(); } else { return buildFromQuery(); } } private JPAPage buildFromEntities() { TopSkip topSkip = formulateTopSkip(); pagedEntities = new ArrayList<Object>(); if (topSkip.skip <= 0) { topSkip.skip = 1; } for (int i = topSkip.skip - 1, j = 0; (j < topSkip.top && i < entities.size()); j++) { pagedEntities.add(entities.get(i++)); } formulateNextPage(); return new JPAPage(startPage, nextPage, pagedEntities, pageSize); } @SuppressWarnings("unchecked") private JPAPage buildFromQuery() { TopSkip topSkip = formulateTopSkip(); query.setFirstResult(topSkip.skip); query.setMaxResults(topSkip.top); pagedEntities = query.getResultList(); formulateNextPage(); return new JPAPage(startPage, nextPage, pagedEntities, pageSize); } private TopSkip formulateTopSkip() { TopSkip topSkip = new TopSkip(); int size = 0; if (pageSize <= 0) { if (skip > 0) { topSkip.skip = skip; } if (top > 0) { topSkip.top = top; } } else { if (skip >= pageSize) { // No Records to fetch startPage = skipToken; nextPage = 0; } else { // Max Results size = top + skip; if (size > pageSize) { if (skip == 0) { topSkip.top = pageSize; } else { topSkip.top = pageSize - skip; } } else { if (top > 0) { topSkip.top = top; } else { topSkip.top = pageSize; } } startPage = skipToken; if (skip > 0) { topSkip.skip = startPage + skip; } else { topSkip.skip = startPage; } } } return topSkip; } private void formulateNextPage() { if (pagedEntities.size() == 0) { nextPage = 0; } else if (pagedEntities.size() < pageSize) { nextPage = 0; } else { nextPage = startPage + pageSize; } } public JPAPageBuilder skip(final int skip) { this.skip = skip; if (skip < 0) { this.skip = 0; } else { this.skip = skip; } return this; } public JPAPageBuilder skipToken(final String skipToken) throws NumberFormatException { if (skipToken == null) { this.skipToken = 0; } else { this.skipToken = new Integer(skipToken).intValue(); if (this.skipToken < 0) { this.skipToken = 0; } } return this; } public JPAPageBuilder top(final int top) { if (top < 0) { this.top = 0; } else { this.top = top; } return this; } public JPAPageBuilder entities(final List<Object> result) { entities = result; return this; } } }