diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/support/RequestContextTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/support/RequestContextTests.java index a01c64b683e..a27b99e8fde 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/support/RequestContextTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/support/RequestContextTests.java @@ -16,19 +16,20 @@ package org.springframework.web.servlet.support; -import static org.junit.Assert.assertEquals; - import java.util.HashMap; import java.util.Map; import org.junit.Before; import org.junit.Test; + import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockServletContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext; +import static org.junit.Assert.*; + /** * @author Dave Syer * @@ -56,7 +57,6 @@ public class RequestContextTests { assertEquals("foo/bar", context.getContextUrl("bar")); } - @org.junit.Ignore // TODO: Arjen to address in SPR-5973 @Test public void testGetContextUrlStringMap() throws Exception { request.setContextPath("foo/"); diff --git a/org.springframework.web/src/main/java/org/springframework/web/util/UriComponents.java b/org.springframework.web/src/main/java/org/springframework/web/util/UriComponents.java index 97f1b2d686f..b57659c4c2b 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/util/UriComponents.java +++ b/org.springframework.web/src/main/java/org/springframework/web/util/UriComponents.java @@ -65,7 +65,7 @@ public final class UriComponents { private final int port; - private final List pathSegments; + private final PathComponent path; private final MultiValueMap queryParams; @@ -73,11 +73,11 @@ public final class UriComponents { private final boolean encoded; - public UriComponents(String scheme, + UriComponents(String scheme, String userInfo, String host, int port, - List pathSegments, + PathComponent path, MultiValueMap queryParams, String fragment, boolean encoded) { @@ -85,10 +85,7 @@ public final class UriComponents { this.userInfo = userInfo; this.host = host; this.port = port; - if (pathSegments == null) { - pathSegments = Collections.emptyList(); - } - this.pathSegments = Collections.unmodifiableList(pathSegments); + this.path = path != null ? path : NULL_PATH_COMPONENT; if (queryParams == null) { queryParams = new LinkedMultiValueMap(0); } @@ -141,28 +138,7 @@ public final class UriComponents { * @return the path. Can be {@code null}. */ public String getPath() { - if (!pathSegments.isEmpty()) { - StringBuilder pathBuilder = new StringBuilder(); - for (String pathSegment : pathSegments) { - if (StringUtils.hasLength(pathSegment)) { - boolean startsWithSlash = pathSegment.charAt(0) == PATH_DELIMITER; - boolean endsWithSlash = - pathBuilder.length() > 0 && pathBuilder.charAt(pathBuilder.length() - 1) == PATH_DELIMITER; - - if (!endsWithSlash && !startsWithSlash) { - pathBuilder.append('/'); - } - else if (endsWithSlash && startsWithSlash) { - pathSegment = pathSegment.substring(1); - } - pathBuilder.append(pathSegment); - } - } - return pathBuilder.toString(); - } - else { - return null; - } + return path.getPath(); } /** @@ -170,9 +146,9 @@ public final class UriComponents { * * @return the path segments. Empty if no path has been set. */ - public List getPathSegments() { - return pathSegments; - } + public List getPathSegments() { + return path.getPathSegments(); + } /** * Returns the query. @@ -265,11 +241,7 @@ public final class UriComponents { String encodedScheme = encodeUriComponent(this.scheme, encoding, Type.SCHEME); String encodedUserInfo = encodeUriComponent(this.userInfo, encoding, Type.USER_INFO); String encodedHost = encodeUriComponent(this.host, encoding, Type.HOST); - List encodedPathSegments = new ArrayList(this.pathSegments.size()); - for (String pathSegment : this.pathSegments) { - String encodedPathSegment = encodeUriComponent(pathSegment, encoding, Type.PATH_SEGMENT); - encodedPathSegments.add(encodedPathSegment); - } + PathComponent encodedPath = path.encode(encoding); MultiValueMap encodedQueryParams = new LinkedMultiValueMap(this.queryParams.size()); for (Map.Entry> entry : this.queryParams.entrySet()) { @@ -283,7 +255,7 @@ public final class UriComponents { } String encodedFragment = encodeUriComponent(this.fragment, encoding, Type.FRAGMENT); - return new UriComponents(encodedScheme, encodedUserInfo, encodedHost, this.port, encodedPathSegments, + return new UriComponents(encodedScheme, encodedUserInfo, encodedHost, this.port, encodedPath, encodedQueryParams, encodedFragment, true); } @@ -350,11 +322,7 @@ public final class UriComponents { String expandedScheme = expandUriComponent(this.scheme, uriVariables); String expandedUserInfo = expandUriComponent(this.userInfo, uriVariables); String expandedHost = expandUriComponent(this.host, uriVariables); - List expandedPathSegments = new ArrayList(this.pathSegments.size()); - for (String pathSegment : this.pathSegments) { - String expandedPathSegment = expandUriComponent(pathSegment, uriVariables); - expandedPathSegments.add(expandedPathSegment); - } + PathComponent expandedPath = path.expand(uriVariables); MultiValueMap expandedQueryParams = new LinkedMultiValueMap(this.queryParams.size()); for (Map.Entry> entry : this.queryParams.entrySet()) { @@ -368,11 +336,11 @@ public final class UriComponents { } String expandedFragment = expandUriComponent(this.fragment, uriVariables); - return new UriComponents(expandedScheme, expandedUserInfo, expandedHost, this.port, expandedPathSegments, + return new UriComponents(expandedScheme, expandedUserInfo, expandedHost, this.port, expandedPath, expandedQueryParams, expandedFragment, false); } - private String expandUriComponent(String source, Map uriVariables) { + private static String expandUriComponent(String source, Map uriVariables) { if (source == null) { return null; } @@ -408,11 +376,7 @@ public final class UriComponents { String expandedScheme = expandUriComponent(this.scheme, valueIterator); String expandedUserInfo = expandUriComponent(this.userInfo, valueIterator); String expandedHost = expandUriComponent(this.host, valueIterator); - List expandedPathSegments = new ArrayList(this.pathSegments.size()); - for (String pathSegment : this.pathSegments) { - String expandedPathSegment = expandUriComponent(pathSegment, valueIterator); - expandedPathSegments.add(expandedPathSegment); - } + PathComponent expandedPath = path.expand(valueIterator); MultiValueMap expandedQueryParams = new LinkedMultiValueMap(this.queryParams.size()); for (Map.Entry> entry : this.queryParams.entrySet()) { @@ -426,11 +390,11 @@ public final class UriComponents { } String expandedFragment = expandUriComponent(this.fragment, valueIterator); - return new UriComponents(expandedScheme, expandedUserInfo, expandedHost, this.port, expandedPathSegments, + return new UriComponents(expandedScheme, expandedUserInfo, expandedHost, this.port, expandedPath, expandedQueryParams, expandedFragment, false); } - private String expandUriComponent(String source, Iterator valueIterator) { + private static String expandUriComponent(String source, Iterator valueIterator) { if (source == null) { return null; } @@ -453,12 +417,12 @@ public final class UriComponents { } - private String getVariableName(String match) { + private static String getVariableName(String match) { int colonIdx = match.indexOf(':'); return colonIdx == -1 ? match : match.substring(0, colonIdx); } - protected String getVariableValueAsString(Object variableValue) { + private static String getVariableValueAsString(Object variableValue) { return variableValue != null ? variableValue.toString() : ""; } @@ -497,9 +461,12 @@ public final class UriComponents { } String path = getPath(); - if (path != null) { - uriBuilder.append(path); - } + if (StringUtils.hasLength(path)) { + if (uriBuilder.length() != 0 && path.charAt(0) != PATH_DELIMITER) { + uriBuilder.append(PATH_DELIMITER); + } + uriBuilder.append(path); + } String query = getQuery(); if (query != null) { @@ -526,7 +493,11 @@ public final class UriComponents { return new URI(toUriString()); } else { - return new URI(getScheme(), getUserInfo(), getHost(), getPort(), getPath(), getQuery(), + String path = getPath(); + if (StringUtils.hasLength(path) && path.charAt(0) != PATH_DELIMITER) { + path = PATH_DELIMITER + path; + } + return new URI(getScheme(), getUserInfo(), getHost(), getPort(), path, getQuery(), getFragment()); } } @@ -555,7 +526,7 @@ public final class UriComponents { if (port != other.port) { return false; } - if (!pathSegments.equals(other.pathSegments)) { + if (!path.equals(other.path)) { return false; } if (!queryParams.equals(other.queryParams)) { @@ -577,7 +548,7 @@ public final class UriComponents { result = 31 * result + (userInfo != null ? userInfo.hashCode() : 0); result = 31 * result + (host != null ? host.hashCode() : 0); result = 31 * result + port; - result = 31 * result + pathSegments.hashCode(); + result = 31 * result + path.hashCode(); result = 31 * result + queryParams.hashCode(); result = 31 * result + (fragment != null ? fragment.hashCode() : 0); return result; @@ -740,4 +711,186 @@ public final class UriComponents { } + /** + * Defines the contract for path (segments). + */ + interface PathComponent { + + String getPath(); + + List getPathSegments(); + + PathComponent encode(String encoding) throws UnsupportedEncodingException; + + PathComponent expand(Map uriVariables); + + PathComponent expand(Iterator valueIterator); + } + + /** + * Represents a path backed by a string. + */ + final static class FullPathComponent implements PathComponent { + + private final String path; + + FullPathComponent(String path) { + this.path = path; + } + + public String getPath() { + return path; + } + + public List getPathSegments() { + String delimiter = new String(new char[]{PATH_DELIMITER}); + String[] pathSegments = StringUtils.tokenizeToStringArray(path, delimiter); + return Collections.unmodifiableList(Arrays.asList(pathSegments)); + } + + public PathComponent encode(String encoding) throws UnsupportedEncodingException { + String encodedPath = encodeUriComponent(getPath(),encoding, Type.PATH); + return new FullPathComponent(encodedPath); + } + + public PathComponent expand(Map uriVariables) { + String expandedPath = expandUriComponent(getPath(), uriVariables); + return new FullPathComponent(expandedPath); + } + + public PathComponent expand(Iterator valueIterator) { + String expandedPath = expandUriComponent(getPath(), valueIterator); + return new FullPathComponent(expandedPath); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } else if (o instanceof FullPathComponent) { + FullPathComponent other = (FullPathComponent) o; + return this.getPath().equals(other.getPath()); + } + return false; + } + + @Override + public int hashCode() { + return getPath().hashCode(); + } + } + + /** + * Represents a path backed by a string list (i.e. path segments). + */ + final static class PathSegmentComponent implements PathComponent { + + private final List pathSegments; + + PathSegmentComponent(List pathSegments) { + this.pathSegments = Collections.unmodifiableList(pathSegments); + } + + public String getPath() { + StringBuilder pathBuilder = new StringBuilder(); + pathBuilder.append(PATH_DELIMITER); + for (Iterator iterator = pathSegments.iterator(); iterator.hasNext(); ) { + String pathSegment = iterator.next(); + pathBuilder.append(pathSegment); + if (iterator.hasNext()) { + pathBuilder.append(PATH_DELIMITER); + } + } + return pathBuilder.toString(); + } + + public List getPathSegments() { + return pathSegments; + } + + public PathComponent encode(String encoding) throws UnsupportedEncodingException { + List pathSegments = getPathSegments(); + List encodedPathSegments = new ArrayList(pathSegments.size()); + for (String pathSegment : pathSegments) { + String encodedPathSegment = encodeUriComponent(pathSegment, encoding, Type.PATH_SEGMENT); + encodedPathSegments.add(encodedPathSegment); + } + return new PathSegmentComponent(encodedPathSegments); + } + + public PathComponent expand(Map uriVariables) { + List pathSegments = getPathSegments(); + List expandedPathSegments = new ArrayList(pathSegments.size()); + for (String pathSegment : pathSegments) { + String expandedPathSegment = expandUriComponent(pathSegment, uriVariables); + expandedPathSegments.add(expandedPathSegment); + } + return new PathSegmentComponent(expandedPathSegments); + } + + public PathComponent expand(Iterator valueIterator) { + List pathSegments = getPathSegments(); + List expandedPathSegments = new ArrayList(pathSegments.size()); + for (String pathSegment : pathSegments) { + String expandedPathSegment = expandUriComponent(pathSegment, valueIterator); + expandedPathSegments.add(expandedPathSegment); + } + return new PathSegmentComponent(expandedPathSegments); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } else if (o instanceof PathSegmentComponent) { + PathSegmentComponent other = (PathSegmentComponent) o; + return this.getPathSegments().equals(other.getPathSegments()); + } + return false; + } + + @Override + public int hashCode() { + return getPathSegments().hashCode(); + } + + } + + /** + * Represents an empty path. + */ + final static PathComponent NULL_PATH_COMPONENT = new PathComponent() { + + public String getPath() { + return null; + } + + public List getPathSegments() { + return Collections.emptyList(); + } + + public PathComponent encode(String encoding) throws UnsupportedEncodingException { + return this; + } + + public PathComponent expand(Map uriVariables) { + return this; + } + + public PathComponent expand(Iterator valueIterator) { + return this; + } + + @Override + public boolean equals(Object o) { + return this == o; + } + + @Override + public int hashCode() { + return 42; + } + + }; + } diff --git a/org.springframework.web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/org.springframework.web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index be70cda8d2c..48970c36f80 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/org.springframework.web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -51,8 +51,6 @@ import org.springframework.util.StringUtils; */ public class UriComponentsBuilder { - private static final char PATH_DELIMITER = '/'; - private static final Pattern QUERY_PARAM_PATTERN = Pattern.compile("([^&=]+)=?([^&=]+)?"); private static final String SCHEME_PATTERN = "([^:/?#]+):"; @@ -89,7 +87,7 @@ public class UriComponentsBuilder { private int port = -1; - private final List pathSegments = new ArrayList(); + private PathComponentBuilder pathBuilder = NULL_PATH_COMPONENT_BUILDER; private final MultiValueMap queryParams = new LinkedMultiValueMap(); @@ -219,7 +217,7 @@ public class UriComponentsBuilder { * @return the URI components */ public UriComponents build(boolean encoded) { - return new UriComponents(scheme, userInfo, host, port, pathSegments, queryParams, fragment, encoded); + return new UriComponents(scheme, userInfo, host, port, pathBuilder.build(), queryParams, fragment, encoded); } // URI components methods @@ -246,8 +244,7 @@ public class UriComponentsBuilder { this.port = uri.getPort(); } if (StringUtils.hasLength(uri.getPath())) { - this.pathSegments.clear(); - path(uri.getPath()); + this.pathBuilder = new FullPathComponentBuilder(uri.getPath()); } if (StringUtils.hasLength(uri.getQuery())) { this.queryParams.clear(); @@ -307,11 +304,7 @@ public class UriComponentsBuilder { return this; } - private String portAsString() { - return this.port != -1 ? Integer.toString(this.port) : null; - } - - /** + /** * Appends the given path to the existing path of this builder. The given path may contain URI template variables. * * @param path the URI path @@ -319,10 +312,9 @@ public class UriComponentsBuilder { */ public UriComponentsBuilder path(String path) { if (path != null) { - String[] pathSegments = StringUtils.tokenizeToStringArray(path, "/"); - pathSegment(pathSegments); + this.pathBuilder = this.pathBuilder.appendPath(path); } else { - pathSegments.clear(); + this.pathBuilder = NULL_PATH_COMPONENT_BUILDER; } return this; } @@ -331,15 +323,14 @@ public class UriComponentsBuilder { * Appends the given path segments to the existing path of this builder. Each given path segments may contain URI * template variables. * - * @param segments the URI path segments + * @param pathSegments the URI path segments * @return this UriComponentsBuilder */ - public UriComponentsBuilder pathSegment(String... segments) throws IllegalArgumentException { - Assert.notNull(segments, "'segments' must not be null"); - Collections.addAll(this.pathSegments, segments); - - return this; - } + public UriComponentsBuilder pathSegment(String... pathSegments) throws IllegalArgumentException { + Assert.notNull(pathSegments, "'segments' must not be null"); + this.pathBuilder = this.pathBuilder.appendPathSegments(pathSegments); + return this; + } /** * Appends the given query to the existing query of this builder. The given query may contain URI template variables. @@ -404,4 +395,100 @@ public class UriComponentsBuilder { return this; } + /** + * Represents a builder for {@link org.springframework.web.util.UriComponents.PathComponent} + */ + private interface PathComponentBuilder { + + UriComponents.PathComponent build(); + + PathComponentBuilder appendPath(String path); + + PathComponentBuilder appendPathSegments(String... pathSegments); + } + + /** + * Represents a builder for full string paths. + */ + private static class FullPathComponentBuilder implements PathComponentBuilder { + + private final StringBuilder path; + + private FullPathComponentBuilder(String path) { + this.path = new StringBuilder(path); + } + + public UriComponents.PathComponent build() { + return new UriComponents.FullPathComponent(path.toString()); + } + + public PathComponentBuilder appendPath(String path) { + this.path.append(path); + return this; + } + + public PathComponentBuilder appendPathSegments(String... pathSegments) { + for (String pathSegment : pathSegments) { + final boolean pathEndsInSlash = path.length() > 0 && path.charAt(path.length() - 1) == '/'; + final boolean segmentStartsWithSlash = pathSegment.charAt(0) == '/'; + + if (path.length() > 0 && !pathEndsInSlash && !segmentStartsWithSlash) { + path.append('/'); + } else if (pathEndsInSlash && segmentStartsWithSlash) { + pathSegment = pathSegment.substring(1); + if (pathSegment.length() == 0) + continue; + } + path.append(pathSegment); + } + return this; + } + } + + /** + * Represents a builder for paths segment paths. + */ + private static class PathSegmentComponentBuilder implements PathComponentBuilder { + + private final List pathSegments = new ArrayList(); + + private PathSegmentComponentBuilder(String... pathSegments) { + Collections.addAll(this.pathSegments, pathSegments); + } + + public UriComponents.PathComponent build() { + return new UriComponents.PathSegmentComponent(pathSegments); + } + + public PathComponentBuilder appendPath(String path) { + String[] pathSegments = StringUtils.tokenizeToStringArray(path, "/"); + Collections.addAll(this.pathSegments, pathSegments); + return this; + } + + public PathComponentBuilder appendPathSegments(String... pathSegments) { + Collections.addAll(this.pathSegments, pathSegments); + return this; + } + } + + + /** + * Represents a builder for an empty path. + */ + private static PathComponentBuilder NULL_PATH_COMPONENT_BUILDER = new PathComponentBuilder() { + + public UriComponents.PathComponent build() { + return UriComponents.NULL_PATH_COMPONENT; + } + + public PathComponentBuilder appendPath(String path) { + return new FullPathComponentBuilder(path); + } + + public PathComponentBuilder appendPathSegments(String... pathSegments) { + return new PathSegmentComponentBuilder(pathSegments); + } + }; + } diff --git a/org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index 7caf2a9721d..a67f45f2be5 100644 --- a/org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -36,18 +36,18 @@ public class UriComponentsBuilderTests { UriComponents result = builder.scheme("http").host("example.com").path("foo").queryParam("bar").fragment("baz").build(); assertEquals("http", result.getScheme()); assertEquals("example.com", result.getHost()); - assertEquals("/foo", result.getPath()); + assertEquals("foo", result.getPath()); assertEquals("bar", result.getQuery()); assertEquals("baz", result.getFragment()); URI expected = new URI("http://example.com/foo?bar#baz"); assertEquals("Invalid result URI", expected, result.toUri()); } - + @Test public void fromPath() throws URISyntaxException { UriComponents result = UriComponentsBuilder.fromPath("foo").queryParam("bar").fragment("baz").build(); - assertEquals("/foo", result.getPath()); + assertEquals("foo", result.getPath()); assertEquals("bar", result.getQuery()); assertEquals("baz", result.getFragment()); @@ -114,7 +114,7 @@ public class UriComponentsBuilderTests { assertNull(result.getUserInfo()); assertNull(result.getHost()); assertEquals(-1, result.getPort()); - assertEquals("/docs/guide/collections/designfaq.html", result.getPath()); + assertEquals("docs/guide/collections/designfaq.html", result.getPath()); assertNull(result.getQuery()); assertEquals("28", result.getFragment()); } diff --git a/org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsTests.java b/org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsTests.java index c599118c003..7957d907db3 100644 --- a/org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsTests.java +++ b/org.springframework.web/src/test/java/org/springframework/web/util/UriComponentsTests.java @@ -26,7 +26,6 @@ import static org.junit.Assert.*; /** @author Arjen Poutsma */ public class UriComponentsTests { - @Test public void encode() { UriComponents uriComponents = UriComponentsBuilder.fromPath("/hotel list").build(); diff --git a/org.springframework.web/src/test/java/org/springframework/web/util/UriUtilsTests.java b/org.springframework.web/src/test/java/org/springframework/web/util/UriUtilsTests.java index b886b773635..4ccd215f140 100644 --- a/org.springframework.web/src/test/java/org/springframework/web/util/UriUtilsTests.java +++ b/org.springframework.web/src/test/java/org/springframework/web/util/UriUtilsTests.java @@ -111,19 +111,19 @@ public class UriUtilsTests { UriUtils.encodeUri("http://www.ietf.org/rfc/rfc3986.txt", ENC)); assertEquals("Invalid encoded URI", "https://www.ietf.org/rfc/rfc3986.txt", UriUtils.encodeUri("https://www.ietf.org/rfc/rfc3986.txt", ENC)); - assertEquals("Invalid encoded URI", "http://www.google.com?q=Z%C3%BCrich", - UriUtils.encodeUri("http://www.google.com?q=Z\u00fcrich", ENC)); + assertEquals("Invalid encoded URI", "http://www.google.com/?q=Z%C3%BCrich", + UriUtils.encodeUri("http://www.google.com/?q=Z\u00fcrich", ENC)); assertEquals("Invalid encoded URI", "http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar#and(java.util.BitSet)", UriUtils.encodeUri( "http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar#and(java.util.BitSet)", ENC)); - assertEquals("Invalid encoded URI", "http://java.sun.com/j2se/1.3", - UriUtils.encodeUri("http://java.sun.com/j2se/1.3", ENC)); - assertEquals("Invalid encoded URI", "/docs/guide/collections/designfaq.html#28", - UriUtils.encodeUri("/docs/guide/collections/designfaq.html#28", ENC)); - assertEquals("Invalid encoded URI", "/../../../demo/jfc/SwingSet2/src/SwingSet2.java", - UriUtils.encodeUri("/../../../demo/jfc/SwingSet2/src/SwingSet2.java", ENC)); + assertEquals("Invalid encoded URI", "http://java.sun.com/j2se/1.3/", + UriUtils.encodeUri("http://java.sun.com/j2se/1.3/", ENC)); + assertEquals("Invalid encoded URI", "docs/guide/collections/designfaq.html#28", + UriUtils.encodeUri("docs/guide/collections/designfaq.html#28", ENC)); + assertEquals("Invalid encoded URI", "../../../demo/jfc/SwingSet2/src/SwingSet2.java", + UriUtils.encodeUri("../../../demo/jfc/SwingSet2/src/SwingSet2.java", ENC)); assertEquals("Invalid encoded URI", "file:///~/calendar", UriUtils.encodeUri("file:///~/calendar", ENC)); assertEquals("Invalid encoded URI", "http://example.com/query=foo@bar", UriUtils.encodeUri("http://example.com/query=foo@bar", ENC)); @@ -136,8 +136,8 @@ public class UriUtilsTests { UriUtils.encodeHttpUrl("http://www.ietf.org/rfc/rfc3986.txt", ENC)); assertEquals("Invalid encoded URI", "https://www.ietf.org/rfc/rfc3986.txt", UriUtils.encodeHttpUrl("https://www.ietf.org/rfc/rfc3986.txt", ENC)); - assertEquals("Invalid encoded HTTP URL", "http://www.google.com?q=Z%C3%BCrich", - UriUtils.encodeHttpUrl("http://www.google.com?q=Z\u00fcrich", ENC)); + assertEquals("Invalid encoded HTTP URL", "http://www.google.com/?q=Z%C3%BCrich", + UriUtils.encodeHttpUrl("http://www.google.com/?q=Z\u00fcrich", ENC)); assertEquals("Invalid encoded HTTP URL", "http://ws.geonames.org/searchJSON?q=T%C5%8Dky%C5%8D&style=FULL&maxRows=300", UriUtils.encodeHttpUrl("http://ws.geonames.org/searchJSON?q=T\u014dky\u014d&style=FULL&maxRows=300", ENC)); assertEquals("Invalid encoded HTTP URL", @@ -146,8 +146,8 @@ public class UriUtilsTests { "http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar", ENC)); assertEquals("Invalid encoded HTTP URL", "http://search.twitter.com/search.atom?q=%23avatar", UriUtils.encodeHttpUrl("http://search.twitter.com/search.atom?q=#avatar", ENC)); - assertEquals("Invalid encoded HTTP URL", "http://java.sun.com/j2se/1.3", - UriUtils.encodeHttpUrl("http://java.sun.com/j2se/1.3", ENC)); + assertEquals("Invalid encoded HTTP URL", "http://java.sun.com/j2se/1.3/", + UriUtils.encodeHttpUrl("http://java.sun.com/j2se/1.3/", ENC)); assertEquals("Invalid encoded HTTP URL", "http://example.com/query=foo@bar", UriUtils.encodeHttpUrl("http://example.com/query=foo@bar", ENC)); }