View Javadoc
1   /*
2    * Copyright 2012-2021 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.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 javax.annotation.Resource;
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpSession;
29  
30  import org.apache.commons.text.StringEscapeUtils;
31  import org.codelibs.core.lang.StringUtil;
32  import org.codelibs.core.net.URLUtil;
33  import org.codelibs.fess.Constants;
34  import org.codelibs.fess.app.web.sso.SsoAction;
35  import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
36  import org.codelibs.fess.helper.LabelTypeHelper;
37  import org.codelibs.fess.helper.OpenSearchHelper;
38  import org.codelibs.fess.helper.PopularWordHelper;
39  import org.codelibs.fess.helper.QueryHelper;
40  import org.codelibs.fess.helper.RoleQueryHelper;
41  import org.codelibs.fess.helper.SearchHelper;
42  import org.codelibs.fess.helper.UserInfoHelper;
43  import org.codelibs.fess.mylasta.action.FessUserBean;
44  import org.codelibs.fess.thumbnail.ThumbnailManager;
45  import org.codelibs.fess.util.ComponentUtil;
46  import org.dbflute.optional.OptionalThing;
47  import org.lastaflute.web.login.LoginManager;
48  import org.lastaflute.web.response.ActionResponse;
49  import org.lastaflute.web.response.HtmlResponse;
50  import org.lastaflute.web.response.next.HtmlNext;
51  import org.lastaflute.web.ruts.process.ActionRuntime;
52  
53  public abstract class FessSearchAction extends FessBaseAction {
54  
55      protected static final String LABEL_FIELD = "label";
56  
57      @Resource
58      protected SearchHelper searchHelper;
59  
60      @Resource
61      protected ThumbnailManager thumbnailManager;
62  
63      @Resource
64      protected LabelTypeHelper labelTypeHelper;
65  
66      @Resource
67      protected QueryHelper queryHelper;
68  
69      @Resource
70      protected RoleQueryHelper roleQueryHelper;
71  
72      @Resource
73      protected UserInfoHelper userInfoHelper;
74  
75      @Resource
76      protected OpenSearchHelper openSearchHelper;
77  
78      @Resource
79      protected PopularWordHelper popularWordHelper;
80  
81      @Resource
82      protected HttpServletRequest request;
83  
84      protected boolean searchLogSupport;
85  
86      protected boolean favoriteSupport;
87  
88      protected boolean thumbnailSupport;
89  
90      @Override
91      public ActionResponse hookBefore(final ActionRuntime runtime) { // application may override
92          searchLogSupport = fessConfig.isSearchLog();
93          favoriteSupport = fessConfig.isUserFavorite();
94          thumbnailSupport = fessConfig.isThumbnailEnabled();
95          runtime.registerData("searchLogSupport", searchLogSupport);
96          runtime.registerData("favoriteSupport", favoriteSupport);
97          runtime.registerData("thumbnailSupport", thumbnailSupport);
98          if (fessConfig.isWebApiPopularWord()) {
99              final List<String> tagList = new ArrayList<>();
100             final String key = ComponentUtil.getVirtualHostHelper().getVirtualHostKey();
101             if (StringUtil.isNotBlank(key)) {
102                 tagList.add(key);
103             }
104             runtime.registerData("popularWords", popularWordHelper.getWordList(SearchRequestType.SEARCH, null,
105                     tagList.toArray(new String[tagList.size()]), null, null, null));
106         }
107         return super.hookBefore(runtime);
108     }
109 
110     @Override
111     protected OptionalThing<LoginManager> myLoginManager() {
112         return OptionalThing.empty();
113     }
114 
115     @Override
116     protected void setupHtmlData(final ActionRuntime runtime) {
117         super.setupHtmlData(runtime);
118         systemHelper.setupSearchHtmlData(this, runtime);
119 
120         runtime.registerData("osddLink", openSearchHelper.hasOpenSearchFile());
121 
122         final List<Map<String, String>> labelTypeItems = labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH,
123                 request.getLocale() == null ? Locale.ROOT : request.getLocale());
124         runtime.registerData("labelTypeItems", labelTypeItems);
125         runtime.registerData("displayLabelTypeItems", labelTypeItems != null && !labelTypeItems.isEmpty());
126 
127         Locale locale = ComponentUtil.getRequestManager().getUserLocale();
128         if (locale == null) {
129             locale = Locale.ENGLISH;
130         }
131         runtime.registerData("langItems", systemHelper.getLanguageItems(locale));
132         final String username = systemHelper.getUsername();
133         runtime.registerData("username", username);
134         runtime.registerData("editableUser", fessLoginAssist.getSavedUserBean().map(FessUserBean::isEditable).orElse(false));
135         runtime.registerData("adminUser", fessConfig.isAdminUser(username) || fessLoginAssist.getSavedUserBean()
136                 .map(user -> user.hasRoles(fessConfig.getAuthenticationAdminRolesAsArray())).orElse(false));
137 
138         runtime.registerData("pageLoginLink", fessConfig.isLoginLinkEnabled());
139     }
140 
141     // ===================================================================================
142     //                                                                             Helpers
143     //                                                                           =========
144     protected boolean isLoginRequired() {
145         if (fessConfig.isLoginRequired() && !fessLoginAssist.getSavedUserBean().isPresent()) {
146             return true;
147         }
148         return false;
149     }
150 
151     protected void buildFormParams(final SearchForm form) {
152 
153         final HttpSession session = request.getSession(false);
154         if (session != null) {
155             final Object resultsPerPage = session.getAttribute(Constants.RESULTS_PER_PAGE);
156             if (resultsPerPage instanceof Integer) {
157                 form.num = (Integer) resultsPerPage;
158             }
159         }
160 
161         // label
162         final List<Map<String, String>> labelTypeItems = labelTypeHelper.getLabelTypeItemList(SearchRequestType.SEARCH,
163                 request.getLocale() == null ? Locale.ROOT : request.getLocale());
164 
165         if (!labelTypeItems.isEmpty() && !form.fields.containsKey(FessSearchAction.LABEL_FIELD)) {
166             final String[] defaultLabelValues = fessConfig.getDefaultLabelValues(getUserBean());
167             if (defaultLabelValues.length > 0) {
168                 form.fields.put(FessSearchAction.LABEL_FIELD, defaultLabelValues);
169             }
170         }
171 
172         final Map<String, String> labelMap = new LinkedHashMap<>();
173         if (!labelTypeItems.isEmpty()) {
174             for (final Map<String, String> map : labelTypeItems) {
175                 labelMap.put(map.get(Constants.ITEM_VALUE), map.get(Constants.ITEM_LABEL));
176             }
177         }
178         request.setAttribute(Constants.LABEL_VALUE_MAP, labelMap);
179 
180         // sort
181         if (StringUtil.isBlank(form.sort)) {
182             final String[] defaultSortValues = fessConfig.getDefaultSortValues(getUserBean());
183             if (defaultSortValues.length == 1) {
184                 form.sort = defaultSortValues[0];
185             } else if (defaultSortValues.length >= 2) {
186                 final StringBuilder sortValueSb = new StringBuilder();
187                 final Set<String> sortFieldNames = new HashSet<>();
188                 for (final String defaultSortValue : defaultSortValues) {
189                     for (final String singleValue : defaultSortValue.split(",")) {
190                         final String sortFieldName = singleValue.split("\\.")[0];
191                         if (!sortFieldNames.contains(sortFieldName)) {
192                             sortFieldNames.add(sortFieldName);
193                             if (sortValueSb.length() > 0) {
194                                 sortValueSb.append(",");
195                             }
196                             sortValueSb.append(singleValue);
197                         }
198                     }
199                 }
200                 form.sort = sortValueSb.toString();
201             }
202         }
203     }
204 
205     protected void buildInitParams() {
206         buildInitParamMap(viewHelper.getInitFacetParamMap(), Constants.FACET_QUERY, Constants.FACET_FORM);
207         buildInitParamMap(viewHelper.getInitGeoParamMap(), Constants.GEO_QUERY, Constants.GEO_FORM);
208     }
209 
210     protected void buildInitParamMap(final Map<String, String> paramMap, final String queryKey, final String formKey) {
211         if (!paramMap.isEmpty()) {
212             final StringBuilder queryBuf = new StringBuilder(100);
213             final StringBuilder formBuf = new StringBuilder(100);
214             for (final Map.Entry<String, String> entry : paramMap.entrySet()) {
215                 queryBuf.append('&');
216                 queryBuf.append(URLUtil.encode(entry.getValue(), Constants.UTF_8));
217                 queryBuf.append('=');
218                 queryBuf.append(URLUtil.encode(entry.getKey(), Constants.UTF_8));
219                 formBuf.append("<input type=\"hidden\" name=\"");
220                 formBuf.append(StringEscapeUtils.escapeHtml4(entry.getValue()));
221                 formBuf.append("\" value=\"");
222                 formBuf.append(StringEscapeUtils.escapeHtml4(entry.getKey()));
223                 formBuf.append("\"/>");
224             }
225             request.setAttribute(queryKey, queryBuf.toString());
226             request.setAttribute(formKey, formBuf.toString());
227         }
228     }
229 
230     protected HtmlResponse redirectToLogin() {
231         return systemHelper.getRedirectResponseToLogin(redirect(SsoAction.class));
232     }
233 
234     protected HtmlResponse redirectToRoot() {
235         return systemHelper.getRedirectResponseToRoot(newHtmlResponseAsRedirect("/"));
236     }
237 
238     protected HtmlNext virtualHost(final HtmlNext path) {
239         return ComponentUtil.getVirtualHostHelper().getVirtualHostPath(path);
240     }
241 }