Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -158,60 +158,133 @@ static Immutable from(String scheme, String host, int port, String path, String
return new Immutable(scheme, host, port, path, query, fragment, false);
}

/**
* @return An immutable copy of this URI.
*/
Immutable asImmutable();

/**
* @return The URI as a string.
*/
String asString();

/**
* @return The authority component of the URI in the form {@code host:port},
* or just {@code host} if the port is not set, or {@code null} if no host is set.
*/
String getAuthority();

/**
* @return The decoded path with percent-encoded characters expanded, or {@code null} if no path is set.
* @see #getCanonicalPath()
*/
String getDecodedPath();

/**
* @return The canonical path with path parameters removed and percent-encoded characters decoded,
* or {@code null} if no path is set.
* @see #getDecodedPath()
* @see #getPath()
*/
String getCanonicalPath();

/**
* @return The fragment component of the URI (after the {@code #} character), or {@code null} if not set.
*/
String getFragment();

/**
* @return The host component of the URI, or {@code null} if not set.
*/
String getHost();

/**
* Get a URI path parameter. Only parameters from the last segment are returned.
* @return The last path parameter or null
* <p>Get a URI path parameter.</p>
* <p>Path parameters were defined in
* <a href="https://www.rfc-editor.org/rfc/rfc2068">RFC 2068</a> and appear
* after a semicolon in the path, such as {@code /path;param}. This is distinct from
* query parameters which appear after the {@code ?} character.</p>
* @return The last path parameter, or {@code null} if no path parameter is present.
* If there are multiple path parameters, only the last one is returned.
* @see #getQuery()
*/
String getParam();

/**
* @return The raw path component of the URI including path parameters, or {@code null} if not set.
* @see #getCanonicalPath()
* @see #getDecodedPath()
*/
String getPath();

/**
* @return The path and query components combined as {@code path?query},
* or just the path if no query is present, or {@code null} if no path is set.
*/
String getPathQuery();

/**
* @return The port number of the URI, or {@code -1} if not set.
*/
int getPort();

/**
* @return The query string component of the URI (after the {@code ?} character
* but before any {@code #} fragment), or {@code null} if not set.
* @see #getParam()
*/
String getQuery();

/**
* @return The URI scheme such as {@code http} or {@code https}, or {@code null} if not set.
*/
String getScheme();

/**
* @return The user info component of the URI authority (before the {@code @} character),
* or {@code null} if not set.
*/
String getUser();

/**
* @return {@code true} if the URI has a host component.
*/
boolean hasAuthority();

/**
* @return {@code true} if the URI has a scheme component.
*/
boolean isAbsolute();

/**
* @return True if the URI has any ambiguous {@link Violation}s.
* <p>Checks if the URI contains any ambiguous path violations that could be
* interpreted differently by different URI parsers.</p>
* @return {@code true} if the URI has any ambiguous {@link Violation}s.
* @see #hasViolations()
* @see UriCompliance#isAmbiguous(Set)
*/
boolean isAmbiguous();

/**
* @return True if the URI has any {@link Violation}s.
* <p>Checks if the URI has any compliance violations against the URI specification
* or best practices.</p>
* @return {@code true} if the URI has any {@link Violation}s.
* @see #getViolations()
* @see #isAmbiguous()
*/
boolean hasViolations();

/**
* @param violation the violation to check.
* @return true if the URI has the passed violation.
* @param violation The violation to check.
* @return {@code true} if the URI has the specified violation.
* @see #getViolations()
*/
boolean hasViolation(Violation violation);

/**
* @return Set of violations in the URI.
* @return The set of {@link Violation}s detected in the URI, or an empty set if none.
* @see #hasViolations()
* @see #hasViolation(Violation)
*/
Collection<Violation> getViolations();

Expand Down Expand Up @@ -804,6 +877,10 @@ private boolean isPathValidForAuthority(String path)
return path.startsWith("/");
}

/**
* Clears all URI components, resetting this mutable to an empty state.
* @return this mutable for chaining.
*/
public Mutable clear()
{
_scheme = null;
Expand All @@ -822,6 +899,11 @@ public Mutable clear()
return this;
}

/**
* Sets the path from a decoded (non-percent-encoded) string.
* @param path The decoded path to set.
* @return this mutable for chaining.
*/
public Mutable decodedPath(String path)
{
_uri = null;
Expand All @@ -840,6 +922,10 @@ public boolean equals(Object o)
return asString().equals(((HttpURI)o).asString());
}

/**
* @param fragment The fragment to set.
* @return this mutable for chaining.
*/
public Mutable fragment(String fragment)
{
_fragment = fragment;
Expand Down Expand Up @@ -935,6 +1021,11 @@ public int hashCode()
return asString().hashCode();
}

/**
* @param host The host to set.
* @return this mutable for chaining.
* @throws IllegalArgumentException if a relative path is set with an authority.
*/
public Mutable host(String host)
{
if (host != null && !isPathValidForAuthority(_path))
Expand Down Expand Up @@ -974,6 +1065,10 @@ public Collection<Violation> getViolations()
return _violations == null ? Collections.emptySet() : Collections.unmodifiableCollection(_violations);
}

/**
* Normalizes the URI by removing the default port if it matches the scheme's default port.
* @return this mutable for chaining.
*/
public Mutable normalize()
{
HttpScheme scheme = _scheme == null ? null : HttpScheme.CACHE.get(_scheme);
Expand All @@ -985,6 +1080,11 @@ public Mutable normalize()
return this;
}

/**
* Sets the path parameter, appending it to the path after a semicolon.
* @param param The path parameter to set.
* @return this mutable for chaining.
*/
public Mutable param(String param)
{
_param = param;
Expand Down Expand Up @@ -1035,6 +1135,12 @@ public Mutable path(String path)
return this;
}

/**
* Sets the path and query from a combined string in the form {@code path?query}.
* @param pathQuery The path and query string to set.
* @return this mutable for chaining.
* @throws IllegalArgumentException if a relative path is set with an authority.
*/
public Mutable pathQuery(String pathQuery)
{
if (hasAuthority() && !isPathValidForAuthority(pathQuery))
Expand All @@ -1052,25 +1158,41 @@ public Mutable pathQuery(String pathQuery)
return this;
}

/**
* @param port The port to set, or {@code -1} to clear the port.
* @return this mutable for chaining.
*/
public Mutable port(int port)
{
_port = (port > 0) ? port : URIUtil.UNDEFINED_PORT;
_uri = null;
return this;
}

/**
* @param query The query string to set.
* @return this mutable for chaining.
*/
public Mutable query(String query)
{
_query = query;
_uri = null;
return this;
}

/**
* @param scheme The {@link HttpScheme} to set.
* @return this mutable for chaining.
*/
public Mutable scheme(HttpScheme scheme)
{
return scheme(scheme.asString());
}

/**
* @param scheme The scheme to set, which will be normalized to lower-case.
* @return this mutable for chaining.
*/
public Mutable scheme(String scheme)
{
_scheme = URIUtil.normalizeScheme(scheme);
Expand All @@ -1084,6 +1206,11 @@ public String toString()
return asString();
}

/**
* Sets all URI components from another {@link HttpURI}.
* @param uri The URI to copy components from.
* @return this mutable for chaining.
*/
public Mutable uri(HttpURI uri)
{
_scheme = uri.getScheme();
Expand All @@ -1101,6 +1228,11 @@ public Mutable uri(HttpURI uri)
return this;
}

/**
* Parses and sets all URI components from a string.
* @param uri The URI string to parse.
* @return this mutable for chaining.
*/
public Mutable uri(String uri)
{
clear();
Expand All @@ -1109,6 +1241,12 @@ public Mutable uri(String uri)
return this;
}

/**
* Parses and sets URI components from a string, handling HTTP method-specific parsing.
* @param method The HTTP method, which affects parsing for CONNECT requests.
* @param uri The URI string to parse.
* @return this mutable for chaining.
*/
public Mutable uri(String method, String uri)
{
if (HttpMethod.CONNECT.is(method))
Expand All @@ -1129,6 +1267,13 @@ else if (uri.startsWith("/"))
return this;
}

/**
* Parses and sets all URI components from a substring.
* @param uri The string containing the URI.
* @param offset The offset within the string where the URI starts.
* @param length The length of the URI substring.
* @return this mutable for chaining.
*/
public Mutable uri(String uri, int offset, int length)
{
clear();
Expand All @@ -1138,6 +1283,11 @@ public Mutable uri(String uri, int offset, int length)
return this;
}

/**
* Sets the user info component of the URI authority.
* @param user The user info to set, or {@code null} to clear it.
* @return this mutable for chaining.
*/
public Mutable user(String user)
{
_user = user;
Expand Down