1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.app.web.base;
17
18 import java.util.ArrayList;
19 import java.util.HashSet;
20 import java.util.LinkedHashMap;
21 import java.util.List;
22 import java.util.Locale;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.apache.commons.text.StringEscapeUtils;
27 import org.codelibs.core.lang.StringUtil;
28 import org.codelibs.core.net.URLUtil;
29 import org.codelibs.fess.Constants;
30 import org.codelibs.fess.app.web.sso.SsoAction;
31 import org.codelibs.fess.chat.ChatClient;
32 import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
33 import org.codelibs.fess.helper.LabelTypeHelper;
34 import org.codelibs.fess.helper.OsddHelper;
35 import org.codelibs.fess.helper.PopularWordHelper;
36 import org.codelibs.fess.helper.QueryHelper;
37 import org.codelibs.fess.helper.RoleQueryHelper;
38 import org.codelibs.fess.helper.SearchHelper;
39 import org.codelibs.fess.helper.UserInfoHelper;
40 import org.codelibs.fess.mylasta.action.FessUserBean;
41 import org.codelibs.fess.query.QueryFieldConfig;
42 import org.codelibs.fess.thumbnail.ThumbnailManager;
43 import org.codelibs.fess.util.ComponentUtil;
44 import org.dbflute.optional.OptionalThing;
45 import org.lastaflute.web.login.LoginManager;
46 import org.lastaflute.web.response.ActionResponse;
47 import org.lastaflute.web.response.HtmlResponse;
48 import org.lastaflute.web.response.next.HtmlNext;
49 import org.lastaflute.web.ruts.process.ActionRuntime;
50
51 import jakarta.annotation.Resource;
52 import jakarta.servlet.http.HttpServletRequest;
53 import jakarta.servlet.http.HttpSession;
54
55
56
57
58
59
60
61
62
63 public abstract class FessSearchAction extends FessBaseAction {
64
65
66
67
68 public FessSearchAction() {
69 super();
70 }
71
72
73 protected static final String LABEL_FIELD = "label";
74
75
76 @Resource
77 protected SearchHelper searchHelper;
78
79
80 @Resource
81 protected ThumbnailManager thumbnailManager;
82
83
84 @Resource
85 protected LabelTypeHelper labelTypeHelper;
86
87
88 @Resource
89 protected QueryHelper queryHelper;
90
91
92 @Resource
93 protected QueryFieldConfig queryFieldConfig;
94
95
96 @Resource
97 protected RoleQueryHelper roleQueryHelper;
98
99
100 @Resource
101 protected UserInfoHelper userInfoHelper;
102
103
104 @Resource
105 protected OsddHelper osddHelper;
106
107
108 @Resource
109 protected PopularWordHelper popularWordHelper;
110
111
112 @Resource
113 protected ChatClient chatClient;
114
115
116 @Resource
117 protected HttpServletRequest request;
118
119
120 protected boolean searchLogSupport;
121
122
123 protected boolean favoriteSupport;
124
125
126 protected boolean thumbnailSupport;
127
128
129
130
131
132
133
134
135 @Override
136 public ActionResponse hookBefore(final ActionRuntime runtime) {
137 searchLogSupport = fessConfig.isSearchLog();
138 favoriteSupport = fessConfig.isUserFavorite();
139 thumbnailSupport = fessConfig.isThumbnailEnabled();
140 runtime.registerData("searchLogSupport", searchLogSupport);
141 runtime.registerData("favoriteSupport", favoriteSupport);
142 runtime.registerData("thumbnailSupport", thumbnailSupport);
143 if (fessConfig.isWebApiPopularWord()) {
144 final List<String> tagList = new ArrayList<>();
145 final String key = ComponentUtil.getVirtualHostHelper().getVirtualHostKey();
146 if (StringUtil.isNotBlank(key)) {
147 tagList.add(key);
148 }
149 runtime.registerData("popularWords", popularWordHelper.getWordList(SearchRequestType.SEARCH, null,
150 tagList.toArray(new String[tagList.size()]), null, null, null));
151 }
152 return super.hookBefore(runtime);
153 }
154
155
156
157
158
159
160
161 @Override
162 protected OptionalThing<LoginManager> myLoginManager() {
163 return OptionalThing.empty();
164 }
165
166
167
168
169
170
171
172 @Override
173 protected void setupHtmlData(final ActionRuntime runtime) {
174 super.setupHtmlData(runtime);
175 systemHelper.setupSearchHtmlData(this, runtime);
176
177 runtime.registerData("osddLink", osddHelper.hasOpenSearchFile());
178 runtime.registerData("clipboardCopyIcon", fessConfig.isClipboardCopyIconEnabled());
179
180 final List<Map<String, String>> labelTypeItems = labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH,
181 request.getLocale() == null ? Locale.ROOT : request.getLocale());
182 runtime.registerData("labelTypeItems", labelTypeItems);
183 runtime.registerData("displayLabelTypeItems", labelTypeItems != null && !labelTypeItems.isEmpty());
184
185 Locale locale = ComponentUtil.getRequestManager().getUserLocale();
186 if (locale == null) {
187 locale = Locale.ENGLISH;
188 }
189 runtime.registerData("langItems", systemHelper.getLanguageItems(locale));
190 final String username = systemHelper.getUsername();
191 runtime.registerData("username", username);
192 runtime.registerData("editableUser", fessLoginAssist.getSavedUserBean().map(FessUserBean::isEditable).orElse(false));
193 runtime.registerData("adminUser",
194 fessConfig.isAdminUser(username) || fessLoginAssist.getSavedUserBean()
195 .map(user -> user.hasRoles(fessConfig.getAuthenticationAdminRolesAsArray()))
196 .orElse(false));
197
198 runtime.registerData("pageLoginLink", fessConfig.isLoginLinkEnabled());
199 runtime.registerData("chatEnabled", chatClient.isAvailable());
200 }
201
202
203
204
205
206
207
208
209
210
211
212 protected boolean isLoginRequired() {
213 if (fessConfig.isLoginRequired() && !fessLoginAssist.getSavedUserBean().isPresent()) {
214 return true;
215 }
216 return false;
217 }
218
219
220
221
222
223
224
225 protected void buildFormParams(final SearchForm form) {
226
227 final HttpSession session = request.getSession(false);
228 if (session != null) {
229 final Object resultsPerPage = session.getAttribute(Constants.RESULTS_PER_PAGE);
230 if (resultsPerPage instanceof Integer) {
231 form.num = (Integer) resultsPerPage;
232 }
233 }
234
235
236 final List<Map<String, String>> labelTypeItems = labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH,
237 request.getLocale() == null ? Locale.ROOT : request.getLocale());
238
239 if (!labelTypeItems.isEmpty() && !form.fields.containsKey(FessSearchAction.LABEL_FIELD)) {
240 final String[] defaultLabelValues = fessConfig.getDefaultLabelValues(getUserBean());
241 if (defaultLabelValues.length > 0) {
242 form.fields.put(FessSearchAction.LABEL_FIELD, defaultLabelValues);
243 }
244 }
245
246 final Map<String, String> labelMap = new LinkedHashMap<>();
247 if (!labelTypeItems.isEmpty()) {
248 for (final Map<String, String> map : labelTypeItems) {
249 labelMap.put(map.get(Constants.ITEM_VALUE), map.get(Constants.ITEM_LABEL));
250 }
251 }
252 request.setAttribute(Constants.LABEL_VALUE_MAP, labelMap);
253
254
255 if (StringUtil.isBlank(form.sort)) {
256 final String[] defaultSortValues = fessConfig.getDefaultSortValues(getUserBean());
257 if (defaultSortValues.length == 1) {
258 form.sort = defaultSortValues[0];
259 } else if (defaultSortValues.length >= 2) {
260 final StringBuilder sortValueSb = new StringBuilder();
261 final Set<String> sortFieldNames = new HashSet<>();
262 for (final String defaultSortValue : defaultSortValues) {
263 for (final String singleValue : defaultSortValue.split(",")) {
264 final String sortFieldName = singleValue.split("\\.")[0];
265 if (!sortFieldNames.contains(sortFieldName)) {
266 sortFieldNames.add(sortFieldName);
267 if (sortValueSb.length() > 0) {
268 sortValueSb.append(",");
269 }
270 sortValueSb.append(singleValue);
271 }
272 }
273 }
274 form.sort = sortValueSb.toString();
275 }
276 }
277 }
278
279
280
281
282
283 protected void buildInitParams() {
284 buildInitParamMap(viewHelper.getInitFacetParamMap(), Constants.FACET_QUERY, Constants.FACET_FORM);
285 buildInitParamMap(viewHelper.getInitGeoParamMap(), Constants.GEO_QUERY, Constants.GEO_FORM);
286 }
287
288
289
290
291
292
293
294
295
296 protected void buildInitParamMap(final Map<String, String> paramMap, final String queryKey, final String formKey) {
297 if (!paramMap.isEmpty()) {
298 final StringBuilder queryBuf = new StringBuilder(100);
299 final StringBuilder formBuf = new StringBuilder(100);
300 for (final Map.Entry<String, String> entry : paramMap.entrySet()) {
301 queryBuf.append('&');
302 queryBuf.append(URLUtil.encode(entry.getValue(), Constants.UTF_8));
303 queryBuf.append('=');
304 queryBuf.append(URLUtil.encode(entry.getKey(), Constants.UTF_8));
305 formBuf.append("<input type=\"hidden\" name=\"");
306 formBuf.append(StringEscapeUtils.escapeHtml4(entry.getValue()));
307 formBuf.append("\" value=\"");
308 formBuf.append(StringEscapeUtils.escapeHtml4(entry.getKey()));
309 formBuf.append("\"/>");
310 }
311 request.setAttribute(queryKey, queryBuf.toString());
312 request.setAttribute(formKey, formBuf.toString());
313 }
314 }
315
316
317
318
319
320
321
322 protected HtmlResponse redirectToLogin() {
323 searchHelper.storeSearchParameters();
324 return systemHelper.getRedirectResponseToLogin(redirect(SsoAction.class));
325 }
326
327
328
329
330
331
332 protected HtmlResponse redirectToRoot() {
333 return systemHelper.getRedirectResponseToRoot(newHtmlResponseAsRedirect("/"));
334 }
335
336
337
338
339
340
341
342
343 protected HtmlNext virtualHost(final HtmlNext path) {
344 return ComponentUtil.getVirtualHostHelper().getVirtualHostPath(path);
345 }
346 }