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.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.regex.Matcher;
23
24 import javax.annotation.PostConstruct;
25
26 import org.codelibs.core.lang.StringUtil;
27 import org.codelibs.fess.Constants;
28 import org.codelibs.fess.es.config.exbhv.PathMappingBhv;
29 import org.codelibs.fess.es.config.exentity.PathMapping;
30 import org.codelibs.fess.util.ComponentUtil;
31 import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
32 import org.lastaflute.web.util.LaRequestUtil;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 public class PathMappingHelper {
37
38 private static final Logger logger = LoggerFactory.getLogger(PathMappingHelper.class);
39
40 private final Map<String, List<PathMapping>> pathMappingMap = new HashMap<>();
41
42 volatile List<PathMapping> cachedPathMappingList = null;
43
44 @PostConstruct
45 public void init() {
46 final List<String> ptList = new ArrayList<>();
47 ptList.add(Constants.PROCESS_TYPE_DISPLAYING);
48 ptList.add(Constants.PROCESS_TYPE_BOTH);
49
50 try {
51 final PathMappingBhv pathMappingBhv = ComponentUtil.getComponent(PathMappingBhv.class);
52 cachedPathMappingList = pathMappingBhv.selectList(cb -> {
53 cb.query().addOrderBy_SortOrder_Asc();
54 cb.query().setProcessType_InScope(ptList);
55 cb.fetchFirst(ComponentUtil.getFessConfig().getPagePathMappingMaxFetchSizeAsInteger());
56 });
57 } catch (final Exception e) {
58 logger.warn("Failed to load path mappings.", e);
59 }
60 }
61
62 public void setPathMappingList(final String sessionId, final List<PathMapping> pathMappingList) {
63 if (sessionId != null) {
64 if (pathMappingList != null) {
65 pathMappingMap.put(sessionId, pathMappingList);
66 } else {
67 removePathMappingList(sessionId);
68 }
69 }
70 }
71
72 public void removePathMappingList(final String sessionId) {
73 pathMappingMap.remove(sessionId);
74 }
75
76 public List<PathMapping> getPathMappingList(final String sessionId) {
77 if (sessionId == null) {
78 return null;
79 }
80 return pathMappingMap.get(sessionId);
81 }
82
83 public String replaceUrl(final String sessionId, final String url) {
84 final List<PathMapping> pathMappingList = getPathMappingList(sessionId);
85 if (pathMappingList == null) {
86 return url;
87 }
88 return replaceUrl(pathMappingList, url);
89 }
90
91 public String replaceUrls(final String text) {
92 if (cachedPathMappingList == null) {
93 synchronized (this) {
94 if (cachedPathMappingList == null) {
95 init();
96 }
97 }
98 }
99 String result = text;
100 for (final PathMapping pathMapping : cachedPathMappingList) {
101 if (matchUserAgent(pathMapping)) {
102 result =
103 result.replaceAll("(\"[^\"]*)" + pathMapping.getRegex() + "([^\"]*\")", "$1" + pathMapping.getReplacement() + "$2");
104 }
105 }
106 return result;
107 }
108
109 public String replaceUrl(final String url) {
110 if (cachedPathMappingList == null) {
111 synchronized (this) {
112 if (cachedPathMappingList == null) {
113 init();
114 }
115 }
116 }
117 return replaceUrl(cachedPathMappingList, url);
118 }
119
120 private String replaceUrl(final List<PathMapping> pathMappingList, final String url) {
121 String newUrl = url;
122 for (final PathMapping pathMapping : pathMappingList) {
123 if (matchUserAgent(pathMapping)) {
124 final Matcher matcher = pathMapping.getMatcher(newUrl);
125 if (matcher.find()) {
126 newUrl = matcher.replaceAll(pathMapping.getReplacement());
127 }
128 }
129 }
130 return newUrl;
131 }
132
133 private boolean matchUserAgent(final PathMapping pathMapping) {
134 if (!pathMapping.hasUAMathcer()) {
135 return true;
136 }
137
138 if (SingletonLaContainerFactory.getExternalContext().getRequest() != null) {
139 return LaRequestUtil.getOptionalRequest().map(request -> {
140 final String userAgent = request.getHeader("user-agent");
141 if (StringUtil.isBlank(userAgent)) {
142 return false;
143 }
144
145 return pathMapping.getUAMatcher(userAgent).find();
146 }).orElse(false);
147 }
148 return false;
149 }
150 }