001/* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014package org.gbif.api.model.common.search; 015 016import org.gbif.api.model.common.paging.Pageable; 017import org.gbif.api.model.common.paging.PageableBase; 018import org.gbif.api.util.IsoDateInterval; 019 020import java.text.DateFormat; 021import java.text.SimpleDateFormat; 022import java.util.Date; 023import java.util.HashMap; 024import java.util.HashSet; 025import java.util.Map; 026import java.util.Set; 027import java.util.StringJoiner; 028 029import static org.gbif.api.model.common.paging.PagingConstants.DEFAULT_PARAM_LIMIT; 030import static org.gbif.api.model.common.paging.PagingConstants.DEFAULT_PARAM_OFFSET; 031 032/** 033 * Generic request class for search operations. This class contains a list of parameters, 034 * a list of desired facets and paging options (page size and offset). 035 */ 036@SuppressWarnings("unused") 037public class SearchRequest<P extends SearchParameter> extends PageableBase { 038 039 private Map<P, Set<String>> parameters = new HashMap<>(); 040 private String q; 041 private boolean highlight; 042 private boolean spellCheck; 043 private int spellCheckCount; 044 private Set<QueryField> qFields = new HashSet<>(); 045 private Set<QueryField> highlightFields = new HashSet<>(); 046 047 public interface QueryField {} 048 049 /** 050 * Constructor with default paging offset & limit. 051 */ 052 public SearchRequest() { 053 super(DEFAULT_PARAM_OFFSET, DEFAULT_PARAM_LIMIT); 054 } 055 056 /** 057 * Simple query constructor with default paging offset & limit. 058 * 059 * @param query string for request 060 */ 061 public SearchRequest(String query) { 062 super(DEFAULT_PARAM_OFFSET, DEFAULT_PARAM_LIMIT); 063 q = query; 064 } 065 066 /** 067 * Minimal paging constructor. 068 */ 069 public SearchRequest(Pageable page) { 070 super(page.getOffset(), page.getLimit()); 071 } 072 073 /** 074 * Minimal paging constructor. 075 */ 076 public SearchRequest(long offset, int limit) { 077 super(offset, limit); 078 } 079 080 081 /** 082 * @return true if highlighted search matches are requested 083 */ 084 public boolean isHighlight() { 085 return highlight; 086 } 087 088 /** 089 * @param highlight the highlight to set 090 */ 091 public void setHighlight(boolean highlight) { 092 this.highlight = highlight; 093 } 094 095 /** 096 * 097 * @return true if spellCheck search is requested 098 */ 099 public boolean isSpellCheck() { 100 return spellCheck; 101 } 102 103 /** 104 * @param spellCheck the highlight to set 105 */ 106 public void setSpellCheck(boolean spellCheck) { 107 this.spellCheck = spellCheck; 108 } 109 110 /** 111 * 112 * @return max number of spell check suggestions requested 113 */ 114 public int getSpellCheckCount() { 115 return spellCheckCount; 116 } 117 118 /** 119 * 120 * @param spellCheckCount number of spell check suggestions 121 */ 122 public void setSpellCheckCount(int spellCheckCount) { 123 this.spellCheckCount = spellCheckCount; 124 } 125 126 /** 127 * Defines whether to match against fields with scientific or vernacular names or both. 128 */ 129 public Set<QueryField> getQFields() { 130 return qFields; 131 } 132 133 public void setQFields(Set<QueryField> qFields) { 134 this.qFields = qFields; 135 } 136 137 /** 138 * Defines the fields to be highlighted if highlighting is activated. 139 */ 140 public Set<QueryField> getHighlightFields() { 141 return highlightFields; 142 } 143 144 public void setHighlightFields(Set<QueryField> highlightFields) { 145 this.highlightFields = highlightFields; 146 } 147 148 /** 149 * List of input parameters of the search operation. 150 * The parameters are handled as the parameter name and the string representation of its value. 151 * 152 * @return the list of parameters 153 */ 154 public Map<P, Set<String>> getParameters() { 155 return parameters; 156 } 157 158 /** 159 * Sets the list of parameters. 160 */ 161 public void setParameters(Map<P, Set<String>> parameters) { 162 this.parameters = parameters; 163 } 164 165 /** 166 * Query parameter. 167 * 168 * @return the q 169 */ 170 public String getQ() { 171 return q; 172 } 173 174 /** 175 * @param q the q to set 176 */ 177 public void setQ(String q) { 178 this.q = q; 179 } 180 181 /** 182 * Adds the specified parameter. 183 * 184 * @param parameter parameter to add values for 185 * @param values list of values of the parameter to add 186 */ 187 public void addParameter(P parameter, Iterable<String> values) { 188 if (parameters.containsKey(parameter)) { 189 Set<String> paramValues = parameters.get(parameter); 190 values.forEach(paramValues::add); 191 } else { 192 Set<String> paramValues = new HashSet<>(); 193 values.forEach(paramValues::add); 194 parameters.put(parameter, paramValues); 195 } 196 } 197 198 /** 199 * Adds the specified parameter. 200 * 201 * @param parameter parameter to add values for 202 * @param values list of values of the parameter to add 203 */ 204 public void addParameter(P parameter, String... values) { 205 for (String value : values) { 206 addParameter(parameter, value); 207 } 208 } 209 210 /** 211 * Adds the specified parameter. 212 * 213 * @param parameter parameter to add values for 214 * @param value value of the parameter to add 215 */ 216 public void addParameter(P parameter, String value) { 217 if (value != null) { 218 if (parameters.containsKey(parameter)) { 219 Set<String> paramValues = parameters.get(parameter); 220 paramValues.add(value); 221 } else { 222 Set<String> paramValues = new HashSet<>(); 223 paramValues.add(value); 224 parameters.put(parameter, paramValues); 225 } 226 } 227 } 228 229 /** 230 * Adds the specified long parameter. 231 * 232 * @param parameter parameter to add values for 233 * @param value value of the parameter to add 234 */ 235 public void addParameter(P parameter, long value) { 236 addParameter(parameter, String.valueOf(value)); 237 } 238 239 /** 240 * Adds the specified int parameter. 241 * 242 * @param parameter parameter to add values for 243 * @param value value of the parameter to add 244 */ 245 public void addParameter(P parameter, int value) { 246 addParameter(parameter, String.valueOf(value)); 247 } 248 249 /** 250 * Adds the specified double parameter. 251 * 252 * @param parameter parameter to add values for 253 * @param value value of the parameter to add 254 */ 255 public void addParameter(P parameter, double value) { 256 addParameter(parameter, String.valueOf(value)); 257 } 258 259 /** 260 * Adds the specified boolean parameter. 261 * 262 * @param parameter parameter to add values for 263 * @param value value of the parameter to add 264 */ 265 public void addParameter(P parameter, boolean value) { 266 addParameter(parameter, String.valueOf(value)); 267 } 268 269 /** 270 * Adds the specified parameter. 271 * 272 * @param parameter parameter to add values for 273 * @param value enum value of the parameter to add 274 */ 275 public void addParameter(P parameter, Enum<?> value) { 276 if (value != null) { 277 addParameter(parameter, value.name()); 278 } 279 } 280 281 /** 282 * Adds the specified date parameter as an ISO date. 283 * 284 * @param parameter parameter to add date for 285 * @param value date value of the parameter to add 286 */ 287 public void addParameter(P parameter, Date value) { 288 if (value != null) { 289 // not thread safe, new instance 290 DateFormat iso = new SimpleDateFormat("yyyy-MM-dd"); 291 addParameter(parameter, iso.format(value)); 292 } 293 } 294 295 /** 296 * Adds the specified date parameter as an ISO date interval. 297 * 298 * @param parameter parameter to add date interval for 299 * @param value date value of the parameter to add 300 */ 301 public void addParameter(P parameter, IsoDateInterval value) { 302 if (value != null) { 303 addParameter(parameter, value.toString()); 304 } 305 } 306 307 @Override 308 public String toString() { 309 return new StringJoiner(", ", SearchRequest.class.getSimpleName() + "[", "]") 310 .add("parameters=" + parameters) 311 .add("q='" + q + "'") 312 .add("highlight=" + highlight) 313 .add("spellCheck=" + spellCheck) 314 .add("spellCheckCount=" + spellCheckCount) 315 .add("offset=" + offset) 316 .add("limit=" + limit) 317 .toString(); 318 } 319}