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