svn commit: r1863395 - /ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1863395 - /ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java

mthl
Author: mthl
Date: Fri Jul 19 14:20:45 2019
New Revision: 1863395

URL: http://svn.apache.org/viewvc?rev=1863395&view=rev
Log:
Improved: Refactor ‘UtilHttp#getPathInfoOnlyParameterMap’
(OFBIZ-11138)

Modified:
    ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java

Modified: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java
URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java?rev=1863395&r1=1863394&r2=1863395&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java (original)
+++ ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilHttp.java Fri Jul 19 14:20:45 2019
@@ -18,6 +18,11 @@
  *******************************************************************************/
 package org.apache.ofbiz.base.util;
 
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.mapping;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
 import static org.apache.ofbiz.base.util.UtilGenerics.checkList;
 
 import java.io.BufferedInputStream;
@@ -34,6 +39,7 @@ import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Currency;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -42,9 +48,11 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.TimeZone;
+import java.util.function.Function;
 
 import javax.net.ssl.SSLContext;
 import javax.servlet.http.HttpServletRequest;
@@ -158,7 +166,7 @@ public final class UtilHttp {
             paramMap.put(name, value);
         }
 
-        paramMap.putAll(getPathInfoOnlyParameterMap(request.getPathInfo(), nameSet, onlyIncludeOrSkip));
+        paramMap.putAll(getPathInfoOnlyParameterMap(request.getPathInfo(), nameSet, onlyIncludeOrSkipPrim));
 
         Map<String, Object> multiPartMap = new HashMap<>();
         if (paramMap.size() == 0) {
@@ -306,58 +314,37 @@ public final class UtilHttp {
         return canonicalizeParameterMap(paramMap);
     }
 
-    public static Map<String, Object> getPathInfoOnlyParameterMap(String pathInfoStr, Set<? extends String> nameSet, Boolean onlyIncludeOrSkip) {
-        boolean onlyIncludeOrSkipPrim = onlyIncludeOrSkip == null ? true : onlyIncludeOrSkip;
-        Map<String, Object> paramMap = new HashMap<>();
-
-        // now add in all path info parameters /~name1=value1/~name2=value2/
-        // note that if a parameter with a given name already exists it will be put into a list with all values
-
-        if (UtilValidate.isNotEmpty(pathInfoStr)) {
-            // make sure string ends with a trailing '/' so we get all values
-            if (!pathInfoStr.endsWith("/")) {
-                pathInfoStr += "/";
-            }
-
-            int current = pathInfoStr.indexOf('/');
-            int last = current;
-            while ((current = pathInfoStr.indexOf('/', last + 1)) != -1) {
-                String element = pathInfoStr.substring(last + 1, current);
-                last = current;
-                if (element.charAt(0) == '~' && element.indexOf('=') > -1) {
-                    String name = element.substring(1, element.indexOf('='));
-                    if (nameSet != null && (onlyIncludeOrSkipPrim ^ nameSet.contains(name))) {
-                        continue;
-                    }
-
-                    String value = element.substring(element.indexOf('=') + 1);
-                    Object curValue = paramMap.get(name);
-                    if (curValue != null) {
-                        List<String> paramList = null;
-                        if (curValue instanceof List<?>) {
-                            paramList = UtilGenerics.checkList(curValue);
-                            paramList.add(value);
-                        } else {
-                            String paramString = (String) curValue;
-                            paramList = new LinkedList<>();
-                            paramList.add(paramString);
-                            paramList.add(value);
-                        }
-                        paramMap.put(name, paramList);
-                    } else {
-                        paramMap.put(name, value);
-                    }
-                }
-            }
-        }
-
-        return canonicalizeParameterMap(paramMap);
+    /**
+     * Extracts the parameters that are passed in the URI path.
+     * <p>
+     * path parameters are denoted by "/~KEY0=VALUE0/~KEY1=VALUE1/".
+     * This is an obsolete syntax for passing parameters to request handlers.
+     *
+     * @param path  the URI path part which can be {@code null}
+     * @param nameSet  the set of parameters keys to include or skip
+     * @param includeOrSkip  toggle where {@code true} means including and {@code false} means skipping
+     * @return a canonicalized parameter map.
+     */
+    static Map<String, Object> getPathInfoOnlyParameterMap(String path, Set<? extends String> nameSet,
+            boolean includeOrSkip) {
+        String path$ = Optional.ofNullable(path).orElse("");
+        Map<String, List<String>> allParams = Arrays.stream(path$.split("/"))
+                .filter(segment -> segment.startsWith("~") && segment.contains("="))
+                .map(kv -> kv.substring(1).split("="))
+                .collect(groupingBy(kv -> kv[0], mapping(kv -> kv[1], toList())));
+
+        // Filter and canonicalize the parameter map.
+        Function<List<String>, Object> canonicalize = val -> (val.size() == 1) ? val.get(0) : val;
+        return allParams.entrySet().stream()
+                .filter(e -> nameSet == null || !(includeOrSkip ^ nameSet.contains(e.getKey())))
+                .collect(collectingAndThen(toMap(Map.Entry::getKey, canonicalize.compose(Map.Entry::getValue)),
+                        UtilHttp::canonicalizeParameterMap));
     }
 
     public static Map<String, Object> getUrlOnlyParameterMap(HttpServletRequest request) {
         // NOTE: these have already been through canonicalizeParameterMap, so not doing it again here
         Map<String, Object> paramMap = getQueryStringOnlyParameterMap(request.getQueryString());
-        paramMap.putAll(getPathInfoOnlyParameterMap(request.getPathInfo(), null, null));
+        paramMap.putAll(getPathInfoOnlyParameterMap(request.getPathInfo(), null, true));
         return paramMap;
     }