in wicket-request/src/main/java/org/apache/wicket/request/Url.java [242:387]
public static Url parse(CharSequence _url, Charset charset, boolean isFullHint)
{
Args.notNull(_url, "_url");
final Url result = new Url(charset);
// the url object resolved the charset, use that
charset = result.getCharset();
String url = _url.toString();
// extract query string part
final String queryString;
final String absoluteUrl;
final int fragmentAt = url.indexOf('#');
// matches url fragment, but doesn't match optional path parameter (e.g. .../#{optional}/...)
if (fragmentAt > -1 && url.length() > fragmentAt + 1 && url.charAt(fragmentAt + 1) != '{')
{
result.fragment = url.substring(fragmentAt + 1);
url = url.substring(0, fragmentAt);
}
final int queryAt = url.indexOf('?');
if (queryAt == -1)
{
queryString = "";
absoluteUrl = url;
}
else
{
absoluteUrl = url.substring(0, queryAt);
queryString = url.substring(queryAt + 1);
}
// get absolute / relative part of url
String relativeUrl;
final int idxOfFirstSlash = absoluteUrl.indexOf('/');
final int protocolAt = absoluteUrl.indexOf("://");
// full urls start either with a "scheme://" or with "//"
boolean protocolLess = absoluteUrl.startsWith("//");
final boolean isFull = (protocolAt > 1 && (protocolAt < idxOfFirstSlash)) || protocolLess;
if (isFull && isFullHint)
{
result.shouldRenderAsFull = true;
if (protocolLess == false)
{
result.protocol = absoluteUrl.substring(0, protocolAt).toLowerCase(Locale.US);
}
final String afterProto = absoluteUrl.substring(protocolAt + 3);
final String hostAndPort;
int relativeAt = afterProto.indexOf('/');
if (relativeAt == -1)
{
relativeAt = afterProto.indexOf(';');
}
if (relativeAt == -1)
{
relativeUrl = "";
hostAndPort = afterProto;
}
else
{
relativeUrl = afterProto.substring(relativeAt);
hostAndPort = afterProto.substring(0, relativeAt);
}
final int credentialsAt = hostAndPort.lastIndexOf('@') + 1;
//square brackets are used for ip6 URLs
final int closeSqrBracketAt = hostAndPort.lastIndexOf(']') + 1;
final int portAt = hostAndPort.substring(credentialsAt)
.substring(closeSqrBracketAt)
.lastIndexOf(':');
if (portAt == -1)
{
result.host = hostAndPort;
result.port = getDefaultPortForProtocol(result.protocol);
}
else
{
final int portOffset = portAt + credentialsAt + closeSqrBracketAt;
result.host = hostAndPort.substring(0, portOffset);
result.port = Integer.parseInt(hostAndPort.substring(portOffset + 1));
}
if (relativeAt < 0)
{
relativeUrl = "/";
}
}
else
{
relativeUrl = absoluteUrl;
}
if (relativeUrl.length() > 0)
{
boolean removeLast = false;
if (relativeUrl.endsWith("/"))
{
// we need to append something and remove it after splitting
// because otherwise the
// trailing slashes will be lost
relativeUrl += "/x";
removeLast = true;
}
String segmentArray[] = Strings.split(relativeUrl, '/');
if (removeLast)
{
segmentArray[segmentArray.length - 1] = null;
}
for (String s : segmentArray)
{
if (s != null)
{
result.segments.add(decodeSegment(s, charset));
}
}
}
if (queryString.length() > 0)
{
String queryArray[] = Strings.split(queryString, '&');
for (String s : queryArray)
{
if (Strings.isEmpty(s) == false)
{
result.parameters.add(parseQueryParameter(s, charset));
}
}
}
return result;
}