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.elevateword;
17  
18  import static org.codelibs.core.stream.StreamUtil.split;
19  import static org.codelibs.core.stream.StreamUtil.stream;
20  
21  import java.io.BufferedReader;
22  import java.io.BufferedWriter;
23  import java.io.InputStream;
24  import java.io.InputStreamReader;
25  import java.io.OutputStreamWriter;
26  import java.io.Reader;
27  import java.io.Writer;
28  import java.nio.file.Files;
29  import java.nio.file.Path;
30  import java.util.stream.Collectors;
31  import java.util.stream.Stream;
32  
33  import javax.annotation.Resource;
34  
35  import org.codelibs.core.beans.util.BeanUtil;
36  import org.codelibs.core.lang.StringUtil;
37  import org.codelibs.fess.Constants;
38  import org.codelibs.fess.app.pager.ElevateWordPager;
39  import org.codelibs.fess.app.service.ElevateWordService;
40  import org.codelibs.fess.app.service.LabelTypeService;
41  import org.codelibs.fess.app.web.CrudMode;
42  import org.codelibs.fess.app.web.base.FessAdminAction;
43  import org.codelibs.fess.es.config.exentity.ElevateWord;
44  import org.codelibs.fess.exception.FessSystemException;
45  import org.codelibs.fess.helper.PermissionHelper;
46  import org.codelibs.fess.helper.SuggestHelper;
47  import org.codelibs.fess.helper.SystemHelper;
48  import org.codelibs.fess.util.ComponentUtil;
49  import org.codelibs.fess.util.RenderDataUtil;
50  import org.dbflute.optional.OptionalEntity;
51  import org.dbflute.optional.OptionalThing;
52  import org.lastaflute.web.Execute;
53  import org.lastaflute.web.response.ActionResponse;
54  import org.lastaflute.web.response.HtmlResponse;
55  import org.lastaflute.web.response.render.RenderData;
56  import org.lastaflute.web.ruts.process.ActionRuntime;
57  
58  /**
59   * @author Keiichi Watanabe
60   */
61  public class AdminElevatewordAction extends FessAdminAction {
62  
63      // ===================================================================================
64      //                                                                           Attribute
65      //                                                                           =========
66      @Resource
67      private ElevateWordService elevateWordService;
68      @Resource
69      private ElevateWordPager elevateWordPager;
70      @Resource
71      protected SuggestHelper suggestHelper;
72      @Resource
73      private LabelTypeService labelTypeService;
74  
75      // ===================================================================================
76      //                                                                               Hook
77      //                                                                              ======
78      @Override
79      protected void setupHtmlData(final ActionRuntime runtime) {
80          super.setupHtmlData(runtime);
81          runtime.registerData("helpLink", systemHelper.getHelpLink(fessConfig.getOnlineHelpNameElevateword()));
82      }
83  
84      // ===================================================================================
85      //                                                                      Search Execute
86      //                                                                      ==============
87      @Execute
88      public HtmlResponse index() {
89          return asListHtml();
90      }
91  
92      @Execute
93      public HtmlResponse list(final OptionalThing<Integer> pageNumber, final SearchForm form) {
94          pageNumber.ifPresent(num -> {
95              elevateWordPager.setCurrentPageNumber(pageNumber.get());
96          }).orElse(() -> {
97              elevateWordPager.setCurrentPageNumber(0);
98          });
99          return asHtml(path_AdminElevateword_AdminElevatewordJsp).renderWith(data -> {
100             searchPaging(data, form);
101         });
102     }
103 
104     @Execute
105     public HtmlResponse search(final SearchForm form) {
106         copyBeanToBean(form, elevateWordPager, op -> op.exclude(Constants.PAGER_CONVERSION_RULE));
107         return asHtml(path_AdminElevateword_AdminElevatewordJsp).renderWith(data -> {
108             searchPaging(data, form);
109         });
110     }
111 
112     @Execute
113     public HtmlResponse reset(final SearchForm form) {
114         elevateWordPager.clear();
115         return asHtml(path_AdminElevateword_AdminElevatewordJsp).renderWith(data -> {
116             searchPaging(data, form);
117         });
118     }
119 
120     protected void searchPaging(final RenderData data, final SearchForm form) {
121         RenderDataUtil.register(data, "elevateWordItems", elevateWordService.getElevateWordList(elevateWordPager)); // page navi
122 
123         // restore from pager
124         copyBeanToBean(elevateWordPager, form, op -> op.include("id"));
125     }
126 
127     // ===================================================================================
128     //                                                                        Edit Execute
129     //                                                                        ============
130     // -----------------------------------------------------
131     //                                            Entry Page
132     //                                            ----------
133     @Execute
134     public HtmlResponse createnew() {
135         saveToken();
136         return asHtml(path_AdminElevateword_AdminElevatewordEditJsp).useForm(CreateForm.class, op -> {
137             op.setup(form -> {
138                 form.initialize();
139                 form.crudMode = CrudMode.CREATE;
140             });
141         }).renderWith(data -> {
142             registerLabels(data);
143         });
144     }
145 
146     @Execute
147     public HtmlResponse edit(final EditForm form) {
148         validate(form, messages -> {}, () -> asListHtml());
149         final String id = form.id;
150         elevateWordService
151                 .getElevateWord(id)
152                 .ifPresent(
153                         entity -> {
154                             copyBeanToBean(entity, form, copyOp -> {
155                                 copyOp.excludeNull();
156                                 copyOp.exclude(Constants.PERMISSIONS);
157                             });
158                             final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
159                             form.permissions =
160                                     stream(entity.getPermissions()).get(
161                                             stream -> stream.map(s -> permissionHelper.decode(s)).filter(StringUtil::isNotBlank).distinct()
162                                                     .collect(Collectors.joining("\n")));
163                         }).orElse(() -> {
164                     throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id), () -> asListHtml());
165                 });
166         saveToken();
167         if (form.crudMode.intValue() == CrudMode.EDIT) {
168             // back
169             form.crudMode = CrudMode.DETAILS;
170             return asDetailsHtml();
171         } else {
172             form.crudMode = CrudMode.EDIT;
173             return asEditHtml();
174         }
175     }
176 
177     // -----------------------------------------------------
178     //                                               Details
179     //                                               -------
180     @Execute
181     public HtmlResponse details(final int crudMode, final String id) {
182         verifyCrudMode(crudMode, CrudMode.DETAILS);
183         saveToken();
184         final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
185         return asHtml(path_AdminElevateword_AdminElevatewordDetailsJsp).useForm(
186                 EditForm.class,
187                 op -> op.setup(form -> {
188                     elevateWordService
189                             .getElevateWord(id)
190                             .ifPresent(
191                                     entity -> {
192                                         copyBeanToBean(entity, form, copyOp -> {
193                                             copyOp.excludeNull();
194                                             copyOp.exclude(Constants.PERMISSIONS);
195                                         });
196                                         form.permissions =
197                                                 stream(entity.getPermissions()).get(
198                                                         stream -> stream.map(permissionHelper::decode).filter(StringUtil::isNotBlank)
199                                                                 .distinct().collect(Collectors.joining("\n")));
200                                         form.crudMode = crudMode;
201                                     })
202                             .orElse(() -> throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id),
203                                     () -> asListHtml()));
204                 })).renderWith(data -> registerLabels(data));
205     }
206 
207     // -----------------------------------------------------
208     //                                              Download
209     //                                               -------
210     @Execute
211     public HtmlResponse downloadpage() {
212         saveToken();
213         return asDownloadHtml();
214     }
215 
216     @Execute
217     public ActionResponse download(final DownloadForm form) {
218         verifyToken(() -> asDownloadHtml());
219 
220         return asStream("elevate.csv").contentTypeOctetStream().stream(out -> {
221             final Path tempFile = Files.createTempFile(null, null);
222             try {
223                 try (Writer writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(tempFile), getCsvEncoding()))) {
224                     elevateWordService.exportCsv(writer);
225                 } catch (final Exception e) {
226                     throwValidationError(messages -> messages.addErrorsFailedToDownloadElevateFile(GLOBAL), () -> asDownloadHtml());
227                 }
228                 try (InputStream in = Files.newInputStream(tempFile)) {
229                     out.write(in);
230                 }
231             } finally {
232                 Files.delete(tempFile);
233             }
234         });
235     }
236 
237     // -----------------------------------------------------
238     //                                                Upload
239     //                                               -------
240     @Execute
241     public HtmlResponse uploadpage() {
242         saveToken();
243         return asUploadHtml();
244     }
245 
246     // -----------------------------------------------------
247     //                                         Actually Crud
248     //                                         -------------
249     @Execute
250     public HtmlResponse create(final CreateForm form) {
251         verifyCrudMode(form.crudMode, CrudMode.CREATE);
252         validate(form, messages -> {}, () -> asEditHtml());
253         verifyToken(() -> asEditHtml());
254         getElevateWord(form).ifPresent(
255                 entity -> {
256                     try {
257                         elevateWordService.store(entity);
258                         suggestHelper.addElevateWord(entity.getSuggestWord(), entity.getReading(), entity.getLabelTypeValues(),
259                                 entity.getPermissions(), entity.getBoost(), false);
260                         saveInfo(messages -> messages.addSuccessCrudCreateCrudTable(GLOBAL));
261                     } catch (final Exception e) {
262                         throwValidationError(messages -> messages.addErrorsCrudFailedToCreateCrudTable(GLOBAL, buildThrowableMessage(e)),
263                                 () -> asEditHtml());
264                     }
265                 }).orElse(() -> {
266             throwValidationError(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL), () -> asEditHtml());
267         });
268         return redirect(getClass());
269     }
270 
271     @Execute
272     public HtmlResponse update(final EditForm form) {
273         verifyCrudMode(form.crudMode, CrudMode.EDIT);
274         validate(form, messages -> {}, () -> asEditHtml());
275         verifyToken(() -> asEditHtml());
276         getElevateWord(form).ifPresent(
277                 entity -> {
278                     try {
279                         elevateWordService.store(entity);
280                         suggestHelper.deleteAllElevateWord(false);
281                         suggestHelper.storeAllElevateWords(false);
282                         saveInfo(messages -> messages.addSuccessCrudUpdateCrudTable(GLOBAL));
283                     } catch (final Exception e) {
284                         throwValidationError(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, buildThrowableMessage(e)),
285                                 () -> asEditHtml());
286                     }
287                 }).orElse(() -> {
288             throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.id), () -> asEditHtml());
289         });
290         return redirect(getClass());
291     }
292 
293     @Execute
294     public HtmlResponse delete(final EditForm form) {
295         verifyCrudMode(form.crudMode, CrudMode.DETAILS);
296         validate(form, messages -> {}, () -> asDetailsHtml());
297         verifyToken(() -> asDetailsHtml());
298         final String id = form.id;
299         elevateWordService
300                 .getElevateWord(id)
301                 .ifPresent(
302                         entity -> {
303                             try {
304                                 elevateWordService.delete(entity);
305                                 suggestHelper.deleteElevateWord(entity.getSuggestWord(), false);
306                                 saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
307                             } catch (final Exception e) {
308                                 throwValidationError(
309                                         messages -> messages.addErrorsCrudFailedToDeleteCrudTable(GLOBAL, buildThrowableMessage(e)),
310                                         () -> asEditHtml());
311                             }
312                         })
313                 .orElse(() -> throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id),
314                         () -> asDetailsHtml()));
315         return redirect(getClass());
316     }
317 
318     @Execute
319     public HtmlResponse upload(final UploadForm form) {
320         validate(form, messages -> {}, () -> asUploadHtml());
321         verifyToken(() -> asUploadHtml());
322         new Thread(() -> {
323             try (Reader reader = new BufferedReader(new InputStreamReader(form.elevateWordFile.getInputStream(), getCsvEncoding()))) {
324                 elevateWordService.importCsv(reader);
325                 suggestHelper.deleteAllElevateWord(false);
326                 suggestHelper.storeAllElevateWords(false);
327             } catch (final Exception e) {
328                 throw new FessSystemException("Failed to import data.", e);
329             }
330         }).start();
331         saveInfo(messages -> messages.addSuccessUploadElevateWord(GLOBAL));
332         return redirect(getClass());
333     }
334 
335     // ===================================================================================
336     //                                                                        Assist Logic
337     //                                                                        ============
338     public static OptionalEntity<ElevateWord> getEntity(final CreateForm form, final String username, final long currentTime) {
339         switch (form.crudMode) {
340         case CrudMode.CREATE:
341             return OptionalEntity.of(new ElevateWord()).map(entity -> {
342                 entity.setCreatedBy(username);
343                 entity.setCreatedTime(currentTime);
344                 return entity;
345             });
346         case CrudMode.EDIT:
347             if (form instanceof EditForm) {
348                 return ComponentUtil.getComponent(ElevateWordService.class).getElevateWord(((EditForm) form).id);
349             }
350             break;
351         default:
352             break;
353         }
354         return OptionalEntity.empty();
355     }
356 
357     public static OptionalEntity<ElevateWord> getElevateWord(final CreateForm form) {
358         final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
359         final String username = systemHelper.getUsername();
360         final long currentTime = systemHelper.getCurrentTimeAsLong();
361 
362         return getEntity(form, username, currentTime).map(
363                 entity -> {
364                     entity.setUpdatedBy(username);
365                     entity.setUpdatedTime(currentTime);
366                     BeanUtil.copyBeanToBean(form, entity, op -> op.exclude(Stream.concat(Stream.of(Constants.COMMON_CONVERSION_RULE),
367                             Stream.of(Constants.PERMISSIONS)).toArray(n -> new String[n])));
368                     final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
369                     entity.setPermissions(split(form.permissions, "\n").get(
370                             stream -> stream.map(permissionHelper::encode).filter(StringUtil::isNotBlank).distinct()
371                                     .toArray(n -> new String[n])));
372                     return entity;
373                 });
374     }
375 
376     protected void registerLabels(final RenderData data) {
377         RenderDataUtil.register(data, "labelTypeItems", labelTypeService.getLabelTypeList());
378     }
379 
380     // ===================================================================================
381     //                                                                        Small Helper
382     //                                                                        ============
383     protected void verifyCrudMode(final int crudMode, final int expectedMode) {
384         if (crudMode != expectedMode) {
385             throwValidationError(messages -> {
386                 messages.addErrorsCrudInvalidMode(GLOBAL, String.valueOf(expectedMode), String.valueOf(crudMode));
387             }, () -> asListHtml());
388         }
389     }
390 
391     private String getCsvEncoding() {
392         return fessConfig.getCsvFileEncoding();
393     }
394 
395     // ===================================================================================
396     //                                                                              JSP
397     //                                                                           =========
398     private HtmlResponse asListHtml() {
399         return asHtml(path_AdminElevateword_AdminElevatewordJsp).renderWith(data -> {
400             RenderDataUtil.register(data, "elevateWordItems", elevateWordService.getElevateWordList(elevateWordPager)); // page navi
401             }).useForm(SearchForm.class, setup -> {
402             setup.setup(form -> {
403                 copyBeanToBean(elevateWordPager, form, op -> op.include("id"));
404             });
405         });
406     }
407 
408     private HtmlResponse asEditHtml() {
409         return asHtml(path_AdminElevateword_AdminElevatewordEditJsp).renderWith(data -> {
410             registerLabels(data);
411         });
412     }
413 
414     private HtmlResponse asDetailsHtml() {
415         return asHtml(path_AdminElevateword_AdminElevatewordDetailsJsp).renderWith(data -> {
416             registerLabels(data);
417         });
418     }
419 
420     private HtmlResponse asUploadHtml() {
421         return asHtml(path_AdminElevateword_AdminElevatewordUploadJsp).useForm(UploadForm.class);
422     }
423 
424     private HtmlResponse asDownloadHtml() {
425         return asHtml(path_AdminElevateword_AdminElevatewordDownloadJsp).useForm(DownloadForm.class);
426     }
427 }