/** * This Source Code Form is subject to the terms of the Mozilla Public 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/. OpenMRS is also distributed under * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. * * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS * graphic logo is a trademark of OpenMRS Inc. */ package org.openmrs.module.webservices.rest.web; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.openmrs.api.APIException; import org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation; import org.openmrs.module.webservices.rest.web.representation.Representation; /** * Holds information related to a REST web service request */ public class RequestContext { private HttpServletRequest request; private HttpServletResponse response; private Representation representation = new DefaultRepresentation(); private Integer startIndex = 0; private Integer limit = RestUtil.getDefaultLimit(); private Boolean includeAll = false; // for resources that represent class hierarchies, this allows requests for a specific type private String type; public RequestContext() { } /** * @return the request */ public HttpServletRequest getRequest() { return request; } /** * @param request the request to set */ public void setRequest(HttpServletRequest request) { this.request = request; } /** * @return the response */ public HttpServletResponse getResponse() { return response; } /** * @param response the response to set */ public void setResponse(HttpServletResponse response) { this.response = response; } /** * @return the representation */ public Representation getRepresentation() { return representation; } /** * @param representation the representation to set */ public void setRepresentation(Representation representation) { this.representation = representation; } /** * @return the type */ public String getType() { return type; } /** * @param type the type to set */ public void setType(String type) { this.type = type; } /** * Should be used to determine whether voided data and/or retired metadata should be returned in * <code>getAll()</code> and <code>search</code> requests. * * @return the <code>Boolean</code> specifying whether or not to include voided data / retired * metadata */ public Boolean getIncludeAll() { return includeAll; } /** * @param includeAll whether or not to include voided data / retired metadata * @see RestUtil#getRequestContext */ public void setIncludeAll(Boolean includeAll) { this.includeAll = includeAll; } /** * Should be used to limit the number of main results returned by search methods * * @return the integer limit set in a request parameter * @see RestUtil#getRequestContext(org.springframework.web.context.request.WebRequest) * @see RestConstants#REQUEST_PROPERTY_FOR_LIMIT */ public Integer getLimit() { return limit; } /** * @param limit the limit to set * @should not accept a value less than one * @should not accept a null value */ public void setLimit(Integer limit) { if (limit == null || limit <= 0) throw new APIException("If you specify a number of results to return, it must be >0 and not null"); if (limit > RestUtil.getAbsoluteLimit()) throw new APIException("Administrator has set absolute limit at " + RestUtil.getAbsoluteLimit()); else this.limit = limit; } /** * Should be used by search methods to jump results to start with this number in the list. Set * by users in a request parameter * * @return the integer startIndex * @see RestUtil#getRequestContext(org.springframework.web.context.request.WebRequest) * @see RestConstants#REQUEST_PROPERTY_FOR_START_INDEX */ public Integer getStartIndex() { return startIndex; } /** * @param startIndex the startIndex to set */ public void setStartIndex(Integer startIndex) { this.startIndex = startIndex; } /** * (Assumes this was a search query) * * @return the hyperlink you would GET to fetch the next page of results for the query */ public Hyperlink getNextLink() { String query = getQueryWithoutStartIndex(); query += RestConstants.REQUEST_PROPERTY_FOR_START_INDEX + "=" + (startIndex + limit); return new Hyperlink("next", request.getRequestURL().append(query).toString()); } /** * (Assumes this was a search query) * * @return the hyperlink you would GET to fetch the previous page of results for the query */ public Hyperlink getPreviousLink() { String query = getQueryWithoutStartIndex(); int prevStart = startIndex - limit; if (prevStart < 0) prevStart = 0; if (prevStart > 0) query += RestConstants.REQUEST_PROPERTY_FOR_START_INDEX + "=" + prevStart; return new Hyperlink("prev", request.getRequestURL().append(query).toString()); } /** * @return the query string from this request, with the startIndex query parameter removed if it * was present */ @SuppressWarnings("unchecked") private String getQueryWithoutStartIndex() { StringBuilder query = new StringBuilder("?"); for (Map.Entry<String, String[]> e : ((Map<String, String[]>) (request.getParameterMap())).entrySet()) { String param = e.getKey(); if (RestConstants.REQUEST_PROPERTY_FOR_START_INDEX.equals(param)) { continue; } for (int i = 0; i < e.getValue().length; ++i) { try { query.append(e.getKey() + "=" + URLEncoder.encode(e.getValue()[i], "UTF-8") + "&"); } catch (UnsupportedEncodingException ex) { throw new RuntimeException("UTF-8 encoding should always be supported", ex); } } } return query.toString(); } /** * Convenience method that returns a parameter value as a string if a request parameter with the * specified name exists in the associated {@link HttpServletRequest} object * * @param name the request parameter name * @return the value * @should return the request parameter of given name if present in the request * @should return null if the wanted request parameter is not present in the request * @should return null if request is null */ public String getParameter(String name) { if (getRequest() == null) { return null; } return getRequest().getParameter(name); } }