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.service;
17  
18  import static org.codelibs.core.stream.StreamUtil.split;
19  import static org.codelibs.core.stream.StreamUtil.stream;
20  
21  import java.io.IOException;
22  import java.io.Reader;
23  import java.io.Writer;
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.stream.Collectors;
27  
28  import javax.annotation.Resource;
29  
30  import org.codelibs.core.beans.util.BeanUtil;
31  import org.codelibs.core.lang.StringUtil;
32  import org.codelibs.fess.Constants;
33  import org.codelibs.fess.app.pager.ElevateWordPager;
34  import org.codelibs.fess.es.client.FessEsClient;
35  import org.codelibs.fess.es.config.cbean.ElevateWordCB;
36  import org.codelibs.fess.es.config.exbhv.ElevateWordBhv;
37  import org.codelibs.fess.es.config.exbhv.ElevateWordToLabelBhv;
38  import org.codelibs.fess.es.config.exentity.ElevateWord;
39  import org.codelibs.fess.es.config.exentity.ElevateWordToLabel;
40  import org.codelibs.fess.helper.PermissionHelper;
41  import org.codelibs.fess.mylasta.direction.FessConfig;
42  import org.codelibs.fess.util.ComponentUtil;
43  import org.dbflute.bhv.readable.EntityRowHandler;
44  import org.dbflute.cbean.result.PagingResultBean;
45  import org.dbflute.optional.OptionalEntity;
46  import org.slf4j.Logger;
47  import org.slf4j.LoggerFactory;
48  
49  import com.orangesignal.csv.CsvConfig;
50  import com.orangesignal.csv.CsvReader;
51  import com.orangesignal.csv.CsvWriter;
52  
53  public class ElevateWordService {
54  
55      private static final Logger logger = LoggerFactory.getLogger(ElevateWordService.class);
56  
57      @Resource
58      protected ElevateWordToLabelBhv elevateWordToLabelBhv;
59  
60      @Resource
61      protected ElevateWordBhv elevateWordBhv;
62  
63      @Resource
64      protected FessConfig fessConfig;
65  
66      @Resource
67      protected FessEsClient fessEsClient;
68  
69      public List<ElevateWord> getElevateWordList(final ElevateWordPager elevateWordPager) {
70  
71          final PagingResultBean<ElevateWord> elevateWordList = elevateWordBhv.selectPage(cb -> {
72              cb.paging(elevateWordPager.getPageSize(), elevateWordPager.getCurrentPageNumber());
73              setupListCondition(cb, elevateWordPager);
74          });
75  
76          // update pager
77          BeanUtil.copyBeanToBean(elevateWordList, elevateWordPager, option -> option.include(Constants.PAGER_CONVERSION_RULE));
78          elevateWordPager.setPageNumberList(elevateWordList.pageRange(op -> {
79              op.rangeSize(fessConfig.getPagingPageRangeSizeAsInteger());
80          }).createPageNumberList());
81  
82          return elevateWordList;
83      }
84  
85      public OptionalEntity<ElevateWord> getElevateWord(final String id) {
86          return elevateWordBhv.selectByPK(id).map(entity -> {
87  
88              final List<ElevateWordToLabel> wctltmList = elevateWordToLabelBhv.selectList(wctltmCb -> {
89                  wctltmCb.query().setElevateWordId_Equal(entity.getId());
90                  wctltmCb.fetchFirst(fessConfig.getPageLabeltypeMaxFetchSizeAsInteger());
91              });
92              if (!wctltmList.isEmpty()) {
93                  final List<String> labelTypeIds = new ArrayList<>(wctltmList.size());
94                  for (final ElevateWordToLabel mapping : wctltmList) {
95                      labelTypeIds.add(mapping.getLabelTypeId());
96                  }
97                  entity.setLabelTypeIds(labelTypeIds.toArray(new String[labelTypeIds.size()]));
98              }
99              return entity;
100         });
101     }
102 
103     public void store(final ElevateWord elevateWord) {
104         final boolean isNew = elevateWord.getId() == null;
105         final String[] labelTypeIds = elevateWord.getLabelTypeIds();
106 
107         elevateWordBhv.insertOrUpdate(elevateWord, op -> {
108             op.setRefreshPolicy(Constants.TRUE);
109         });
110         final String elevateWordId = elevateWord.getId();
111         if (isNew) {
112             // Insert
113             if (labelTypeIds != null) {
114                 final List<ElevateWordToLabel> wctltmList = new ArrayList<>();
115                 for (final String id : labelTypeIds) {
116                     final ElevateWordToLabel mapping = new ElevateWordToLabel();
117                     mapping.setElevateWordId(elevateWordId);
118                     mapping.setLabelTypeId(id);
119                     wctltmList.add(mapping);
120                 }
121                 elevateWordToLabelBhv.batchInsert(wctltmList, op -> {
122                     op.setRefreshPolicy(Constants.TRUE);
123                 });
124             }
125         } else {
126             // Update
127             if (labelTypeIds != null) {
128                 final List<ElevateWordToLabel> list = elevateWordToLabelBhv.selectList(wctltmCb -> {
129                     wctltmCb.query().setElevateWordId_Equal(elevateWordId);
130                     wctltmCb.fetchFirst(fessConfig.getPageLabeltypeMaxFetchSizeAsInteger());
131                 });
132                 final List<ElevateWordToLabel> newList = new ArrayList<>();
133                 final List<ElevateWordToLabel> matchedList = new ArrayList<>();
134                 for (final String id : labelTypeIds) {
135                     boolean exist = false;
136                     for (final ElevateWordToLabel mapping : list) {
137                         if (mapping.getLabelTypeId().equals(id)) {
138                             exist = true;
139                             matchedList.add(mapping);
140                             break;
141                         }
142                     }
143                     if (!exist) {
144                         // new
145                         final ElevateWordToLabel mapping = new ElevateWordToLabel();
146                         mapping.setElevateWordId(elevateWordId);
147                         mapping.setLabelTypeId(id);
148                         newList.add(mapping);
149                     }
150                 }
151                 list.removeAll(matchedList);
152                 elevateWordToLabelBhv.batchInsert(newList, op -> {
153                     op.setRefreshPolicy(Constants.TRUE);
154                 });
155                 elevateWordToLabelBhv.batchDelete(list, op -> {
156                     op.setRefreshPolicy(Constants.TRUE);
157                 });
158             }
159         }
160     }
161 
162     public void delete(final ElevateWord elevateWord) {
163 
164         elevateWordBhv.delete(elevateWord, op -> {
165             op.setRefreshPolicy(Constants.TRUE);
166         });
167 
168     }
169 
170     protected void setupListCondition(final ElevateWordCB cb, final ElevateWordPager elevateWordPager) {
171         if (elevateWordPager.id != null) {
172             cb.query().docMeta().setId_Equal(elevateWordPager.id);
173         }
174         // TODO Long, Integer, String supported only.
175 
176         // setup condition
177         cb.query().addOrderBy_SuggestWord_Asc();
178 
179         // search
180 
181     }
182 
183     public void importCsv(final Reader reader) {
184         final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
185         final CsvConfig cfg = new CsvConfig(',', '"', '"');
186         cfg.setEscapeDisabled(false);
187         cfg.setQuoteDisabled(false);
188         @SuppressWarnings("resource")
189         final CsvReader csvReader = new CsvReader(reader, cfg);
190         try {
191             List<String> list;
192             csvReader.readValues(); // ignore header
193             while ((list = csvReader.readValues()) != null) {
194                 final String suggestWord = getValue(list, 0);
195                 if (StringUtil.isBlank(suggestWord)) {
196                     // skip
197                     continue;
198                 }
199                 try {
200                     final String[] permissions =
201                             split(getValue(list, 2), ",").get(
202                                     stream -> stream.map(permissionHelper::encode).filter(StringUtil::isNotBlank).distinct()
203                                             .toArray(n -> new String[n]));
204                     final String label = getValue(list, 3);
205                     ElevateWord elevateWord = elevateWordBhv.selectEntity(cb -> {
206                         cb.query().setSuggestWord_Equal(suggestWord);
207                         if (permissions.length > 0) {
208                             cb.query().setPermissions_InScope(stream(permissions).get(stream -> stream.collect(Collectors.toList())));
209                         }
210                         if (StringUtil.isNotBlank(label)) {
211                             cb.query().setTargetLabel_Equal(label);
212                         }
213                     }).orElse(null);
214                     final String reading = getValue(list, 1);
215                     final String boost = getValue(list, 4);
216                     final long now = ComponentUtil.getSystemHelper().getCurrentTimeAsLong();
217                     if (elevateWord == null) {
218                         elevateWord = new ElevateWord();
219                         elevateWord.setSuggestWord(suggestWord);
220                         elevateWord.setReading(reading);
221                         elevateWord.setPermissions(permissions);
222                         elevateWord.setTargetLabel(label);
223                         elevateWord.setBoost(StringUtil.isBlank(boost) ? 1.0f : Float.parseFloat(boost));
224                         elevateWord.setCreatedBy(Constants.SYSTEM_USER);
225                         elevateWord.setCreatedTime(now);
226                         elevateWordBhv.insert(elevateWord);
227                     } else if (StringUtil.isBlank(reading) && StringUtil.isBlank(boost)) {
228                         elevateWordBhv.delete(elevateWord);
229                     } else {
230                         elevateWord.setReading(reading);
231                         elevateWord.setPermissions(permissions);
232                         elevateWord.setBoost(StringUtil.isBlank(boost) ? 1.0f : Float.parseFloat(boost));
233                         elevateWord.setUpdatedBy(Constants.SYSTEM_USER);
234                         elevateWord.setUpdatedTime(now);
235                         elevateWordBhv.update(elevateWord);
236                     }
237                 } catch (final Exception e) {
238                     logger.warn("Failed to read a sugget elevate word: " + list, e);
239                 }
240             }
241             elevateWordBhv.refresh();
242         } catch (final IOException e) {
243             logger.warn("Failed to read a sugget elevate word.", e);
244         }
245     }
246 
247     public void exportCsv(final Writer writer) {
248         final PermissionHelper permissionHelper = ComponentUtil.getPermissionHelper();
249         final CsvConfig cfg = new CsvConfig(',', '"', '"');
250         cfg.setEscapeDisabled(false);
251         cfg.setQuoteDisabled(false);
252         @SuppressWarnings("resource")
253         final CsvWriter csvWriter = new CsvWriter(writer, cfg);
254         try {
255             final List<String> list = new ArrayList<>();
256             list.add("SuggestWord");
257             list.add("Reading");
258             list.add("Permissions");
259             list.add("Label");
260             list.add("Boost");
261             csvWriter.writeValues(list);
262 
263             elevateWordBhv.selectCursor(cb -> cb.query().matchAll(), new EntityRowHandler<ElevateWord>() {
264                 @Override
265                 public void handle(final ElevateWord entity) {
266                     final List<String> list = new ArrayList<>();
267                     final String permissions =
268                             stream(entity.getPermissions()).get(
269                                     stream -> stream.map(s -> permissionHelper.decode(s)).filter(StringUtil::isNotBlank).distinct()
270                                             .collect(Collectors.joining(",")));
271                     addToList(list, entity.getSuggestWord());
272                     addToList(list, entity.getReading());
273                     addToList(list, permissions);
274                     addToList(list, entity.getTargetLabel());
275                     addToList(list, entity.getBoost());
276                     try {
277                         csvWriter.writeValues(list);
278                     } catch (final IOException e) {
279                         logger.warn("Failed to write a sugget elevate word: " + entity, e);
280                     }
281                 }
282 
283                 private void addToList(final List<String> list, final Object value) {
284                     if (value == null) {
285                         list.add(StringUtil.EMPTY);
286                     } else {
287                         list.add(value.toString());
288                     }
289                 }
290             });
291 
292             csvWriter.flush();
293         } catch (final IOException e) {
294             logger.warn("Failed to write a sugget elevate word.", e);
295         }
296     }
297 
298     static String getValue(final List<String> list, final int index) {
299         if (index >= list.size()) {
300             return StringUtil.EMPTY;
301         }
302         String item = list.get(index).trim();
303         if (StringUtil.isBlank(item)) {
304             return StringUtil.EMPTY;
305         }
306         if (item.length() > 1 && item.charAt(0) == '"' && item.charAt(item.length() - 1) == '"') {
307             item = item.substring(1, item.length() - 1);
308         }
309         return item;
310     }
311 
312 }