MIFOSX-321: tidy up some of backend implementation for client pagination and sorting example.

This commit is contained in:
Keith Woodlock
2013-05-02 01:56:32 +01:00
parent c73ac95466
commit f107d185e8
6 changed files with 102 additions and 77 deletions
@@ -3,36 +3,25 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.pagination;
package org.mifosplatform.infrastructure.core.service;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
public class Page<E> {
private int totalFilteredRecords;
private List<E> pageItems = new ArrayList<E>();
private final int totalFilteredRecords;
private final List<E> pageItems;
public void setPageItems(List<E> pageItems) {
public Page(final List<E> pageItems, final int totalFilteredRecords) {
this.pageItems = pageItems;
this.totalFilteredRecords = totalFilteredRecords;
}
public int getTotalFilteredRecords() {
return this.totalFilteredRecords;
}
public void setTotalFilteredRecords(int totalFilteredRecords) {
this.totalFilteredRecords = totalFilteredRecords;
}
public List<E> getPageItems() {
return pageItems;
}
@Override
public String toString() {
return new Gson().toJson(this);
}
}
}
@@ -3,7 +3,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.pagination;
package org.mifosplatform.infrastructure.core.service;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
@@ -13,16 +15,11 @@ public class PaginationHelper<E> {
public Page<E> fetchPage(final JdbcTemplate jt, final String sqlCountRows, final String sqlFetchRows, final Object args[],
final RowMapper<E> rowMapper) {
final Page<E> page = new Page<E>();
page.getPageItems().addAll(jt.query(sqlFetchRows, args, rowMapper));
final List<E> items = jt.query(sqlFetchRows, args, rowMapper);
// determine how many rows are available
final int totalFilteredRecords = jt.queryForInt(sqlCountRows);
page.setTotalFilteredRecords(totalFilteredRecords);
return page;
return new Page<E>(items, totalFilteredRecords);
}
}
@@ -33,6 +33,7 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
@@ -40,7 +41,6 @@ import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionDat
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.mifosplatform.portfolio.group.service.SearchParameters;
import org.mifosplatform.portfolio.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -90,18 +90,19 @@ public class ClientsApiResource {
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllPaginatedAndSorted(@QueryParam("sqlSearch") final String sqlSearch,
@QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId,
@QueryParam("displayName") final String displayName, @QueryParam("firstName") final String firstname,
@QueryParam("lastName") final String lastname, @QueryParam("underHierarchy") final String hierarchy,
@QueryParam("offset") final int offset, @QueryParam("limit") final int limit, @QueryParam("orderBy") final String orderBy,
public String retrieveAll(@QueryParam("sqlSearch") final String sqlSearch, @QueryParam("officeId") final Long officeId,
@QueryParam("externalId") final String externalId, @QueryParam("displayName") final String displayName,
@QueryParam("firstName") final String firstname, @QueryParam("lastName") final String lastname,
@QueryParam("underHierarchy") final String hierarchy, @QueryParam("offset") final Integer offset,
@QueryParam("limit") final Integer limit, @QueryParam("orderBy") final String orderBy,
@QueryParam("sortOrder") final String sortOrder) {
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
final SearchParameters searchParameters = SearchParameters.forClients(sqlSearch, officeId, externalId, displayName, firstname,
lastname, hierarchy);
Page<ClientData> clientData = this.clientReadPlatformService.retrieveAllPaginatedAndSorted(searchParameters, offset, limit,
orderBy, sortOrder);
lastname, hierarchy, offset, limit, orderBy, sortOrder);
final Page<ClientData> clientData = this.clientReadPlatformService.retrieveAll(searchParameters);
return this.toApiJsonSerializer.serialize(clientData);
}
@@ -123,7 +124,7 @@ public class ClientsApiResource {
return this.toApiJsonSerializer.serialize(settings, clientData, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@@ -7,19 +7,17 @@ package org.mifosplatform.portfolio.client.service;
import java.util.Collection;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.group.service.SearchParameters;
import org.mifosplatform.portfolio.pagination.Page;
public interface ClientReadPlatformService {
ClientData retrieveTemplate();
Collection<ClientData> retrieveAll(SearchParameters searchParameters);
Page<ClientData> retrieveAllPaginatedAndSorted(SearchParameters searchParameters, int offset, int limit, String sortBy, String sortOrder);
Page<ClientData> retrieveAll(SearchParameters searchParameters);
ClientData retrieveOne(Long clientId);
@@ -16,6 +16,8 @@ import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeData;
@@ -29,8 +31,6 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
import org.mifosplatform.portfolio.group.service.SearchParameters;
import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData;
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
import org.mifosplatform.portfolio.pagination.Page;
import org.mifosplatform.portfolio.pagination.PaginationHelper;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
@@ -46,6 +46,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
private final OfficeReadPlatformService officeReadPlatformService;
// data mappers
private final PaginationHelper<ClientData> paginationHelper = new PaginationHelper<ClientData>();
private final ClientMapper clientMapper = new ClientMapper();
private final ClientLookupMapper lookupMapper = new ClientLookupMapper();
private final ClientMembersOfGroupMapper membersOfGroupMapper = new ClientMembersOfGroupMapper();
@@ -72,49 +73,41 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
}
@Override
public Collection<ClientData> retrieveAll(final SearchParameters searchParameters) {
public Page<ClientData> retrieveAll(final SearchParameters searchParameters) {
final AppUser currentUser = context.authenticatedUser();
final String hierarchy = currentUser.getOffice().getHierarchy();
final String hierarchySearchString = hierarchy + "%";
String sql = "select " + this.clientMapper.schema() + " where o.hierarchy like ?";
StringBuilder sqlBuilder = new StringBuilder(200);
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
sqlBuilder.append(this.clientMapper.schema());
sqlBuilder.append(" where o.hierarchy like ?");
final String extraCriteria = buildSqlStringFromClientCriteria(searchParameters);
if (StringUtils.isNotBlank(extraCriteria)) sql += " and (" + extraCriteria + ")";
if (StringUtils.isNotBlank(extraCriteria)) {
sqlBuilder.append(" and (").append(extraCriteria).append(")");
}
sql += " order by c.display_name ASC, c.account_no ASC";
// DONT order by default - just use database natural ordering so doesnt
// have to scan entire database table.
// sql += " order by c.display_name ASC, c.account_no ASC";
if (searchParameters.isOrderByRequested()) {
sqlBuilder.append(" order by ").append(searchParameters.getOrderBy()).append(' ').append(searchParameters.getSortOrder());
}
return this.jdbcTemplate.query(sql, clientMapper, new Object[] { hierarchySearchString });
}
if (searchParameters.isLimited()) {
sqlBuilder.append(" limit ").append(searchParameters.getLimit());
}
@Override
public Page<ClientData> retrieveAllPaginatedAndSorted(final SearchParameters searchParameters, final int offset, final int limit,
final String orderby, final String sortOrder) {
if (searchParameters.isOffset()) {
sqlBuilder.append(" offset ").append(searchParameters.getOffset());
}
final AppUser currentUser = context.authenticatedUser();
final String hierarchy = currentUser.getOffice().getHierarchy();
final String hierarchySearchString = hierarchy + "%";
String sql = "select SQL_CALC_FOUND_ROWS " + this.clientMapper.schema() + " where o.hierarchy like ?";
final String extraCriteria = buildSqlStringFromClientCriteria(searchParameters);
if (StringUtils.isNotBlank(extraCriteria)) sql += " and (" + extraCriteria + ")";
if (orderby != null && sortOrder != null) {
if (!orderby.equalsIgnoreCase("") && !sortOrder.equalsIgnoreCase("")) {
sql += " order by " + orderby + " " + sortOrder;
}
} else
sql += " order by c.display_name ASC, c.account_no ASC";
PaginationHelper<ClientData> ph = new PaginationHelper<ClientData>();
String sqlCountRows = "SELECT FOUND_ROWS()";
String sqlFetchRows = sql;
if (limit != 0) sqlFetchRows = sql + " LIMIT " + limit + " OFFSET " + offset;
return ph.fetchPage(jdbcTemplate, sqlCountRows, sqlFetchRows, new Object[] { hierarchySearchString }, clientMapper);
final String sqlCountRows = "SELECT FOUND_ROWS()";
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
new Object[] { hierarchySearchString }, this.clientMapper);
}
private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) {
@@ -1,6 +1,8 @@
package org.mifosplatform.portfolio.group.service;
public class SearchParameters {
import org.apache.commons.lang.StringUtils;
public final class SearchParameters {
private final String sqlSearch;
private final Long officeId;
@@ -9,19 +11,32 @@ public class SearchParameters {
private final String hierarchy;
private final String firstname;
private final String lastname;
private final Integer offset;
private final Integer limit;
private final String orderBy;
private final String sortOrder;
public static SearchParameters from(final String sqlSearch, final Long officeId, final String externalId, final String name,
final String hierarchy) {
return new SearchParameters(sqlSearch, officeId, externalId, name, hierarchy, null, null);
return new SearchParameters(sqlSearch, officeId, externalId, name, hierarchy, null, null, null, null, null, null);
}
public static SearchParameters forClients(final String sqlSearch, final Long officeId, final String externalId,
final String displayName, final String firstname, final String lastname, final String hierarchy) {
return new SearchParameters(sqlSearch, officeId, externalId, displayName, hierarchy, firstname, lastname);
final String displayName, final String firstname, final String lastname, final String hierarchy, final Integer offset,
final Integer limit, final String orderBy, final String sortOrder) {
Integer maxLimitAllowed = 200;
if (limit != null && limit < maxLimitAllowed && limit > 0) {
maxLimitAllowed = limit;
}
return new SearchParameters(sqlSearch, officeId, externalId, displayName, hierarchy, firstname, lastname, offset, maxLimitAllowed,
orderBy, sortOrder);
}
private SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name,
final String hierarchy, final String firstname, final String lastname) {
final String hierarchy, final String firstname, final String lastname, final Integer offset, final Integer limit,
final String orderBy, final String sortOrder) {
this.sqlSearch = sqlSearch;
this.officeId = officeId;
this.externalId = externalId;
@@ -29,6 +44,14 @@ public class SearchParameters {
this.hierarchy = hierarchy;
this.firstname = firstname;
this.lastname = lastname;
this.offset = offset;
this.limit = limit;
this.orderBy = orderBy;
this.sortOrder = sortOrder;
}
public boolean isOrderByRequested() {
return StringUtils.isNotBlank(this.orderBy) && StringUtils.isNotBlank(this.sortOrder);
}
public String getSqlSearch() {
@@ -58,4 +81,28 @@ public class SearchParameters {
public String getLastname() {
return this.lastname;
}
public Integer getOffset() {
return this.offset;
}
public Integer getLimit() {
return this.limit;
}
public String getOrderBy() {
return this.orderBy;
}
public String getSortOrder() {
return this.sortOrder;
}
public boolean isLimited() {
return this.limit != null && this.limit.intValue() > 0;
}
public boolean isOffset() {
return this.offset != null;
}
}