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