Polished UriComponents implementation
(cherry picked from commit c3b624d
)
This commit is contained in:
parent
e3fa49063e
commit
b2bd319d47
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = "/hotels/42?filter={value}";
|
||||
* UriComponentsBuilder.fromUriString(uriString).buildAndExpand("hot&cold");
|
||||
* </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 = "/hotels/42?filter={value}";
|
||||
* UriComponentsBuilder.fromUriString(uriString).buildAndExpand("hot&cold");
|
||||
* </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 = "/hotels/42?filter={value}";
|
||||
* UriComponentsBuilder.fromUriString(uriString).buildAndExpand("hot&cold");
|
||||
* </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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue