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