diff --git a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java index a4a46ba2c0..c1476d053b 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java @@ -43,7 +43,7 @@ import org.springframework.util.StringUtils; */ final class HierarchicalUriComponents extends UriComponents { - private static final char PATH_DELIMITER = '/'; + private static final char PATH_DELIMITER = '/'; private final String userInfo; @@ -57,9 +57,9 @@ final class HierarchicalUriComponents extends UriComponents { private final boolean encoded; + /** * Package-private constructor. All arguments are optional, and can be {@code null}. - * * @param scheme the scheme * @param userInfo the user info * @param host the host @@ -70,9 +70,8 @@ final class HierarchicalUriComponents extends UriComponents { * @param encoded whether the components are already encoded * @param verify whether the components need to be checked for illegal characters */ - HierarchicalUriComponents(String scheme, String userInfo, String host, int port, - PathComponent path, MultiValueMap queryParams, - String fragment, boolean encoded, boolean verify) { + HierarchicalUriComponents(String scheme, String userInfo, String host, int port, PathComponent path, + MultiValueMap queryParams, String fragment, boolean encoded, boolean verify) { super(scheme, fragment); this.userInfo = userInfo; @@ -87,6 +86,7 @@ final class HierarchicalUriComponents extends UriComponents { } } + // component getters @Override @@ -95,19 +95,19 @@ final class HierarchicalUriComponents extends UriComponents { } @Override - public String getUserInfo() { + public String getUserInfo() { return this.userInfo; - } + } - @Override - public String getHost() { + @Override + public String getHost() { return this.host; - } + } - @Override - public int getPort() { + @Override + public int getPort() { return this.port; - } + } @Override public String getPath() { @@ -154,32 +154,30 @@ final class HierarchicalUriComponents extends UriComponents { } /** - * Returns the map of query parameters. - * - * @return the query parameters. Empty if no query has been set. - */ - @Override - public MultiValueMap getQueryParams() { + * Returns the map of query parameters. Empty if no query has been set. + */ + @Override + public MultiValueMap getQueryParams() { return this.queryParams; - } + } + // encoding /** - * Encodes all URI components using their specific encoding rules, and returns the result as a new - * {@code UriComponents} instance. - * - * @param encoding the encoding of the values contained in this map - * @return the encoded uri components - * @throws UnsupportedEncodingException if the given encoding is not supported - */ - @Override - public HierarchicalUriComponents encode(String encoding) throws UnsupportedEncodingException { - Assert.hasLength(encoding, "'encoding' must not be empty"); + * Encodes all URI components using their specific encoding rules, and returns the result as a new + * {@code UriComponents} instance. + * @param encoding the encoding of the values contained in this map + * @return the encoded uri components + * @throws UnsupportedEncodingException if the given encoding is not supported + */ + @Override + public HierarchicalUriComponents encode(String encoding) throws UnsupportedEncodingException { + Assert.hasLength(encoding, "'encoding' must not be empty"); - if (this.encoded) { - return this; - } + if (this.encoded) { + return this; + } String encodedScheme = encodeUriComponent(this.getScheme(), encoding, Type.SCHEME); String encodedUserInfo = encodeUriComponent(this.userInfo, encoding, Type.USER_INFO); @@ -200,18 +198,16 @@ final class HierarchicalUriComponents extends UriComponents { return new HierarchicalUriComponents(encodedScheme, encodedUserInfo, encodedHost, this.port, encodedPath, encodedQueryParams, encodedFragment, true, false); - } + } - /** + /** * Encodes the given source into an encoded String using the rules specified * by the given component and with the given options. - * * @param source the source string * @param encoding the encoding of the source string * @param type the URI component for the source * @return the encoded URI - * @throws IllegalArgumentException when the given uri parameter is not a - * valid URI + * @throws IllegalArgumentException when the given uri parameter is not a valid URI */ static String encodeUriComponent(String source, String encoding, Type type) throws UnsupportedEncodingException { @@ -228,36 +224,33 @@ final class HierarchicalUriComponents extends UriComponents { private static byte[] encodeBytes(byte[] source, Type type) { Assert.notNull(source, "'source' must not be null"); - Assert.notNull(type, "'type' must not be null"); + Assert.notNull(type, "'type' must not be null"); + ByteArrayOutputStream bos = new ByteArrayOutputStream(source.length); + for (int i = 0; i < source.length; i++) { + int b = source[i]; + if (b < 0) { + b += 256; + } + if (type.isAllowed(b)) { + bos.write(b); + } + else { + bos.write('%'); + char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, 16)); + char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, 16)); + bos.write(hex1); + bos.write(hex2); + } + } + return bos.toByteArray(); + } - ByteArrayOutputStream bos = new ByteArrayOutputStream(source.length); - for (int i = 0; i < source.length; i++) { - int b = source[i]; - if (b < 0) { - b += 256; - } - if (type.isAllowed(b)) { - bos.write(b); - } - else { - bos.write('%'); - - char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, 16)); - char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, 16)); - - bos.write(hex1); - bos.write(hex2); - } - } - return bos.toByteArray(); - } // verifying /** * Verifies all URI components to determine whether they contain any illegal * characters, throwing an {@code IllegalArgumentException} if so. - * * @throws IllegalArgumentException if any component has illegal characters */ private void verify() { @@ -277,7 +270,6 @@ final class HierarchicalUriComponents extends UriComponents { verifyUriComponent(getFragment(), Type.FRAGMENT); } - private static void verifyUriComponent(String source, Type type) { if (source == null) { return; @@ -309,6 +301,7 @@ final class HierarchicalUriComponents extends UriComponents { } } + // expanding @Override @@ -337,47 +330,46 @@ final class HierarchicalUriComponents extends UriComponents { } /** - * Normalize the path removing sequences like "path/..". - * @see StringUtils#cleanPath(String) - */ - @Override - public UriComponents normalize() { + * Normalize the path removing sequences like "path/..". + * @see StringUtils#cleanPath(String) + */ + @Override + public UriComponents normalize() { String normalizedPath = StringUtils.cleanPath(getPath()); return new HierarchicalUriComponents(getScheme(), this.userInfo, this.host, this.port, new FullPathComponent(normalizedPath), this.queryParams, getFragment(), this.encoded, false); - } + } + // other functionality - /** - * Returns a URI string from this {@code UriComponents} instance. - * - * @return the URI string - */ - @Override - public String toUriString() { - StringBuilder uriBuilder = new StringBuilder(); + /** + * Returns a URI string from this {@code UriComponents} instance. + */ + @Override + public String toUriString() { + StringBuilder uriBuilder = new StringBuilder(); - if (getScheme() != null) { - uriBuilder.append(getScheme()); - uriBuilder.append(':'); - } + if (getScheme() != null) { + uriBuilder.append(getScheme()); + uriBuilder.append(':'); + } - if (this.userInfo != null || this.host != null) { - uriBuilder.append("//"); - if (this.userInfo != null) { + if (this.userInfo != null || this.host != null) { + uriBuilder.append("//"); + if (this.userInfo != null) { uriBuilder.append(this.userInfo); - uriBuilder.append('@'); - } - if (this.host != null) { + uriBuilder.append('@'); + } + if (this.host != null) { uriBuilder.append(host); - } - if (this.port != -1) { - uriBuilder.append(':'); + } + if (this.port != -1) { + uriBuilder.append(':'); uriBuilder.append(port); - } - } + } + } String path = getPath(); if (StringUtils.hasLength(path)) { @@ -389,53 +381,51 @@ final class HierarchicalUriComponents extends UriComponents { String query = getQuery(); if (query != null) { - uriBuilder.append('?'); - uriBuilder.append(query); - } + uriBuilder.append('?'); + uriBuilder.append(query); + } - if (getFragment() != null) { - uriBuilder.append('#'); + if (getFragment() != null) { + uriBuilder.append('#'); uriBuilder.append(getFragment()); - } + } - return uriBuilder.toString(); - } + return uriBuilder.toString(); + } - /** - * Returns a {@code URI} from this {@code UriComponents} instance. - * - * @return the URI - */ - @Override - public URI toUri() { - try { - if (this.encoded) { - return new URI(toString()); - } - else { + /** + * Returns a {@code URI} from this {@code UriComponents} instance. + */ + @Override + public URI toUri() { + try { + if (this.encoded) { + return new URI(toString()); + } + else { 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()); - } - } - catch (URISyntaxException ex) { - throw new IllegalStateException("Could not create URI object: " + ex.getMessage(), ex); - } - } + } + } + catch (URISyntaxException ex) { + throw new IllegalStateException("Could not create URI object: " + ex.getMessage(), ex); + } + } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof OpaqueUriComponents)) { + if (!(obj instanceof OpaqueUriComponents)) { return false; } - HierarchicalUriComponents other = (HierarchicalUriComponents) o; + HierarchicalUriComponents other = (HierarchicalUriComponents) obj; if (ObjectUtils.nullSafeEquals(getScheme(), other.getScheme())) { return false; @@ -474,157 +464,155 @@ final class HierarchicalUriComponents extends UriComponents { return result; } + // inner types - /** - * Enumeration used to identify the parts of a URI. - *

- * Contains methods to indicate whether a given character is valid in a specific URI component. - * - * @author Arjen Poutsma - * @see RFC 3986 - */ - static enum Type { + /** + * Enumeration used to identify the parts of a URI. + *

Contains methods to indicate whether a given character is valid in a specific URI component. + * @see RFC 3986 + */ + static enum Type { - SCHEME { - @Override - public boolean isAllowed(int c) { - return isAlpha(c) || isDigit(c) || '+' == c || '-' == c || '.' == c; - } - }, - AUTHORITY { - @Override - public boolean isAllowed(int c) { - return isUnreserved(c) || isSubDelimiter(c) || ':' == c || '@' == c; - } - }, - USER_INFO { - @Override - public boolean isAllowed(int c) { - return isUnreserved(c) || isSubDelimiter(c) || ':' == c; - } - }, - HOST { - @Override - public boolean isAllowed(int c) { - return isUnreserved(c) || isSubDelimiter(c); - } - }, - PORT { - @Override - public boolean isAllowed(int c) { - return isDigit(c); - } - }, - PATH { - @Override - public boolean isAllowed(int c) { - return isPchar(c) || '/' == c; - } - }, - PATH_SEGMENT { - @Override - public boolean isAllowed(int c) { - return isPchar(c); - } - }, - QUERY { - @Override - public boolean isAllowed(int c) { - return isPchar(c) || '/' == c || '?' == c; - } - }, - QUERY_PARAM { - @Override - public boolean isAllowed(int c) { - if ('=' == c || '+' == c || '&' == c) { - return false; - } - else { - return isPchar(c) || '/' == c || '?' == c; - } - } - }, - FRAGMENT { - @Override - public boolean isAllowed(int c) { - return isPchar(c) || '/' == c || '?' == c; - } - }; + SCHEME { + @Override + public boolean isAllowed(int c) { + return isAlpha(c) || isDigit(c) || '+' == c || '-' == c || '.' == c; + } + }, + AUTHORITY { + @Override + public boolean isAllowed(int c) { + return isUnreserved(c) || isSubDelimiter(c) || ':' == c || '@' == c; + } + }, + USER_INFO { + @Override + public boolean isAllowed(int c) { + return isUnreserved(c) || isSubDelimiter(c) || ':' == c; + } + }, + HOST { + @Override + public boolean isAllowed(int c) { + return isUnreserved(c) || isSubDelimiter(c); + } + }, + PORT { + @Override + public boolean isAllowed(int c) { + return isDigit(c); + } + }, + PATH { + @Override + public boolean isAllowed(int c) { + return isPchar(c) || '/' == c; + } + }, + PATH_SEGMENT { + @Override + public boolean isAllowed(int c) { + return isPchar(c); + } + }, + QUERY { + @Override + public boolean isAllowed(int c) { + return isPchar(c) || '/' == c || '?' == c; + } + }, + QUERY_PARAM { + @Override + public boolean isAllowed(int c) { + if ('=' == c || '+' == c || '&' == c) { + return false; + } + else { + return isPchar(c) || '/' == c || '?' == c; + } + } + }, + FRAGMENT { + @Override + public boolean isAllowed(int c) { + return isPchar(c) || '/' == c || '?' == c; + } + }; - /** - * Indicates whether the given character is allowed in this URI component. - * - * @param c the character - * @return {@code true} if the character is allowed; {@code false} otherwise - */ - public abstract boolean isAllowed(int c); + /** + * Indicates whether the given character is allowed in this URI component. + * + * @param c the character + * @return {@code true} if the character is allowed; {@code false} otherwise + */ + public abstract boolean isAllowed(int c); - /** - * Indicates whether the given character is in the {@code ALPHA} set. - * - * @see RFC 3986, appendix A - */ - protected boolean isAlpha(int c) { - return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'; - } + /** + * Indicates whether the given character is in the {@code ALPHA} set. + * + * @see RFC 3986, appendix A + */ + protected boolean isAlpha(int c) { + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'; + } - /** - * Indicates whether the given character is in the {@code DIGIT} set. - * - * @see RFC 3986, appendix A - */ - protected boolean isDigit(int c) { - return c >= '0' && c <= '9'; - } + /** + * Indicates whether the given character is in the {@code DIGIT} set. + * + * @see RFC 3986, appendix A + */ + protected boolean isDigit(int c) { + return c >= '0' && c <= '9'; + } - /** - * Indicates whether the given character is in the {@code gen-delims} set. - * - * @see RFC 3986, appendix A - */ - protected boolean isGenericDelimiter(int c) { - return ':' == c || '/' == c || '?' == c || '#' == c || '[' == c || ']' == c || '@' == c; - } + /** + * Indicates whether the given character is in the {@code gen-delims} set. + * + * @see RFC 3986, appendix A + */ + protected boolean isGenericDelimiter(int c) { + return ':' == c || '/' == c || '?' == c || '#' == c || '[' == c || ']' == c || '@' == c; + } - /** - * Indicates whether the given character is in the {@code sub-delims} set. - * - * @see RFC 3986, appendix A - */ - protected boolean isSubDelimiter(int c) { - return '!' == c || '$' == c || '&' == c || '\'' == c || '(' == c || ')' == c || '*' == c || '+' == c || - ',' == c || ';' == c || '=' == c; - } + /** + * Indicates whether the given character is in the {@code sub-delims} set. + * + * @see RFC 3986, appendix A + */ + protected boolean isSubDelimiter(int c) { + return '!' == c || '$' == c || '&' == c || '\'' == c || '(' == c || ')' == c || '*' == c || '+' == c || + ',' == c || ';' == c || '=' == c; + } - /** - * Indicates whether the given character is in the {@code reserved} set. - * - * @see RFC 3986, appendix A - */ - protected boolean isReserved(char c) { - return isGenericDelimiter(c) || isReserved(c); - } + /** + * Indicates whether the given character is in the {@code reserved} set. + * + * @see RFC 3986, appendix A + */ + protected boolean isReserved(char c) { + return isGenericDelimiter(c) || isReserved(c); + } - /** - * Indicates whether the given character is in the {@code unreserved} set. - * - * @see RFC 3986, appendix A - */ - protected boolean isUnreserved(int c) { - return isAlpha(c) || isDigit(c) || '-' == c || '.' == c || '_' == c || '~' == c; - } + /** + * Indicates whether the given character is in the {@code unreserved} set. + * + * @see RFC 3986, appendix A + */ + protected boolean isUnreserved(int c) { + return isAlpha(c) || isDigit(c) || '-' == c || '.' == c || '_' == c || '~' == c; + } - /** - * Indicates whether the given character is in the {@code pchar} set. - * - * @see RFC 3986, appendix A - */ - protected boolean isPchar(int c) { - return isUnreserved(c) || isSubDelimiter(c) || ':' == c || '@' == c; - } + /** + * Indicates whether the given character is in the {@code pchar} set. + * + * @see RFC 3986, appendix A + */ + protected boolean isPchar(int c) { + return isUnreserved(c) || isSubDelimiter(c) || ':' == c || '@' == c; + } + } - } /** * Defines the contract for path (segments). @@ -640,9 +628,9 @@ final class HierarchicalUriComponents extends UriComponents { void verify(); PathComponent expand(UriTemplateVariables uriVariables); - } + /** * Represents a path backed by a string. */ @@ -679,14 +667,9 @@ final class HierarchicalUriComponents extends UriComponents { } @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; + public boolean equals(Object obj) { + return (this == obj || (obj instanceof FullPathComponent && + getPath().equals(((FullPathComponent) obj).getPath()))); } @Override @@ -750,14 +733,9 @@ final class HierarchicalUriComponents extends UriComponents { } @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; + public boolean equals(Object obj) { + return (this == obj || (obj instanceof PathSegmentComponent && + getPathSegments().equals(((PathSegmentComponent) obj).getPathSegments()))); } @Override @@ -844,8 +822,8 @@ final class HierarchicalUriComponents extends UriComponents { } @Override - public boolean equals(Object o) { - return this == o; + public boolean equals(Object obj) { + return (this == obj); } @Override diff --git a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java index fb07addf8f..d896518b29 100644 --- a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java @@ -45,6 +45,7 @@ final class OpaqueUriComponents extends UriComponents { this.ssp = schemeSpecificPart; } + @Override public String getSchemeSpecificPart() { return this.ssp; @@ -134,15 +135,15 @@ final class OpaqueUriComponents extends UriComponents { } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof OpaqueUriComponents)) { + if (!(obj instanceof OpaqueUriComponents)) { return false; } - OpaqueUriComponents other = (OpaqueUriComponents) o; + OpaqueUriComponents other = (OpaqueUriComponents) obj; if (ObjectUtils.nullSafeEquals(getScheme(), other.getScheme())) { return false; diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponents.java b/spring-web/src/main/java/org/springframework/web/util/UriComponents.java index 85605c972c..f04c5f695b 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponents.java @@ -35,8 +35,8 @@ import org.springframework.util.MultiValueMap; * variables. * * @author Arjen Poutsma - * @see UriComponentsBuilder * @since 3.1 + * @see UriComponentsBuilder */ public abstract class UriComponents { @@ -45,97 +45,80 @@ public abstract class UriComponents { /** Captures URI template variable names. */ private static final Pattern NAMES_PATTERN = Pattern.compile("\\{([^/]+?)\\}"); + private final String scheme; private final String fragment; + protected UriComponents(String scheme, String fragment) { this.scheme = scheme; this.fragment = fragment; } + // component getters /** - * Returns the scheme. - * - * @return the scheme. Can be {@code null}. + * Returns the scheme. Can be {@code null}. */ public final String getScheme() { return scheme; } /** - * Returns the scheme specific part. - * - * @retur the scheme specific part. Can be {@code null}. + * Returns the scheme specific part. Can be {@code null}. */ public abstract String getSchemeSpecificPart(); /** - * Returns the user info. - * - * @return the user info. Can be {@code null}. + * Returns the user info. Can be {@code null}. */ public abstract String getUserInfo(); /** - * Returns the host. - * - * @return the host. Can be {@code null}. + * Returns the host. Can be {@code null}. */ public abstract String getHost(); /** * Returns the port. Returns {@code -1} if no port has been set. - * - * @return the port */ public abstract int getPort(); /** - * Returns the path. - * - * @return the path. Can be {@code null}. + * Returns the path. Can be {@code null}. */ public abstract String getPath(); /** - * Returns the list of path segments. - * - * @return the path segments. Empty if no path has been set. + * Returns the list of path segments. Empty if no path has been set. */ public abstract List getPathSegments(); /** - * Returns the query. - * - * @return the query. Can be {@code null}. + * Returns the query. Can be {@code null}. */ public abstract String getQuery(); /** - * Returns the map of query parameters. - * - * @return the query parameters. Empty if no query has been set. + * Returns the map of query parameters. Empty if no query has been set. */ public abstract MultiValueMap getQueryParams(); /** - * Returns the fragment. - * - * @return the fragment. Can be {@code null}. + * Returns the fragment. Can be {@code null}. */ public final String getFragment() { - return fragment; + return this.fragment; } + // encoding /** - * Encodes all URI components using their specific encoding rules, and returns the result + * Encode all URI components using their specific encoding rules, and returns the result * as a new {@code UriComponents} instance. This method uses UTF-8 to encode. - * * @return the encoded uri components */ public final UriComponents encode() { @@ -148,48 +131,43 @@ public abstract class UriComponents { } /** - * Encodes all URI components using their specific encoding rules, and + * Encode all URI components using their specific encoding rules, and * returns the result as a new {@code UriComponents} instance. - * * @param encoding the encoding of the values contained in this map * @return the encoded uri components * @throws UnsupportedEncodingException if the given encoding is not supported */ public abstract UriComponents encode(String encoding) throws UnsupportedEncodingException; + // expanding /** * Replaces all URI template variables with the values from a given map. The map keys * represent variable names; the values variable values. The order of variables is not * significant. - * * @param uriVariables the map of URI variables * @return the expanded uri components */ public final UriComponents expand(Map uriVariables) { Assert.notNull(uriVariables, "'uriVariables' must not be null"); - return expandInternal(new MapTemplateVariables(uriVariables)); } /** * Replaces all URI template variables with the values from a given array. The array * represent variable values. The order of variables is significant. - * * @param uriVariableValues URI variable values * @return the expanded uri components */ public final UriComponents expand(Object... uriVariableValues) { Assert.notNull(uriVariableValues, "'uriVariableValues' must not be null"); - return expandInternal(new VarArgsTemplateVariables(uriVariableValues)); } /** * Replaces all URI template variables with the values from the given {@link * UriTemplateVariables} - * * @param uriVariables URI template values * @return the expanded uri components */ @@ -227,15 +205,11 @@ public abstract class UriComponents { /** * Returns a URI string from this {@code UriComponents} instance. - * - * @return the URI string */ public abstract String toUriString(); /** * Returns a {@code URI} from this {@code UriComponents} instance. - * - * @return the URI */ public abstract URI toUri(); @@ -246,14 +220,13 @@ public abstract class UriComponents { /** * Normalize the path removing sequences like "path/..". - * * @see org.springframework.util.StringUtils#cleanPath(String) */ public abstract UriComponents normalize(); + /** * Defines the contract for URI Template variables - * * @see HierarchicalUriComponents#expand */ interface UriTemplateVariables { @@ -281,6 +254,7 @@ public abstract class UriComponents { } } + /** * URI template variables backed by a variable argument array. */ @@ -301,5 +275,4 @@ public abstract class UriComponents { } } - } diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java index bddba4c848..dc53ec6481 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java @@ -32,8 +32,8 @@ import org.springframework.util.StringUtils; /** * Builder for {@link UriComponents}. - *

- * Typical usage involves: + * + *

Typical usage involves: *
    *
  1. Create a {@code UriComponentsBuilder} with one of the static factory methods (such as * {@link #fromPath(String)} or {@link #fromUri(URI)})
  2. @@ -46,10 +46,10 @@ import org.springframework.util.StringUtils; * * @author Arjen Poutsma * @author Rossen Stoyanchev + * @since 3.1 * @see #newInstance() * @see #fromPath(String) * @see #fromUri(URI) - * @since 3.1 */ public class UriComponentsBuilder { diff --git a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java index 9498f91a08..e976a43b54 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,9 @@ import org.springframework.util.Assert; * *

    All {@code encode*(String, String} methods in this class operate in a similar way: *

      - *
    • Valid characters for the specific URI component as defined in RFC 3986 stay the same.
    • - *
    • All other characters are converted into one or more bytes in the given encoding scheme. Each of the - * resulting bytes is written as a hexadecimal string in the "%xy" format.
    • + *
    • Valid characters for the specific URI component as defined in RFC 3986 stay the same.
    • + *
    • All other characters are converted into one or more bytes in the given encoding scheme. Each of the + * resulting bytes is written as a hexadecimal string in the "%xy" format.
    • *
    * * @author Arjen Poutsma @@ -64,6 +64,7 @@ public abstract class UriUtils { private static final Pattern HTTP_URL_PATTERN = Pattern.compile( "^" + HTTP_PATTERN + "(//(" + USERINFO_PATTERN + "@)?" + HOST_PATTERN + "(:" + PORT_PATTERN + ")?" + ")?" + PATH_PATTERN + "(\\?" + LAST_PATTERN + ")?"); + // encoding /** @@ -73,8 +74,8 @@ public abstract class UriUtils { * characters in query parameter names and query parameter values because they cannot * be parsed in a reliable way. Instead use: *
    -	 *  UriComponents uriComponents = UriComponentsBuilder.fromUri("/path?name={value}").buildAndExpand("a=b");
    -	 *  String encodedUri = uriComponents.encode().toUriString();
    +	 * UriComponents uriComponents = UriComponentsBuilder.fromUri("/path?name={value}").buildAndExpand("a=b");
    +	 * String encodedUri = uriComponents.encode().toUriString();
     	 * 
    * @param uri the URI to be encoded * @param encoding the character encoding to encode to @@ -114,8 +115,8 @@ public abstract class UriUtils { * characters in query parameter names and query parameter values because they cannot * be parsed in a reliable way. Instead use: *
    -	 *  UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl("/path?name={value}").buildAndExpand("a=b");
    -	 *  String encodedUri = uriComponents.encode().toUriString();
    +	 * UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl("/path?name={value}").buildAndExpand("a=b");
    +	 * String encodedUri = uriComponents.encode().toUriString();
     	 * 
    * @param httpUrl the HTTP URL to be encoded * @param encoding the character encoding to encode to @@ -167,42 +168,42 @@ public abstract class UriUtils { String host, String port, String path, String query, String fragment, String encoding) throws UnsupportedEncodingException { - Assert.hasLength(encoding, "'encoding' must not be empty"); - StringBuilder sb = new StringBuilder(); + Assert.hasLength(encoding, "'encoding' must not be empty"); + StringBuilder sb = new StringBuilder(); - if (scheme != null) { - sb.append(encodeScheme(scheme, encoding)); - sb.append(':'); - } + if (scheme != null) { + sb.append(encodeScheme(scheme, encoding)); + sb.append(':'); + } - if (authority != null) { - sb.append("//"); - if (userInfo != null) { - sb.append(encodeUserInfo(userInfo, encoding)); - sb.append('@'); - } - if (host != null) { - sb.append(encodeHost(host, encoding)); - } - if (port != null) { - sb.append(':'); - sb.append(encodePort(port, encoding)); - } - } + if (authority != null) { + sb.append("//"); + if (userInfo != null) { + sb.append(encodeUserInfo(userInfo, encoding)); + sb.append('@'); + } + if (host != null) { + sb.append(encodeHost(host, encoding)); + } + if (port != null) { + sb.append(':'); + sb.append(encodePort(port, encoding)); + } + } - sb.append(encodePath(path, encoding)); + sb.append(encodePath(path, encoding)); - if (query != null) { - sb.append('?'); - sb.append(encodeQuery(query, encoding)); - } + if (query != null) { + sb.append('?'); + sb.append(encodeQuery(query, encoding)); + } - if (fragment != null) { - sb.append('#'); - sb.append(encodeFragment(fragment, encoding)); - } + if (fragment != null) { + sb.append('#'); + sb.append(encodeFragment(fragment, encoding)); + } - return sb.toString(); + return sb.toString(); } @@ -334,11 +335,11 @@ public abstract class UriUtils { /** * Decodes the given encoded source String into an URI. Based on the following rules: *
      - *
    • Alphanumeric characters {@code "a"} through {@code "z"}, {@code "A"} through {@code "Z"}, and - * {@code "0"} through {@code "9"} stay the same.
    • - *
    • Special characters {@code "-"}, {@code "_"}, {@code "."}, and {@code "*"} stay the same.
    • - *
    • A sequence "%xy" is interpreted as a hexadecimal representation of the character.
    • - *
    + *
  3. Alphanumeric characters {@code "a"} through {@code "z"}, {@code "A"} through {@code "Z"}, and + * {@code "0"} through {@code "9"} stay the same.
  4. + *
  5. Special characters {@code "-"}, {@code "_"}, {@code "."}, and {@code "*"} stay the same.
  6. + *
  7. A sequence "%xy" is interpreted as a hexadecimal representation of the character.
  8. + * * @param source the source string * @param encoding the encoding * @return the decoded URI diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index 378c8704fb..e01436319b 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -16,9 +16,6 @@ package org.springframework.web.util; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; @@ -26,10 +23,15 @@ import java.util.HashMap; import java.util.Map; import org.junit.Test; + import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -/** @author Arjen Poutsma */ +import static org.junit.Assert.*; + +/** + * @author Arjen Poutsma + */ public class UriComponentsBuilderTests { @Test