Polished UriComponents implementation

(cherry picked from commit c3b624d)
This commit is contained in:
Juergen Hoeller 2013-05-03 13:22:11 +02:00
parent e3fa49063e
commit b2bd319d47
4 changed files with 88 additions and 169 deletions

View File

@ -177,11 +177,9 @@ final class HierarchicalUriComponents extends UriComponents {
@Override
public HierarchicalUriComponents encode(String encoding) throws UnsupportedEncodingException {
Assert.hasLength(encoding, "'encoding' must not be empty");
if (this.encoded) {
return this;
}
String encodedScheme = encodeUriComponent(this.getScheme(), encoding, Type.SCHEME);
String encodedUserInfo = encodeUriComponent(this.userInfo, encoding, Type.USER_INFO);
String encodedHost = encodeUriComponent(this.host, encoding, Type.HOST);
@ -198,7 +196,6 @@ final class HierarchicalUriComponents extends UriComponents {
encodedQueryParams.put(encodedName, encodedValues);
}
String encodedFragment = encodeUriComponent(this.getFragment(), encoding, Type.FRAGMENT);
return new HierarchicalUriComponents(encodedScheme, encodedUserInfo, encodedHost, this.port, encodedPath,
encodedQueryParams, encodedFragment, true, false);
}
@ -212,15 +209,11 @@ final class HierarchicalUriComponents extends UriComponents {
* @return the encoded URI
* @throws IllegalArgumentException when the given uri parameter is not a valid URI
*/
static String encodeUriComponent(String source, String encoding, Type type)
throws UnsupportedEncodingException {
static String encodeUriComponent(String source, String encoding, Type type) throws UnsupportedEncodingException {
if (source == null) {
return null;
}
Assert.hasLength(encoding, "'encoding' must not be empty");
byte[] bytes = encodeBytes(source.getBytes(encoding), type);
return new String(bytes, "US-ASCII");
}
@ -229,8 +222,7 @@ final class HierarchicalUriComponents extends UriComponents {
Assert.notNull(source, "'source' 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];
for (byte b : source) {
if (b < 0) {
b += 256;
}
@ -277,9 +269,7 @@ final class HierarchicalUriComponents extends UriComponents {
if (source == null) {
return;
}
int length = source.length();
for (int i=0; i < length; i++) {
char ch = source.charAt(i);
if (ch == '%') {
@ -309,8 +299,7 @@ final class HierarchicalUriComponents extends UriComponents {
@Override
protected HierarchicalUriComponents expandInternal(UriTemplateVariables uriVariables) {
Assert.state(!encoded, "Cannot expand an already encoded UriComponents object");
Assert.state(!this.encoded, "Cannot expand an already encoded UriComponents object");
String expandedScheme = expandUriComponent(this.getScheme(), uriVariables);
String expandedUserInfo = expandUriComponent(this.userInfo, uriVariables);
String expandedHost = expandUriComponent(this.host, uriVariables);
@ -327,7 +316,6 @@ final class HierarchicalUriComponents extends UriComponents {
expandedQueryParams.put(expandedName, expandedValues);
}
String expandedFragment = expandUriComponent(this.getFragment(), uriVariables);
return new HierarchicalUriComponents(expandedScheme, expandedUserInfo, expandedHost, this.port, expandedPath,
expandedQueryParams, expandedFragment, false, false);
}
@ -353,12 +341,10 @@ final class HierarchicalUriComponents extends UriComponents {
@Override
public String toUriString() {
StringBuilder uriBuilder = new StringBuilder();
if (getScheme() != null) {
uriBuilder.append(getScheme());
uriBuilder.append(':');
}
if (this.userInfo != null || this.host != null) {
uriBuilder.append("//");
if (this.userInfo != null) {
@ -373,7 +359,6 @@ final class HierarchicalUriComponents extends UriComponents {
uriBuilder.append(port);
}
}
String path = getPath();
if (StringUtils.hasLength(path)) {
if (uriBuilder.length() != 0 && path.charAt(0) != PATH_DELIMITER) {
@ -381,18 +366,15 @@ final class HierarchicalUriComponents extends UriComponents {
}
uriBuilder.append(path);
}
String query = getQuery();
if (query != null) {
uriBuilder.append('?');
uriBuilder.append(query);
}
if (getFragment() != null) {
uriBuilder.append('#');
uriBuilder.append(getFragment());
}
return uriBuilder.toString();
}
@ -431,15 +413,13 @@ final class HierarchicalUriComponents extends UriComponents {
return false;
}
HierarchicalUriComponents other = (HierarchicalUriComponents) obj;
boolean rtn = true;
rtn &= ObjectUtils.nullSafeEquals(getScheme(), other.getScheme());
rtn &= ObjectUtils.nullSafeEquals(getUserInfo(), other.getUserInfo());
rtn &= ObjectUtils.nullSafeEquals(getHost(), other.getHost());
rtn &= getPort() == other.getPort();
rtn &= this.path.equals(other.path);
rtn &= this.queryParams.equals(other.queryParams);
rtn &= ObjectUtils.nullSafeEquals(getFragment(), other.getFragment());
return rtn;
return ObjectUtils.nullSafeEquals(getScheme(), other.getScheme()) &&
ObjectUtils.nullSafeEquals(getUserInfo(), other.getUserInfo()) &&
ObjectUtils.nullSafeEquals(getHost(), other.getHost()) &&
getPort() == other.getPort() &&
this.path.equals(other.path) &&
this.queryParams.equals(other.queryParams) &&
ObjectUtils.nullSafeEquals(getFragment(), other.getFragment());
}
@Override
@ -532,15 +512,12 @@ final class HierarchicalUriComponents extends UriComponents {
/**
* 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 <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>
*/
protected boolean isAlpha(int c) {
@ -549,7 +526,6 @@ final class HierarchicalUriComponents extends UriComponents {
/**
* Indicates whether the given character is in the {@code DIGIT} set.
*
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>
*/
protected boolean isDigit(int c) {
@ -558,7 +534,6 @@ final class HierarchicalUriComponents extends UriComponents {
/**
* Indicates whether the given character is in the {@code gen-delims} set.
*
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>
*/
protected boolean isGenericDelimiter(int c) {
@ -567,7 +542,6 @@ final class HierarchicalUriComponents extends UriComponents {
/**
* Indicates whether the given character is in the {@code sub-delims} set.
*
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>
*/
protected boolean isSubDelimiter(int c) {
@ -577,7 +551,6 @@ final class HierarchicalUriComponents extends UriComponents {
/**
* Indicates whether the given character is in the {@code reserved} set.
*
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>
*/
protected boolean isReserved(char c) {
@ -586,7 +559,6 @@ final class HierarchicalUriComponents extends UriComponents {
/**
* Indicates whether the given character is in the {@code unreserved} set.
*
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>
*/
protected boolean isUnreserved(int c) {
@ -595,7 +567,6 @@ final class HierarchicalUriComponents extends UriComponents {
/**
* Indicates whether the given character is in the {@code pchar} set.
*
* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>
*/
protected boolean isPchar(int c) {
@ -624,11 +595,11 @@ final class HierarchicalUriComponents extends UriComponents {
/**
* Represents a path backed by a string.
*/
final static class FullPathComponent implements PathComponent {
static final class FullPathComponent implements PathComponent {
private final String path;
FullPathComponent(String path) {
public FullPathComponent(String path) {
this.path = path;
}
@ -668,14 +639,15 @@ final class HierarchicalUriComponents extends UriComponents {
}
}
/**
* Represents a path backed by a string list (i.e. path segments).
*/
final static class PathSegmentComponent implements PathComponent {
static final class PathSegmentComponent implements PathComponent {
private final List<String> pathSegments;
PathSegmentComponent(List<String> pathSegments) {
public PathSegmentComponent(List<String> pathSegments) {
this.pathSegments = Collections.unmodifiableList(pathSegments);
}
@ -732,17 +704,17 @@ final class HierarchicalUriComponents extends UriComponents {
public int hashCode() {
return getPathSegments().hashCode();
}
}
/**
* Represents a collection of PathComponents.
*/
final static class PathComponentComposite implements PathComponent {
static final class PathComponentComposite implements PathComponent {
private final List<PathComponent> pathComponents;
PathComponentComposite(List<PathComponent> pathComponents) {
public PathComponentComposite(List<PathComponent> pathComponents) {
this.pathComponents = pathComponents;
}
@ -763,15 +735,15 @@ final class HierarchicalUriComponents extends UriComponents {
}
public PathComponent encode(String encoding) throws UnsupportedEncodingException {
List<PathComponent> encodedComponents = new ArrayList<PathComponent>(pathComponents.size());
for (PathComponent pathComponent : pathComponents) {
List<PathComponent> encodedComponents = new ArrayList<PathComponent>(this.pathComponents.size());
for (PathComponent pathComponent : this.pathComponents) {
encodedComponents.add(pathComponent.encode(encoding));
}
return new PathComponentComposite(encodedComponents);
}
public void verify() {
for (PathComponent pathComponent : pathComponents) {
for (PathComponent pathComponent : this.pathComponents) {
pathComponent.verify();
}
}
@ -786,41 +758,32 @@ final class HierarchicalUriComponents extends UriComponents {
}
/**
* Represents an empty path.
*/
final static PathComponent NULL_PATH_COMPONENT = new PathComponent() {
static final PathComponent NULL_PATH_COMPONENT = new PathComponent() {
public String getPath() {
return null;
}
public List<String> getPathSegments() {
return Collections.emptyList();
}
public PathComponent encode(String encoding) throws UnsupportedEncodingException {
return this;
}
public void verify() {
}
public PathComponent expand(UriTemplateVariables uriVariables) {
return this;
}
@Override
public boolean equals(Object obj) {
return (this == obj);
}
@Override
public int hashCode() {
return 42;
}
};
}

View File

@ -98,10 +98,14 @@ final class OpaqueUriComponents extends UriComponents {
String expandedScheme = expandUriComponent(this.getScheme(), uriVariables);
String expandedSSp = expandUriComponent(this.ssp, uriVariables);
String expandedFragment = expandUriComponent(this.getFragment(), uriVariables);
return new OpaqueUriComponents(expandedScheme, expandedSSp, expandedFragment);
}
@Override
public UriComponents normalize() {
return this;
}
@Override
public String toUriString() {
StringBuilder uriBuilder = new StringBuilder();
@ -131,10 +135,6 @@ final class OpaqueUriComponents extends UriComponents {
}
}
@Override
public UriComponents normalize() {
return this;
}
@Override
public boolean equals(Object obj) {
@ -146,11 +146,10 @@ final class OpaqueUriComponents extends UriComponents {
}
OpaqueUriComponents other = (OpaqueUriComponents) obj;
boolean rtn = true;
rtn &= ObjectUtils.nullSafeEquals(getScheme(), other.getScheme());
rtn &= ObjectUtils.nullSafeEquals(this.ssp, other.ssp);
rtn &= ObjectUtils.nullSafeEquals(getFragment(), other.getFragment());
return rtn;
return ObjectUtils.nullSafeEquals(getScheme(), other.getScheme()) &&
ObjectUtils.nullSafeEquals(this.ssp, other.ssp) &&
ObjectUtils.nullSafeEquals(getFragment(), other.getFragment());
}
@Override

View File

@ -64,7 +64,7 @@ public abstract class UriComponents implements Serializable {
* Returns the scheme. Can be {@code null}.
*/
public final String getScheme() {
return scheme;
return this.scheme;
}
/**
@ -115,11 +115,9 @@ public abstract class UriComponents implements Serializable {
}
// encoding
/**
* 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.
* 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() {
@ -140,9 +138,6 @@ public abstract class UriComponents implements Serializable {
*/
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
@ -174,6 +169,30 @@ public abstract class UriComponents implements Serializable {
*/
abstract UriComponents expandInternal(UriTemplateVariables uriVariables);
/**
* Normalize the path removing sequences like "path/..".
* @see org.springframework.util.StringUtils#cleanPath(String)
*/
public abstract UriComponents normalize();
/**
* Returns a URI string from this {@code UriComponents} instance.
*/
public abstract String toUriString();
/**
* Returns a {@code URI} from this {@code UriComponents} instance.
*/
public abstract URI toUri();
@Override
public final String toString() {
return toUriString();
}
// static expansion helpers
static String expandUriComponent(String source, UriTemplateVariables uriVariables) {
if (source == null) {
return null;
@ -197,34 +216,13 @@ public abstract class UriComponents implements Serializable {
private static String getVariableName(String match) {
int colonIdx = match.indexOf(':');
return colonIdx == -1 ? match : match.substring(0, colonIdx);
return (colonIdx != -1 ? match.substring(0, colonIdx) : match);
}
private static String getVariableValueAsString(Object variableValue) {
return variableValue != null ? variableValue.toString() : "";
return (variableValue != null ? variableValue.toString() : "");
}
/**
* Returns a URI string from this {@code UriComponents} instance.
*/
public abstract String toUriString();
/**
* Returns a {@code URI} from this {@code UriComponents} instance.
*/
public abstract URI toUri();
@Override
public final String toString() {
return toUriString();
}
/**
* 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
@ -233,9 +231,9 @@ public abstract class UriComponents implements Serializable {
interface UriTemplateVariables {
Object getValue(String name);
}
/**
* URI template variables backed by a map.
*/
@ -268,11 +266,11 @@ public abstract class UriComponents implements Serializable {
}
public Object getValue(String name) {
if (!valueIterator.hasNext()) {
if (!this.valueIterator.hasNext()) {
throw new IllegalArgumentException(
"Not enough variable values available to expand '" + name + "'");
}
return valueIterator.next();
return this.valueIterator.next();
}
}

View File

@ -100,9 +100,9 @@ public class UriComponentsBuilder {
private String fragment;
/**
* Default constructor. Protected to prevent direct instantiation.
*
* @see #newInstance()
* @see #fromPath(String)
* @see #fromUri(URI)
@ -110,11 +110,11 @@ public class UriComponentsBuilder {
protected UriComponentsBuilder() {
}
// Factory methods
/**
* Returns a new, empty builder.
*
* @return the new {@code UriComponentsBuilder}
*/
public static UriComponentsBuilder newInstance() {
@ -123,7 +123,6 @@ public class UriComponentsBuilder {
/**
* Returns a builder that is initialized with the given path.
*
* @param path the path to initialize with
* @return the new {@code UriComponentsBuilder}
*/
@ -135,7 +134,6 @@ public class UriComponentsBuilder {
/**
* Returns a builder that is initialized with the given {@code URI}.
*
* @param uri the URI to initialize with
* @return the new {@code UriComponentsBuilder}
*/
@ -147,20 +145,16 @@ public class UriComponentsBuilder {
/**
* Returns a builder that is initialized with the given URI string.
*
* <p><strong>Note:</strong> The presence of reserved characters can prevent
* correct parsing of the URI string. For example if a query parameter
* contains {@code '='} or {@code '&'} characters, the query string cannot
* be parsed unambiguously. Such values should be substituted for URI
* variables to enable correct parsing:
*
* <pre>
* String uriString = &quot;/hotels/42?filter={value}&quot;;
* UriComponentsBuilder.fromUriString(uriString).buildAndExpand(&quot;hot&amp;cold&quot;);
* </pre>
*
* @param uri
* the URI string to initialize with
* @param uri the URI string to initialize with
* @return the new {@code UriComponentsBuilder}
*/
public static UriComponentsBuilder fromUriString(String uri) {
@ -168,7 +162,6 @@ public class UriComponentsBuilder {
Matcher m = URI_PATTERN.matcher(uri);
if (m.matches()) {
UriComponentsBuilder builder = new UriComponentsBuilder();
String scheme = m.group(2);
String userInfo = m.group(5);
String host = m.group(6);
@ -176,19 +169,14 @@ public class UriComponentsBuilder {
String path = m.group(9);
String query = m.group(11);
String fragment = m.group(13);
boolean opaque = false;
if (StringUtils.hasLength(scheme)) {
String s = uri.substring(scheme.length());
if (!s.startsWith(":/")) {
opaque = true;
}
}
builder.scheme(scheme);
if (opaque) {
String ssp = uri.substring(scheme.length()).substring(1);
if (StringUtils.hasLength(fragment)) {
@ -205,11 +193,9 @@ public class UriComponentsBuilder {
builder.path(path);
builder.query(query);
}
if (StringUtils.hasText(fragment)) {
builder.fragment(fragment);
}
return builder;
}
else {
@ -219,18 +205,15 @@ public class UriComponentsBuilder {
/**
* Creates a new {@code UriComponents} object from the string HTTP URL.
*
* <p><strong>Note:</strong> The presence of reserved characters can prevent
* correct parsing of the URI string. For example if a query parameter
* contains {@code '='} or {@code '&'} characters, the query string cannot
* be parsed unambiguously. Such values should be substituted for URI
* variables to enable correct parsing:
*
* <pre>
* String uriString = &quot;/hotels/42?filter={value}&quot;;
* UriComponentsBuilder.fromUriString(uriString).buildAndExpand(&quot;hot&amp;cold&quot;);
* </pre>
*
* @param httpUrl the source URI
* @return the URI components of the URI
*/
@ -258,12 +241,10 @@ public class UriComponentsBuilder {
}
// build methods
/**
* Builds a {@code UriComponents} instance from the various components contained in this builder.
*
* @return the URI components
*/
public UriComponents build() {
@ -273,18 +254,17 @@ public class UriComponentsBuilder {
/**
* Builds a {@code UriComponents} instance from the various components
* contained in this builder.
*
* @param encoded whether all the components set in this builder are
* encoded ({@code true}) or not ({@code false}).
* @return the URI components
*/
public UriComponents build(boolean encoded) {
if (ssp != null) {
return new OpaqueUriComponents(scheme, ssp, fragment);
if (this.ssp != null) {
return new OpaqueUriComponents(this.scheme, this.ssp, this.fragment);
}
else {
return new HierarchicalUriComponents(
scheme, userInfo, host, port, pathBuilder.build(), queryParams, fragment, encoded, true);
return new HierarchicalUriComponents(this.scheme, this.userInfo, this.host, this.port,
this.pathBuilder.build(), this.queryParams, this.fragment, encoded, true);
}
}
@ -292,7 +272,6 @@ public class UriComponentsBuilder {
* Builds a {@code UriComponents} instance and replaces URI template variables
* with the values from a map. This is a shortcut method, which combines
* calls to {@link #build()} and then {@link UriComponents#expand(Map)}.
*
* @param uriVariables the map of URI variables
* @return the URI components with expanded values
*/
@ -304,7 +283,6 @@ public class UriComponentsBuilder {
* Builds a {@code UriComponents} instance and replaces URI template variables
* with the values from an array. This is a shortcut method, which combines
* calls to {@link #build()} and then {@link UriComponents#expand(Object...)}.
*
* @param uriVariableValues URI variable values
* @return the URI components with expanded values
*/
@ -312,19 +290,17 @@ public class UriComponentsBuilder {
return build(false).expand(uriVariableValues);
}
// URI components methods
/**
* Initializes all components of this URI builder with the components of the given URI.
*
* @param uri the URI
* @return this UriComponentsBuilder
*/
public UriComponentsBuilder uri(URI uri) {
Assert.notNull(uri, "'uri' must not be null");
this.scheme = uri.getScheme();
if (uri.isOpaque()) {
this.ssp = uri.getRawSchemeSpecificPart();
resetHierarchicalComponents();
@ -369,9 +345,7 @@ public class UriComponentsBuilder {
/**
* Sets the URI scheme. The given scheme may contain URI template variables,
* and may also be {@code null} to clear the scheme of this builder.
*
* @param scheme
* the URI scheme
* @param scheme the URI scheme
* @return this UriComponentsBuilder
*/
public UriComponentsBuilder scheme(String scheme) {
@ -384,7 +358,6 @@ public class UriComponentsBuilder {
* {@linkplain #userInfo(String) user-info}, {@linkplain #host(String) host},
* {@linkplain #port(int) port}, {@linkplain #path(String) path}, and
* {@link #query(String) query}.
*
* @param ssp the URI scheme-specific-part, may contain URI template parameters
* @return this UriComponentsBuilder
*/
@ -398,7 +371,6 @@ public class UriComponentsBuilder {
* Sets the URI user info. The given user info may contain URI template
* variables, and may also be {@code null} to clear the user info of this
* builder.
*
* @param userInfo the URI user info
* @return this UriComponentsBuilder
*/
@ -411,7 +383,6 @@ public class UriComponentsBuilder {
/**
* Sets the URI host. The given host may contain URI template variables, and
* may also be {@code null} to clear the host of this builder.
*
* @param host the URI host
* @return this UriComponentsBuilder
*/
@ -423,7 +394,6 @@ public class UriComponentsBuilder {
/**
* Sets the URI port. Passing {@code -1} will clear the port of this builder.
*
* @param port the URI port
* @return this UriComponentsBuilder
*/
@ -437,7 +407,6 @@ public class UriComponentsBuilder {
/**
* Appends the given path to the existing path of this builder. The given
* path may contain URI template variables.
*
* @param path the URI path
* @return this UriComponentsBuilder
*/
@ -449,7 +418,6 @@ public class UriComponentsBuilder {
/**
* Sets the path of this builder overriding all existing path and path segment values.
*
* @param path the URI path; a {@code null} value results in an empty path.
* @return this UriComponentsBuilder
*/
@ -462,7 +430,6 @@ 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 pathSegments the URI path segments
* @return this UriComponentsBuilder
*/
@ -476,18 +443,15 @@ public class UriComponentsBuilder {
/**
* Appends the given query to the existing query of this builder.
* The given query may contain URI template variables.
*
* <p><strong>Note:</strong> The presence of reserved characters can prevent
* correct parsing of the URI string. For example if a query parameter
* contains {@code '='} or {@code '&'} characters, the query string cannot
* be parsed unambiguously. Such values should be substituted for URI
* variables to enable correct parsing:
*
* <pre>
* String uriString = &quot;/hotels/42?filter={value}&quot;;
* UriComponentsBuilder.fromUriString(uriString).buildAndExpand(&quot;hot&amp;cold&quot;);
* </pre>
*
* @param query the query string
* @return this UriComponentsBuilder
*/
@ -511,7 +475,6 @@ public class UriComponentsBuilder {
/**
* Sets the query of this builder overriding all existing query parameters.
*
* @param query the query string; a {@code null} value removes all query parameters.
* @return this UriComponentsBuilder
*/
@ -527,11 +490,8 @@ public class UriComponentsBuilder {
* given name or any of the values may contain URI template variables. If no
* values are given, the resulting URI will contain the query parameter name
* only (i.e. {@code ?foo} instead of {@code ?foo=bar}.
*
* @param name
* the query parameter name
* @param values
* the query parameter values
* @param name the query parameter name
* @param values the query parameter values
* @return this UriComponentsBuilder
*/
public UriComponentsBuilder queryParam(String name, Object... values) {
@ -553,11 +513,8 @@ public class UriComponentsBuilder {
* Sets the query parameter values overriding all existing query values for
* the same parameter. If no values are given, the query parameter is
* removed.
*
* @param name
* the query parameter name
* @param values
* the query parameter values
* @param name the query parameter name
* @param values the query parameter values
* @return this UriComponentsBuilder
*/
public UriComponentsBuilder replaceQueryParam(String name, Object... values) {
@ -574,9 +531,7 @@ public class UriComponentsBuilder {
* Sets the URI fragment. The given fragment may contain URI template
* variables, and may also be {@code null} to clear the fragment of this
* builder.
*
* @param fragment
* the URI fragment
* @param fragment the URI fragment
* @return this UriComponentsBuilder
*/
public UriComponentsBuilder fragment(String fragment) {
@ -592,12 +547,14 @@ public class UriComponentsBuilder {
private interface PathComponentBuilder {
PathComponent build();
}
private static class CompositePathComponentBuilder implements PathComponentBuilder {
private LinkedList<PathComponentBuilder> componentBuilders = new LinkedList<PathComponentBuilder>();
private final LinkedList<PathComponentBuilder> componentBuilders = new LinkedList<PathComponentBuilder>();
public CompositePathComponentBuilder() {
}
@ -650,8 +607,8 @@ public class UriComponentsBuilder {
public PathComponent build() {
int size = this.componentBuilders.size();
List<PathComponent> components = new ArrayList<PathComponent>(size);
for (int i = 0; i < size; i++) {
PathComponent pathComponent = this.componentBuilders.get(i).build();
for (PathComponentBuilder componentBuilder : this.componentBuilders) {
PathComponent pathComponent = componentBuilder.build();
if (pathComponent != null) {
components.add(pathComponent);
}
@ -666,9 +623,10 @@ public class UriComponentsBuilder {
}
}
private static class FullPathComponentBuilder implements PathComponentBuilder {
private StringBuilder path = new StringBuilder();
private final StringBuilder path = new StringBuilder();
public void append(String path) {
this.path.append(path);
@ -690,9 +648,10 @@ public class UriComponentsBuilder {
}
}
private static class PathSegmentComponentBuilder implements PathComponentBuilder {
private List<String> pathSegments = new LinkedList<String>();
private final List<String> pathSegments = new LinkedList<String>();
public void append(String... pathSegments) {
for (String pathSegment : pathSegments) {
@ -703,8 +662,8 @@ public class UriComponentsBuilder {
}
public PathComponent build() {
return this.pathSegments.isEmpty() ?
null : new HierarchicalUriComponents.PathSegmentComponent(this.pathSegments);
return (this.pathSegments.isEmpty() ? null :
new HierarchicalUriComponents.PathSegmentComponent(this.pathSegments));
}
}