@ -39,6 +39,7 @@ import org.springframework.util.StringUtils;
@@ -39,6 +39,7 @@ import org.springframework.util.StringUtils;
* Extension of { @link UriComponents } for hierarchical URIs .
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @author Phillip Webb
* @since 3 . 1 . 3
* @see < a href = "http://tools.ietf.org/html/rfc3986#section-1.2.3" > Hierarchical URIs < / a >
@ -73,8 +74,9 @@ final class HierarchicalUriComponents extends UriComponents {
@@ -73,8 +74,9 @@ 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 , String port , PathComponent path ,
MultiValueMap < String , String > queryParams , String fragment , boolean encoded , boolean verify ) {
HierarchicalUriComponents ( String scheme , String userInfo , String host , String port ,
PathComponent path , MultiValueMap < String , String > queryParams ,
String fragment , boolean encoded , boolean verify ) {
super ( scheme , fragment ) ;
this . userInfo = userInfo ;
@ -175,41 +177,44 @@ final class HierarchicalUriComponents extends UriComponents {
@@ -175,41 +177,44 @@ final class HierarchicalUriComponents extends UriComponents {
// encoding
/ * *
* Encodes all URI components using their specific encoding rules , and returns the result as a new
* { @code UriComponents } instance .
* Encode all URI components using their specific encoding rules and return
* 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 ;
}
String encodedScheme = encodeUriComponent ( getScheme ( ) , encoding , Type . SCHEME ) ;
String encodedUserInfo = encodeUriComponent ( this . userInfo , encoding , Type . USER_INFO ) ;
String encodedHost = encodeUriComponent ( this . host , encoding , getHostType ( ) ) ;
Assert . hasLength ( encoding , "Encoding must not be empty" ) ;
String schemeTo = encodeUriComponent ( getScheme ( ) , encoding , Type . SCHEME ) ;
String userInfoTo = encodeUriComponent ( this . userInfo , encoding , Type . USER_INFO ) ;
String hostTo = encodeUriComponent ( this . host , encoding , getHostType ( ) ) ;
PathComponent pathTo = this . path . encode ( encoding ) ;
MultiValueMap < String , String > paramsTo = encodeQueryParams ( encoding ) ;
String fragmentTo = encodeUriComponent ( this . getFragment ( ) , encoding , Type . FRAGMENT ) ;
return new HierarchicalUriComponents ( schemeTo , userInfoTo , hostTo , this . port ,
pathTo , paramsTo , fragmentTo , true , false ) ;
}
PathComponent encodedPath = this . path . encode ( encoding ) ;
MultiValueMap < String , String > encodedQueryParams =
new LinkedMultiValueMap < String , String > ( this . queryParams . size ( ) ) ;
private MultiValueMap < String , String > encodeQueryParams ( String encoding ) throws UnsupportedEncodingException {
int size = this . queryParams . size ( ) ;
MultiValueMap < String , String > result = new LinkedMultiValueMap < String , String > ( size ) ;
for ( Map . Entry < String , List < String > > entry : this . queryParams . entrySet ( ) ) {
String encodedName = encodeUriComponent ( entry . getKey ( ) , encoding , Type . QUERY_PARAM ) ;
List < String > encodedValues = new ArrayList < String > ( entry . getValue ( ) . size ( ) ) ;
String name = encodeUriComponent ( entry . getKey ( ) , encoding , Type . QUERY_PARAM ) ;
List < String > v alues = new ArrayList < String > ( entry . getValue ( ) . size ( ) ) ;
for ( String value : entry . getValue ( ) ) {
String encodedValue = encodeUriComponent ( value , encoding , Type . QUERY_PARAM ) ;
encodedValues . add ( encodedValue ) ;
values . add ( encodeUriComponent ( value , encoding , Type . QUERY_PARAM ) ) ;
}
encodedQueryParams . put ( e ncodedN ame, encodedV alues) ;
result . put ( name , v alues) ;
}
String encodedFragment = encodeUriComponent ( this . getFragment ( ) , encoding , Type . FRAGMENT ) ;
return new HierarchicalUriComponents ( encodedScheme , encodedUserInfo , encodedHost , this . port , encodedPath ,
encodedQueryParams , encodedFragment , true , false ) ;
return result ;
}
/ * *
* Encodes the given source into an encoded String using the rules specified
* Encode 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
@ -217,7 +222,9 @@ final class HierarchicalUriComponents extends UriComponents {
@@ -217,7 +222,9 @@ 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 ;
}
@ -291,17 +298,19 @@ final class HierarchicalUriComponents extends UriComponents {
@@ -291,17 +298,19 @@ final class HierarchicalUriComponents extends UriComponents {
int u = Character . digit ( hex1 , 16 ) ;
int l = Character . digit ( hex2 , 16 ) ;
if ( u = = - 1 | | l = = - 1 ) {
throw new IllegalArgumentException ( "Invalid encoded sequence \"" + source . substring ( i ) + "\"" ) ;
throw new IllegalArgumentException ( "Invalid encoded sequence \"" +
source . substring ( i ) + "\"" ) ;
}
i + = 2 ;
}
else {
throw new IllegalArgumentException ( "Invalid encoded sequence \"" + source . substring ( i ) + "\"" ) ;
throw new IllegalArgumentException ( "Invalid encoded sequence \"" +
source . substring ( i ) + "\"" ) ;
}
}
else if ( ! type . isAllowed ( ch ) ) {
throw new IllegalArgumentException (
"Invalid character '" + ch + "' for " + type . name ( ) + " in \"" + source + "\"" ) ;
throw new IllegalArgumentException ( "Invalid character '" + ch + "' for " +
type . name ( ) + " in \"" + source + "\"" ) ;
}
}
}
@ -312,25 +321,31 @@ final class HierarchicalUriComponents extends UriComponents {
@@ -312,25 +321,31 @@ final class HierarchicalUriComponents extends UriComponents {
@Override
protected HierarchicalUriComponents expandInternal ( UriTemplateVariables uriVariables ) {
Assert . state ( ! this . encoded , "Cannot expand an already encoded UriComponents object" ) ;
String expandedScheme = expandUriComponent ( getScheme ( ) , uriVariables ) ;
String expandedUserInfo = expandUriComponent ( this . userInfo , uriVariables ) ;
String expandedHost = expandUriComponent ( this . host , uriVariables ) ;
String expandedPort = expandUriComponent ( this . port , uriVariables ) ;
PathComponent expandedPath = this . path . expand ( uriVariables ) ;
MultiValueMap < String , String > expandedQueryParams =
new LinkedMultiValueMap < String , String > ( this . queryParams . size ( ) ) ;
String schemeTo = expandUriComponent ( getScheme ( ) , uriVariables ) ;
String userInfoTo = expandUriComponent ( this . userInfo , uriVariables ) ;
String hostTo = expandUriComponent ( this . host , uriVariables ) ;
String portTo = expandUriComponent ( this . port , uriVariables ) ;
PathComponent pathTo = this . path . expand ( uriVariables ) ;
MultiValueMap < String , String > paramsTo = expandQueryParams ( uriVariables ) ;
String fragmentTo = expandUriComponent ( this . getFragment ( ) , uriVariables ) ;
return new HierarchicalUriComponents ( schemeTo , userInfoTo , hostTo , portTo ,
pathTo , paramsTo , fragmentTo , false , false ) ;
}
private MultiValueMap < String , String > expandQueryParams ( UriTemplateVariables variables ) {
int size = this . queryParams . size ( ) ;
MultiValueMap < String , String > result = new LinkedMultiValueMap < String , String > ( size ) ;
for ( Map . Entry < String , List < String > > entry : this . queryParams . entrySet ( ) ) {
String expandedName = expandUriComponent ( entry . getKey ( ) , uriVariables ) ;
List < String > expandedValues = new ArrayList < String > ( entry . getValue ( ) . size ( ) ) ;
String name = expandUriComponent ( entry . getKey ( ) , v ariables) ;
List < String > v alues = new ArrayList < String > ( entry . getValue ( ) . size ( ) ) ;
for ( String value : entry . getValue ( ) ) {
String expandedValue = expandUriComponent ( value , uriVariables ) ;
expandedValues . add ( expandedValue ) ;
values . add ( expandUriComponent ( value , variables ) ) ;
}
expandedQueryParams . put ( expandedName , expandedValues ) ;
result . put ( name , v alues) ;
}
String expandedFragment = expandUriComponent ( this . getFragment ( ) , uriVariables ) ;
return new HierarchicalUriComponents ( expandedScheme , expandedUserInfo , expandedHost , expandedPort , expandedPath ,
expandedQueryParams , expandedFragment , false , false ) ;
return result ;
}
/ * *
@ -468,7 +483,7 @@ final class HierarchicalUriComponents extends UriComponents {
@@ -468,7 +483,7 @@ final class HierarchicalUriComponents extends UriComponents {
* < p > Contains methods to indicate whether a given character is valid in a specific URI component .
* @see < a href = "http://www.ietf.org/rfc/rfc3986.txt" > RFC 3986 < / a >
* /
static enum Type {
enum Type {
SCHEME {
@Override