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.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 }