1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.helper;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Locale;
23 import java.util.Map;
24 import java.util.regex.Pattern;
25
26 import javax.annotation.PostConstruct;
27
28 import org.apache.logging.log4j.LogManager;
29 import org.apache.logging.log4j.Logger;
30 import org.codelibs.core.lang.StringUtil;
31 import org.codelibs.core.misc.Pair;
32 import org.codelibs.fess.es.config.exbhv.RelatedContentBhv;
33 import org.codelibs.fess.es.config.exentity.RelatedContent;
34 import org.codelibs.fess.util.ComponentUtil;
35
36 public class RelatedContentHelper extends AbstractConfigHelper {
37
38 private static final Logger logger = LogManager.getLogger(RelatedContentHelper.class);
39
40 protected Map<String, Pair<Map<String, String>, List<Pair<Pattern, String>>>> relatedContentMap = Collections.emptyMap();
41
42 protected String regexPrefix = "regex:";
43
44 protected String queryPlaceHolder = "__QUERY__";
45
46 @PostConstruct
47 public void init() {
48 if (logger.isDebugEnabled()) {
49 logger.debug("Initialize {}", this.getClass().getSimpleName());
50 }
51 load();
52 }
53
54 public List<RelatedContent> getAvailableRelatedContentList() {
55 return ComponentUtil.getComponent(RelatedContentBhv.class).selectList(cb -> {
56 cb.query().matchAll();
57 cb.query().addOrderBy_SortOrder_Asc();
58 cb.query().addOrderBy_Term_Asc();
59 cb.fetchFirst(ComponentUtil.getFessConfig().getPageRelatedcontentMaxFetchSizeAsInteger());
60 });
61 }
62
63 @Override
64 public int load() {
65 final Map<String, Pair<Map<String, String>, List<Pair<Pattern, String>>>> relatedContentMap = new HashMap<>();
66 getAvailableRelatedContentList().stream().forEach(entity -> {
67 final String key = getHostKey(entity);
68 Pair<Map<String, String>, List<Pair<Pattern, String>>> pair = relatedContentMap.get(key);
69 if (pair == null) {
70 pair = new Pair<>(new HashMap<>(), new ArrayList<>());
71 relatedContentMap.put(key, pair);
72 }
73 if (entity.getTerm().startsWith(regexPrefix)) {
74 final String regex = entity.getTerm().substring(regexPrefix.length());
75 if (StringUtil.isBlank(regex)) {
76 logger.warn("Unknown regex pattern: {}", entity.getTerm());
77 } else {
78 pair.getSecond().add(new Pair<>(Pattern.compile(regex), entity.getContent()));
79 }
80 } else {
81 pair.getFirst().put(toLowerCase(entity.getTerm()), entity.getContent());
82 }
83 });
84 this.relatedContentMap = relatedContentMap;
85 return relatedContentMap.size();
86 }
87
88 protected String getHostKey(final RelatedContent entity) {
89 final String key = entity.getVirtualHost();
90 return StringUtil.isBlank(key) ? StringUtil.EMPTY : key;
91 }
92
93 public String[] getRelatedContents(final String query) {
94 final String key = ComponentUtil.getVirtualHostHelper().getVirtualHostKey();
95 final Pair<Map<String, String>, List<Pair<Pattern, String>>> pair = relatedContentMap.get(key);
96 if (pair != null) {
97 final List<String> contentList = new ArrayList<>();
98 final String content = pair.getFirst().get(toLowerCase(query));
99 if (StringUtil.isNotBlank(content)) {
100 contentList.add(content);
101 }
102 for (final Pair<Pattern, String> regexData : pair.getSecond()) {
103 if (regexData.getFirst().matcher(query).matches()) {
104 contentList.add(regexData.getSecond().replace(queryPlaceHolder, query));
105 }
106 }
107 return contentList.toArray(new String[contentList.size()]);
108 }
109 return StringUtil.EMPTY_STRINGS;
110 }
111
112 private String toLowerCase(final String term) {
113 return term != null ? term.toLowerCase(Locale.ROOT) : term;
114 }
115
116 public void setRegexPrefix(final String regexPrefix) {
117 this.regexPrefix = regexPrefix;
118 }
119
120 public void setQueryPlaceHolder(final String queryPlaceHolder) {
121 this.queryPlaceHolder = queryPlaceHolder;
122 }
123
124 }