1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.app.web.admin.elevateword;
17
18 import static org.codelibs.core.stream.StreamUtil.split;
19 import static org.codelibs.core.stream.StreamUtil.stream;
20
21 import java.io.BufferedReader;
22 import java.io.BufferedWriter;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.io.OutputStreamWriter;
26 import java.io.Reader;
27 import java.io.Writer;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30 import java.util.stream.Collectors;
31 import java.util.stream.Stream;
32
33 import org.apache.logging.log4j.LogManager;
34 import org.apache.logging.log4j.Logger;
35 import org.codelibs.core.beans.util.BeanUtil;
36 import org.codelibs.core.concurrent.CommonPoolUtil;
37 import org.codelibs.core.lang.StringUtil;
38 import org.codelibs.fess.Constants;
39 import org.codelibs.fess.annotation.Secured;
40 import org.codelibs.fess.app.pager.ElevateWordPager;
41 import org.codelibs.fess.app.service.ElevateWordService;
42 import org.codelibs.fess.app.service.LabelTypeService;
43 import org.codelibs.fess.app.web.CrudMode;
44 import org.codelibs.fess.app.web.base.FessAdminAction;
45 import org.codelibs.fess.exception.FessSystemException;
46 import org.codelibs.fess.helper.PermissionHelper;
47 import org.codelibs.fess.helper.SuggestHelper;
48 import org.codelibs.fess.helper.SystemHelper;
49 import org.codelibs.fess.opensearch.config.exentity.ElevateWord;
50 import org.codelibs.fess.util.ComponentUtil;
51 import org.codelibs.fess.util.RenderDataUtil;
52 import org.dbflute.optional.OptionalEntity;
53 import org.dbflute.optional.OptionalThing;
54 import org.lastaflute.web.Execute;
55 import org.lastaflute.web.response.ActionResponse;
56 import org.lastaflute.web.response.HtmlResponse;
57 import org.lastaflute.web.response.render.RenderData;
58 import org.lastaflute.web.ruts.process.ActionRuntime;
59
60 import jakarta.annotation.Resource;
61
62
63
64
65
66 public class AdminElevatewordAction extends FessAdminAction {
67
68
69
70
71 public AdminElevatewordAction() {
72 super();
73 }
74
75
76 public static final String ROLE = "admin-elevateword";
77
78 private static final Logger logger = LogManager.getLogger(AdminElevatewordAction.class);
79
80
81
82
83 @Resource
84 private ElevateWordService elevateWordService;
85 @Resource
86 private ElevateWordPager elevateWordPager;
87
88 @Resource
89 protected SuggestHelper suggestHelper;
90 @Resource
91 private LabelTypeService labelTypeService;
92
93
94
95
96 @Override
97 protected void setupHtmlData(final ActionRuntime runtime) {
98 super.setupHtmlData(runtime);
99 runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameElevateword()));
100 }
101
102 @Override
103 protected String getActionRole() {
104 return ROLE;
105 }
106
107
108
109
110
111
112
113
114
115 @Execute
116 @Secured({ ROLE, ROLE + VIEW })
117 public HtmlResponse index() {
118 return asListHtml();
119 }
120
121
122
123
124
125
126
127
128 @Execute
129 @Secured({ ROLE, ROLE + VIEW })
130 public HtmlResponse list(final OptionalThing<Integer> pageNumber, final SearchForm form) {
131 pageNumber.ifPresent(num -> {
132 elevateWordPager.setCurrentPageNumber(pageNumber.get());
133 }).orElse(() -> {
134 elevateWordPager.setCurrentPageNumber(0);
135 });
136 return asHtml(path_AdminElevateword_AdminElevatewordJsp).renderWith(data -> {
137 searchPaging(data, form);
138 });
139 }
140
141
142
143
144
145
146
147 @Execute
148 @Secured({ ROLE, ROLE + VIEW })
149 public HtmlResponse search(final SearchForm form) {
150 copyBeanToBean(form, elevateWordPager, op -> op.exclude(Constants.PAGER_CONVERSION_RULE));
151 return asHtml(path_AdminElevateword_AdminElevatewordJsp).renderWith(data -> {
152 searchPaging(data, form);
153 });
154 }
155
156
157
158
159
160
161
162 @Execute
163 @Secured({ ROLE, ROLE + VIEW })
164 public HtmlResponse reset(final SearchForm form) {
165 elevateWordPager.clear();
166 return asHtml(path_AdminElevateword_AdminElevatewordJsp).renderWith(data -> {
167 searchPaging(data, form);
168 });
169 }
170
171
172
173
174
175
176
177 protected void searchPaging(final RenderData data, final SearchForm form) {
178 RenderDataUtil.register(data, "elevateWordItems", elevateWordService.getElevateWordList(elevateWordPager));
179
180
181 copyBeanToBean(elevateWordPager, form, op -> op.include("id"));
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195 @Execute
196 @Secured({ ROLE })
197 public HtmlResponse createnew() {
198 saveToken();
199 return asHtml(path_AdminElevateword_AdminElevatewordEditJsp).useForm(CreateForm.class, op -> {
200 op.setup(form -> {
201 form.initialize();
202 form.crudMode = CrudMode.CREATE;
203 });
204 }).renderWith(data -> {
205 registerLabels(data);
206 });
207 }
208
209
210
211
212
213
214
215 @Execute
216 @Secured({ ROLE })
217 public HtmlResponse edit(final EditForm form) {
218 validate(form, messages -> {}, this::asListHtml);
219 final String id = form.id;
220 elevateWordService.getElevateWord(id).ifPresent(entity -> {
221 copyBeanToBean(entity, form, copyOp -> {
222 copyOp.excludeNull();
223 copyOp.exclude(Constants.PERMISSIONS);
224 });
225 final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
226 form.permissions = stream(entity.getPermissions()).get(stream -> stream.map(s -> permissionHelper.decode(s))
227 .filter(StringUtil::isNotBlank)
228 .distinct()
229 .collect(Collectors.joining("\n")));
230 }).orElse(() -> {
231 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), this::asListHtml);
232 });
233 saveToken();
234 if (form.crudMode.intValue() == CrudMode.EDIT) {
235
236 form.crudMode = CrudMode.DETAILS;
237 return asDetailsHtml();
238 }
239 form.crudMode = CrudMode.EDIT;
240 return asEditHtml();
241 }
242
243
244
245
246
247
248
249
250
251
252
253 @Execute
254 @Secured({ ROLE, ROLE + VIEW })
255 public HtmlResponse details(final int crudMode, final String id) {
256 verifyCrudMode(crudMode, CrudMode.DETAILS, this::asListHtml);
257 saveToken();
258 final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
259 return asHtml(path_AdminElevateword_AdminElevatewordDetailsJsp).useForm(EditForm.class, op -> op.setup(form -> {
260 elevateWordService.getElevateWord(id).ifPresent(entity -> {
261 copyBeanToBean(entity, form, copyOp -> {
262 copyOp.excludeNull();
263 copyOp.exclude(Constants.PERMISSIONS);
264 });
265 form.permissions = stream(entity.getPermissions()).get(stream -> stream.map(permissionHelper::decode)
266 .filter(StringUtil::isNotBlank)
267 .distinct()
268 .collect(Collectors.joining("\n")));
269 form.crudMode = crudMode;
270 }).orElse(() -> throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), this::asListHtml));
271 })).renderWith(this::registerLabels);
272 }
273
274
275
276
277
278
279
280
281
282 @Execute
283 @Secured({ ROLE, ROLE + VIEW })
284 public HtmlResponse downloadpage() {
285 saveToken();
286 return asDownloadHtml();
287 }
288
289
290
291
292
293
294
295 @Execute
296 @Secured({ ROLE, ROLE + VIEW })
297 public ActionResponse download(final DownloadForm form) {
298 verifyToken(this::asDownloadHtml);
299
300 return asStream("elevate.csv").contentTypeOctetStream().stream(out -> {
301 final Path tempFile = ComponentUtil.getSystemHelper().createTempFile("fess-elevate-", ".csv").toPath();
302 try {
303 try (Writer writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(tempFile), getCsvEncoding()))) {
304 elevateWordService.exportCsv(writer);
305 } catch (final Exception e) {
306 logger.warn("Failed to process a request.", e);
307 throwValidationError(messages -> messages.addErrorsFailedToDownloadElevateFile(GLOBAL), this::asDownloadHtml);
308 }
309 try (InputStream in = Files.newInputStream(tempFile)) {
310 out.write(in);
311 }
312 } finally {
313 Files.delete(tempFile);
314 }
315 });
316 }
317
318
319
320
321
322
323
324
325
326 @Execute
327 @Secured({ ROLE })
328 public HtmlResponse uploadpage() {
329 saveToken();
330 return asUploadHtml();
331 }
332
333
334
335
336
337
338
339
340
341
342 @Execute
343 @Secured({ ROLE })
344 public HtmlResponse create(final CreateForm form) {
345 verifyCrudMode(form.crudMode, CrudMode.CREATE, this::asListHtml);
346 validate(form, messages -> {}, this::asEditHtml);
347 verifyToken(this::asEditHtml);
348 getElevateWord(form).ifPresent(entity -> {
349 try {
350 elevateWordService.store(entity);
351 suggestHelper.addElevateWord(entity.getSuggestWord(), entity.getReading(), entity.getLabelTypeValues(),
352 entity.getPermissions(), entity.getBoost(), false);
353 saveInfo(messages -> messages.addSuccessCrudCreateCrudTable(GLOBAL));
354 } catch (final Exception e) {
355 logger.warn("Failed to process a request.", e);
356 throwValidationError(messages -> messages.addErrorsCrudFailedToCreateCrudTable(GLOBAL, buildThrowableMessage(e)),
357 this::asEditHtml);
358 }
359 }).orElse(() -> {
360 throwValidationError(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL), this::asEditHtml);
361 });
362 return redirect(getClass());
363 }
364
365
366
367
368
369
370
371 @Execute
372 @Secured({ ROLE })
373 public HtmlResponse update(final EditForm form) {
374 verifyCrudMode(form.crudMode, CrudMode.EDIT, this::asListHtml);
375 validate(form, messages -> {}, this::asEditHtml);
376 verifyToken(this::asEditHtml);
377 getElevateWord(form).ifPresent(entity -> {
378 try {
379 elevateWordService.store(entity);
380 suggestHelper.deleteAllElevateWord(false);
381 suggestHelper.storeAllElevateWords(false);
382 saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
383 } catch (final Exception e) {
384 logger.warn("Failed to process a request.", e);
385 throwValidationError(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, buildThrowableMessage(e)),
386 this::asEditHtml);
387 }
388 }).orElse(() -> {
389 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.id), this::asEditHtml);
390 });
391 return redirect(getClass());
392 }
393
394
395
396
397
398
399
400 @Execute
401 @Secured({ ROLE })
402 public HtmlResponse delete(final EditForm form) {
403 verifyCrudMode(form.crudMode, CrudMode.DETAILS, this::asListHtml);
404 validate(form, messages -> {}, this::asDetailsHtml);
405 verifyToken(this::asDetailsHtml);
406 final String id = form.id;
407 elevateWordService.getElevateWord(id).ifPresent(entity -> {
408 try {
409 elevateWordService.delete(entity);
410 suggestHelper.deleteElevateWord(entity.getSuggestWord(), false);
411 saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
412 } catch (final Exception e) {
413 logger.warn("Failed to process a request.", e);
414 throwValidationError(messages -> messages.addErrorsCrudFailedToDeleteCrudTable(GLOBAL, buildThrowableMessage(e)),
415 this::asEditHtml);
416 }
417 }).orElse(() -> throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), this::asDetailsHtml));
418 return redirect(getClass());
419 }
420
421
422
423
424
425
426
427 @Execute
428 @Secured({ ROLE })
429 public HtmlResponse upload(final UploadForm form) {
430 validate(form, messages -> {}, this::asUploadHtml);
431 verifyToken(this::asUploadHtml);
432 CommonPoolUtil.execute(() -> {
433 try (Reader reader = new BufferedReader(new InputStreamReader(form.elevateWordFile.getInputStream(), getCsvEncoding()))) {
434 elevateWordService.importCsv(reader);
435 suggestHelper.deleteAllElevateWord(false);
436 suggestHelper.storeAllElevateWords(false);
437 } catch (final Exception e) {
438 throw new FessSystemException("Failed to import elevate word data: fileName=" + form.elevateWordFile.getFileName(), e);
439 }
440 });
441 saveInfo(messages -> messages.addSuccessUploadElevateWord(GLOBAL));
442 return redirect(getClass());
443 }
444
445
446
447
448
449
450
451
452
453
454
455
456 public static OptionalEntity<ElevateWord> getEntity(final CreateForm form, final String username, final long currentTime) {
457 switch (form.crudMode) {
458 case CrudMode.CREATE:
459 return OptionalEntity.of(new ElevateWord()).map(entity -> {
460 entity.setCreatedBy(username);
461 entity.setCreatedTime(currentTime);
462 return entity;
463 });
464 case CrudMode.EDIT:
465 if (form instanceof EditForm) {
466 return ComponentUtil.getComponent(ElevateWordService.class).getElevateWord(((EditForm) form).id);
467 }
468 break;
469 default:
470 break;
471 }
472 return OptionalEntity.empty();
473 }
474
475
476
477
478
479
480
481 public static OptionalEntity<ElevateWord> getElevateWord(final CreateForm form) {
482 final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
483 final String username = systemHelper.getUsername();
484 final long currentTime = systemHelper.getCurrentTimeAsLong();
485
486 return getEntity(form, username, currentTime).map(entity -> {
487 entity.setUpdatedBy(username);
488 entity.setUpdatedTime(currentTime);
489 BeanUtil.copyBeanToBean(form, entity,
490 op -> op.exclude(Stream.concat(Stream.of(Constants.COMMON_CONVERSION_RULE), Stream.of(Constants.PERMISSIONS))
491 .toArray(n -> new String[n])));
492 final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
493 entity.setPermissions(split(form.permissions, "\n").get(
494 stream -> stream.map(permissionHelper::encode).filter(StringUtil::isNotBlank).distinct().toArray(n -> new String[n])));
495 return entity;
496 });
497 }
498
499
500
501
502
503
504 protected void registerLabels(final RenderData data) {
505 RenderDataUtil.register(data, "labelTypeItems", labelTypeService.getLabelTypeList());
506 }
507
508
509
510
511 private String getCsvEncoding() {
512 return fessConfig.getCsvFileEncoding();
513 }
514
515
516
517
518 private HtmlResponse asListHtml() {
519 return asHtml(path_AdminElevateword_AdminElevatewordJsp).renderWith(data -> {
520 RenderDataUtil.register(data, "elevateWordItems", elevateWordService.getElevateWordList(elevateWordPager));
521 }).useForm(SearchForm.class, setup -> {
522 setup.setup(form -> {
523 copyBeanToBean(elevateWordPager, form, op -> op.include("id"));
524 });
525 });
526 }
527
528 private HtmlResponse asEditHtml() {
529 return asHtml(path_AdminElevateword_AdminElevatewordEditJsp).renderWith(data -> {
530 registerLabels(data);
531 });
532 }
533
534 private HtmlResponse asDetailsHtml() {
535 return asHtml(path_AdminElevateword_AdminElevatewordDetailsJsp).renderWith(data -> {
536 registerLabels(data);
537 });
538 }
539
540 private HtmlResponse asUploadHtml() {
541 return asHtml(path_AdminElevateword_AdminElevatewordUploadJsp).useForm(UploadForm.class);
542 }
543
544 private HtmlResponse asDownloadHtml() {
545 return asHtml(path_AdminElevateword_AdminElevatewordDownloadJsp).useForm(DownloadForm.class);
546 }
547 }