<?xml version="1.0"?>
<!--

    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

    Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.

    The contents of this file are subject to the terms of either the GNU
    General Public License Version 2 only ("GPL") or the Common Development
    and Distribution License("CDDL") (collectively, the "License").  You
    may not use this file except in compliance with the License.  You can
    obtain a copy of the License at
    http://glassfish.java.net/public/CDDL+GPL_1_1.html
    or packager/legal/LICENSE.txt.  See the License for the specific
    language governing permissions and limitations under the License.

    When distributing the software, include this License Header Notice in each
    file and include the License file at packager/legal/LICENSE.txt.

    GPL Classpath Exception:
    Oracle designates this particular file as subject to the "Classpath"
    exception as provided by Oracle in the GPL Version 2 section of the License
    file that accompanied this code.

    Modifications:
    If applicable, add the following below the License Header, with the fields
    enclosed by brackets [] replaced by your own identifying information:
    "Portions Copyright [year] [name of copyright owner]"

    Contributor(s):
    If you wish your version of this file to be governed by only the CDDL or
    only the GPL Version 2, indicate your decision by adding "[Contributor]
    elects to include this software in this distribution under the [CDDL or GPL
    Version 2] license."  If you don't indicate a single choice of license, a
    recipient has the option to distribute your version of this file under
    either the CDDL, the GPL Version 2 or to extend the choice of license to
    its licensees as provided above.  However, if you add GPL Version 2 code
    and therefore, elected the GPL Version 2 license, then the option applies
    only if the new code is made subject to such option by the copyright
    holder.

-->
<!DOCTYPE chapter [<!ENTITY % ents SYSTEM "jersey.ent" > %ents; ]>
<chapter xmlns="http://docbook.org/ns/docbook"
         version="5.0"
         xml:lang="en"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd
                             http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"
         xml:id="uris-and-links">
    <title>URIs and Links</title>

    <section>
        <title>Building URIs</title>

        <para>
            A very important aspect of REST is hyperlinks, URIs, in representations that clients can use to transition the
            Web service to new application states (this is otherwise known as "hypermedia as the engine of application state").
            HTML forms present a good example of this in practice.
        </para>

        <para>
            Building URIs and building them safely is not easy with &jdk6.URI;, which is why JAX-RS has the
            &jaxrs.core.UriBuilder; class that makes it simple and easy to build URIs safely.
            &lit.jaxrs.core.UriBuilder; can be used to build new URIs or build from existing URIs. For resource
            classes it is more than likely that URIs will be built from the base URI the web service is deployed at
            or from the request URI. The class &jaxrs.core.UriInfo; provides such information (in addition to further
            information, see next section).
        </para>

        <para>The following example shows URI building with &lit.jaxrs.core.UriInfo; and &lit.jaxrs.core.UriBuilder;
            from the bookmark example:

            <example>
                <title>URI building</title>
                <programlisting language="java" linenumbering="numbered">@Path("/users/")
public class UsersResource {

    @Context
    UriInfo uriInfo;

    ...

    @GET
    @Produces("application/json")
    public JSONArray getUsersAsJsonArray() {
        JSONArray uriArray = new JSONArray();
        for (UserEntity userEntity : getUsers()) {
            UriBuilder ub = uriInfo.getAbsolutePathBuilder();
            URI userUri = ub.
                    path(userEntity.getUserId()).
                    build();
            uriArray.put(userUri.toASCIIString());
        }
        return uriArray;
    }
}</programlisting>
            </example>

            &lit.jaxrs.core.UriInfo; is obtained using the @Context annotation, and in this particular example injection onto
            the field of the root resource class is performed, previous examples showed the use of @Context on resource method
            parameters.
        </para>

        <para>
            &lit.jaxrs.core.UriInfo; can be used to obtain URIs and associated &lit.jaxrs.core.UriBuilder; instances for
            the following URIs: the base URI the application is deployed at; the request URI; and the absolute path URI, which
            is the request URI minus any query components.
        </para>

        <para>
            The <literal>getUsersAsJsonArray</literal> method constructs a <literal>JSONArrray</literal>, where each element
            is a URI identifying a specific user resource. The URI is built from the absolute path of the request URI by
            calling
            <link xlink:href="&jaxrs.javadoc.uri;/core/UriInfo.html#getAbsolutePathBuilder()">UriInfo.getAbsolutePathBuilder()</link>.
            A new path segment is added, which is the user ID, and then the URI is built. Notice that it is not necessary to
            worry about the inclusion of <literal>'/'</literal> characters or that the user ID may contain characters that need
            to be percent encoded. &lit.jaxrs.core.UriBuilder; takes care of such details.
        </para>

        <para>&lit.jaxrs.core.UriBuilder; can be used to build/replace query or matrix parameters. URI templates can also be
            declared, for example the following will build the URI <literal>"http://localhost/segment?name=value"</literal>:

            <example>
                <title>Building URIs using query parameters</title>
                <programlisting language="java" linenumbering="numbered">UriBuilder.fromUri("http://localhost/")
    .path("{a}")
    .queryParam("name", "{value}")
    .build("segment", "value");</programlisting>
            </example>
        </para>
    </section>

    <section>
        <title>Resolve and Relativize</title>

        <para>JAX-RS 2.0 introduced additional URI resolution and relativization methods in the &lit.jaxrs.core.UriBuilder;:

            <itemizedlist>
                <listitem><para><link xlink:href="&jaxrs.javadoc.uri;/core/UriInfo.html#resolve(java.net.URI)">UriInfo.resolve(java.net.URI)</link></para></listitem>
                <listitem><para><link xlink:href="&jaxrs.javadoc.uri;/core/UriInfo.html#relativize(java.net.URI)">UriInfo.relativize(java.net.URI)</link></para></listitem>
                <listitem><para><link xlink:href="&jaxrs.javadoc.uri;/core/UriBuilder.html#resolveTemplate(java.lang.String, java.lang.Object)">UriBuilder.resolveTemplate(...)</link> (various arguments)</para></listitem>
            </itemizedlist>

            Resolve and relativize methods in &jaxrs.core.UriInfo; are essentially counterparts to the methods listed above -
            <link xlink:href="&jaxrs.javadoc.uri;/core/UriInfo.html#resolve(java.net.URI)">UriInfo.resolve(java.net.URI)</link>
            resolves given relative URI to an absolute URI using application context URI as the base URI;
            <link xlink:href="&jaxrs.javadoc.uri;/core/UriInfo.html#relativize(java.net.URI)">UriInfo.relativize(java.net.URI)</link>
            then transforms an absolute URI to a relative one, using again the applications context URI as the base URI.
        </para>

        <para>
            &lit.jaxrs.core.UriBuilder; also introduces a set of methods that provide ways of resolving URI templates by replacing
            individual templates with a provided value(s). A short example:

            <programlisting language="java" linenumbering="numbered">final URI uri = UriBuilder.fromUri("http://{host}/{path}?q={param}")
    .resolveTemplate("host", "localhost")
    .resolveTemplate("path", "myApp")
    .resolveTemplate("param", "value").build();

uri.toString(); // returns "http://localhost/myApp?q=value"</programlisting>

            See the &jaxrs.core.UriBuilder; javadoc for more details.
        </para>
    </section>

    <section>
        <title>Link</title>

        <para>
            JAX-RS 2.0 introduces &jaxrs.core.Link; class, which serves as a representation of Web Link defined in
            <link xlink:href="http://tools.ietf.org/html/rfc5988">RFC 5988</link>.
            The JAX-RS &lit.jaxrs.core.Link; class adds API support for providing additional metadata in HTTP messages,
            for example, if you are consuming a REST interface of a public library, you might have a resource returning
            description of a single book. Then you can include links to related resources, such as a book category,
            author, etc. to make the produced response concise but complete at the same time. Clients are then able to
            query all the additional information they are interested in and are not forced to consume details they are
            not interested in. At the same time, this approach relieves the server resources as only the information that
            is truly requested is being served to the clients.
        </para>

        <para>
            A &lit.jaxrs.core.Link; can be serialized to an HTTP message (tyically a response) as additional HTTP header
            (there might be multiple &lit.jaxrs.core.Link; headers provided, thus multiple links can be served in a single
            message). Such HTTP header may look like:
            <screen language="text" linenumbering="unnumbered">Link: &lt;http://example.com/TheBook/chapter2&gt;; rel="prev"; title="previous chapter"</screen>
        </para>

        <para>
            Producing and consuming Links with JAX-RS API is demonstrated in the following example:

            <programlisting language="java" linenumbering="unnumbered">// server side - adding links to a response:
Response r = Response.ok().
    link("http://oracle.com", "parent").
    link(new URI("http://jersey.java.net"), "framework").
    build();

...

// client-side processing:
final Response response = target.request().get();

URI u = response.getLink("parent").getUri();
URI u = response.getLink("framework").getUri();</programlisting>
        </para>
        <para>
            Instances of &lit.jaxrs.core.Link; can be also created directly by invoking one of the factory methods on the
            &jaxrs.core.Link; API that returns a &jaxrs.core.Link.Builder; that can be used to configure and produce new
            links.
        </para>
    </section>
</chapter>
