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.app.web.admin.searchlog;
17
18 import org.codelibs.fess.Constants;
19 import org.codelibs.fess.annotation.Secured;
20 import org.codelibs.fess.app.pager.SearchLogPager;
21 import org.codelibs.fess.app.service.SearchLogService;
22 import org.codelibs.fess.app.web.CrudMode;
23 import org.codelibs.fess.app.web.base.FessAdminAction;
24 import org.codelibs.fess.util.RenderDataUtil;
25 import org.lastaflute.web.Execute;
26 import org.lastaflute.web.response.HtmlResponse;
27 import org.lastaflute.web.response.render.RenderData;
28 import org.lastaflute.web.ruts.process.ActionRuntime;
29
30 import jakarta.annotation.Resource;
31
32 /**
33 * Admin action for Search Log.
34 *
35 */
36 public class AdminSearchlogAction extends FessAdminAction {
37
38 /**
39 * Default constructor.
40 */
41 public AdminSearchlogAction() {
42 super();
43 }
44
45 /** Role name for admin search log operations */
46 public static final String ROLE = "admin-searchlog";
47
48 private static final String[] CONDITION_FIELDS =
49 { "logType", "queryId", "userSessionId", "accessType", "requestedTimeRange", "pageSize" };
50
51 // ===================================================================================
52 // Attribute
53 // =========
54 /** Service for managing search log data */
55 @Resource
56 private SearchLogService searchLogService;
57 /** Pager for paginating search log results */
58 @Resource
59 private SearchLogPager searchLogPager;
60
61 // ===================================================================================
62 // Hook
63 // ======
64 @Override
65 protected void setupHtmlData(final ActionRuntime runtime) {
66 super.setupHtmlData(runtime);
67 runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameSearchlog()));
68 }
69
70 @Override
71 protected String getActionRole() {
72 return ROLE;
73 }
74
75 // ===================================================================================
76 // Search Execute
77 // ==============
78 /**
79 * Displays the search log management index page.
80 *
81 * @return HTML response for the search log list page
82 */
83 @Execute
84 @Secured({ ROLE, ROLE + VIEW })
85 public HtmlResponse index() {
86 saveToken();
87 return asListHtml();
88 }
89
90 /**
91 * Displays a paginated list of search log entries.
92 *
93 * @param pageNumber the page number to display
94 * @param form the search form containing filter criteria
95 * @return HTML response with the search log list
96 */
97 @Execute
98 @Secured({ ROLE, ROLE + VIEW })
99 public HtmlResponse list(final Integer pageNumber, final SearchForm form) {
100 saveToken();
101 searchLogPager.setCurrentPageNumber(pageNumber);
102 return asHtml(path_AdminSearchlog_AdminSearchlogJsp).renderWith(data -> {
103 searchPaging(data, form);
104 });
105 }
106
107 /**
108 * Searches for search log entries based on the provided search criteria.
109 *
110 * @param form the search form containing search criteria
111 * @return HTML response with filtered search log results
112 */
113 @Execute
114 @Secured({ ROLE, ROLE + VIEW })
115 public HtmlResponse search(final SearchForm form) {
116 saveToken();
117 searchLogPager.clear();
118 copyBeanToBean(form, searchLogPager, op -> op.exclude(Constants.PAGER_CONVERSION_RULE));
119 searchLogPager.setPageSize(form.getPageSize());
120 return asHtml(path_AdminSearchlog_AdminSearchlogJsp).renderWith(data -> {
121 searchPaging(data, form);
122 });
123 }
124
125 /**
126 * Resets the search criteria and displays all search log entries.
127 *
128 * @param form the search form to reset
129 * @return HTML response with the reset search log list
130 */
131 @Execute
132 @Secured({ ROLE, ROLE + VIEW })
133 public HtmlResponse reset(final SearchForm form) {
134 saveToken();
135 searchLogPager.clear();
136 return asHtml(path_AdminSearchlog_AdminSearchlogJsp).renderWith(data -> {
137 searchPaging(data, form);
138 });
139 }
140
141 /**
142 * Returns to the search log list from a detail view.
143 *
144 * @param form the search form containing current state
145 * @return HTML response for the search log list page
146 */
147 @Execute
148 @Secured({ ROLE, ROLE + VIEW })
149 public HtmlResponse back(final SearchForm form) {
150 saveToken();
151 return asHtml(path_AdminSearchlog_AdminSearchlogJsp).renderWith(data -> {
152 searchPaging(data, form);
153 });
154 }
155
156 /**
157 * Sets up search paging data for rendering the search log list.
158 *
159 * @param data the render data to populate
160 * @param form the search form containing current search criteria
161 */
162 protected void searchPaging(final RenderData data, final SearchForm form) {
163 RenderDataUtil.register(data, "searchLogItems", searchLogService.getSearchLogList(searchLogPager)); // page navi
164
165 // restore from pager
166 copyBeanToBean(searchLogPager, form, op -> op.include(CONDITION_FIELDS));
167 }
168
169 // ===================================================================================
170 // Edit Execute
171 // ============
172
173 // -----------------------------------------------------
174 // Details
175 // -------
176 /**
177 * Displays the details of a specific search log entry.
178 *
179 * @param crudMode the CRUD mode for the operation
180 * @param logType the type of log entry
181 * @param id the ID of the search log entry to display
182 * @return HTML response for the search log details page
183 */
184 @Execute
185 @Secured({ ROLE, ROLE + VIEW })
186 public HtmlResponse details(final int crudMode, final String logType, final String id) {
187 verifyCrudMode(crudMode, CrudMode.DETAILS, this::asListHtml);
188 saveToken();
189 return asDetailsHtml().useForm(EditForm.class, op -> {
190 op.setup(form -> {
191 form.id = id;
192 form.logType = logType;
193 form.crudMode = crudMode;
194 });
195 }).renderWith(data -> {
196 RenderDataUtil.register(data, "logParamItems", searchLogService.getSearchLogMap(logType, id));
197 });
198 }
199
200 // -----------------------------------------------------
201 // Actually Crud
202 // -------------
203 /**
204 * Deletes a specific search log entry.
205 *
206 * @param form the edit form containing the log entry information
207 * @return HTML response redirecting to the list page after deletion
208 */
209 @Execute
210 @Secured({ ROLE })
211 public HtmlResponse delete(final EditForm form) {
212 verifyCrudMode(form.crudMode, CrudMode.DETAILS, this::asListHtml);
213 validate(form, messages -> {}, this::asDetailsHtml);
214 verifyToken(this::asDetailsHtml);
215 searchLogService.getSearchLog(form.logType, form.id).alwaysPresent(e -> {
216 searchLogService.deleteSearchLog(e);
217 saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
218 });
219 return redirect(getClass());
220 }
221
222 /**
223 * Deletes all search log entries.
224 *
225 * @return HTML response redirecting to the list page after deletion
226 */
227 @Execute
228 @Secured({ ROLE })
229 public HtmlResponse deleteall() {
230 verifyToken(this::asListHtml);
231 searchLogPager.clear();
232 // TODO delete logs
233 saveInfo(messages -> messages.addSuccessCrawlingInfoDeleteAll(GLOBAL));
234 return redirect(getClass());
235 }
236
237 // ===================================================================================
238 // Assist Logic
239 // ============
240
241 // ===================================================================================
242 // Small Helper
243 // ============
244 // JSP
245 // =========
246
247 private HtmlResponse asListHtml() {
248 return asHtml(path_AdminSearchlog_AdminSearchlogJsp).renderWith(data -> {
249 RenderDataUtil.register(data, "searchLogItems", searchLogService.getSearchLogList(searchLogPager)); // page navi
250 }).useForm(SearchForm.class, setup -> {
251 setup.setup(form -> {
252 copyBeanToBean(searchLogPager, form, op -> op.include(CONDITION_FIELDS));
253 });
254 });
255 }
256
257 private HtmlResponse asDetailsHtml() {
258 return asHtml(path_AdminSearchlog_AdminSearchlogDetailsJsp);
259 }
260 }