View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.entity;
17  
18  import static org.codelibs.core.stream.StreamUtil.stream;
19  
20  import java.util.Locale;
21  import java.util.Map;
22  
23  import org.codelibs.core.lang.StringUtil;
24  import org.codelibs.fess.util.ComponentUtil;
25  
26  import jakarta.servlet.http.HttpServletRequest;
27  
28  /**
29   * The search request parameters.
30   */
31  public abstract class SearchRequestParams {
32  
33      /**
34       * Default constructor.
35       */
36      protected SearchRequestParams() {
37          // Default constructor
38      }
39  
40      /** The parameter for negative query. */
41      public static final String AS_NQ = "nq";
42  
43      /** The parameter for OR query. */
44      public static final String AS_OQ = "oq";
45  
46      /** The parameter for exact phrase query. */
47      public static final String AS_EPQ = "epq";
48  
49      /** The parameter for query. */
50      public static final String AS_Q = "q";
51  
52      /** The parameter for filetype. */
53      public static final String AS_FILETYPE = "filetype";
54  
55      /** The parameter for sitesearch. */
56      public static final String AS_SITESEARCH = "sitesearch";
57  
58      /** The parameter for occurrence. */
59      public static final String AS_OCCURRENCE = "occt";
60  
61      /** The parameter for timestamp. */
62      public static final String AS_TIMESTAMP = "timestamp";
63  
64      /**
65       * Returns the query.
66       *
67       * @return The query.
68       */
69      public abstract String getQuery();
70  
71      /**
72       * Returns the fields.
73       *
74       * @return The fields.
75       */
76      public abstract Map<String, String[]> getFields();
77  
78      /**
79       * Returns the conditions.
80       *
81       * @return The conditions.
82       */
83      public abstract Map<String, String[]> getConditions();
84  
85      /**
86       * Returns the languages.
87       *
88       * @return The languages.
89       */
90      public abstract String[] getLanguages();
91  
92      /**
93       * Returns the geo info.
94       *
95       * @return The geo info.
96       */
97      public abstract GeoInfo getGeoInfo();
98  
99      /**
100      * Returns the facet info.
101      *
102      * @return The facet info.
103      */
104     public abstract FacetInfo getFacetInfo();
105 
106     /**
107      * Returns the highlight info.
108      *
109      * @return The highlight info.
110      */
111     public abstract HighlightInfo getHighlightInfo();
112 
113     /**
114      * Returns the sort.
115      *
116      * @return The sort.
117      */
118     public abstract String getSort();
119 
120     /**
121      * Returns the start position.
122      *
123      * @return The start position.
124      */
125     public abstract int getStartPosition();
126 
127     /**
128      * Returns the page size.
129      *
130      * @return The page size.
131      */
132     public abstract int getPageSize();
133 
134     /**
135      * Returns the offset.
136      *
137      * @return The offset.
138      */
139     public abstract int getOffset();
140 
141     /**
142      * Returns the extra queries.
143      *
144      * @return The extra queries.
145      */
146     public abstract String[] getExtraQueries();
147 
148     /**
149      * Returns the attribute.
150      *
151      * @param name The name of the attribute.
152      * @return The attribute.
153      */
154     public abstract Object getAttribute(String name);
155 
156     /**
157      * Returns the locale.
158      *
159      * @return The locale.
160      */
161     public abstract Locale getLocale();
162 
163     /**
164      * Returns the search request type.
165      *
166      * @return The search request type.
167      */
168     public abstract SearchRequestType getType();
169 
170     /**
171      * Returns the similar document hash.
172      *
173      * @return The similar document hash.
174      */
175     public abstract String getSimilarDocHash();
176 
177     /**
178      * Returns the track total hits.
179      *
180      * @return The track total hits.
181      */
182     public String getTrackTotalHits() {
183         return null;
184     }
185 
186     /**
187      * Returns the min score.
188      *
189      * @return The min score.
190      */
191     public Float getMinScore() {
192         return null;
193     }
194 
195     /**
196      * Returns true if the request has a condition query, otherwise false.
197      *
198      * @return True if the request has a condition query, otherwise false.
199      */
200     public boolean hasConditionQuery() {
201         final Map<String, String[]> conditions = getConditions();
202         return !isEmptyArray(conditions.get(AS_Q))//
203                 || !isEmptyArray(conditions.get(AS_EPQ))//
204                 || !isEmptyArray(conditions.get(AS_OQ))//
205                 || !isEmptyArray(conditions.get(AS_NQ))//
206                 || !isEmptyArray(conditions.get(AS_TIMESTAMP))//
207                 || !isEmptyArray(conditions.get(AS_SITESEARCH))//
208                 || !isEmptyArray(conditions.get(AS_FILETYPE));
209     }
210 
211     /**
212      * Returns true if the array is empty, otherwise false.
213      *
214      * @param values The array.
215      * @return True if the array is empty, otherwise false.
216      */
217     protected boolean isEmptyArray(final String[] values) {
218         if (values == null || values.length == 0) {
219             return true;
220         }
221         return stream(values).get(stream -> stream.allMatch(StringUtil::isBlank));
222     }
223 
224     /**
225      * Simplifies the array.
226      *
227      * @param values The array.
228      * @return The simplified array.
229      */
230     protected static String[] simplifyArray(final String[] values) {
231         return stream(values).get(stream -> stream.filter(StringUtil::isNotBlank).distinct().toArray(n -> new String[n]));
232     }
233 
234     /**
235      * Returns the parameter value array.
236      *
237      * @param request The request.
238      * @param param The parameter.
239      * @return The parameter value array.
240      */
241     public static String[] getParamValueArray(final HttpServletRequest request, final String param) {
242         return simplifyArray(request.getParameterValues(param));
243     }
244 
245     /**
246      * Creates a facet info.
247      *
248      * @param request The request.
249      * @return The facet info.
250      */
251     protected FacetInfo createFacetInfo(final HttpServletRequest request) {
252         final String[] fields = getParamValueArray(request, "facet.field");
253         final String[] queries = getParamValueArray(request, "facet.query");
254         if (fields.length == 0 && queries.length == 0) {
255             return null;
256         }
257         final FacetInfo facetInfo = new FacetInfo();
258         facetInfo.field = fields;
259         facetInfo.query = queries;
260         final String sizeStr = request.getParameter("facet.size");
261         if (StringUtil.isNotBlank(sizeStr)) {
262             facetInfo.size = Integer.parseInt(sizeStr);
263         }
264         final String minDocCountStr = request.getParameter("facet.minDocCount");
265         if (StringUtil.isNotBlank(minDocCountStr)) {
266             facetInfo.minDocCount = Long.parseLong(minDocCountStr);
267         }
268         final String sort = request.getParameter("facet.sort");
269         if (StringUtil.isNotBlank(sort)) {
270             facetInfo.sort = sort;
271         }
272         final String missing = request.getParameter("facet.missing");
273         if (StringUtil.isNotBlank(missing)) {
274             facetInfo.missing = missing;
275         }
276         return facetInfo;
277     }
278 
279     /**
280      * Creates a geo info.
281      *
282      * @param request The request.
283      * @return The geo info.
284      */
285     protected GeoInfo createGeoInfo(final HttpServletRequest request) {
286         return new GeoInfo(request);
287     }
288 
289     /**
290      * The search request type.
291      */
292     public enum SearchRequestType {
293         /** Search request type. */
294         SEARCH,
295         /** Admin search request type. */
296         ADMIN_SEARCH,
297         /** JSON request type. */
298         JSON,
299         /** GSA request type. */
300         GSA,
301         /** Suggest request type. */
302         SUGGEST;
303     }
304 
305     /**
306      * Returns the response fields.
307      *
308      * @return The response fields.
309      */
310     public String[] getResponseFields() {
311         return ComponentUtil.getQueryFieldConfig().getResponseFields();
312     }
313 }