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.stopwords;
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.StopwordsPager;
29  import org.codelibs.fess.app.service.StopwordsService;
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.dict.stopwords.StopwordsItem;
34  import org.codelibs.fess.util.ComponentUtil;
35  import org.codelibs.fess.util.RenderDataUtil;
36  import org.dbflute.optional.OptionalEntity;
37  import org.dbflute.optional.OptionalThing;
38  import org.lastaflute.web.Execute;
39  import org.lastaflute.web.response.ActionResponse;
40  import org.lastaflute.web.response.HtmlResponse;
41  import org.lastaflute.web.response.render.RenderData;
42  import org.lastaflute.web.ruts.process.ActionRuntime;
43  import org.lastaflute.web.validation.VaErrorHook;
44  
45  /**
46   * @author ma2tani
47   */
48  public class AdminDictStopwordsAction extends FessAdminAction {
49  
50      public static final String ROLE = "admin-dict";
51  
52      // ===================================================================================
53      //                                                                           Attribute
54      //                                                                           =========
55      @Resource
56      private StopwordsService stopwordsService;
57      @Resource
58      private StopwordsPager stopwordsPager;
59  
60      // ===================================================================================
61      //                                                                               Hook
62      //                                                                              ======
63      @Override
64      protected void setupHtmlData(final ActionRuntime runtime) {
65          super.setupHtmlData(runtime);
66          runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameDictStopwords()));
67      }
68  
69      @Override
70      protected String getActionRole() {
71          return ROLE;
72      }
73  
74      // ===================================================================================
75      //                                                                      Search Execute
76      //                                                                      ==============
77      @Execute
78      @Secured({ ROLE, ROLE + VIEW })
79      public HtmlResponse index(final SearchForm form) {
80          validate(form, messages -> {}, this::asDictIndexHtml);
81          stopwordsPager.clear();
82          return asHtml(path_AdminDictStopwords_AdminDictStopwordsJsp).renderWith(data -> {
83              searchPaging(data, form);
84          });
85      }
86  
87      @Execute
88      @Secured({ ROLE, ROLE + VIEW })
89      public HtmlResponse list(final OptionalThing<Integer> pageNumber, final SearchForm form) {
90          validate(form, messages -> {}, this::asDictIndexHtml);
91          pageNumber.ifPresent(num -> {
92              stopwordsPager.setCurrentPageNumber(pageNumber.get());
93          }).orElse(() -> {
94              stopwordsPager.setCurrentPageNumber(0);
95          });
96          return asHtml(path_AdminDictStopwords_AdminDictStopwordsJsp).renderWith(data -> {
97              searchPaging(data, form);
98          });
99      }
100 
101     @Execute
102     @Secured({ ROLE, ROLE + VIEW })
103     public HtmlResponse search(final SearchForm form) {
104         validate(form, messages -> {}, this::asDictIndexHtml);
105         copyBeanToBean(form, stopwordsPager, op -> op.exclude(Constants.PAGER_CONVERSION_RULE));
106         return asHtml(path_AdminDictStopwords_AdminDictStopwordsJsp).renderWith(data -> {
107             searchPaging(data, form);
108         });
109     }
110 
111     @Execute
112     @Secured({ ROLE, ROLE + VIEW })
113     public HtmlResponse reset(final SearchForm form) {
114         validate(form, messages -> {}, this::asDictIndexHtml);
115         stopwordsPager.clear();
116         return asHtml(path_AdminDictStopwords_AdminDictStopwordsJsp).renderWith(data -> {
117             searchPaging(data, form);
118         });
119     }
120 
121     protected void searchPaging(final RenderData data, final SearchForm form) {
122         // page navi
123         RenderDataUtil.register(data, "stopwordsItemItems", stopwordsService.getStopwordsList(form.dictId, stopwordsPager));
124 
125         // restore from pager
126         BeanUtil.copyBeanToBean(stopwordsPager, form, op -> {
127             op.exclude(Constants.PAGER_CONVERSION_RULE);
128         });
129     }
130 
131     // ===================================================================================
132     //                                                                        Edit Execute
133     //                                                                        ============
134     // -----------------------------------------------------
135     //                                            Entry Page
136     //                                            ----------
137     @Execute
138     @Secured({ ROLE })
139     public HtmlResponse createnew(final String dictId) {
140         saveToken();
141         return asHtml(path_AdminDictStopwords_AdminDictStopwordsEditJsp).useForm(CreateForm.class, op -> {
142             op.setup(form -> {
143                 form.initialize();
144                 form.crudMode = CrudMode.CREATE;
145                 form.dictId = dictId;
146             });
147         });
148     }
149 
150     @Execute
151     @Secured({ ROLE })
152     public HtmlResponse edit(final EditForm form) {
153         validate(form, messages -> {}, () -> asListHtml(form.dictId));
154         stopwordsService.getStopwordsItem(form.dictId, form.id).ifPresent(entity -> {
155             form.input = entity.getInputValue();
156         }).orElse(() -> {
157             throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()),
158                     () -> asListHtml(form.dictId));
159         });
160         saveToken();
161         if (form.crudMode.intValue() == CrudMode.EDIT) {
162             // back
163             form.crudMode = CrudMode.DETAILS;
164             return asDetailsHtml();
165         }
166         form.crudMode = CrudMode.EDIT;
167         return asEditHtml();
168     }
169 
170     // -----------------------------------------------------
171     //                                               Details
172     //                                               -------
173     @Execute
174     @Secured({ ROLE, ROLE + VIEW })
175     public HtmlResponse details(final String dictId, final int crudMode, final long id) {
176         verifyCrudMode(crudMode, CrudMode.DETAILS, dictId);
177         saveToken();
178         return asDetailsHtml().useForm(EditForm.class, op -> {
179             op.setup(form -> {
180                 stopwordsService.getStopwordsItem(dictId, id).ifPresent(entity -> {
181                     form.input = entity.getInputValue();
182                 }).orElse(() -> {
183                     throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, dictId + ":" + id),
184                             () -> asListHtml(dictId));
185                 });
186                 form.id = id;
187                 form.crudMode = crudMode;
188                 form.dictId = dictId;
189             });
190         });
191     }
192 
193     // -----------------------------------------------------
194     //                                              Download
195     //                                               -------
196     @Execute
197     @Secured({ ROLE, ROLE + VIEW })
198     public HtmlResponse downloadpage(final String dictId) {
199         saveToken();
200         return asHtml(path_AdminDictStopwords_AdminDictStopwordsDownloadJsp).useForm(DownloadForm.class, op -> {
201             op.setup(form -> {
202                 form.dictId = dictId;
203             });
204         }).renderWith(data -> {
205             stopwordsService.getStopwordsFile(dictId).ifPresent(file -> {
206                 RenderDataUtil.register(data, "path", file.getPath());
207             }).orElse(() -> {
208                 throwValidationError(messages -> messages.addErrorsFailedToDownloadStopwordsFile(GLOBAL), this::asDictIndexHtml);
209             });
210         });
211     }
212 
213     @Execute
214     @Secured({ ROLE, ROLE + VIEW })
215     public ActionResponse download(final DownloadForm form) {
216         validate(form, messages -> {}, () -> downloadpage(form.dictId));
217         verifyTokenKeep(() -> downloadpage(form.dictId));
218         return stopwordsService.getStopwordsFile(form.dictId)
219                 .map(file -> asStream(new File(file.getPath()).getName()).contentTypeOctetStream().stream(out -> {
220                     file.writeOut(out);
221                 })).orElseGet(() -> {
222                     throwValidationError(messages -> messages.addErrorsFailedToDownloadStopwordsFile(GLOBAL),
223                             () -> downloadpage(form.dictId));
224                     return null;
225                 });
226     }
227 
228     // -----------------------------------------------------
229     //                                                Upload
230     //                                               -------
231     @Execute
232     @Secured({ ROLE })
233     public HtmlResponse uploadpage(final String dictId) {
234         saveToken();
235         return asHtml(path_AdminDictStopwords_AdminDictStopwordsUploadJsp).useForm(UploadForm.class, op -> {
236             op.setup(form -> {
237                 form.dictId = dictId;
238             });
239         }).renderWith(data -> {
240             stopwordsService.getStopwordsFile(dictId).ifPresent(file -> {
241                 RenderDataUtil.register(data, "path", file.getPath());
242             }).orElse(() -> {
243                 throwValidationError(messages -> messages.addErrorsFailedToDownloadStopwordsFile(GLOBAL), this::asDictIndexHtml);
244             });
245         });
246     }
247 
248     @Execute
249     @Secured({ ROLE })
250     public HtmlResponse upload(final UploadForm form) {
251         validate(form, messages -> {}, () -> uploadpage(form.dictId));
252         verifyToken(() -> uploadpage(form.dictId));
253         return stopwordsService.getStopwordsFile(form.dictId).map(file -> {
254             try (InputStream inputStream = form.stopwordsFile.getInputStream()) {
255                 file.update(inputStream);
256             } catch (final IOException e) {
257                 throwValidationError(messages -> messages.addErrorsFailedToUploadStopwordsFile(GLOBAL),
258                         () -> redirectWith(getClass(), moreUrl("uploadpage/" + form.dictId)));
259             }
260             saveInfo(messages -> messages.addSuccessUploadStopwordsFile(GLOBAL));
261             return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
262         }).orElseGet(() -> {
263             throwValidationError(messages -> messages.addErrorsFailedToUploadStopwordsFile(GLOBAL), () -> uploadpage(form.dictId));
264             return null;
265         });
266 
267     }
268 
269     // -----------------------------------------------------
270     //                                         Actually Crud
271     //                                         -------------
272     @Execute
273     @Secured({ ROLE })
274     public HtmlResponse create(final CreateForm form) {
275         verifyCrudMode(form.crudMode, CrudMode.CREATE, form.dictId);
276         validate(form, messages -> {}, this::asEditHtml);
277         verifyToken(this::asEditHtml);
278         createStopwordsItem(form, this::asEditHtml).ifPresent(entity -> {
279             stopwordsService.store(form.dictId, entity);
280             saveInfo(messages -> messages.addSuccessCrudCreateCrudTable(GLOBAL));
281         }).orElse(() -> throwValidationError(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL), this::asEditHtml));
282         return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
283     }
284 
285     @Execute
286     @Secured({ ROLE })
287     public HtmlResponse update(final EditForm form) {
288         verifyCrudMode(form.crudMode, CrudMode.EDIT, form.dictId);
289         validate(form, messages -> {}, this::asEditHtml);
290         verifyToken(this::asEditHtml);
291         createStopwordsItem(form, this::asEditHtml).ifPresent(entity -> {
292             stopwordsService.store(form.dictId, entity);
293             saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
294         }).orElse(() -> throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()),
295                 this::asEditHtml));
296         return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
297     }
298 
299     @Execute
300     @Secured({ ROLE })
301     public HtmlResponse delete(final EditForm form) {
302         verifyCrudMode(form.crudMode, CrudMode.DETAILS, form.dictId);
303         validate(form, messages -> {}, this::asDetailsHtml);
304         verifyToken(this::asDetailsHtml);
305         stopwordsService.getStopwordsItem(form.dictId, form.id).ifPresent(entity -> {
306             stopwordsService.delete(form.dictId, entity);
307             saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
308         }).orElse(() -> {
309             throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()), this::asDetailsHtml);
310         });
311         return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
312     }
313 
314     //===================================================================================
315     //                                                                        Assist Logic
316     //                                                                        ============
317 
318     private static OptionalEntity<StopwordsItem> getEntity(final CreateForm form) {
319         switch (form.crudMode) {
320         case CrudMode.CREATE:
321             final StopwordsItem entity = new StopwordsItem(0, StringUtil.EMPTY);
322             return OptionalEntity.of(entity);
323         case CrudMode.EDIT:
324             if (form instanceof EditForm) {
325                 return ComponentUtil.getComponent(StopwordsService.class).getStopwordsItem(form.dictId, ((EditForm) form).id);
326             }
327             break;
328         default:
329             break;
330         }
331         return OptionalEntity.empty();
332     }
333 
334     public static OptionalEntity<StopwordsItem> createStopwordsItem(final CreateForm form, final VaErrorHook hook) {
335         return getEntity(form).map(entity -> {
336             final String newInput = form.input;
337             validateStopwordsString(newInput, "input", hook);
338             entity.setNewInput(newInput);
339             return entity;
340         });
341     }
342 
343     // ===================================================================================
344     //                                                                        Small Helper
345     //                                                                        ============
346     protected void verifyCrudMode(final int crudMode, final int expectedMode, final String dictId) {
347         if (crudMode != expectedMode) {
348             throwValidationError(messages -> {
349                 messages.addErrorsCrudInvalidMode(GLOBAL, String.valueOf(expectedMode), String.valueOf(crudMode));
350             }, () -> asListHtml(dictId));
351         }
352     }
353 
354     private static void validateStopwordsString(final String values, final String propertyName, final VaErrorHook hook) {
355         // TODO validation
356     }
357 
358     // ===================================================================================
359     //                                                                              JSP
360     //                                                                           =========
361 
362     protected HtmlResponse asDictIndexHtml() {
363         return redirect(AdminDictAction.class);
364     }
365 
366     private HtmlResponse asListHtml(final String dictId) {
367         return asHtml(path_AdminDictStopwords_AdminDictStopwordsJsp).renderWith(data -> {
368             RenderDataUtil.register(data, "stopwordsItemItems", stopwordsService.getStopwordsList(dictId, stopwordsPager));
369         }).useForm(SearchForm.class, setup -> {
370             setup.setup(form -> {
371                 copyBeanToBean(stopwordsPager, form, op -> op.include("id"));
372             });
373         });
374     }
375 
376     private HtmlResponse asEditHtml() {
377         return asHtml(path_AdminDictStopwords_AdminDictStopwordsEditJsp);
378     }
379 
380     private HtmlResponse asDetailsHtml() {
381         return asHtml(path_AdminDictStopwords_AdminDictStopwordsDetailsJsp);
382     }
383 
384 }