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.service;
17  
18  import java.io.IOException;
19  import java.io.Reader;
20  import java.io.Writer;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import javax.annotation.Resource;
25  
26  import org.apache.logging.log4j.LogManager;
27  import org.apache.logging.log4j.Logger;
28  import org.codelibs.core.beans.util.BeanUtil;
29  import org.codelibs.core.lang.StringUtil;
30  import org.codelibs.fess.Constants;
31  import org.codelibs.fess.app.pager.BadWordPager;
32  import org.codelibs.fess.es.client.SearchEngineClient;
33  import org.codelibs.fess.es.config.cbean.BadWordCB;
34  import org.codelibs.fess.es.config.exbhv.BadWordBhv;
35  import org.codelibs.fess.es.config.exentity.BadWord;
36  import org.codelibs.fess.mylasta.direction.FessConfig;
37  import org.codelibs.fess.util.ComponentUtil;
38  import org.dbflute.bhv.readable.EntityRowHandler;
39  import org.dbflute.cbean.result.PagingResultBean;
40  import org.dbflute.optional.OptionalEntity;
41  
42  import com.orangesignal.csv.CsvConfig;
43  import com.orangesignal.csv.CsvReader;
44  import com.orangesignal.csv.CsvWriter;
45  
46  public class BadWordService {
47  
48      private static final String DELETE_PREFIX = "--";
49  
50      private static final Logger logger = LogManager.getLogger(BadWordService.class);
51  
52      @Resource
53      protected BadWordBhv badWordBhv;
54  
55      @Resource
56      protected SearchEngineClient searchEngineClient;
57  
58      @Resource
59      protected FessConfig fessConfig;
60  
61      public List<BadWord> getBadWordList(final BadWordPager badWordPager) {
62  
63          final PagingResultBean<BadWord> badWordList = badWordBhv.selectPage(cb -> {
64              cb.paging(badWordPager.getPageSize(), badWordPager.getCurrentPageNumber());
65              setupListCondition(cb, badWordPager);
66          });
67  
68          // update pager
69          BeanUtil.copyBeanToBean(badWordList, badWordPager, option -> option.include(Constants.PAGER_CONVERSION_RULE));
70          badWordPager.setPageNumberList(
71                  badWordList.pageRange(op -> op.rangeSize(fessConfig.getPagingPageRangeSizeAsInteger())).createPageNumberList());
72  
73          return badWordList;
74      }
75  
76      public OptionalEntity<BadWord> getBadWord(final String id) {
77          return badWordBhv.selectByPK(id);
78      }
79  
80      public void store(final BadWord badWord) {
81  
82          badWordBhv.insertOrUpdate(badWord, op -> op.setRefreshPolicy(Constants.TRUE));
83  
84      }
85  
86      public void delete(final BadWord badWord) {
87  
88          badWordBhv.delete(badWord, op -> op.setRefreshPolicy(Constants.TRUE));
89  
90      }
91  
92      protected void setupListCondition(final BadWordCB cb, final BadWordPager badWordPager) {
93          if (badWordPager.id != null) {
94              cb.query().docMeta().setId_Equal(badWordPager.id);
95          }
96          // TODO Long, Integer, String supported only.
97  
98          // setup condition
99          cb.query().addOrderBy_SuggestWord_Asc();
100 
101         // search
102 
103     }
104 
105     public void importCsv(final Reader reader) {
106         @SuppressWarnings("resource")
107         final CsvReader csvReader = new CsvReader(reader, new CsvConfig());
108         try {
109             List<String> list;
110             csvReader.readValues(); // ignore header
111             while ((list = csvReader.readValues()) != null) {
112                 String targetWord = getValue(list, 0);
113                 if (StringUtil.isBlank(targetWord)) {
114                     // skip
115                     continue;
116                 }
117                 try {
118                     boolean isDelete = false;
119                     if (targetWord.startsWith(DELETE_PREFIX)) {
120                         isDelete = true;
121                         targetWord = targetWord.substring(2);
122                     }
123                     final String target = targetWord;
124                     BadWord badWord = badWordBhv.selectEntity(cb -> cb.query().setSuggestWord_Equal(target)).orElse(null);//TODO
125                     final long now = ComponentUtil.getSystemHelper().getCurrentTimeAsLong();
126                     if (isDelete) {
127                         badWordBhv.delete(badWord);
128                     } else if (badWord == null) {
129                         badWord = new BadWord();
130                         badWord.setSuggestWord(targetWord);
131                         badWord.setCreatedBy(Constants.SYSTEM_USER);
132                         badWord.setCreatedTime(now);
133                         badWordBhv.insert(badWord);
134                     } else {
135                         badWord.setUpdatedBy(Constants.SYSTEM_USER);
136                         badWord.setUpdatedTime(now);
137                         badWordBhv.update(badWord);
138                     }
139                 } catch (final Exception e) {
140                     logger.warn("Failed to read a sugget elevate word: {}", list, e);
141                 }
142             }
143             searchEngineClient.refresh("_all"); // TODO replace _all
144         } catch (final IOException e) {
145             logger.warn("Failed to read a sugget elevate word.", e);
146         }
147     }
148 
149     public void exportCsv(final Writer writer) {
150         final CsvConfig cfg = new CsvConfig(',', '"', '"');
151         cfg.setEscapeDisabled(false);
152         cfg.setQuoteDisabled(false);
153         @SuppressWarnings("resource")
154         final CsvWriter csvWriter = new CsvWriter(writer, cfg);
155         try {
156             final List<String> list = new ArrayList<>();
157             list.add("BadWord");
158             csvWriter.writeValues(list);
159 
160             badWordBhv.selectCursor(cb -> cb.query().matchAll(), new EntityRowHandler<BadWord>() {
161                 @Override
162                 public void handle(final BadWord entity) {
163                     final List<String> list = new ArrayList<>();
164                     addToList(list, entity.getSuggestWord());
165                     try {
166                         csvWriter.writeValues(list);
167                     } catch (final IOException e) {
168                         logger.warn("Failed to write a sugget bad word: {}", entity, e);
169                     }
170                 }
171 
172                 private void addToList(final List<String> list, final Object value) {
173                     if (value == null) {
174                         list.add(StringUtil.EMPTY);
175                     } else {
176                         list.add(value.toString());
177                     }
178                 }
179             });
180 
181             csvWriter.flush();
182         } catch (final IOException e) {
183             logger.warn("Failed to write a sugget bad word.", e);
184         }
185     }
186 
187     private static String getValue(final List<String> list, final int index) {
188         if (index >= list.size()) {
189             return StringUtil.EMPTY;
190         }
191         String item = list.get(index).trim();
192         if (StringUtil.isBlank(item)) {
193             return StringUtil.EMPTY;
194         }
195         if (item.length() > 1 && item.charAt(0) == '"' && item.charAt(item.length() - 1) == '"') {
196             item = item.substring(1, item.length() - 1);
197         }
198         return item;
199     }
200 }