Author: davsclaus Date: Tue Jul 12 09:22:06 2011 New Revision: 1145506 URL: http://svn.apache.org/viewvc?rev=1145506&view=rev Log: CAMEL-4211: endpoint uris now support multiple values for the same key.
Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/HttpJettyProducerTwoParametersWithSameKeyTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/URISupport.java camel/trunk/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/URISupport.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/URISupport.java?rev=1145506&r1=1145505&r2=1145506&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/util/URISupport.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/URISupport.java Tue Jul 12 09:22:06 2011 @@ -22,7 +22,9 @@ import java.net.URISyntaxException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -74,7 +76,28 @@ public final class URISupport { if (p >= 0) { String name = URLDecoder.decode(parameter.substring(0, p), CHARSET); String value = URLDecoder.decode(parameter.substring(p + 1), CHARSET); - rc.put(name, value); + + // does the key already exist? + if (rc.containsKey(name)) { + // yes it does, so make sure we can support multiple values, but using a list + // to hold the multiple values + Object existing = rc.get(name); + List<String> list; + if (existing instanceof List) { + list = CastUtils.cast((List<?>) existing); + } else { + // create a new list to hold the multiple values + list = new ArrayList<String>(); + String s = existing != null ? existing.toString() : null; + if (s != null) { + list.add(s); + } + } + list.add(value); + rc.put(name, list); + } else { + rc.put(name, value); + } } else { rc.put(parameter, null); } @@ -134,6 +157,7 @@ public final class URISupport { return value; } + @SuppressWarnings("unchecked") public static String createQueryString(Map<Object, Object> options) throws URISyntaxException { try { if (options.size() > 0) { @@ -147,12 +171,23 @@ public final class URISupport { } String key = (String) o; - String value = (String) options.get(key); - rc.append(URLEncoder.encode(key, CHARSET)); - // only append if value is not null - if (value != null) { - rc.append("="); - rc.append(URLEncoder.encode(value, CHARSET)); + Object value = options.get(key); + + // the value may be a list since the same key has multiple values + if (value instanceof List) { + List<String> list = (List<String>) value; + for (Iterator<String> it = list.iterator(); it.hasNext();) { + String s = it.next(); + appendQueryStringParameter(key, s, rc); + // append & separator if there is more in the list to append + if (it.hasNext()) { + rc.append("&"); + } + } + } else { + // use the value as a String + String s = value != null ? value.toString() : null; + appendQueryStringParameter(key, s, rc); } } return rc.toString(); @@ -166,6 +201,16 @@ public final class URISupport { } } + private static void appendQueryStringParameter(String key, String value, StringBuilder rc) throws UnsupportedEncodingException { + rc.append(URLEncoder.encode(key, CHARSET)); + // only append if value is not null + if (value != null) { + rc.append("="); + rc.append(URLEncoder.encode(value, CHARSET)); + } + } + + /** * Creates a URI from the original URI and the remaining parameters * <p/> Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java?rev=1145506&r1=1145505&r2=1145506&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/URISupportTest.java Tue Jul 12 09:22:06 2011 @@ -143,4 +143,12 @@ public class URISupportTest extends Cont assertEquals("http://localhost:23271/myapp/mytest?foo=abc+def&bar=123%2C456&name=S%C3%B8ren", out.toASCIIString()); } + public void testNormalizeEndpointUriWithDualParameters() throws Exception { + String out1 = URISupport.normalizeUri("smtp://localhost?to=foo&to=bar&from=me"); + assertEquals("smtp://localhost?from=me&to=foo&to=bar", out1); + + String out2 = URISupport.normalizeUri("smtp://localhost?to=foo&to=bar&from=me&from=you"); + assertEquals("smtp://localhost?from=me&from=you&to=foo&to=bar", out2); + } + } Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/HttpJettyProducerTwoParametersWithSameKeyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/HttpJettyProducerTwoParametersWithSameKeyTest.java?rev=1145506&view=auto ============================================================================== --- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/HttpJettyProducerTwoParametersWithSameKeyTest.java (added) +++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/HttpJettyProducerTwoParametersWithSameKeyTest.java Tue Jul 12 09:22:06 2011 @@ -0,0 +1,73 @@ +/** + * 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.camel.component.jetty.jettyproducer; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.http.HttpMessage; +import org.apache.camel.component.jetty.BaseJettyTest; +import org.junit.Test; + +/** + * + */ +public class HttpJettyProducerTwoParametersWithSameKeyTest extends BaseJettyTest { + + @Test + public void testTwoParametersWithSameKey() throws Exception { + // these tests does not run well on Windows + if (isPlatform("windows")) { + return; + } + + // give Jetty time to startup properly + Thread.sleep(1000); + + Exchange a = template.request("jetty:http://localhost:{{port}}/myapp?from=me&to=foo&to=bar", null); + assertNotNull(a); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("jetty://http://localhost:{{port}}/myapp").process(new Processor() { + public void process(Exchange exchange) throws Exception { + String from = exchange.getIn().getHeader("from", String.class); + assertEquals("me", from); + + HttpServletRequest req = exchange.getIn(HttpMessage.class).getRequest(); + + // TODO: Http/Jetty should support headers with multiple values + String[] values = req.getParameterValues("to"); + assertNotNull(values); + assertEquals(2, values.length); + assertEquals("foo", values[0]); + assertEquals("bar", values[1]); + + exchange.getOut().setBody("OK"); + } + }); + } + }; + } + +}