1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.app.web.admin.dict.mapping;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import javax.annotation.Resource;
25
26 import org.codelibs.core.beans.util.BeanUtil;
27 import org.codelibs.core.lang.StringUtil;
28 import org.codelibs.fess.Constants;
29 import org.codelibs.fess.app.pager.CharMappingPager;
30 import org.codelibs.fess.app.service.CharMappingService;
31 import org.codelibs.fess.app.web.CrudMode;
32 import org.codelibs.fess.app.web.admin.dict.AdminDictAction;
33 import org.codelibs.fess.app.web.base.FessAdminAction;
34 import org.codelibs.fess.dict.mapping.CharMappingItem;
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
46
47
48
49
50 public class AdminDictMappingAction extends FessAdminAction {
51
52
53
54
55 @Resource
56 private CharMappingService charMappingService;
57 @Resource
58 private CharMappingPager charMappingPager;
59
60
61
62
63 @Override
64 protected void setupHtmlData(final ActionRuntime runtime) {
65 super.setupHtmlData(runtime);
66 runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameDictMapping()));
67 }
68
69
70
71
72 @Execute
73 public HtmlResponse index(final SearchForm form) {
74 validate(form, messages -> {}, () -> asDictIndexHtml());
75 return asHtml(path_AdminDictMapping_AdminDictMappingJsp).renderWith(data -> {
76 searchPaging(data, form);
77 });
78 }
79
80 @Execute
81 public HtmlResponse list(final OptionalThing<Integer> pageNumber, final SearchForm form) {
82 validate(form, messages -> {}, () -> asDictIndexHtml());
83 pageNumber.ifPresent(num -> {
84 charMappingPager.setCurrentPageNumber(pageNumber.get());
85 }).orElse(() -> {
86 charMappingPager.setCurrentPageNumber(0);
87 });
88 return asHtml(path_AdminDictMapping_AdminDictMappingJsp).renderWith(data -> {
89 searchPaging(data, form);
90 });
91 }
92
93 @Execute
94 public HtmlResponse search(final SearchForm form) {
95 validate(form, messages -> {}, () -> asDictIndexHtml());
96 copyBeanToBean(form, charMappingPager, op -> op.exclude(Constants.PAGER_CONVERSION_RULE));
97 return asHtml(path_AdminDictMapping_AdminDictMappingJsp).renderWith(data -> {
98 searchPaging(data, form);
99 });
100 }
101
102 @Execute
103 public HtmlResponse reset(final SearchForm form) {
104 validate(form, messages -> {}, () -> asDictIndexHtml());
105 charMappingPager.clear();
106 return asHtml(path_AdminDictMapping_AdminDictMappingJsp).renderWith(data -> {
107 searchPaging(data, form);
108 });
109 }
110
111 protected void searchPaging(final RenderData data, final SearchForm form) {
112
113 RenderDataUtil.register(data, "charMappingItemItems", charMappingService.getCharMappingList(form.dictId, charMappingPager));
114
115
116 BeanUtil.copyBeanToBean(charMappingPager, form, op -> {
117 op.exclude(Constants.PAGER_CONVERSION_RULE);
118 });
119 }
120
121
122
123
124
125
126
127 @Execute
128 public HtmlResponse createnew(final String dictId) {
129 saveToken();
130 return asHtml(path_AdminDictMapping_AdminDictMappingEditJsp).useForm(CreateForm.class, op -> {
131 op.setup(form -> {
132 form.initialize();
133 form.crudMode = CrudMode.CREATE;
134 form.dictId = dictId;
135 });
136 });
137 }
138
139 @Execute
140 public HtmlResponse edit(final EditForm form) {
141 validate(form, messages -> {}, () -> asListHtml(form.dictId));
142 charMappingService
143 .getCharMappingItem(form.dictId, form.id)
144 .ifPresent(entity -> {
145 form.inputs = entity.getInputsValue();
146 form.output = entity.getOutput();
147 })
148 .orElse(() -> {
149 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()),
150 () -> asListHtml(form.dictId));
151 });
152 saveToken();
153 if (form.crudMode.intValue() == CrudMode.EDIT) {
154
155 form.crudMode = CrudMode.DETAILS;
156 return asDetailsHtml();
157 } else {
158 form.crudMode = CrudMode.EDIT;
159 return asEditHtml();
160 }
161 }
162
163
164
165
166 @Execute
167 public HtmlResponse details(final String dictId, final int crudMode, final long id) {
168 verifyCrudMode(crudMode, CrudMode.DETAILS, dictId);
169 saveToken();
170 return asDetailsHtml().useForm(
171 EditForm.class,
172 op -> {
173 op.setup(form -> {
174 charMappingService
175 .getCharMappingItem(dictId, id)
176 .ifPresent(entity -> {
177 form.inputs = entity.getInputsValue();
178 form.output = entity.getOutput();
179 })
180 .orElse(() -> {
181 throwValidationError(
182 messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, dictId + ":" + id),
183 () -> asListHtml(dictId));
184 });
185 form.id = id;
186 form.crudMode = crudMode;
187 form.dictId = dictId;
188 });
189 });
190 }
191
192
193
194
195 @Execute
196 public HtmlResponse downloadpage(final String dictId) {
197 saveToken();
198 return asHtml(path_AdminDictMapping_AdminDictMappingDownloadJsp).useForm(DownloadForm.class, op -> {
199 op.setup(form -> {
200 form.dictId = dictId;
201 });
202 }).renderWith(data -> {
203 charMappingService.getCharMappingFile(dictId).ifPresent(file -> {
204 RenderDataUtil.register(data, "path", file.getPath());
205 }).orElse(() -> {
206 throwValidationError(messages -> messages.addErrorsFailedToDownloadMappingFile(GLOBAL), () -> asDictIndexHtml());
207 });
208 });
209 }
210
211 @Execute
212 public ActionResponse download(final DownloadForm form) {
213 validate(form, messages -> {}, () -> downloadpage(form.dictId));
214 verifyTokenKeep(() -> downloadpage(form.dictId));
215 return charMappingService.getCharMappingFile(form.dictId).map(file -> {
216 return asStream(new File(file.getPath()).getName()).contentTypeOctetStream().stream(out -> {
217 try (InputStream inputStream = file.getInputStream()) {
218 out.write(inputStream);
219 }
220 });
221 }).orElseGet(() -> {
222 throwValidationError(messages -> messages.addErrorsFailedToDownloadMappingFile(GLOBAL), () -> downloadpage(form.dictId));
223 return null;
224 });
225 }
226
227
228
229
230 @Execute
231 public HtmlResponse uploadpage(final String dictId) {
232 saveToken();
233 return asHtml(path_AdminDictMapping_AdminDictMappingUploadJsp).useForm(UploadForm.class, op -> {
234 op.setup(form -> {
235 form.dictId = dictId;
236 });
237 }).renderWith(data -> {
238 charMappingService.getCharMappingFile(dictId).ifPresent(file -> {
239 RenderDataUtil.register(data, "path", file.getPath());
240 }).orElse(() -> {
241 throwValidationError(messages -> messages.addErrorsFailedToDownloadMappingFile(GLOBAL), () -> asDictIndexHtml());
242 });
243 });
244 }
245
246 @Execute
247 public HtmlResponse upload(final UploadForm form) {
248 validate(form, messages -> {}, () -> uploadpage(form.dictId));
249 verifyToken(() -> uploadpage(form.dictId));
250 return charMappingService.getCharMappingFile(form.dictId).map(file -> {
251 try (InputStream inputStream = form.charMappingFile.getInputStream()) {
252 file.update(inputStream);
253 } catch (final IOException e) {
254 throwValidationError(messages -> messages.addErrorsFailedToUploadMappingFile(GLOBAL), () -> {
255 return redirectWith(getClass(), moreUrl("uploadpage/" + form.dictId));
256 });
257 }
258 saveInfo(messages -> messages.addSuccessUploadMappingFile(GLOBAL));
259 return redirectWith(getClass(), moreUrl("uploadpage/" + form.dictId));
260 }).orElseGet(() -> {
261 throwValidationError(messages -> messages.addErrorsFailedToUploadMappingFile(GLOBAL), () -> uploadpage(form.dictId));
262 return null;
263 });
264
265 }
266
267
268
269
270 @Execute
271 public HtmlResponse create(final CreateForm form) {
272 verifyCrudMode(form.crudMode, CrudMode.CREATE, form.dictId);
273 validate(form, messages -> {}, () -> asEditHtml());
274 verifyToken(() -> asEditHtml());
275 createCharMappingItem(form, () -> asEditHtml()).ifPresent(
276 entity -> {
277 try {
278 charMappingService.store(form.dictId, entity);
279 saveInfo(messages -> messages.addSuccessCrudCreateCrudTable(GLOBAL));
280 } catch (final Exception e) {
281 throwValidationError(messages -> messages.addErrorsCrudFailedToCreateCrudTable(GLOBAL, buildThrowableMessage(e)),
282 () -> asEditHtml());
283 }
284 }).orElse(() -> {
285 throwValidationError(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL), () -> asEditHtml());
286 });
287 return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
288 }
289
290 @Execute
291 public HtmlResponse update(final EditForm form) {
292 verifyCrudMode(form.crudMode, CrudMode.EDIT, form.dictId);
293 validate(form, messages -> {}, () -> asEditHtml());
294 verifyToken(() -> asEditHtml());
295 createCharMappingItem(form, () -> asEditHtml()).ifPresent(
296 entity -> {
297 try {
298 charMappingService.store(form.dictId, entity);
299 saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
300 } catch (final Exception e) {
301 throwValidationError(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, buildThrowableMessage(e)),
302 () -> asEditHtml());
303 }
304 }).orElse(() -> {
305 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()), () -> asEditHtml());
306 });
307 return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
308 }
309
310 @Execute
311 public HtmlResponse delete(final EditForm form) {
312 verifyCrudMode(form.crudMode, CrudMode.DETAILS, form.dictId);
313 validate(form, messages -> {}, () -> asDetailsHtml());
314 verifyToken(() -> asDetailsHtml());
315 charMappingService
316 .getCharMappingItem(form.dictId, form.id)
317 .ifPresent(
318 entity -> {
319 try {
320 charMappingService.delete(form.dictId, entity);
321 saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
322 } catch (final Exception e) {
323 throwValidationError(
324 messages -> messages.addErrorsCrudFailedToDeleteCrudTable(GLOBAL, buildThrowableMessage(e)),
325 () -> asEditHtml());
326 }
327 })
328 .orElse(() -> {
329 throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()),
330 () -> asDetailsHtml());
331 });
332 return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
333 }
334
335
336
337
338
339 private OptionalEntity<CharMappingItem> getEntity(final CreateForm form) {
340 switch (form.crudMode) {
341 case CrudMode.CREATE:
342 final CharMappingItem entity = new CharMappingItem(0, StringUtil.EMPTY_STRINGS, StringUtil.EMPTY);
343 return OptionalEntity.of(entity);
344 case CrudMode.EDIT:
345 if (form instanceof EditForm) {
346 return ComponentUtil.getComponent(CharMappingService.class).getCharMappingItem(form.dictId, ((EditForm) form).id);
347 }
348 break;
349 default:
350 break;
351 }
352 return OptionalEntity.empty();
353 }
354
355 public OptionalEntity<CharMappingItem> createCharMappingItem(final CreateForm form, final VaErrorHook hook) {
356 return getEntity(form).map(entity -> {
357 final String[] newInputs = splitLine(form.inputs);
358 validateMappingString(newInputs, "inputs", hook);
359 entity.setNewInputs(newInputs);
360 final String newOutput = form.output;
361 entity.setNewOutput(newOutput);
362 return entity;
363 });
364 }
365
366
367
368
369 protected void verifyCrudMode(final int crudMode, final int expectedMode, final String dictId) {
370 if (crudMode != expectedMode) {
371 throwValidationError(messages -> {
372 messages.addErrorsCrudInvalidMode(GLOBAL, String.valueOf(expectedMode), String.valueOf(crudMode));
373 }, () -> asListHtml(dictId));
374 }
375 }
376
377 private void validateMappingString(final String[] values, final String propertyName, final VaErrorHook hook) {
378 if (values.length == 0) {
379 return;
380 }
381 for (final String value : values) {
382 if (value.indexOf(',') >= 0) {
383 throwValidationError(messages -> {
384 messages.addErrorsInvalidStrIsIncluded(propertyName, value, ",");
385 }, hook);
386 }
387 if (value.indexOf("=>") >= 0) {
388 throwValidationError(messages -> {
389 messages.addErrorsInvalidStrIsIncluded(propertyName, value, "=>");
390 }, hook);
391 }
392 }
393 }
394
395 private static String[] splitLine(final String value) {
396 if (StringUtil.isBlank(value)) {
397 return StringUtil.EMPTY_STRINGS;
398 }
399 final String[] values = value.split("[\r\n]");
400 final List<String> list = new ArrayList<>(values.length);
401 for (final String line : values) {
402 if (StringUtil.isNotBlank(line)) {
403 list.add(line.trim());
404 }
405 }
406 return list.toArray(new String[list.size()]);
407 }
408
409
410
411
412
413 protected HtmlResponse asDictIndexHtml() {
414 return redirect(AdminDictAction.class);
415 }
416
417 private HtmlResponse asListHtml(final String dictId) {
418 return asHtml(path_AdminDictMapping_AdminDictMappingJsp).renderWith(data -> {
419 RenderDataUtil.register(data, "charMappingItemItems", charMappingService.getCharMappingList(dictId, charMappingPager));
420 }).useForm(SearchForm.class, setup -> {
421 setup.setup(form -> {
422 copyBeanToBean(charMappingPager, form, op -> op.include("id"));
423 });
424 });
425 }
426
427 private HtmlResponse asEditHtml() {
428 return asHtml(path_AdminDictMapping_AdminDictMappingEditJsp);
429 }
430
431 private HtmlResponse asDetailsHtml() {
432 return asHtml(path_AdminDictMapping_AdminDictMappingDetailsJsp);
433 }
434
435 }