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