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