package org.gbif.occurrence.search.heatmap; import org.gbif.api.model.occurrence.search.OccurrenceSearchParameter; import org.gbif.api.util.SearchTypeValidator; import org.gbif.api.util.VocabularyUtils; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import com.google.common.base.Strings; import com.google.common.collect.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class OccurrenceHeatmapRequestProvider { public static final String POLYGON_PATTERN = "POLYGON((%s))"; public static final String PARAM_QUERY_STRING = "q"; public static final String GEOM_PARAM = "geom"; public static final String ZOOM_PARAM = "z"; private static final int DEFAULT_ZOOM_LEVEL = 3; private static final Logger LOG = LoggerFactory.getLogger(OccurrenceHeatmapRequestProvider.class); /** * Making constructor private. */ private OccurrenceHeatmapRequestProvider() { //empty block } /** * Translate the raw value into value that API understands. */ private static String translateFilterValue(OccurrenceSearchParameter param, String value) { if (param == OccurrenceSearchParameter.GEOMETRY) { try { //checks if the parameters is in WKT format SearchTypeValidator.validate(OccurrenceSearchParameter.GEOMETRY, value); return value; } catch (IllegalArgumentException ex) { //if not is WKT, assumes to be a POLYGON return String.format(POLYGON_PATTERN, value); } } if (Enum.class.isAssignableFrom(param.type())) { return value.toUpperCase(); } return value; } public static OccurrenceHeatmapRequest buildOccurrenceHeatmapRequest(HttpServletRequest request) { OccurrenceHeatmapRequest occurrenceHeatmapSearchRequest = new OccurrenceHeatmapRequest(); String q = request.getParameter(PARAM_QUERY_STRING); if (!Strings.isNullOrEmpty(q)) { occurrenceHeatmapSearchRequest.setQ(q); } // find search parameter enum based filters setSearchParams(occurrenceHeatmapSearchRequest, request); return occurrenceHeatmapSearchRequest; } /** * Iterates over the params map and adds to the search request the recognized parameters (i.e.: those that have a * correspondent value in the P generic parameter). * Empty (of all size) and null parameters are discarded. */ private static void setSearchParams(OccurrenceHeatmapRequest occurrenceHeatmapSearchRequest, HttpServletRequest request) { for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) { OccurrenceSearchParameter p = findSearchParam(entry.getKey()); if (p != null) { for (String val : removeEmptyParameters(entry.getValue())) { String translatedVal = translateFilterValue(p,val); //this transformation is require SearchTypeValidator.validate(p, translatedVal); occurrenceHeatmapSearchRequest.addParameter(p, translatedVal); } } } occurrenceHeatmapSearchRequest.setZoom(getIntParam(request, ZOOM_PARAM, DEFAULT_ZOOM_LEVEL)); if (request.getParameterMap().containsKey(GEOM_PARAM)) { occurrenceHeatmapSearchRequest.setGeometry(request.getParameterMap().get(GEOM_PARAM)[0]); } LOG.debug("Querying using Geometry", occurrenceHeatmapSearchRequest.getGeometry()); } private static OccurrenceSearchParameter findSearchParam(String name) { try { return (OccurrenceSearchParameter) VocabularyUtils.lookupEnum(name, OccurrenceSearchParameter.class); } catch (IllegalArgumentException e) { // we have all params here, not only the enum ones, so this is ok to end up here a few times } return null; } /** * Removes all empty and null parameters from the list. * Each value is trimmed(String.trim()) in order to remove all sizes of empty parameters. */ private static List<String> removeEmptyParameters(String[] parameters) { List<String> cleanParameters = Lists.newArrayListWithCapacity(parameters.length); for (String param : parameters) { String cleanParam = Strings.nullToEmpty(param).trim(); if (!cleanParam.isEmpty()) { cleanParameters.add(cleanParam); } } return cleanParameters; } public static int getIntParam(HttpServletRequest request, String param, int defaultVal) { String[] vals = request.getParameterValues(param); if (vals != null && vals.length > 0) { try { return Integer.parseInt(vals[0]); } catch (NumberFormatException e) { return defaultVal; } } return defaultVal; } }