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