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.api.admin.badword;
17  
18  import static org.codelibs.fess.app.web.admin.badword.AdminBadwordAction.getBadWord;
19  
20  import java.io.BufferedReader;
21  import java.io.BufferedWriter;
22  import java.io.InputStream;
23  import java.io.InputStreamReader;
24  import java.io.OutputStreamWriter;
25  import java.io.Reader;
26  import java.io.Writer;
27  import java.nio.file.Files;
28  import java.nio.file.Path;
29  import java.util.List;
30  import java.util.stream.Collectors;
31  
32  import javax.annotation.Resource;
33  
34  import org.codelibs.core.concurrent.CommonPoolUtil;
35  import org.codelibs.fess.app.pager.BadWordPager;
36  import org.codelibs.fess.app.service.BadWordService;
37  import org.codelibs.fess.app.web.CrudMode;
38  import org.codelibs.fess.app.web.admin.badword.UploadForm;
39  import org.codelibs.fess.app.web.api.ApiResult;
40  import org.codelibs.fess.app.web.api.ApiResult.ApiUpdateResponse;
41  import org.codelibs.fess.app.web.api.ApiResult.Status;
42  import org.codelibs.fess.app.web.api.admin.FessApiAdminAction;
43  import org.codelibs.fess.es.config.exentity.BadWord;
44  import org.codelibs.fess.exception.FessSystemException;
45  import org.codelibs.fess.helper.SuggestHelper;
46  import org.codelibs.fess.util.ComponentUtil;
47  import org.lastaflute.web.Execute;
48  import org.lastaflute.web.response.JsonResponse;
49  import org.lastaflute.web.response.StreamResponse;
50  
51  public class ApiAdminBadwordAction extends FessApiAdminAction {
52  
53      @Resource
54      private BadWordService badWordService;
55  
56      @Resource
57      protected SuggestHelper suggestHelper;
58  
59      // GET /api/admin/badword/settings
60      // POST /api/admin/badword/settings
61      @Execute
62      public JsonResponse<ApiResult> settings(final SearchBody body) {
63          validateApi(body, messages -> {});
64          final BadWordPager pager = copyBeanToNewBean(body, BadWordPager.class);
65          final List<BadWord> list = badWordService.getBadWordList(pager);
66          return asJson(
67                  new ApiResult.ApiConfigsResponse<EditBody>().settings(list.stream().map(this::createEditBody).collect(Collectors.toList()))
68                          .total(pager.getAllRecordCount()).status(ApiResult.Status.OK).result());
69      }
70  
71      // GET /api/admin/badword/{id}
72      @Execute
73      public JsonResponse<ApiResult> get$setting(final String id) {
74  
75          final BadWord entity = badWordService.getBadWord(id).orElseGet(() -> {
76              throwValidationErrorApi(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id));
77              return null;
78          });
79  
80          final EditBody body = createEditBody(entity);
81          return asJson(new ApiResult.ApiConfigResponse().setting(body).status(ApiResult.Status.OK).result());
82      }
83  
84      // PUT /api/admin/badword/setting
85      @Execute
86      public JsonResponse<ApiResult> put$setting(final CreateBody body) {
87          validateApi(body, messages -> {});
88          body.crudMode = CrudMode.CREATE;
89          final BadWord entity = getBadWord(body).orElseGet(() -> {
90              throwValidationErrorApi(messages -> {
91                  messages.addErrorsCrudFailedToCreateInstance(GLOBAL);
92              });
93              return null;
94          });
95          try {
96              badWordService.store(entity);
97              suggestHelper.addBadWord(entity.getSuggestWord(), false);
98          } catch (final Exception e) {
99              throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToCreateCrudTable(GLOBAL, buildThrowableMessage(e)));
100         }
101         return asJson(new ApiResult.ApiUpdateResponse().id(entity.getId()).created(true).status(ApiResult.Status.OK).result());
102     }
103 
104     // POST /api/admin/user/setting
105     @Execute
106     public JsonResponse<ApiResult> post$setting(final EditBody body) {
107         validateApi(body, messages -> {});
108         body.crudMode = CrudMode.EDIT;
109         final BadWord badWord = getBadWord(body).map(entity -> {
110             try {
111                 badWordService.store(entity);
112                 suggestHelper.storeAllBadWords(false);
113             } catch (final Exception e) {
114                 throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, buildThrowableMessage(e)));
115             }
116             return entity;
117         }).orElseGet(() -> {
118             throwValidationErrorApi(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, body.id));
119             return null;
120         });
121 
122         return asJson(new ApiUpdateResponse().id(badWord.getId()).created(false).status(Status.OK).result());
123     }
124 
125     // DELETE /api/admin/badword/setting/{id}
126     @Execute
127     public JsonResponse<ApiResult> delete$setting(final String id) {
128         try {
129             badWordService.getBadWord(id).ifPresent(entity -> {
130                 try {
131                     badWordService.delete(entity);
132                     suggestHelper.deleteBadWord(entity.getSuggestWord());
133                     saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));
134                 } catch (final Exception e) {
135                     throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToDeleteCrudTable(GLOBAL, buildThrowableMessage(e)));
136                 }
137             }).orElse(() -> {
138                 throwValidationErrorApi(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, id));
139             });
140         } catch (final Exception e) {
141             throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToDeleteCrudTable(GLOBAL, buildThrowableMessage(e)));
142         }
143         return asJson(new ApiResult.ApiUpdateResponse().id(id).created(false).status(ApiResult.Status.OK).result());
144     }
145 
146     // POST /api/admin/badword/upload
147     @Execute
148     public JsonResponse<ApiResult> post$upload(final UploadForm body) {
149         validateApi(body, messages -> {});
150         CommonPoolUtil.execute(() -> {
151             try (Reader reader = new BufferedReader(new InputStreamReader(body.badWordFile.getInputStream(), getCsvEncoding()))) {
152                 badWordService.importCsv(reader);
153                 suggestHelper.storeAllBadWords(false);
154             } catch (final Exception e) {
155                 throw new FessSystemException("Failed to import data.", e);
156             }
157         });
158         return asJson(new ApiResult.ApiResponse().status(ApiResult.Status.OK).result());
159     }
160 
161     // GET /api/admin/badword/download
162     @Execute
163     public StreamResponse get$download(final DownloadBody body) {
164         validateApi(body, messages -> {});
165         return asStream("badword.csv").contentTypeOctetStream().stream(out -> {
166             final Path tempFile = ComponentUtil.getSystemHelper().createTempFile("fess-badword-", ".csv").toPath();
167             try {
168                 try (Writer writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(tempFile), getCsvEncoding()))) {
169                     badWordService.exportCsv(writer);
170                 } catch (final Exception e) {
171                     throwValidationErrorApi(messages -> messages.addErrorsFailedToDownloadBadwordFile(GLOBAL));
172                 }
173                 try (InputStream in = Files.newInputStream(tempFile)) {
174                     out.write(in);
175                 }
176             } finally {
177                 Files.delete(tempFile);
178             }
179         });
180     }
181 
182     protected EditBody createEditBody(final BadWord entity) {
183         final EditBody body = new EditBody();
184         copyBeanToBean(entity, body, copyOp -> {
185             copyOp.excludeNull();
186         });
187         return body;
188     }
189 
190     private String getCsvEncoding() {
191         return fessConfig.getCsvFileEncoding();
192     }
193 
194 }