org.refcodes.web.Url Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-web Show documentation
Show all versions of refcodes-web Show documentation
This artifact provides web (HTTP) related definitions and types being used
by REFCODES.ORG web related functionality and artifacts.
The newest version!
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// /////////////////////////////////////////////////////////////////////////////
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// -----------------------------------------------------------------------------
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// -----------------------------------------------------------------------------
// Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0")
// -----------------------------------------------------------------------------
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////
package org.refcodes.web;
import java.net.MalformedURLException;
import java.net.URL;
import org.refcodes.data.Delimiter;
import org.refcodes.data.Scheme;
import org.refcodes.mixin.CredentialsAccessor;
import org.refcodes.mixin.Dumpable;
import org.refcodes.mixin.PathAccessor;
import org.refcodes.mixin.PortAccessor;
import org.refcodes.net.IpAddress;
import org.refcodes.net.IpAddressAccessor;
/**
* The {@link Url} class represents an immutable URL: An URL looks something
* like this:
*
* "scheme://[identity[:secret]@]host[:port][/path][?query][#fragment] In
* contrast to the java.net
{@link URL}, this URL also supports
* "relative" locators with neither a scheme nor a host declaration. If the
* relative locator starts with a "/" slash, then we assume not having a host
* being provided: "/path?query#fragment" When it does *not* start with a "/"
* slash, then we assume that the first element being the host:
* "[identity[:secret]@]host[:port]/path[?query][#fragment]"
*/
public class Url implements Dumpable, SchemeAccessor, HostAccessor, IpAddressAccessor, PortAccessor, PathAccessor, QueryFieldsAccessor, FragmentAccessor, CredentialsAccessor {
// /////////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////////
protected Scheme _scheme = null;
protected String _protocol = null;
protected String _host = null;
protected int[] _ipAddress = null;
protected String _path = null;
protected int _port = -1;
protected FormFields _queryFields = null;
protected String _identity = null;
protected String _secret = null;
protected String _fragment = null;
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
/**
* Default constructor. Make sure to set required attributes for a valid
* URL.
*/
protected Url() {}
/**
* Creates an {@link Url} from the provided {@link Url}.
*
* @param aUrl The {@link Url} from which to construct this instance.
*/
public Url( Url aUrl ) {
_scheme = aUrl.getScheme();
if ( _scheme == null ) {
_protocol = aUrl.toProtocol();
}
_host = aUrl.getHost();
_ipAddress = aUrl.getIpAddress();
setPath( aUrl.getPath() );
_port = aUrl.getPort();
_queryFields = new FormFields( aUrl.getQueryFields() );
_identity = aUrl.getIdentity();
_secret = aUrl.getSecret();
_fragment = aUrl.getFragment();
}
/**
* Constructs an {@link Url} from the provided URL {@link String}.
*
* @param aUrl The URL {@link String} to be parsed. The URL consists of the
* scheme (protocol), the identify and the secret (optional), the
* host as well as an optional port and the (optional) path.
*
* @throws MalformedURLException in case the provided URL is considered
* being malformed.
*/
public Url( String aUrl ) throws MalformedURLException {
fromUrl( aUrl );
}
/**
* Constructs an {@link Url} from the provided URL {@link String}.
*
* @param aUrl The URL {@link String} to be parsed. The URL consists of the
* scheme (protocol), the identify and the secret (optional), the
* host as well as an optional port and the (optional) path.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
*
* @throws MalformedURLException in case the provided URL is considered
* being malformed.
*/
public Url( String aUrl, FormFields aQueryFields ) throws MalformedURLException {
fromUrl( aUrl );
_queryFields = aQueryFields;
}
/**
* Constructs an {@link Url} from the provided URL {@link String}.
*
* @param aUrl The URL {@link String} to be parsed. The URL consists of the
* scheme (protocol), the identify and the secret (optional), the
* host as well as an optional port and the (optional) path.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
* @param aFragment The fragment to be set.
*
* @throws MalformedURLException in case the provided URL is considered
* being malformed.
*/
public Url( String aUrl, FormFields aQueryFields, String aFragment ) throws MalformedURLException {
fromUrl( aUrl );
_queryFields = aQueryFields;
_fragment = aFragment;
}
/**
* Constructs an {@link Url} from the provided {@link URL} instance.
*
* @param aURL The {@link URL} to be used.
*/
public Url( URL aURL ) {
fromURL( aURL );
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aScheme The {@link Scheme} (e.g. HTTP or HTTPS) to be used for the
* destination URL.
* @param aHost The host to which the destination URL is to point to.
*/
public Url( Scheme aScheme, String aHost ) {
_scheme = aScheme;
_host = aHost;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aScheme The {@link Scheme} (e.g. HTTP or HTTPS) to be used for the
* destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPort The port to be used when connecting to the host.
*/
public Url( Scheme aScheme, String aHost, int aPort ) {
_scheme = aScheme;
_host = aHost;
_port = aPort;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aScheme The {@link Scheme} (e.g. HTTP or HTTPS) to be used for the
* destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPort The port to be used when connecting to the host.
* @param aPath The path on the host to which the base destination URL is to
* point to.
*/
public Url( Scheme aScheme, String aHost, int aPort, String aPath ) {
_scheme = aScheme;
_host = aHost;
_port = aPort;
setPath( aPath );
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aScheme The {@link Scheme} (e.g. HTTP or HTTPS) to be used for the
* destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPort The port to be used when connecting to the host.
* @param aPath The path on the host to which the base destination URL is to
* point to.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
*/
public Url( Scheme aScheme, String aHost, int aPort, String aPath, FormFields aQueryFields ) {
_scheme = aScheme;
_host = aHost;
_port = aPort;
setPath( aPath );
_queryFields = aQueryFields;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aScheme The {@link Scheme} (e.g. HTTP or HTTPS) to be used for the
* destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPort The port to be used when connecting to the host.
* @param aPath The path on the host to which the base destination URL is to
* point to.
* @param aFragment The fragment to be set.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
*/
public Url( Scheme aScheme, String aHost, int aPort, String aPath, FormFields aQueryFields, String aFragment ) {
_scheme = aScheme;
_host = aHost;
_port = aPort;
setPath( aPath );
_queryFields = aQueryFields;
_fragment = aFragment;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aProtocol The protocol {@link String} (e.g. "http://" or
* "https://") to be used for the destination URL.
* @param aHost The host to which the destination URL is to point to.
*/
public Url( String aProtocol, String aHost ) {
setProtocol( aProtocol );
_host = aHost;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aProtocol The protocol {@link String} (e.g. "http://" or
* "https://") to be used for the destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPort The port to be used when connecting to the host.
*/
public Url( String aProtocol, String aHost, int aPort ) {
setProtocol( aProtocol );
_host = aHost;
_port = aPort;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aProtocol The protocol {@link String} (e.g. "http://" or
* "https://") to be used for the destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPort The port to be used when connecting to the host.
* @param aPath The path on the host to which the base destination URL is to
* point to.
*/
public Url( String aProtocol, String aHost, int aPort, String aPath ) {
setProtocol( aProtocol );
_host = aHost;
_port = aPort;
setPath( aPath );
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aProtocol The protocol {@link String} (e.g. "http://" or
* "https://") to be used for the destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPort The port to be used when connecting to the host.
* @param aPath The path on the host to which the base destination URL is to
* point to.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
*/
public Url( String aProtocol, String aHost, int aPort, String aPath, FormFields aQueryFields ) {
setProtocol( aProtocol );
_host = aHost;
_port = aPort;
setPath( aPath );
_queryFields = aQueryFields;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aProtocol The protocol {@link String} (e.g. "http://" or
* "https://") to be used for the destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPort The port to be used when connecting to the host.
* @param aPath The path on the host to which the base destination URL is to
* point to.
* @param aFragment The fragment to be set.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
*/
public Url( String aProtocol, String aHost, int aPort, String aPath, FormFields aQueryFields, String aFragment ) {
setProtocol( aProtocol );
_host = aHost;
_port = aPort;
setPath( aPath );
_queryFields = aQueryFields;
_fragment = aFragment;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aScheme The {@link Scheme} (e.g. HTTP or HTTPS) to be used for the
* destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPath The path on the host to which the base destination URL is to
* point to.
*/
public Url( Scheme aScheme, String aHost, String aPath ) {
_scheme = aScheme;
_host = aHost;
setPath( aPath );
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aScheme The {@link Scheme} (e.g. HTTP or HTTPS) to be used for the
* destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPath The path on the host to which the base destination URL is to
* point to.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
*/
public Url( Scheme aScheme, String aHost, String aPath, FormFields aQueryFields ) {
_scheme = aScheme;
_host = aHost;
setPath( aPath );
_queryFields = aQueryFields;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aScheme The {@link Scheme} (e.g. HTTP or HTTPS) to be used for the
* destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPath The path on the host to which the base destination URL is to
* point to.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
* @param aFragment The fragment to be set.
*/
public Url( Scheme aScheme, String aHost, String aPath, FormFields aQueryFields, String aFragment ) {
_scheme = aScheme;
_host = aHost;
setPath( aPath );
_queryFields = aQueryFields;
_fragment = aFragment;
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aProtocol The protocol {@link String} (e.g. "http://" or
* "https://") to be used for the destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPath The path on the host to which the base destination URL is to
* point to.
*/
public Url( String aProtocol, String aHost, String aPath ) {
setProtocol( aProtocol );
_host = aHost;
setPath( aPath );
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aProtocol The protocol {@link String} (e.g. "http://" or
* "https://") to be used for the destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPath The path on the host to which the base destination URL is to
* point to.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
*/
public Url( String aProtocol, String aHost, String aPath, FormFields aQueryFields ) {
setProtocol( aProtocol );
_host = aHost;
setPath( aPath );
_queryFields = aQueryFields;
}
/**
* Constructs a new {@link Url} from the given {@link Url} instances by
* adding the other {@link Url}'s data to the first {@link Url}'s data. E.g.
* a path from the other {@link Url} is append to the first {@link Url}'s
* path, the query parameters are added or overwritten accordingly and so
* on.
*
* @param aUrl The {@link Url} which is to be enriched.
* @param aOtherUrl The {@link Url} enriching the given {@link Url}.
*/
public Url( Url aUrl, Url aOtherUrl ) {
this( aUrl != null ? aUrl : aOtherUrl );
if ( aUrl != null ) {
// Scheme |-->
if ( aOtherUrl.getScheme() != null ) {
setScheme( aOtherUrl.getScheme() );
}
else {
if ( aOtherUrl.toProtocol() != null ) {
setProtocol( aOtherUrl.toProtocol() );
}
}
// Scheme <--|
// User Info |-->
if ( aOtherUrl.getIdentity() != null ) {
_identity = aOtherUrl.getIdentity();
}
if ( aOtherUrl.getSecret() != null ) {
_secret = aOtherUrl.getSecret();
}
// User Info <--|
// Host |-->
if ( aOtherUrl.getHost() != null ) {
setHost( aOtherUrl.getHost() );
}
// Host <--|
// Path |-->
String theOtherPath = aOtherUrl.getPath();
if ( theOtherPath != null ) {
String thePath = getPath();
if ( thePath == null ) {
thePath = "";
}
thePath = Url.toTruncatePathSuffix( thePath );
theOtherPath = Url.toTruncatePathPrefix( theOtherPath );
setPath( thePath + Delimiter.PATH.getChar() + theOtherPath );
}
// Path <--|
// Query fields |-->
getQueryFields().putAll( aOtherUrl.getQueryFields() );
// Query fields <--|
// Fragment |-->
if ( aOtherUrl.getFragment() != null ) {
_fragment = aOtherUrl.getFragment();
}
// Fragment <--|
}
}
/**
* Constructs an {@link Url} with the common attributes.
*
* @param aProtocol The protocol {@link String} (e.g. "http://" or
* "https://") to be used for the destination URL.
* @param aHost The host to which the destination URL is to point to.
* @param aPath The path on the host to which the base destination URL is to
* point to.
* @param aQueryFields The Query-Fields to be used for the HTTP
* Query-String.
* @param aFragment The fragment to be set.
*/
public Url( String aProtocol, String aHost, String aPath, FormFields aQueryFields, String aFragment ) {
setProtocol( aProtocol );
_host = aHost;
setPath( aPath );
_queryFields = aQueryFields;
_fragment = aFragment;
}
/**
* Some {@link Url} algebra: Adds the provided path to the given {@link Url}
* by prepending it to the {@link Url}'s path.
*
* @param aUrl The {@link Url} to which to add the path.
* @param aPaths The paths to be added to the given {@link Url}.
*/
public Url( Url aUrl, String... aPaths ) {
this( aUrl );
if ( _path != null && _path.length() != 0 ) {
_path = Url.toTruncatePathSuffix( _path );
}
else {
_path = "" + Delimiter.PATH.getChar();
}
String thePath = "";
for ( String ePath : aPaths ) {
if ( thePath.length() > 0 ) {
thePath = thePath + Delimiter.PATH.getChar();
}
thePath = thePath + Url.toTruncatePath( ePath );
}
_path = _path + Delimiter.PATH.getChar() + thePath;
}
// /////////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@Override
public String getFragment() {
return _fragment;
}
/**
* {@inheritDoc}
*/
@Override
public String getHost() {
// try {
// String theHost = IpAddress.toString( _ipAddress );
// if ( theHost != null && theHost.length() > 0 ) {
// return theHost;
// }
// }
// catch ( IllegalArgumentException e ) {}
return _host;
}
/**
* {@inheritDoc}
*/
@Override
public String getIdentity() {
return _identity;
}
/**
* {@inheritDoc}
*/
@Override
public int[] getIpAddress() {
return _ipAddress;
}
/**
* {@inheritDoc}
*/
@Override
public String getPath() {
return _path;
}
/**
* {@inheritDoc}
*/
@Override
public int getPort() {
return _port;
}
/**
* {@inheritDoc}
*/
@Override
public FormFields getQueryFields() {
if ( _queryFields == null ) {
synchronized ( this ) {
if ( _queryFields == null ) {
_queryFields = new FormFields();
}
}
}
return _queryFields;
}
/**
* {@inheritDoc}
*/
@Override
public Scheme getScheme() {
return _scheme;
}
/**
* {@inheritDoc}
*/
@Override
public String getSecret() {
return _secret;
}
/**
* {@inheritDoc}
*/
@Override
public String toProtocol() {
return _scheme != null ? _scheme.toProtocol() : _protocol;
}
/**
* Returns the "host" depending on whether an IP-Address has been provided
* or a host name.
*
* @return The determined host.
*/
public String toHost() {
final String theHost = getHost();
final String theCidrNotation = toCidrNotation();
if ( theHost != null && theHost.length() > 0 && theCidrNotation != null && theCidrNotation.length() > 0 ) {
throw new IllegalStateException( "Either the or the can be set, but not both of them: Host := <" + theHost + ">, IP-Address = <" + theCidrNotation + ">. Make sure only one ofd them is set!" );
}
return theHost != null ? theHost : theCidrNotation;
}
/**
* Creates the complete "HTTP" URL {@link String} from the {@link Url}
* instance's state.
*
* @return The URL {@link String} for the given {@link Url}.
*/
public String toHttpUrl() {
final StringBuilder theBuilder = new StringBuilder();
// Scheme |-->
final String theScheme = toProtocol();
if ( theScheme != null && theScheme.length() != 0 ) {
theBuilder.append( theScheme );
}
// Scheme <--|
// AuthTypeCredentials |-->
final String theIdentity = getIdentity();
if ( theIdentity != null ) {
theBuilder.append( theIdentity );
if ( getSecret() != null ) {
theBuilder.append( Delimiter.URL_CREDENTIALS.getChar() );
theBuilder.append( getSecret() );
}
theBuilder.append( Delimiter.URL_USER_INFO.getChar() );
}
else {
if ( getSecret() != null ) {
throw new IllegalStateException( "The property requires an property not being null or of an empty length!" );
}
}
// AuthTypeCredentials <--|
// Host |-->
final String theHost = toHost();
if ( theHost != null && theHost.length() != 0 ) {
theBuilder.append( theHost );
// Port |-->
final int thePort = getPort();
if ( thePort != -1 ) {
theBuilder.append( Delimiter.URL_PORT.getChar() );
theBuilder.append( thePort );
}
// Port <--|
}
// Host <--|
// Path |-->
String thePath = getPath();
if ( thePath != null ) {
while ( thePath.length() > 0 && thePath.charAt( 0 ) == Delimiter.PATH.getChar() ) {
thePath = thePath.substring( 1 );
}
if ( !theBuilder.toString().endsWith( "" + Delimiter.PATH.getChar() ) ) {
theBuilder.append( Delimiter.PATH.getChar() );
}
theBuilder.append( thePath );
}
// Path <--|
// Query fields |-->
final FormFields theFields = getQueryFields();
if ( theFields != null && theFields.size() > 0 ) {
final String theQueryString = theFields.toUrlQueryString();
if ( theQueryString != null && theQueryString.length() > 0 ) {
theBuilder.append( theQueryString );
}
}
// Query fields <--|
// Fragment |-->
final String theFragment = getFragment();
if ( theFragment != null && theFragment.length() > 0 ) {
theBuilder.append( Delimiter.URL_FRAGMENT.getChar() );
theBuilder.append( theFragment );
}
// Fragment <--|
return theBuilder.toString();
}
/**
* Creates the locator part from the {@link Url} instance's state, excluding
* the fragment or the query fields.
*
* @return The locator for the given {@link Url}.
*/
public String toLocator() {
final StringBuilder theBuilder = new StringBuilder();
// Scheme |-->
final String theScheme = toProtocol();
if ( theScheme != null && theScheme.length() != 0 ) {
theBuilder.append( theScheme );
}
// Scheme <--|
// AuthTypeCredentials |-->
final String theIdentity = getIdentity();
if ( theIdentity != null ) {
theBuilder.append( theIdentity );
if ( getSecret() != null ) {
theBuilder.append( Delimiter.URL_CREDENTIALS.getChar() );
theBuilder.append( getSecret() );
}
theBuilder.append( Delimiter.URL_USER_INFO.getChar() );
}
else {
if ( getSecret() != null ) {
throw new IllegalStateException( "The property requires an property not being null or of an empty length!" );
}
}
// AuthTypeCredentials <--|
// Host |-->
final String theHost = toHost();
if ( theHost != null && theHost.length() != 0 ) {
theBuilder.append( theHost );
// Host <--|
// Port |-->
final int thePort = getPort();
if ( thePort != -1 ) {
theBuilder.append( Delimiter.URL_PORT.getChar() );
theBuilder.append( thePort );
}
// Port <--|
}
// Path |-->
String thePath = getPath();
if ( thePath != null ) {
while ( thePath.length() > 0 && thePath.charAt( 0 ) == Delimiter.PATH.getChar() ) {
thePath = thePath.substring( 1 );
}
if ( !theBuilder.toString().endsWith( "" + Delimiter.PATH.getChar() ) ) {
theBuilder.append( Delimiter.PATH.getChar() );
}
theBuilder.append( thePath );
}
// Path <--|
return theBuilder.toString();
}
/**
* Constructs an {@link URL} instance from your {@link Url}'s state.
*
* @return The according {@link URL} instance.
*
* @throws MalformedURLException thrown in case the state of your
* {@link Url} instance cannot be used to construct a valid
* {@link URL}, you may be missing some properties.
*/
public URL toURL() throws MalformedURLException {
return new URL( toHttpUrl() );
}
@Override
public String toString() {
return toHttpUrl();
}
// /////////////////////////////////////////////////////////////////////////
// HOOKS:
// /////////////////////////////////////////////////////////////////////////
/**
* Uses the given {@link String} to set the {@link Url}'s state.
*
* @param aUrl The URL from which to determine the state.
*
* @throws MalformedURLException in case the provided URL is considered
* being malformed.
*/
protected void fromUrl( String aUrl ) throws MalformedURLException {
try {
String theUrl = aUrl;
// |--> Scheme
final Scheme theScheme = Scheme.fromScheme( theUrl );
if ( theScheme != null ) {
setScheme( theScheme );
theUrl = theUrl.substring( theScheme.toProtocol().length() );
}
// Scheme <--|
// User-Info |-->
int index = theUrl.indexOf( Delimiter.URL_USER_INFO.getChar() );
if ( index != -1 ) {
final String theUserInfo = theUrl.substring( 0, index );
if ( theUserInfo.length() > 0 ) {
final int i = theUserInfo.indexOf( Delimiter.URL_CREDENTIALS.getChar() );
if ( i == -1 ) {
_identity = theUserInfo;
}
else {
_identity = theUserInfo.substring( 0, i );
_secret = theUserInfo.substring( i + 1 );
}
}
theUrl = theUrl.substring( index + 1 );
}
// User-Info <--|
// Host -->
index = theUrl.indexOf( Delimiter.PATH.getChar() );
if ( index != 0 ) { // we have a host, not a path!
if ( index == -1 ) {
index = theUrl.indexOf( Delimiter.URL_QUERY.getChar() );
if ( index == -1 ) {
index = theUrl.indexOf( Delimiter.URL_FRAGMENT.getChar() );
}
}
if ( index == -1 ) {
setHost( theUrl );
theUrl = null; // done!
}
else {
final String theHost = theUrl.substring( 0, index );
if ( theHost != null && theHost.length() > 0 ) {
final int i = theHost.indexOf( Delimiter.URL_PORT.getChar() );
if ( i == -1 ) {
setHost( theHost );
}
else {
setHost( theHost.substring( 0, i ) );
setPort( Integer.parseInt( theHost.substring( i + 1 ) ) );
}
}
theUrl = theUrl.substring( index );
// Host <--|
}
}
// Path |-->
if ( theUrl != null && theUrl.length() > 0 ) {
index = theUrl.indexOf( Delimiter.URL_QUERY.getChar(), 1 );
if ( index == -1 ) {
index = theUrl.indexOf( Delimiter.URL_FRAGMENT.getChar(), 1 );
}
if ( index == -1 ) {
setPath( theUrl );
}
else {
final String thePath = theUrl.substring( 0, index );
setPath( thePath );
theUrl = theUrl.substring( index );
// Path <--|
if ( theUrl.length() > 0 ) {
// Query Fields |-->
if ( theUrl.charAt( 0 ) == Delimiter.URL_QUERY.getChar() ) {
final String theQueryString;
index = theUrl.indexOf( Delimiter.URL_FRAGMENT.getChar() );
if ( index == -1 ) {
theQueryString = theUrl;
}
else {
theQueryString = theUrl.substring( 0, index );
}
final FormFields theQueryFields = new FormFields( theQueryString );
_queryFields = theQueryFields;
}
// Query Fields <--|
// Fragment |-->
index = theUrl.indexOf( Delimiter.URL_FRAGMENT.getChar() );
if ( index != -1 ) {
final String theFragment = theUrl.substring( index + 1 );
_fragment = theFragment;
}
// Fragment <--|
}
}
}
}
catch ( Exception e ) {
fromURL( new URL( aUrl ) );
}
}
protected void fromURL( URL aUrl ) {
// Scheme |-->
Scheme theScheme = Scheme.fromName( aUrl.getProtocol() );
if ( theScheme == null ) {
theScheme = Scheme.fromProtocol( aUrl.getProtocol() );
}
setScheme( theScheme );
// Scheme <--|
// Host |-->
setHost( aUrl.getHost() );
// Host <--|
// Port |-->
setPort( aUrl.getPort() );
// Port <--|
// Identity |-->
final String theUserInfo = aUrl.getUserInfo();
if ( theUserInfo != null && theUserInfo.length() > 0 ) {
final int index = theUserInfo.indexOf( Delimiter.URL_CREDENTIALS.getChar() );
if ( index == -1 ) {
_identity = theUserInfo;
}
else {
_identity = theUserInfo.substring( 0, index );
_secret = theUserInfo.substring( index + 1 );
}
}
// Identity <--|
// Path |-->
final String thePath = aUrl.getPath();
if ( thePath != null && thePath.length() > 0 ) {
setPath( thePath );
}
// Path <--|
// Query |-->
if ( aUrl.getQuery() != null && aUrl.getQuery().length() > 0 ) {
final FormFields theFormFields = new FormFields( aUrl.getQuery() );
_queryFields = theFormFields;
}
// Query <--|
// Fragment |-->
if ( aUrl.getRef() != null && aUrl.getRef().length() > 0 ) {
_fragment = aUrl.getRef();
}
// Fragment <--|
}
protected void setScheme( Scheme aScheme ) {
_scheme = aScheme;
_protocol = null;
}
protected void setProtocol( String aProtocol ) {
final Scheme theScheme = Scheme.fromProtocol( aProtocol );
if ( theScheme != null ) {
_scheme = theScheme;
_protocol = null;
}
else {
_scheme = null;
_protocol = aProtocol;
}
}
protected void setHost( String aHost ) {
try {
final int[] theIpAddress = IpAddress.fromAnyCidrNotation( aHost );
if ( theIpAddress != null && theIpAddress.length > 0 ) {
_ipAddress = theIpAddress;
_host = null;
}
else {
_ipAddress = null;
_host = aHost;
}
}
catch ( IllegalArgumentException e ) {
_host = aHost;
_ipAddress = null;
}
}
protected void setIpAddress( int[] aIpAddress ) {
// Probe the IP-Address |-->
IpAddress.toString( aIpAddress );
// Probe the IP-Address <--|
_ipAddress = aIpAddress;
_host = null;
}
protected void setPort( int aPort ) {
_port = aPort;
}
protected void setPath( String aPath ) {
if ( aPath != null && aPath.length() != 0 && aPath.charAt( 0 ) != Delimiter.PATH.getChar() ) {
aPath = Delimiter.PATH.getChar() + aPath;
}
_path = aPath;
}
// /////////////////////////////////////////////////////////////////////////
// HELPER:
// /////////////////////////////////////////////////////////////////////////
/**
* Removes any leading path delimiters (as of {@link Delimiter#PATH}).
*
* @param aPath The path to be processed.
*
* @return The path without any leading path delimiters.
*/
protected static String toTruncatePathPrefix( String aPath ) {
if ( aPath != null ) {
while ( aPath.length() > 0 && aPath.charAt( 0 ) == Delimiter.PATH.getChar() ) {
aPath = aPath.substring( 1 );
}
}
return aPath;
}
/**
* Removes any trailing path delimiters (as of {@link Delimiter#PATH}).
*
* @param aPath The path to be processed.
*
* @return The path without any trailing path delimiters.
*/
protected static String toTruncatePathSuffix( String aPath ) {
if ( aPath != null ) {
while ( aPath.length() > 0 && aPath.charAt( aPath.length() - 1 ) == Delimiter.PATH.getChar() ) {
aPath = aPath.substring( 0, aPath.length() - 1 );
}
}
return aPath;
}
/**
* Removes any leading and trailing path delimiters (as of
* {@link Delimiter#PATH}).
*
* @param aPath The path to be processed.
*
* @return The path with neither any leading nor any trailing path
* delimiters.
*/
protected static String toTruncatePath( String aPath ) {
return toTruncatePathPrefix( toTruncatePathSuffix( aPath ) );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy