SLING-6761 - HTL: uri manipulator breaks query parameter encoding

* switched to java.net.URI#getRawQuery from java.net.URI#getQuery
* made sure parameters supplied through the parameter manipulation options
are translated into application/x-www-form-urlencoded format

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1789700 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java
index 888e98f..3988caf 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtension.java
@@ -18,8 +18,10 @@
  ******************************************************************************/
 package org.apache.sling.scripting.sightly.impl.engine.extension;
 
+import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -308,17 +310,21 @@
             queryParameters) {
         for (Map.Entry<String, Object> entry : queryParameters.entrySet()) {
             Object entryValue = entry.getValue();
-            if (runtimeObjectModel.isCollection(entryValue)) {
-                Collection<Object> collection = runtimeObjectModel.toCollection(entryValue);
-                Collection<String> values = new ArrayList<>(collection.size());
-                for (Object o : collection) {
-                    values.add(runtimeObjectModel.toString(o));
+            try {
+                if (runtimeObjectModel.isCollection(entryValue)) {
+                    Collection<Object> collection = runtimeObjectModel.toCollection(entryValue);
+                    Collection<String> values = new ArrayList<>(collection.size());
+                    for (Object o : collection) {
+                        values.add(URLEncoder.encode(runtimeObjectModel.toString(o), "UTF-8"));
+                    }
+                    parameters.put(entry.getKey(), values);
+                } else {
+                    Collection<String> values = new ArrayList<>(1);
+                    values.add(URLEncoder.encode(runtimeObjectModel.toString(entryValue), "UTF-8"));
+                    parameters.put(entry.getKey(), values);
                 }
-                parameters.put(entry.getKey(), values);
-            } else {
-                Collection<String> values = new ArrayList<>(1);
-                values.add(runtimeObjectModel.toString(entryValue));
-                parameters.put(entry.getKey(), values);
+            } catch (UnsupportedEncodingException e) {
+                throw new SightlyException(e);
             }
         }
     }
@@ -385,7 +391,7 @@
             } else {
                 this.path = processingPath.substring(0, pathLength);
             }
-            String query = uri.getQuery();
+            String query = uri.getRawQuery();
             if (StringUtils.isNotEmpty(query)) {
                 String[] keyValuePairs = query.split("&");
                 for (String keyValuePair : keyValuePairs) {
diff --git a/src/test/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtensionTest.java b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtensionTest.java
new file mode 100644
index 0000000..6d3299b
--- /dev/null
+++ b/src/test/java/org/apache/sling/scripting/sightly/impl/engine/extension/URIManipulationFilterExtensionTest.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.impl.engine.extension;
+
+import java.util.HashMap;
+import javax.script.Bindings;
+import javax.script.SimpleBindings;
+
+import org.apache.sling.scripting.sightly.render.AbstractRuntimeObjectModel;
+import org.apache.sling.scripting.sightly.render.RenderContext;
+import org.apache.sling.scripting.sightly.render.RuntimeObjectModel;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class URIManipulationFilterExtensionTest {
+
+    private static RenderContext renderContext;
+    private URIManipulationFilterExtension underTest;
+
+    @BeforeClass
+    public static void prepareTests() {
+        // wire only the AbstractRuntimeObjectModel
+        renderContext = new RenderContext() {
+            @Override
+            public RuntimeObjectModel getObjectModel() {
+                return new AbstractRuntimeObjectModel() {
+                };
+            }
+
+            @Override
+            public Bindings getBindings() {
+                return new SimpleBindings();
+            }
+
+            @Override
+            public Object call(String functionName, Object... arguments) {
+                return null;
+            }
+        };
+    }
+
+    @Before
+    public void setUp() {
+        underTest = new URIManipulationFilterExtension();
+    }
+
+    @Test
+    public void testPercentEncodedURLs_SLING_6761() {
+        assertEquals(
+                "/example/search.html?q=6%25-10%25",
+                underTest.call(renderContext, "/example/search?q=6%25-10%25", new HashMap<String, Object>() {{
+                    put(URIManipulationFilterExtension.EXTENSION, "html");
+                }})
+        );
+        assertEquals(
+                "/example/search.a.html?q=6%25-10%25&s=%40sling&t=%25sling",
+                underTest.call(renderContext, "/example/search?q=6%25-10%25", new HashMap<String, Object>() {{
+                    put(URIManipulationFilterExtension.EXTENSION, "html");
+                    put(URIManipulationFilterExtension.ADD_SELECTORS, "a");
+                    put(URIManipulationFilterExtension.ADD_QUERY, new HashMap<String, Object>() {{
+                        put("s", "@sling");
+                        put("t", "%sling");
+                    }});
+                }})
+        );
+    }
+
+
+}