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