Pārlūkot izejas kodu

fix #1615 groovy and function support

Shinsuke Sugaya 7 gadi atpakaļ
vecāks
revīzija
12c07bd508

+ 2 - 22
src/main/java/org/codelibs/fess/app/web/go/GoAction.java

@@ -21,7 +21,6 @@ import java.net.URLEncoder;
 import java.util.Map;
 
 import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
 
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.core.net.URLUtil;
@@ -40,7 +39,6 @@ import org.lastaflute.web.Execute;
 import org.lastaflute.web.response.ActionResponse;
 import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.response.StreamResponse;
-import org.lastaflute.web.util.LaRequestUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -146,31 +144,13 @@ public class GoAction extends FessSearchAction {
                     return redirect(ErrorAction.class);
                 }
             } else {
-                return redirect(targetUrl + hash);
+                return HtmlResponse.fromRedirectPathAsIs(targetUrl + hash);
             }
         } else {
-            return redirect(targetUrl + hash);
+            return HtmlResponse.fromRedirectPathAsIs(DocumentUtil.encodeUrl(targetUrl + hash));
         }
     }
 
-    protected ActionResponse redirect(final String url) {
-        final HttpServletRequest request2 = LaRequestUtil.getRequest();
-        final String enc = request2.getCharacterEncoding() == null ? Constants.UTF_8 : request2.getCharacterEncoding();
-        final StringBuilder buf = new StringBuilder(url.length() + 100);
-        for (final char c : url.toCharArray()) {
-            if (CharUtil.isUrlChar(c)) {
-                buf.append(c);
-            } else {
-                try {
-                    buf.append(URLEncoder.encode(String.valueOf(c), enc));
-                } catch (final UnsupportedEncodingException e) {
-                    buf.append(c);
-                }
-            }
-        }
-        return HtmlResponse.fromRedirectPathAsIs(buf.toString());
-    }
-
     protected boolean isFileSystemPath(final String url) {
         return url.startsWith("file:") || url.startsWith("smb:") || url.startsWith("ftp:");
     }

+ 24 - 4
src/main/java/org/codelibs/fess/es/config/exentity/PathMapping.java

@@ -15,22 +15,30 @@
  */
 package org.codelibs.fess.es.config.exentity;
 
+import java.util.function.BiFunction;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.fess.es.config.bsentity.BsPathMapping;
+import org.codelibs.fess.util.ComponentUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * @author FreeGen
  */
 public class PathMapping extends BsPathMapping {
 
+    private static final Logger logger = LoggerFactory.getLogger(PathMapping.class);
+
     private static final long serialVersionUID = 1L;
 
-    private Pattern regexPattern;
+    protected Pattern userAgentPattern;
+
+    protected Pattern regexPattern;
 
-    private Pattern userAgentPattern;
+    protected BiFunction<String, Matcher, String> pathMapper;
 
     public String getId() {
         return asDocMeta().id();
@@ -48,11 +56,23 @@ public class PathMapping extends BsPathMapping {
         asDocMeta().version(version);
     }
 
-    public Matcher getMatcher(final CharSequence input) {
+    public String process(final String input) {
         if (regexPattern == null) {
             regexPattern = Pattern.compile(getRegex());
         }
-        return regexPattern.matcher(input);
+        final Matcher matcher = regexPattern.matcher(input);
+        if (matcher.find()) {
+            if (pathMapper == null) {
+                final String replacement = StringUtil.isNotBlank(getReplacement()) ? getReplacement() : StringUtil.EMPTY;
+                pathMapper = ComponentUtil.getPathMappingHelper().createPathMatcher(matcher, replacement);
+            }
+            try {
+                return pathMapper.apply(input, matcher);
+            } catch (Exception e) {
+                logger.warn("Failed to apply " + pathMapper, e);
+            }
+        }
+        return input;
     }
 
     public boolean hasUAMathcer() {

+ 28 - 8
src/main/java/org/codelibs/fess/helper/PathMappingHelper.java

@@ -19,6 +19,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.function.BiFunction;
 import java.util.regex.Matcher;
 
 import javax.annotation.PostConstruct;
@@ -28,6 +29,8 @@ import org.codelibs.fess.Constants;
 import org.codelibs.fess.es.config.exbhv.PathMappingBhv;
 import org.codelibs.fess.es.config.exentity.PathMapping;
 import org.codelibs.fess.util.ComponentUtil;
+import org.codelibs.fess.util.DocumentUtil;
+import org.codelibs.fess.util.GroovyUtil;
 import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
 import org.lastaflute.web.util.LaRequestUtil;
 import org.slf4j.Logger;
@@ -37,6 +40,10 @@ public class PathMappingHelper {
 
     private static final Logger logger = LoggerFactory.getLogger(PathMappingHelper.class);
 
+    private static final String FUNCTION_ENCODEURL_MATCHER = "function:encodeUrl";
+
+    private static final String GROOVY_MATCHER = "groovy:";
+
     private final Map<String, List<PathMapping>> pathMappingMap = new HashMap<>();
 
     volatile List<PathMapping> cachedPathMappingList = null;
@@ -126,18 +133,31 @@ public class PathMappingHelper {
         return replaceUrl(cachedPathMappingList, url);
     }
 
+    public BiFunction<String, Matcher, String> createPathMatcher(final Matcher matcher, final String replacement) {
+        if (replacement.equals(FUNCTION_ENCODEURL_MATCHER)) {
+            return (u, m) -> DocumentUtil.encodeUrl(u);
+        } else if (replacement.startsWith(GROOVY_MATCHER)) {
+            final String template = replacement.substring(GROOVY_MATCHER.length());
+            return (u, m) -> {
+                final Map<String, Object> paramMap = new HashMap<>();
+                paramMap.put("url", u);
+                paramMap.put("matcher", m);
+                final Object value = GroovyUtil.evaluate(template, paramMap);
+                if (value == null) {
+                    return u;
+                }
+                return value.toString();
+            };
+        } else {
+            return (u, m) -> m.replaceAll(replacement);
+        }
+    }
+
     private String replaceUrl(final List<PathMapping> pathMappingList, final String url) {
         String newUrl = url;
         for (final PathMapping pathMapping : pathMappingList) {
             if (matchUserAgent(pathMapping)) {
-                final Matcher matcher = pathMapping.getMatcher(newUrl);
-                if (matcher.find()) {
-                    String replacement = pathMapping.getReplacement();
-                    if (replacement == null) {
-                        replacement = StringUtil.EMPTY;
-                    }
-                    newUrl = matcher.replaceAll(replacement);
-                }
+                newUrl = pathMapping.process(newUrl);
             }
         }
         return newUrl;

+ 24 - 0
src/main/java/org/codelibs/fess/util/DocumentUtil.java

@@ -15,11 +15,16 @@
  */
 package org.codelibs.fess.util;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+import org.codelibs.fess.Constants;
+import org.codelibs.fess.crawler.util.CharUtil;
 import org.codelibs.fess.taglib.FessFunctions;
+import org.lastaflute.web.util.LaRequestUtil;
 
 public final class DocumentUtil {
 
@@ -107,4 +112,23 @@ public final class DocumentUtil {
         }
         return null;
     }
+
+    public static String encodeUrl(final String url) {
+        final String enc =
+                LaRequestUtil.getOptionalRequest().filter(req -> req.getCharacterEncoding() != null).map(req -> req.getCharacterEncoding())
+                        .orElse(Constants.UTF_8);
+        final StringBuilder buf = new StringBuilder(url.length() + 100);
+        for (final char c : url.toCharArray()) {
+            if (CharUtil.isUrlChar(c)) {
+                buf.append(c);
+            } else {
+                try {
+                    buf.append(URLEncoder.encode(String.valueOf(c), enc));
+                } catch (final UnsupportedEncodingException e) {
+                    buf.append(c);
+                }
+            }
+        }
+        return buf.toString();
+    }
 }