You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by et...@apache.org on 2008/08/15 21:24:02 UTC
svn commit: r686334 - in /incubator/shindig/trunk/java/common/src:
main/java/org/apache/shindig/common/uri/
test/java/org/apache/shindig/common/uri/
Author: etnu
Date: Fri Aug 15 12:24:01 2008
New Revision: 686334
URL: http://svn.apache.org/viewvc?rev=686334&view=rev
Log:
Created more useful Uri abstractions than the built in java.net.URI. This facilitates disassembling and reconstructing uris in a more flexible manner than the ad-hoc parsing being done currently.
One missing piece of functionality at the moment is the ability to set raw, unencoded query strings. This will be a temporary barrier to using this code in signed fetch and oauth due to the encoding requirements that differ from java.net.URLEncoder.
Added:
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/UriBuilder.java
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriBuilderTest.java
incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java
Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java?rev=686334&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/Uri.java Fri Aug 15 12:24:01 2008
@@ -0,0 +1,175 @@
+/*
+ * 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.shindig.common.uri;
+
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collection;
+
+/**
+* Represents a Uniform Resource Identifier (URI) reference as defined by <a
+* href="http://tools.ietf.org/html/rfc3986">RFC 3986</a>.
+*
+* Assumes that all url components are UTF-8 encoded.
+*/
+public final class Uri {
+ private final String text;
+ private final String scheme;
+ private final String authority;
+ private final String path;
+ private final String queryString;
+ private final Multimap<String, String> query;
+ private final String fragment;
+
+ /**
+ * Produces a new Uri from a text representation.
+ *
+ * @param text The text uri.
+ * @return A new Uri, parsed into components.
+ */
+ public static Uri parse(String text) {
+ try {
+ URI uri = new URI(text);
+ return new Uri(uri.getScheme(),
+ uri.getAuthority(),
+ uri.getPath(),
+ UriBuilder.splitParameters(uri.getRawQuery()),
+ uri.getFragment());
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ Uri(String scheme, String authority, String path, Multimap<String, String> query,
+ String fragment) {
+ this.scheme = scheme;
+ this.authority = authority;
+ this.path = path;
+ this.query = Multimaps.unmodifiableMultimap(query);
+ this.queryString = UriBuilder.joinParameters(query);
+ this.fragment = fragment;
+
+ StringBuilder out = new StringBuilder();
+
+ if (scheme != null) {
+ out.append(scheme).append(':');
+ }
+ if (authority != null) {
+ out.append("//").append(authority);
+ }
+ if (path != null) {
+ out.append(path);
+ }
+ if (queryString != null) {
+ out.append('?').append(queryString);
+ }
+ if (fragment != null) {
+ out.append('#').append(fragment);
+ }
+ this.text = out.toString();
+ }
+
+ /**
+ * Converts the Uri to a java.net.URI.
+ */
+ public URI toJavaUri() throws URISyntaxException {
+ return new URI(scheme, authority, path, queryString, fragment);
+ }
+
+ /**
+ * @return The scheme part of the uri, or null if none was specified.
+ */
+ public String getScheme() {
+ return scheme;
+ }
+
+ /**
+ * @return The authority part of the uri, or null if none was specified.
+ */
+ public String getAuthority() {
+ return authority;
+ }
+
+ /**
+ * @return The path part of the uri, or null if none was specified.
+ */
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * @return The query part of the uri, or null if none was specified.
+ */
+ public String getQuery() {
+ return queryString;
+ }
+
+ /**
+ * @return The query part of the uri, separated into component parts.
+ */
+ public Multimap<String, String> getQueryParameters() {
+ return query;
+ }
+
+ /**
+ * @return All query parameters with the given name.
+ */
+ public Collection<String> getQueryParameters(String name) {
+ return query.get(name);
+ }
+
+ /**
+ * @return The first query parameter value with the given name.
+ */
+ public String getQueryParameter(String name) {
+ Collection<String> values = query.get(name);
+ if (values == null || values.isEmpty()) {
+ return null;
+ }
+ return values.iterator().next();
+ }
+
+ /**
+ * @return The query fragment.
+ */
+ public String getFragment() {
+ return fragment;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+
+ @Override
+ public int hashCode() {
+ return text.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object rhs) {
+ if (rhs == this) {return true;}
+ if (!(rhs instanceof Uri)) {return false;}
+
+ return text.equals(((Uri)rhs).text);
+ }
+}
Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/UriBuilder.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/UriBuilder.java?rev=686334&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/UriBuilder.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/uri/UriBuilder.java Fri Aug 15 12:24:01 2008
@@ -0,0 +1,224 @@
+/*
+ * 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.shindig.common.uri;
+
+import org.apache.shindig.common.util.Utf8UrlCoder;
+
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Constructs Uris from inputs.
+ */
+public class UriBuilder {
+ private static final Pattern QUERY_PATTERN = Pattern.compile("([^&=]+)=([^&=]*)");
+
+ private String scheme;
+ private String authority;
+ private String path;
+ private Multimap<String, String> query;
+ private String fragment;
+
+ /**
+ * Construct a new builder from an existing uri.
+ */
+ public UriBuilder(Uri uri) {
+ scheme = uri.getScheme();
+ authority = uri.getAuthority();
+ path = uri.getPath();
+ query = Multimaps.newLinkedListMultimap(uri.getQueryParameters());
+ fragment = uri.getFragment();
+ }
+
+ /**
+ * Create an empty builder.
+ */
+ public UriBuilder() {
+ query = Multimaps.newLinkedListMultimap();
+ }
+
+ /**
+ * Construct a builder by parsing a string.
+ */
+ public static UriBuilder parse(String text) {
+ return new UriBuilder(Uri.parse(text));
+ }
+
+ /**
+ * Convert the builder to a Uri.
+ */
+ public Uri toUri() {
+ return new Uri(scheme, authority, path, query, fragment);
+ }
+
+ /**
+ * @return The scheme part of the uri, or null if none was specified.
+ */
+ public String getScheme() {
+ return scheme;
+ }
+
+ public UriBuilder setScheme(String scheme) {
+ this.scheme = scheme;
+ return this;
+ }
+
+ /**
+ * @return The authority part of the uri, or null if none was specified.
+ */
+ public String getAuthority() {
+ return authority;
+ }
+
+ public UriBuilder setAuthority(String authority) {
+ this.authority = authority;
+ return this;
+ }
+
+ /**
+ * @return The path part of the uri, or null if none was specified.
+ */
+ public String getPath() {
+ return path;
+ }
+
+ public UriBuilder setPath(String path) {
+ this.path = path;
+ return this;
+ }
+
+ /**
+ * @return The query part of the uri, or null if none was specified.
+ */
+ public String getQuery() {
+ return joinParameters(query);
+ }
+
+ public UriBuilder setQuery(String query) {
+ this.query.clear();
+ this.query.putAll(splitParameters(query));
+ return this;
+ }
+
+ public UriBuilder addQueryParameter(String name, String value) {
+ query.put(name, value);
+ return this;
+ }
+
+ public UriBuilder addQueryParameters(Map<String, String> parameters) {
+ for (Map.Entry<String, String> entry : parameters.entrySet()) {
+ query.put(entry.getKey(), entry.getValue());
+ }
+ return this;
+ }
+
+ /**
+ * @return The query part of the uri, separated into component parts.
+ */
+ public Multimap<String, String> getQueryParameters() {
+ return query;
+ }
+
+ /**
+ * @return All query parameters with the given name.
+ */
+ public Collection<String> getQueryParameters(String name) {
+ return query.get(name);
+ }
+
+ /**
+ * @return The first query parameter value with the given name.
+ */
+ public String getQueryParameter(String name) {
+ Collection<String> values = query.get(name);
+ if (values == null || values.isEmpty()) {
+ return null;
+ }
+ return values.iterator().next();
+ }
+
+ /**
+ * @return The query fragment.
+ */
+ public String getFragment() {
+ return fragment;
+ }
+
+ public UriBuilder setFragment(String fragment) {
+ this.fragment = fragment;
+ return this;
+ }
+
+ /**
+ * Utility method for joining key / value pair parameters into a string.
+ */
+ static String joinParameters(Multimap<String, String> query) {
+ if (query.size() == 0) {
+ return null;
+ }
+ StringBuilder buf = new StringBuilder();
+ boolean firstDone = false;
+ for (Map.Entry<String, String> entry : query.entries()) {
+ if (firstDone) {
+ buf.append("&");
+ }
+ firstDone = true;
+ buf.append(Utf8UrlCoder.encode(entry.getKey()))
+ .append("=")
+ .append(Utf8UrlCoder.encode(entry.getValue()));
+ }
+ return buf.toString();
+ }
+
+ static Multimap<String, String> splitParameters(String query) {
+ if (query == null) {
+ return Multimaps.immutableMultimap();
+ }
+ Multimap<String, String> params = Multimaps.newLinkedListMultimap();
+ Matcher paramMatcher = QUERY_PATTERN.matcher(query);
+ while (paramMatcher.find()) {
+ params.put(Utf8UrlCoder.decode(paramMatcher.group(1)),
+ Utf8UrlCoder.decode(paramMatcher.group(2)));
+ }
+ return Multimaps.unmodifiableMultimap(params);
+ }
+
+ @Override
+ public String toString() {
+ return toUri().toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return toUri().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object rhs) {
+ if (rhs == this) {return true;}
+ if (!(rhs instanceof UriBuilder)) {return false;}
+
+ return toString().equals(rhs.toString());
+ }
+}
Added: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriBuilderTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriBuilderTest.java?rev=686334&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriBuilderTest.java (added)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriBuilderTest.java Fri Aug 15 12:24:01 2008
@@ -0,0 +1,283 @@
+/*
+ * 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://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.shindig.common.uri;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Tests for UriBuilder
+ */
+public class UriBuilderTest {
+
+ @Test
+ public void allPartsUsed() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .setQuery("hello=world")
+ .setFragment("foo");
+ assertEquals("http://apache.org/shindig?hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void noSchemeUsed() {
+ UriBuilder builder = new UriBuilder()
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .setQuery("hello=world")
+ .setFragment("foo");
+ assertEquals("//apache.org/shindig?hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void noAuthorityUsed() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setPath("/shindig")
+ .setQuery("hello=world")
+ .setFragment("foo");
+ assertEquals("http:/shindig?hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void noPathUsed() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setQuery("hello=world")
+ .setFragment("foo");
+ assertEquals("http://apache.org?hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void noQueryUsed() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .setFragment("foo");
+ assertEquals("http://apache.org/shindig#foo", builder.toString());
+ }
+
+ @Test
+ public void noFragmentUsed() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .setQuery("hello=world");
+ assertEquals("http://apache.org/shindig?hello=world", builder.toString());
+ }
+
+ @Test
+ public void hostRelativePaths() {
+ UriBuilder builder = new UriBuilder()
+ .setPath("/shindig")
+ .setQuery("hello=world")
+ .setFragment("foo");
+ assertEquals("/shindig?hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void relativePaths() {
+ UriBuilder builder = new UriBuilder()
+ .setPath("foo")
+ .setQuery("hello=world")
+ .setFragment("foo");
+ assertEquals("foo?hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void noPathNoHostNoAuthority() {
+ UriBuilder builder = new UriBuilder()
+ .setQuery("hello=world")
+ .setFragment("foo");
+ assertEquals("?hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void justSchemeAndAuthority() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org");
+ assertEquals("http://apache.org", builder.toString());
+ }
+
+ @Test
+ public void justPath() {
+ UriBuilder builder = new UriBuilder()
+ .setPath("/shindig");
+ assertEquals("/shindig", builder.toString());
+ }
+
+ @Test
+ public void justAuthorityAndPath() {
+ UriBuilder builder = new UriBuilder()
+ .setAuthority("apache.org")
+ .setPath("/shindig");
+ assertEquals("//apache.org/shindig", builder.toString());
+ }
+
+ @Test
+ public void justQuery() {
+ UriBuilder builder = new UriBuilder()
+ .setQuery("hello=world");
+ assertEquals("?hello=world", builder.toString());
+ }
+
+ @Test
+ public void justFragment() {
+ UriBuilder builder = new UriBuilder()
+ .setFragment("foo");
+ assertEquals("#foo", builder.toString());
+ }
+
+ @Test
+ public void addSingleQueryParameter() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .addQueryParameter("hello", "world")
+ .setFragment("foo");
+ assertEquals("http://apache.org/shindig?hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void addTwoQueryParameters() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .addQueryParameter("hello", "world")
+ .addQueryParameter("foo", "bar")
+ .setFragment("foo");
+ assertEquals("http://apache.org/shindig?hello=world&foo=bar#foo", builder.toString());
+ }
+
+ @Test
+ public void addIdenticalParameters() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .addQueryParameter("hello", "world")
+ .addQueryParameter("hello", "goodbye")
+ .setFragment("foo");
+ assertEquals("http://apache.org/shindig?hello=world&hello=goodbye#foo", builder.toString());
+ }
+
+ @Test
+ public void addBatchParameters() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .addQueryParameters(Maps.immutableMap("foo", "bar", "hello", "world"))
+ .setFragment("foo");
+ assertEquals("http://apache.org/shindig?foo=bar&hello=world#foo", builder.toString());
+ }
+
+ @Test
+ public void queryStringIsUnescaped() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .setQuery("hello+world=world%26bar");
+ assertEquals("world&bar", builder.getQueryParameter("hello world"));
+ }
+
+ @Test
+ public void queryParamsAreEscaped() {
+ UriBuilder builder = new UriBuilder()
+ .setScheme("http")
+ .setAuthority("apache.org")
+ .setPath("/shindig")
+ .addQueryParameter("hello world", "foo&bar")
+ .setFragment("foo");
+ assertEquals("http://apache.org/shindig?hello+world=foo%26bar#foo", builder.toString());
+ }
+
+ @Test
+ public void parse() {
+ UriBuilder builder = UriBuilder.parse("http://apache.org/shindig?foo=bar%26baz&foo=three#blah");
+
+ assertEquals("http", builder.getScheme());
+ assertEquals("apache.org", builder.getAuthority());
+ assertEquals("/shindig", builder.getPath());
+ assertEquals("foo=bar%26baz&foo=three", builder.getQuery());
+ assertEquals("blah", builder.getFragment());
+
+ assertEquals("bar&baz", builder.getQueryParameter("foo"));
+
+ Collection<String> values = Arrays.asList("bar&baz", "three");
+ assertEquals(values, builder.getQueryParameters("foo"));
+
+ assertEquals(2, builder.getQueryParameters().size());
+ }
+
+ @Test
+ public void constructFromUriAndBack() {
+ Uri uri = Uri.parse("http://apache.org/foo/bar?foo=bar#foo");
+ UriBuilder builder = new UriBuilder(uri);
+
+ assertEquals(uri, builder.toUri());
+ }
+
+ @Test
+ public void constructFromUriAndModify() {
+ Uri uri = Uri.parse("http://apache.org/foo/bar?foo=bar#foo");
+ UriBuilder builder = new UriBuilder(uri);
+
+ builder.setAuthority("example.org");
+ builder.addQueryParameter("bar", "foo");
+
+ assertEquals("http://example.org/foo/bar?foo=bar&bar=foo#foo", builder.toString());
+ }
+
+ @Test
+ public void equalsAndHashCodeOk() {
+ UriBuilder uri = UriBuilder.parse("http://example.org/foo/bar/baz?blah=blah#boo");
+ Multimap<String, String> params = UriBuilder.splitParameters("blah=blah");
+ UriBuilder uri2 = new UriBuilder(Uri.parse("http://example.org/foo/bar/baz?blah=blah#boo"));
+
+ assertTrue(uri.equals(uri2));
+ assertTrue(uri2.equals(uri));
+
+ assertTrue(uri.equals(uri));
+
+ assertFalse(uri.equals(null));
+ assertFalse(uri.equals("http://example.org/foo/bar/baz?blah=blah#boo"));
+ assertFalse(uri.equals(Uri.parse("http://example.org/foo/bar/baz?blah=blah#boo")));
+
+ assertTrue(uri.hashCode() == uri2.hashCode());
+ }
+}
Added: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java?rev=686334&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java (added)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/uri/UriTest.java Fri Aug 15 12:24:01 2008
@@ -0,0 +1,164 @@
+/*
+ * 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://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.shindig.common.uri;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Multimap;
+
+import org.junit.Test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Tests for Uri.
+ */
+public class UriTest {
+ @Test
+ public void parseFull() {
+ Uri uri = Uri.parse("http://apache.org/foo?a=b&a=c&b=d+e#blah");
+
+ assertEquals("http", uri.getScheme());
+ assertEquals("apache.org", uri.getAuthority());
+ assertEquals("/foo", uri.getPath());
+ assertEquals("a=b&a=c&b=d+e", uri.getQuery());
+ Collection<String> params = Arrays.asList("b", "c");
+ assertEquals(params, uri.getQueryParameters("a"));
+ assertEquals("b", uri.getQueryParameter("a"));
+ assertEquals("d e", uri.getQueryParameter("b"));
+ assertEquals("blah", uri.getFragment());
+
+ assertEquals("http://apache.org/foo?a=b&a=c&b=d+e#blah", uri.toString());
+ }
+
+ @Test
+ public void parseNoScheme() {
+ Uri uri = Uri.parse("//apache.org/foo?a=b&a=c&b=d+e#blah");
+
+ assertEquals(null, uri.getScheme());
+ assertEquals("apache.org", uri.getAuthority());
+ assertEquals("/foo", uri.getPath());
+ assertEquals("a=b&a=c&b=d+e", uri.getQuery());
+ Collection<String> params = Arrays.asList("b", "c");
+ assertEquals(params, uri.getQueryParameters("a"));
+ assertEquals("b", uri.getQueryParameter("a"));
+ assertEquals("d e", uri.getQueryParameter("b"));
+ assertEquals("blah", uri.getFragment());
+ }
+
+ @Test
+ public void parseNoAuthority() {
+ Uri uri = Uri.parse("http:/foo?a=b&a=c&b=d+e#blah");
+
+ assertEquals("http", uri.getScheme());
+ assertEquals(null, uri.getAuthority());
+ assertEquals("/foo", uri.getPath());
+ assertEquals("a=b&a=c&b=d+e", uri.getQuery());
+ Collection<String> params = Arrays.asList("b", "c");
+ assertEquals(params, uri.getQueryParameters("a"));
+ assertEquals("b", uri.getQueryParameter("a"));
+ assertEquals("d e", uri.getQueryParameter("b"));
+ assertEquals("blah", uri.getFragment());
+ }
+
+ @Test
+ public void parseNoPath() {
+ Uri uri = Uri.parse("http://apache.org?a=b&a=c&b=d+e#blah");
+
+ assertEquals("http", uri.getScheme());
+ assertEquals("apache.org", uri.getAuthority());
+ // Path is never null.
+ assertEquals("", uri.getPath());
+ assertEquals("a=b&a=c&b=d+e", uri.getQuery());
+ Collection<String> params = Arrays.asList("b", "c");
+ assertEquals(params, uri.getQueryParameters("a"));
+ assertEquals("b", uri.getQueryParameter("a"));
+ assertEquals("d e", uri.getQueryParameter("b"));
+ assertEquals("blah", uri.getFragment());
+ }
+
+ @Test
+ public void parseNoQuery() {
+ Uri uri = Uri.parse("http://apache.org/foo#blah");
+
+ assertEquals("http", uri.getScheme());
+ assertEquals("apache.org", uri.getAuthority());
+ assertEquals("/foo", uri.getPath());
+ assertEquals(null, uri.getQuery());
+ assertEquals(0, uri.getQueryParameters().size());
+ assertEquals(null, uri.getQueryParameter("foo"));
+ assertEquals("blah", uri.getFragment());
+ }
+
+ @Test
+ public void parseNoFragment() {
+ Uri uri = Uri.parse("http://apache.org/foo?a=b&a=c&b=d+e");
+
+ assertEquals("http", uri.getScheme());
+ assertEquals("apache.org", uri.getAuthority());
+ assertEquals("/foo", uri.getPath());
+ assertEquals("a=b&a=c&b=d+e", uri.getQuery());
+ assertEquals(null, uri.getFragment());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void parseInvalidHost() {
+ Uri.parse("http://A&E%#%#%/foo?a=b#blah");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void parseInvalidScheme() {
+ Uri.parse("----://apache.org/foo?a=b#blah");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void parseInvalidPath() {
+ Uri.parse("http://apache.org/foo\\---(&%?a=b#blah");
+ }
+
+ @Test
+ public void toJavaUri() throws URISyntaxException {
+ URI javaUri = URI.create("http://example.org/foo/bar/baz?blah=blah#boo");
+ Uri uri = Uri.parse("http://example.org/foo/bar/baz?blah=blah#boo");
+
+ assertEquals(javaUri, uri.toJavaUri());
+ }
+
+ @Test
+ public void equalsAndHashCodeOk() {
+ Uri uri = Uri.parse("http://example.org/foo/bar/baz?blah=blah#boo");
+ Multimap<String, String> params = UriBuilder.splitParameters("blah=blah");
+ Uri uri2 = new Uri("http", "example.org", "/foo/bar/baz", params, "boo");
+
+ assertTrue(uri.equals(uri2));
+ assertTrue(uri2.equals(uri));
+
+ assertTrue(uri.equals(uri));
+
+ assertFalse(uri.equals(null));
+ assertFalse(uri.equals("http://example.org/foo/bar/baz?blah=blah#boo"));
+
+ assertTrue(uri.hashCode() == uri2.hashCode());
+ }
+}