Documentation

Introduction

This page provides an example-based guide to Urin. In-depth details of the API are available in the online javadoc, which can also be found in the standard jar.

Model of URIs and relative references in Urin

The model of URIs and relative references in Urin reflects that defined in RFC 3986. The RFC defines two top level structures:

These are modelled in Urin as Urin and RelativeReference respectively. These classes provide factory methods that allow any valid URI or relative reference to be generated.

Producing URIs and relative references

Producing a URI is simply a case of calling the relevant factory method on an instance of the Scheme class, for example:

scheme("ftp").urin( authority(registeredName("ftp.is.co.za")), path("rfc", "rfc1808.txt") ).asString();

Generates the String ftp://ftp.is.co.za/rfc/rfc1808.txt.

It is also possible to generate an instance of java.net.URI, like so:

scheme("mailto").urin( rootlessPath("John.Doe@example.com") ).asUri();

This produces mailto:John.Doe@example.com. Note, however, that java.net.URI implements the obsoleted RFC 2396, meaning there are certain valid URIs which can be produced using Urin, but which can't be represented by java.net.URI.

Generating a relative reference follows the same pattern, for example:

scheme("rsync").relativeReference( rootlessPath(Segment.<String>dotDot(), segment("sibling")), query("some-query") ).asString();

This returns a String containing ../sibling?some-query. It is possible to retrieve this as a java.net.URI in the same way as for a net.sourceforge.urin.Urin, by calling the asUri() method. Of note in this example:

Producing HTTP and HTTPS URIs and relative references

Urin provides specific support for generating HTTP and HTTPS URIs for convenience, and to implement the rules and encoding specified in addition to those specified for general URIs. These are implemented in the Http and Https classes. For example:

http( registeredName("www.example.com"), port(80), path("music", "AC/DC", "Back in Black"), queryParameters( queryParameter("track", "Hells Bells"), queryParameter("version", "Radio edit") ), fragment("verse 2") ).asString();

Generates the String http://www.example.com/music/AC%2FDC/Back%20in%20Black?track=Hells+Bells&version=Radio+edit#verse%202. Notice a number of HTTP specific features:

An equivalent set of methods for generating HTTPS URIs exist on the Https class.

Parsing

The Scheme class implements parseUrinReference, parseUrin, and parseRelativeReference methods to produce an instances of their respective types from a String. For example, we can parse the URI ldap://[2001:db8::7]/c=GB?objectClass?one as follows:

try { parsedUrin = scheme("ldap").parseUrin("ldap://[2001:db8::7]/c=GB?objectClass?one"); } catch (ParseException e) { // handle parse failure }

Where ParseException would be thrown if the String wasn't a valid URI.

Normalisation

RFC 3986 specifies a number of methods of URI normalisation such as the handling of unnecessary encoding and non-preferred case, and the handling of . and .. segments, which are applied by Urin. For example:

HTTP.parseUrin("HTTP://www.example.com/.././some%20pat%68").asString()

Returns the String http://www.example.com/some%20path, as a result of normalisation rules having been applied.

Resolution

Relative references can be turned into URIs by resolving them, relative to a context URI. In Urin, this is achieved using the resolve method on Urin, for example:

http( authority(registeredName("www.example.com")), path("child-1") ).resolve( HTTP.relativeReference( rootlessPath(Segment.<String>dotDot(), segment("child-2")), queryParameters(queryParameter("extra-query")) ) ).asString();

This returns the String http://www.example.com/child-2?extra-query.

Implementing scheme-specific rules

Urin also provides a mechanism for schemes with extra rules to be implemented, as demonstrated in the Http class, which handles the non-default encoding of the space character, and the encoding of parameters in the query component of the HTTP scheme.

This is achieved by extending the Query class. The source code for HttpQuery has an example of this in action.