View Javadoc
1   /*
2    * Copyright 2012-2021 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.app.web.admin.dict.protwords;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.io.InputStream;
21  
22  import javax.annotation.Resource;
23  
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.ProtwordsPager;
29  import org.codelibs.fess.app.service.ProtwordsService;
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.protwords.ProtwordsItem;
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  /**
48   * @author ma2tani
49   */
50  public class AdminDictProtwordsAction extends FessAdminAction {
51  
52      public static final String ROLE = "admin-dict";
53  
54      // ===================================================================================
55      //                                                                           Attribute
56      //                                                                           =========
57      @Resource
58      private ProtwordsService protwordsService;
59      @Resource
60      private ProtwordsPager protwordsPager;
61  
62      // ===================================================================================
63      //                                                                               Hook
64      //                                                                              ======
65      @Override
66      protected void setupHtmlData(final ActionRuntime runtime) {
67          super.setupHtmlData(runtime);
68          runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameDictProtwords()));
69      }
70  
71      @Override
72      protected String getActionRole() {
73          return ROLE;
74      }
75  
76      // ===================================================================================
77      //                                                                      Search Execute
78      //                                                                      ==============
79      @Execute
80      @Secured({ ROLE, ROLE + VIEW })
81      public HtmlResponse index(final SearchForm form) {
82          validate(form, messages -> {}, this::asDictIndexHtml);
83          protwordsPager.clear();
84          return asHtml(path_AdminDictProtwords_AdminDictProtwordsJsp).renderWith(data -> {
85              searchPaging(data, form);
86          });
87      }
88  
89      @Execute
90      @Secured({ ROLE, ROLE + VIEW })
91      public HtmlResponse list(final OptionalThing<Integer> pageNumber, final SearchForm form) {
92          validate(form, messages -> {}, this::asDictIndexHtml);
93          pageNumber.ifPresent(num -> {
94              protwordsPager.setCurrentPageNumber(pageNumber.get());
95          }).orElse(() -> {
96              protwordsPager.setCurrentPageNumber(0);
97          });
98          return asHtml(path_AdminDictProtwords_AdminDictProtwordsJsp).renderWith(data -> {
99              searchPaging(data, form);
100         });
101     }
102 
103     @Execute
104     @Secured({ ROLE, ROLE + VIEW })
105     public HtmlResponse search(final SearchForm form) {
106         validate(form, messages -> {}, this::asDictIndexHtml);
107         copyBeanToBean(form, protwordsPager, op -> op.exclude(Constants.PAGER_CONVERSION_RULE));
108         return asHtml(path_AdminDictProtwords_AdminDictProtwordsJsp).renderWith(data -> {
109             searchPaging(data, form);
110         });
111     }
112 
113     @Execute
114     @Secured({ ROLE, ROLE + VIEW })
115     public HtmlResponse reset(final SearchForm form) {
116         validate(form, messages -> {}, this::asDictIndexHtml);
117         protwordsPager.clear();
118         return asHtml(path_AdminDictProtwords_AdminDictProtwordsJsp).renderWith(data -> {
119             searchPaging(data, form);
120         });
121     }
122 
123     protected void searchPaging(final RenderData data, final SearchForm form) {
124         // page navi
125         RenderDataUtil.register(data, "protwordsItemItems", protwordsService.getProtwordsList(form.dictId, protwordsPager));
126 
127         // restore from pager
128         BeanUtil.copyBeanToBean(protwordsPager, form, op -> {
129             op.exclude(Constants.PAGER_CONVERSION_RULE);
130         });
131     }
132 
133     // ===================================================================================
134     //                                                                        Edit Execute
135     //                                                                        ============
136     // -----------------------------------------------------
137     //                                            Entry Page
138     //                                            ----------
139     @Execute
140     @Secured({ ROLE })
141     public HtmlResponse createnew(final String dictId) {
142         saveToken();
143         return asHtml(path_AdminDictProtwords_AdminDictProtwordsEditJsp).useForm(CreateForm.class, op -> {
144             op.setup(form -> {
145                 form.initialize();
146                 form.crudMode = CrudMode.CREATE;
147                 form.dictId = dictId;
148             });
149         });
150     }
151 
152     @Execute
153     @Secured({ ROLE })
154     public HtmlResponse edit(final EditForm form) {
155         validate(form, messages -> {}, () -> asListHtml(form.dictId));
156         protwordsService.getProtwordsItem(form.dictId, form.id).ifPresent(entity -> {
157             form.input = entity.getInputValue();
158         }).orElse(() -> {
159             throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()),
160                     () -> asListHtml(form.dictId));
161         });
162         saveToken();
163         if (form.crudMode.intValue() == CrudMode.EDIT) {
164             // back
165             form.crudMode = CrudMode.DETAILS;
166             return asDetailsHtml();
167         }
168         form.crudMode = CrudMode.EDIT;
169         return asEditHtml();
170     }
171 
172     // -----------------------------------------------------
173     //                                               Details
174     //                                               -------
175     @Execute
176     @Secured({ ROLE, ROLE + VIEW })
177     public HtmlResponse details(final String dictId, final int crudMode, final long id) {
178         verifyCrudMode(crudMode, CrudMode.DETAILS, dictId);
179         saveToken();
180         return asDetailsHtml().useForm(EditForm.class, op -> {
181             op.setup(form -> {
182                 protwordsService.getProtwordsItem(dictId, id).ifPresent(entity -> {
183                     form.input = entity.getInputValue();
184                 }).orElse(() -> {
185                     throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, dictId + ":" + id),
186                             () -> asListHtml(dictId));
187                 });
188                 form.id = id;
189                 form.crudMode = crudMode;
190                 form.dictId = dictId;
191             });
192         });
193     }
194 
195     // -----------------------------------------------------
196     //                                              Download
197     //                                               -------
198     @Execute
199     @Secured({ ROLE, ROLE + VIEW })
200     public HtmlResponse downloadpage(final String dictId) {
201         saveToken();
202         return asHtml(path_AdminDictProtwords_AdminDictProtwordsDownloadJsp).useForm(DownloadForm.class, op -> {
203             op.setup(form -> {
204                 form.dictId = dictId;
205             });
206         }).renderWith(data -> {
207             protwordsService.getProtwordsFile(dictId).ifPresent(file -> {
208                 RenderDataUtil.register(data, "path", file.getPath());
209             }).orElse(() -> {
210                 throwValidationError(messages -> messages.addErrorsFailedToDownloadProtwordsFile(GLOBAL), this::asDictIndexHtml);
211             });
212         });
213     }
214 
215     @Execute
216     @Secured({ ROLE, ROLE + VIEW })
217     public ActionResponse download(final DownloadForm form) {
218         validate(form, messages -> {}, () -> downloadpage(form.dictId));
219         verifyTokenKeep(() -> downloadpage(form.dictId));
220         return protwordsService.getProtwordsFile(form.dictId)
221                 .map(file -> asStream(new File(file.getPath()).getName()).contentTypeOctetStream().stream(out -> {
222                     file.writeOut(out);
223                 })).orElseGet(() -> {
224                     throwValidationError(messages -> messages.addErrorsFailedToDownloadProtwordsFile(GLOBAL),
225                             () -> downloadpage(form.dictId));
226                     return null;
227                 });
228     }
229 
230     // -----------------------------------------------------
231     //                                                Upload
232     //                                               -------
233     @Execute
234     @Secured({ ROLE })
235     public HtmlResponse uploadpage(final String dictId) {
236         saveToken();
237         return asHtml(path_AdminDictProtwords_AdminDictProtwordsUploadJsp).useForm(UploadForm.class, op -> {
238             op.setup(form -> {
239                 form.dictId = dictId;
240             });
241         }).renderWith(data -> {
242             protwordsService.getProtwordsFile(dictId).ifPresent(file -> {
243                 RenderDataUtil.register(data, "path", file.getPath());
244             }).orElse(() -> {
245                 throwValidationError(messages -> messages.addErrorsFailedToDownloadProtwordsFile(GLOBAL), this::asDictIndexHtml);
246             });
247         });
248     }
249 
250     @Execute
251     @Secured({ ROLE })
252     public HtmlResponse upload(final UploadForm form) {
253         validate(form, messages -> {}, () -> uploadpage(form.dictId));
254         verifyToken(() -> uploadpage(form.dictId));
255         return protwordsService.getProtwordsFile(form.dictId).map(file -> {
256             try (InputStream inputStream = form.protwordsFile.getInputStream()) {
257                 file.update(inputStream);
258             } catch (final IOException e) {
259                 throwValidationError(messages -> messages.addErrorsFailedToUploadProtwordsFile(GLOBAL),
260                         () -> redirectWith(getClass(), moreUrl("uploadpage/" + form.dictId)));
261             }
262             saveInfo(messages -> messages.addSuccessUploadProtwordsFile(GLOBAL));
263             return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
264         }).orElseGet(() -> {
265             throwValidationError(messages -> messages.addErrorsFailedToUploadProtwordsFile(GLOBAL), () -> uploadpage(form.dictId));
266             return null;
267         });
268 
269     }
270 
271     // -----------------------------------------------------
272     //                                         Actually Crud
273     //                                         -------------
274     @Execute
275     @Secured({ ROLE })
276     public HtmlResponse create(final CreateForm form) {
277         verifyCrudMode(form.crudMode, CrudMode.CREATE, form.dictId);
278         validate(form, messages -> {}, this::asEditHtml);
279         verifyToken(this::asEditHtml);
280         createProtwordsItem(form, this::asEditHtml).ifPresent(entity -> {
281             protwordsService.store(form.dictId, entity);
282             saveInfo(messages -> messages.addSuccessCrudCreateCrudTable(GLOBAL));
283         }).orElse(() -> throwValidationError(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL), this::asEditHtml));
284         return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
285     }
286 
287     @Execute
288     @Secured({ ROLE })
289     public HtmlResponse update(final EditForm form) {
290         verifyCrudMode(form.crudMode, CrudMode.EDIT, form.dictId);
291         validate(form, messages -> {}, this::asEditHtml);
292         verifyToken(this::asEditHtml);
293         createProtwordsItem(form, this::asEditHtml).ifPresent(entity -> {
294             protwordsService.store(form.dictId, entity);
295             saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
296         }).orElse(() -> throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()),
297                 this::asEditHtml));
298         return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
299     }
300 
301     @Execute
302     @Secured({ ROLE })
303     public HtmlResponse delete(final EditForm form) {
304         verifyCrudMode(form.crudMode, CrudMode.DETAILS, form.dictId);
305         validate(form, messages -> {}, this::asDetailsHtml);
306         verifyToken(this::asDetailsHtml);
307         protwordsService.getProtwordsItem(form.dictId, form.id).ifPresent(entity -> {
308             protwordsService.delete(form.dictId, entity);
309             saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
310         }).orElse(() -> {
311             throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()), this::asDetailsHtml);
312         });
313         return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
314     }
315 
316     //===================================================================================
317     //                                                                        Assist Logic
318     //                                                                        ============
319 
320     private static OptionalEntity<ProtwordsItem> getEntity(final CreateForm form) {
321         switch (form.crudMode) {
322         case CrudMode.CREATE:
323             final ProtwordsItem entity = new ProtwordsItem(0, StringUtil.EMPTY);
324             return OptionalEntity.of(entity);
325         case CrudMode.EDIT:
326             if (form instanceof EditForm) {
327                 return ComponentUtil.getComponent(ProtwordsService.class).getProtwordsItem(form.dictId, ((EditForm) form).id);
328             }
329             break;
330         default:
331             break;
332         }
333         return OptionalEntity.empty();
334     }
335 
336     protected OptionalEntity<ProtwordsItem> createProtwordsItem(final CreateForm form, final VaErrorHook hook) {
337         try {
338             return createProtwordsItem(this, form, hook);
339         } catch (final ValidationErrorException e) {
340             saveToken();
341             throw e;
342         }
343     }
344 
345     public static OptionalEntity<ProtwordsItem> createProtwordsItem(final FessBaseAction action, final CreateForm form,
346             final VaErrorHook hook) {
347         return getEntity(form).map(entity -> {
348             final String newInput = form.input;
349             validateProtwordsString(action, newInput, "input", hook);
350             entity.setNewInput(newInput);
351             return entity;
352         });
353     }
354 
355     // ===================================================================================
356     //                                                                        Small Helper
357     //                                                                        ============
358     protected void verifyCrudMode(final int crudMode, final int expectedMode, final String dictId) {
359         if (crudMode != expectedMode) {
360             throwValidationError(messages -> {
361                 messages.addErrorsCrudInvalidMode(GLOBAL, String.valueOf(expectedMode), String.valueOf(crudMode));
362             }, () -> asListHtml(dictId));
363         }
364     }
365 
366     private static void validateProtwordsString(final FessBaseAction action, final String values, final String propertyName,
367             final VaErrorHook hook) {
368         // TODO validation
369     }
370 
371     // ===================================================================================
372     //                                                                              JSP
373     //                                                                           =========
374 
375     protected HtmlResponse asDictIndexHtml() {
376         return redirect(AdminDictAction.class);
377     }
378 
379     private HtmlResponse asListHtml(final String dictId) {
380         return asHtml(path_AdminDictProtwords_AdminDictProtwordsJsp).renderWith(data -> {
381             RenderDataUtil.register(data, "protwordsItemItems", protwordsService.getProtwordsList(dictId, protwordsPager));
382         }).useForm(SearchForm.class, setup -> {
383             setup.setup(form -> {
384                 copyBeanToBean(protwordsPager, form, op -> op.include("id"));
385             });
386         });
387     }
388 
389     private HtmlResponse asEditHtml() {
390         return asHtml(path_AdminDictProtwords_AdminDictProtwordsEditJsp);
391     }
392 
393     private HtmlResponse asDetailsHtml() {
394         return asHtml(path_AdminDictProtwords_AdminDictProtwordsDetailsJsp);
395     }
396 
397 }