📄 uri.java
字号:
public URI( String scheme, String userinfo, String host, int port,
String path, String queryString, String fragment )
throws MalformedURIException
{
if ( scheme == null || scheme.trim().length() == 0 )
throw new MalformedURIException( "Argument scheme is null or an empty string" );
if ( host == null ) {
if ( userinfo != null )
throw new MalformedURIException( "Argument userInfo must be null if host is null" );
if ( port != -1 )
throw new MalformedURIException( "Argument port must be null if host is null" );
} else if ( host.trim().length() == 0 )
throw new IllegalArgumentException( "Argument host is an empty string" );
if ( path != null ) {
if ( path.indexOf('?') != -1 && queryString != null )
throw new MalformedURIException( "Argument queryString is illegal if path includes query string" );
if ( path.indexOf('#') != -1 && fragment != null )
throw new MalformedURIException( "Argument fragment is illegal if path includes fragment identifier" );
} else if ( path.trim().length() == 0 )
throw new IllegalArgumentException( "Argument path is an empty string" );
setScheme( scheme );
setHost( host );
setPort( port );
setUserinfo( userinfo );
setPath( path );
setQueryString( queryString );
setFragment( fragment );
}
/**
* Initialize all fields of this URI from another URI.
*
* @param other the URI to copy (cannot be null)
*/
private void initialize( URI other )
{
_scheme = other.getScheme();
_userinfo = other.getUserinfo();
_host = other.getHost();
_port = other.getPort();
_path = other.getPath();
_queryString = other.getQueryString();
_fragment = other.getFragment();
}
/**
* Initializes this URI from a base URI and a URI specification string.
* See RFC 2396 Section 4 and Appendix B for specifications on parsing
* the URI and Section 5 for specifications on resolving relative URIs
* and relative paths.
*
* @param base the base URI (may be null if uriSpec is an absolute URI)
* @param uriSpec the URI spec string which may be an absolute or
* relative URI (can only be null/empty if base is not null)
* @throws MalformedURIException base is null and uriSpec is not an
* absolute URI or uriSpec violates syntax rules
*/
private void initialize( URI base, String uriSpec )
throws MalformedURIException
{
int uriSpecLen;
int index;
int startPos;
char testChar;
if ( base == null && ( uriSpec == null || uriSpec.trim().length() == 0) )
throw new MalformedURIException( "Argument base is null and argument uriSpec is null or an empty string" );
// just make a copy of the base if spec is empty
if ( uriSpec == null || uriSpec.trim().length() == 0 ) {
initialize( base );
return;
}
uriSpec = uriSpec.trim();
uriSpecLen = uriSpec.length();
index = 0;
// check for scheme
if ( uriSpec.indexOf( ':' ) == -1 ) {
if ( base == null )
throw new MalformedURIException( "No scheme found in URI." );
} else {
initializeScheme( uriSpec );
index = _scheme.length() + 1;
}
// two slashes means generic URI syntax, so we get the authority
if ( ( index + 1 < uriSpecLen ) && ( uriSpec.substring( index ).startsWith( "//" ) ) ) {
index += 2;
startPos = index;
// get authority - everything up to path, query or fragment
testChar = '\0';
while ( index < uriSpecLen ) {
testChar = uriSpec.charAt( index );
if ( testChar == '/' || testChar == '?' || testChar == '#' )
break;
index++;
}
// if we found authority, parse it out, otherwise we set the
// host to empty string
if ( index > startPos )
initializeAuthority( uriSpec.substring( startPos, index ) );
else
_host = "";
}
initializePath( uriSpec.substring( index ) );
// Resolve relative URI to base URI - see RFC 2396 Section 5.2
// In some cases, it might make more sense to throw an exception
// (when scheme is specified is the string spec and the base URI
// is also specified, for example), but we're just following the
// RFC specifications
if ( base != null ) {
// check to see if this is the current doc - RFC 2396 5.2 #2
// note that this is slightly different from the RFC spec in that
// we don't include the check for query string being null
// - this handles cases where the urispec is just a query
// string or a fragment (e.g. "?y" or "#s") -
// see <http://www.ics.uci.edu/~fielding/url/test1.html> which
// identified this as a bug in the RFC
if ( _path.length() == 0 && _scheme == null && _host == null ) {
_scheme = base.getScheme();
_userinfo = base.getUserinfo();
_host = base.getHost();
_port = base.getPort();
_path = base.getPath();
if ( _queryString == null )
_queryString = base.getQueryString();
return;
}
// check for scheme - RFC 2396 5.2 #3
// if we found a scheme, it means absolute URI, so we're done
if ( _scheme == null )
_scheme = base.getScheme();
else
return;
// check for authority - RFC 2396 5.2 #4
// if we found a host, then we've got a network path, so we're done
if ( _host == null ) {
_userinfo = base.getUserinfo();
_host = base.getHost();
_port = base.getPort();
} else
return;
// check for absolute path - RFC 2396 5.2 #5
if ( _path.length() > 0 && _path.startsWith( "/" ) )
return;
// if we get to this point, we need to resolve relative path
// RFC 2396 5.2 #6
String tmpPath = new String();
String basePath = base.getPath();
// 6a - get all but the last segment of the base URI path
if ( basePath != null ) {
int lastSlash = basePath.lastIndexOf( '/' );
if ( lastSlash != -1 )
tmpPath = basePath.substring( 0, lastSlash + 1 );
}
// 6b - append the relative URI path
tmpPath = tmpPath.concat( tmpPath );
// 6c - remove all "./" where "." is a complete path segment
index = -1;
while ( ( index = tmpPath.indexOf( "/./" ) ) != -1 )
tmpPath = tmpPath.substring( 0, index + 1 ).concat( tmpPath.substring( index + 3 ) );
// 6d - remove "." if path ends with "." as a complete path segment
if ( tmpPath.endsWith("/.") )
tmpPath = tmpPath.substring( 0, tmpPath.length() - 1 );
// 6e - remove all "<segment>/../" where "<segment>" is a complete
// path segment not equal to ".."
index = -1;
int segIndex = -1;
String tempString = null;
while ( ( index = tmpPath.indexOf( "/../" ) ) > 0 ) {
tempString = tmpPath.substring( 0, tmpPath.indexOf( "/../" ) );
segIndex = tempString.lastIndexOf( '/' );
if ( segIndex != -1 )
if ( !tempString.substring( segIndex++ ).equals( ".." ) )
tmpPath = tmpPath.substring( 0, segIndex ).concat( tmpPath.substring( index + 4 ) );
}
// 6f - remove ending "<segment>/.." where "<segment>" is a
// complete path segment
if ( tmpPath.endsWith( "/.." ) ) {
tempString = tmpPath.substring( 0, tmpPath.length() - 3 );
segIndex = tempString.lastIndexOf( '/' );
if ( segIndex != -1 )
tmpPath = tmpPath.substring( 0, segIndex + 1 );
}
_path = tmpPath;
}
}
/**
* Initialize the scheme for this URI from a URI string spec.
*
* @param uriSpec the URI specification (cannot be null)
* @throws MalformedURIException URI does not have a conformant scheme
*/
private void initializeScheme( String uriSpec )
throws MalformedURIException
{
int uriSpecLen = uriSpec.length();
int index = 0;
String scheme = null;
char testChar = '\0';
while ( index < uriSpecLen ) {
testChar = uriSpec.charAt( index );
if ( testChar == ':' || testChar == '/' || testChar == '?' || testChar == '#' )
break;
index++;
}
scheme = uriSpec.substring( 0, index );
if ( scheme.length() == 0 )
throw new MalformedURIException( "No scheme found in URI." );
else
setScheme( scheme );
}
/**
* Initialize the authority (userinfo, host and port) for this
* URI from a URI string spec.
*
* @param uriSpec the URI specification (cannot be null)
* @throws MalformedURIException uriSpec violates syntax rules
*/
private void initializeAuthority( String uriSpec )
throws MalformedURIException
{
int index = 0;
int start = 0;
int end = uriSpec.length();
char testChar = '\0';
String userinfo = null;
// userinfo is everything up @
if ( uriSpec.indexOf( '@', start ) != -1 ) {
while ( index < end ) {
testChar = uriSpec.charAt( index );
if ( testChar == '@' )
break;
index++;
}
userinfo = uriSpec.substring( start, index );
index++;
}
// host is everything up to ':'
String host = null;
start = index;
while ( index < end ) {
testChar = uriSpec.charAt( index );
if ( testChar == ':' )
break;
index++;
}
host = uriSpec.substring( start, index );
int port = -1;
if ( host.length() > 0 ) {
// port
if ( testChar == ':' ) {
index++;
start = index;
while ( index < end )
index++;
String portStr = uriSpec.substring( start, index );
if ( portStr.length() > 0 ) {
for ( int i = 0 ; i < portStr.length() ; i++ )
if ( !isDigit( portStr.charAt( i ) ) )
throw new MalformedURIException( portStr + " is invalid. Port should only contain digits!" );
try {
port = Integer.parseInt( portStr );
} catch ( NumberFormatException nfe ) {
// can't happen
}
}
}
}
setHost( host );
setPort( port );
setUserinfo( userinfo );
}
/**
* Initialize the path for this URI from a URI string spec.
*
* @param uriSpec the URI specification (cannot be null)
* @throws MalformedURIException uriSpec violates syntax rules
*/
private void initializePath( String uriSpec )
throws MalformedURIException
{
if ( uriSpec == null )
throw new MalformedURIException( "Argument uriSpec is null" );
int index = 0;
int start = 0;
int end = uriSpec.length();
char testChar = '\0';
// path - everything up to query string or fragment
while ( index < end ) {
testChar = uriSpec.charAt( index );
if ( testChar == '?' || testChar == '#' )
break;
// check for valid escape sequence
if ( testChar == '%' ) {
if ( index + 2 >= end || ! isHex( uriSpec.charAt( index + 1 ) ) ||
! isHex( uriSpec.charAt( index + 2 ) ) )
throw new MalformedURIException( "Path contains invalid escape sequence!" );
} else if ( ! isReservedCharacter( testChar ) &&
! isUnreservedCharacter( testChar ) ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -