package net.eusashead.bjugquerydsl.hateoas; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.data.domain.Page; import org.springframework.web.util.UriTemplate; import com.theoryinpractise.halbuilder.api.ReadableRepresentation; import com.theoryinpractise.halbuilder.api.Representation; import com.theoryinpractise.halbuilder.api.RepresentationFactory; /** * Simple class to build * a HAL representation * response and set * etag/last-modified/location * headers as required * @author patrickvk * */ public class HalPageResponseEntityBuilder extends BaseHalRepresentationBuilder implements ResponseEntityBuilder<ReadableRepresentation> { public HalPageResponseEntityBuilder(RepresentationFactory representationFactory, RepresentationConverter converter, HttpServletRequest request, String fieldVariable) { super(representationFactory, converter, request, fieldVariable); } /** * Add all bean properties * from the supplied bean * to the representation * @param value * @return */ public ResponseEntityBuilder<ReadableRepresentation> withPage(Page<?> value, String uriTemplate, String... includeFields) { String[] fields = requestedFields == null ? includeFields : requestedFields; // Extract page data such as size, page number representation.withProperty("size", value.getSize()); representation.withProperty("number", value.getNumber()); representation.withProperty("numberOfElements", value.getNumberOfElements()); representation.withProperty("totalElements", value.getTotalElements()); // Next/back links if (value.hasNextPage()) { buildNextLink(representation, request); } if (value.hasPreviousPage()) { buildPreviousLink(representation, request); } // Build the content of the page for (Object object : value.getContent()) { Representation content = converter.convert(object, new UriTemplate(uriTemplate), fields); this.representation.withRepresentation("content", content); } return this; } private void buildNextLink(Representation representation, HttpServletRequest request) { Map<String, String[]> params = modifyPageNumber(request, 1); String link = buildLink(params); representation.withLink("next", link); } private void buildPreviousLink(Representation representation, HttpServletRequest request) { Map<String, String[]> params = modifyPageNumber(request, -1); String link = buildLink(params); representation.withLink("previous", link); } private String buildLink(Map<String, String[]> params) { String queryString = buildQueryString(params); System.out.println(queryString); String link = String.format("%s?%s", request.getRequestURI(), queryString); return link; } private String buildQueryString(Map<String, String[]> params) { StringBuilder builder = new StringBuilder(); for (String key : params.keySet()) { for (String val : params.get(key)) { builder.append(key); builder.append("="); builder.append(val); builder.append("&"); } } if (builder.lastIndexOf("&") == (builder.length() - 1)) { builder.deleteCharAt(builder.length() - 1); } return builder.toString(); } /** * Get the existing request * parameters and increment * the page parameter (or decrement) * @param request * @param modifier * @return */ private Map<String, String[]> modifyPageNumber(HttpServletRequest request, int modifier) { Map<String, String[]> oldParams = request.getParameterMap(); Map<String, String[]> newParams = new HashMap<String, String[]>(); for (String key : oldParams.keySet()) { String[] value = oldParams.get(key); if (key.equals("page")) { int page = Integer.parseInt(value[0]) + modifier; newParams.put("page", new String[]{Integer.valueOf(page).toString()}); } else { newParams.put(key, value); } } return newParams; } }