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