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

    Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License v. 2.0, which is available at
    http://www.eclipse.org/legal/epl-2.0.

    This Source Code may also be made available under the following Secondary
    Licenses when the conditions for such availability set forth in the
    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    version 2 with the GNU Classpath Exception, which is available at
    https://www.gnu.org/software/classpath/license.html.

    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

-->

<!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="jaxrs-resources">
    <title>JAX-RS Application, Resources and Sub-Resources</title>

    <para>This chapter presents an overview of the core JAX-RS concepts - resources and sub-resources.</para>

    <para>The JAX-RS &jax-rs.version; JavaDoc can be found online <link xlink:href="&jaxrs.release.uri;/apidocs/index.html">here</link>.
    </para>

    <para>The JAX-RS &jax-rs.version; specification draft can be found online <link
            xlink:href="http://jcp.org/en/jsr/summary?id=339">here</link>.
    </para>

    <section>
        <title>Root Resource Classes</title>

        <para>
            <emphasis>Root resource classes</emphasis>
            are POJOs (Plain Old Java Objects) that are annotated with &jaxrs.Path;
            have at least one method annotated with &jaxrs.Path; or a resource method designator annotation such as &jaxrs.GET;,
            &jaxrs.PUT;, &jaxrs.POST;, &jaxrs.DELETE;. Resource methods are methods of a resource class annotated with a resource
            method designator. This section shows how to use Jersey to annotate Java objects to create RESTful web services.
        </para>

        <para>The following code example is a very simple example of a root
            resource class using JAX-RS annotations. The example code shown here is
            from one of the samples that ships with Jersey, the zip file of which can
            be found in the maven repository
            <link xlink:href="http://central.maven.org/maven2/org/glassfish/jersey/examples/helloworld//&version;/">here</link>.
        </para>
        <para>
            <example>
                <title>Simple hello world root resource class</title>
                <programlisting language="java" linenumbering="numbered">package org.glassfish.jersey.examples.helloworld;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("helloworld")
public class HelloWorldResource {
    public static final String CLICHED_MESSAGE = "Hello World!";

@GET
@Produces("text/plain")
    public String getHello() {
        return CLICHED_MESSAGE;
    }
}</programlisting>
            </example>
            Let's look at some of the JAX-RS annotations used in this example.
        </para>

        <section>
            <title>@Path</title>

            <para>The &jaxrs.Path; annotation's value is a relative URI path. In the example above, the Java class will be hosted at the URI path
                <literal>/helloworld</literal>. This is an extremely simple use of the &jaxrs.Path; annotation. What makes JAX-RS so useful is that you can embed variables in the URIs.
            </para>

            <para>
                <emphasis>URI path templates</emphasis>
                are URIs with variables embedded within the URI syntax. These variables are substituted at runtime in order for a resource to respond to a request based on the substituted URI. Variables are denoted by curly braces. For example, look at the following &jaxrs.Path; annotation:

                <programlisting language="java" linenumbering="unnumbered">@Path("/users/{username}")</programlisting>

                In this type of example, a user will be prompted to enter their name, and then a Jersey web service configured to respond to requests to this URI path template will respond. For example, if the user entered their username as "Galileo", the web service will respond to the following URL:
                <literal>http://example.com/users/Galileo</literal>
            </para>

            <para>To obtain the value of the username variable the &jaxrs.PathParam; may be used on method parameter of a request method, for example:
                <example>
                    <title>Specifying URI path parameter</title>
                    <programlisting language="java" linenumbering="numbered">@Path("/users/{username}")
public class UserResource {

    @GET
    @Produces("text/xml")
    public String getUser(@PathParam("username") String userName) {
        ...
    }
}</programlisting>
                </example>
                If it is required that a user name must only consist of
                lower and upper case numeric characters then it is possible to declare a
                particular regular expression, which overrides the default regular
                expression, "[^/]+", for example:
                <programlisting language="java">@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]*}")</programlisting>
                In this type of example the username variable will only match user names that begin with one upper or lower case letter and zero or more alpha numeric characters and the underscore character. If a user name does not match that a 404 (Not Found) response will occur.
            </para>

            <para>A &jaxrs.Path; value may or may not begin with a '/', it makes no difference. Likewise, by default, a &jaxrs.Path; value may or may not end in a '/', it makes no difference, and thus request URLs that end or do not end in a '/' will both
                be matched.
            </para>
        </section>

        <section>
            <title>@GET, @PUT, @POST, @DELETE, ... (HTTP Methods)</title>

            <para>&jaxrs.GET;, &jaxrs.PUT;, &jaxrs.POST;, &jaxrs.DELETE; and &jaxrs.HEAD;
                are
                <emphasis>resource method designator</emphasis>
                annotations defined
                by JAX-RS and which correspond to the similarly named HTTP methods. In
                the example above, the annotated Java method will process HTTP GET
                requests. The behavior of a resource is determined by which of the HTTP
                methods the resource is responding to.
            </para>

            <para>The following example is an extract from the storage service
                sample that shows the use of the PUT method to create or update a
                storage container:
            </para>

            <para>
                <example>
                    <title>PUT method</title>
                    <programlisting language="java" linenumbering="numbered">@PUT
public Response putContainer() {
    System.out.println("PUT CONTAINER " + container);

    URI uri = uriInfo.getAbsolutePath();
    Container c = new Container(container, uri.toString());

    Response r;
    if (!MemoryStore.MS.hasContainer(c)) {
        r = Response.created(uri).build();
    } else {
        r = Response.noContent().build();
    }

    MemoryStore.MS.createContainer(c);
    return r;
}</programlisting>
                </example>
                By default the JAX-RS runtime will automatically support the methods HEAD and OPTIONS, if not explicitly
                implemented. For HEAD the runtime will invoke the implemented GET method (if present) and ignore the
                response entity (if set). A response returned for the OPTIONS method depends on the requested media type
                defined in the 'Accept' header. The OPTIONS method can return a response with a set of supported
                resource methods in the 'Allow' header or return
                a <link xlink:href="http://wadl.java.net/">WADL</link> document.
                See <link linkend="wadl">wadl section</link> for more information.
            </para>
        </section>

        <section>
            <title>@Produces</title>

            <para>
                The &jaxrs.Produces; annotation is used to specify the MIME media types of representations a resource can
                produce and send back to the client. In this example, the Java method will produce representations identified
                by the MIME media type "text/plain". &jaxrs.Produces; can be applied at both the class and method levels.
                Here's an example:
            </para>

            <para>
                <example>
                    <title>Specifying output MIME type</title>
                    <programlisting language="java" linenumbering="numbered">@Path("/myResource")
@Produces("text/plain")
public class SomeResource {
    @GET
    public String doGetAsPlainText() {
        ...
    }

    @GET
    @Produces("text/html")
    public String doGetAsHtml() {
        ...
    }
}</programlisting>
                </example>
                The
                <literal>doGetAsPlainText</literal>
                method defaults to the MIME type of the &jaxrs.Produces; annotation at the class level. The
                <literal>doGetAsHtml</literal>
                method's &jaxrs.Produces; annotation overrides the class-level &jaxrs.Produces; setting, and specifies that the
                method can produce HTML rather than plain text.
            </para>

            <para>If a resource class is capable of producing more that one MIME
                media type then the resource method chosen will correspond to the most
                acceptable media type as declared by the client. More specifically the
                Accept header of the HTTP request declares what is most acceptable. For
                example if the Accept header is "<literal>Accept: text/plain</literal>" then the
                <literal>doGetAsPlainText</literal>
                method will be invoked.
                Alternatively if the Accept header is "
                <literal>Accept: text/plain;q=0.9, text/html</literal>", which declares that the client can accept media types of
                "text/plain" and "text/html" but prefers the latter, then the
                <literal>doGetAsHtml</literal>
                method will be invoked.
            </para>

            <para>More than one media type may be declared in the same &jaxrs.Produces; declaration, for example:
            </para>

            <para>
                <example>
                    <title>Using multiple output MIME types</title>
                    <programlisting language="java" linenumbering="numbered">@GET
@Produces({"application/xml", "application/json"})
public String doGetAsXmlOrJson() {
    ...
}</programlisting>
                </example>
                The
                <literal>doGetAsXmlOrJson</literal>
                method will get
                invoked if either of the media types "application/xml" and
                "application/json" are acceptable. If both are equally acceptable then
                the former will be chosen because it occurs first.
            </para>

            <para>Optionally, server can also specify the quality factor for individual media types. These are
                considered if several are equally acceptable by the client. For example:</para>

            <para>
                <example>
                    <title>Server-side content negotiation</title>
                    <programlisting language="java" linenumbering="numbered">@GET
@Produces({"application/xml; qs=0.9", "application/json"})
public String doGetAsXmlOrJson() {
    ...
}</programlisting>
                </example>
                In the above sample, if client accepts both "application/xml" and "application/json" (equally),
                then a server always sends "application/json", since "application/xml" has a lower quality factor.
            </para>

            <para>The examples above refers explicitly to MIME media types for
                clarity. It is possible to refer to constant values, which may reduce
                typographical errors, see the constant field values of &jaxrs.core.MediaType;.
            </para>
        </section>

        <section>
            <title>@Consumes</title>
            <para>The &jaxrs.Consumes; annotation is used to specify the MIME media types of representations
                that can be consumed by a resource. The above example can be modified to set the cliched
                message as follows:
            </para>

            <para>
                <example>
                    <title>Specifying input MIME type</title>
                    <programlisting language="java" linenumbering="numbered">@POST
@Consumes("text/plain")
public void postClichedMessage(String message) {
    // Store the message
}</programlisting>
                </example>
            </para>

            <para>In this example, the Java method will consume representations
                identified by the MIME media type "text/plain". Notice that the resource
                method returns void. This means no representation is returned and
                response with a status code of 204 (No Content) will be returned to the client.
            </para>

            <para>&jaxrs.Consumes; can be applied at both the class and the method levels and more than one media type
                may be declared in the same &jaxrs.Consumes; declaration.
            </para>
        </section>
    </section>

    <section>
        <title>Parameter Annotations (@*Param)</title>

        <para>Parameters of a resource method may be annotated with parameter-based annotations to extract information
            from a request. One of the previous examples presented the use of &jaxrs.PathParam; to extract a path
            parameter from the path component of the request URL that matched the path declared in &jaxrs.Path;.
        </para>

        <para>&jaxrs.QueryParam; is used to extract query parameters from the Query component of the request URL.
            The following example is an extract from the sparklines sample:
        </para>

        <example>
            <title>Query parameters</title>
            <programlisting language="java" linenumbering="numbered">@Path("smooth")
@GET
public Response smooth(
    @DefaultValue("2") @QueryParam("step") int step,
    @DefaultValue("true") @QueryParam("min-m") boolean hasMin,
    @DefaultValue("true") @QueryParam("max-m") boolean hasMax,
    @DefaultValue("true") @QueryParam("last-m") boolean hasLast,
    @DefaultValue("blue") @QueryParam("min-color") ColorParam minColor,
    @DefaultValue("green") @QueryParam("max-color") ColorParam maxColor,
    @DefaultValue("red") @QueryParam("last-color") ColorParam lastColor) {
    ...
}</programlisting>
        </example>

        <para>If a query parameter "step" exists in the query component of the
            request URI then the "step" value will be extracted and parsed as a
            32 bit signed integer and assigned to the step method parameter. If "step"
            does not exist then a default value of 2, as declared in the &jaxrs.DefaultValue;
            annotation, will be assigned to the step method parameter. If the "step"
            value cannot be parsed as a 32 bit signed integer then a HTTP 404 (Not
            Found) response is returned. User defined Java types such as
            <literal>ColorParam</literal>
            may be used, which as implemented as
            follows:
        </para>

        <example>
            <title>Custom Java type for consuming request parameters</title>
            <programlisting language="java" linenumbering="numbered">public class ColorParam extends Color {

    public ColorParam(String s) {
        super(getRGB(s));
    }

    private static int getRGB(String s) {
        if (s.charAt(0) == '#') {
            try {
                Color c = Color.decode("0x" + s.substring(1));
                return c.getRGB();
            } catch (NumberFormatException e) {
                throw new WebApplicationException(400);
            }
        } else {
            try {
                Field f = Color.class.getField(s);
                return ((Color)f.get(null)).getRGB();
            } catch (Exception e) {
                throw new WebApplicationException(400);
            }
        }
    }
}</programlisting>
        </example>

        <para>In general the Java type of the method parameter may:</para>

        <orderedlist>
            <listitem>
                <para>Be a primitive type;</para>
            </listitem>

            <listitem>
                <para>Have a constructor that accepts a single
                    <literal>String</literal>
                    argument;
                </para>
            </listitem>

            <listitem>
                <para>Have a static method named
                    <literal>valueOf</literal>
                    or
                    <literal>fromString</literal>
                    that accepts a single
                    <literal>String</literal>
                    argument (see, for example,
                    <literal>Integer.valueOf(String)</literal>
                    and <literal>java.util.UUID.fromString(String)</literal>);
                </para>
            </listitem>
            <listitem>
                <para>Have a registered implementation of <literal>javax.ws.rs.ext.ParamConverterProvider</literal> JAX-RS
                    extension SPI that returns a <literal>javax.ws.rs.ext.ParamConverter</literal> instance capable of
                    a "from string" conversion for the type.
                     or
                </para>
            </listitem>

            <listitem>
                <para>Be <literal>List&lt;T&gt;</literal>,
                    <literal>Set&lt;T&gt;</literal>
                    or
                    <literal>SortedSet&lt;T&gt;</literal>, where
                    <literal>T</literal>
                    satisfies 2 or 3 above. The resulting collection is read-only.
                </para>
            </listitem>
        </orderedlist>

        <para>Sometimes parameters may contain more than one value for the same
            name. If this is the case then types in 5) may be used to obtain all
            values.
        </para>

        <para>If the &jaxrs.DefaultValue; is not used in conjunction with &jaxrs.QueryParam;
            and the query parameter is not present in the request then value will be
            an empty collection for<literal>List</literal>, <literal>Set</literal> or <literal>SortedSet</literal>,
            &lit.null; for other object types, and the Java-defined default for primitive types.
        </para>

        <para>The &jaxrs.PathParam; and the other parameter-based annotations, &jaxrs.MatrixParam;,
            &jaxrs.HeaderParam;, &jaxrs.CookieParam;, &jaxrs.FormParam; obey the same rules as &jaxrs.QueryParam;.
            &jaxrs.MatrixParam; extracts information from URL path segments. &jaxrs.HeaderParam; extracts information
            from the HTTP headers. &jaxrs.CookieParam; extracts information from the cookies declared in cookie related HTTP
            headers.
        </para>

        <para>&jaxrs.FormParam; is slightly special because it extracts information from a request representation that
            is of the MIME media type
            <literal>"application/x-www-form-urlencoded"</literal>
            and conforms to the encoding
            specified by HTML forms, as described here. This parameter is very useful for extracting information that is
            POSTed by HTML forms, for example the following extracts the form parameter named "name" from the POSTed form
            data:
        </para>

        <para>
            <example>
                <title>Processing POSTed HTML form</title>
                <programlisting language="java" linenumbering="numbered">@POST
@Consumes("application/x-www-form-urlencoded")
public void post(@FormParam("name") String name) {
    // Store the message
}</programlisting>
            </example>
        </para>

        <para>If it is necessary to obtain a general map of parameter name to
            values then, for query and path parameters it is possible to do the
            following:
        </para>

        <para>
            <example>
                <title>Obtaining general map of URI path and/or query parameters</title>
                <programlisting language="java" linenumbering="numbered">@GET
public String get(@Context UriInfo ui) {
    MultivaluedMap&lt;String, String&gt; queryParams = ui.getQueryParameters();
    MultivaluedMap&lt;String, String&gt; pathParams = ui.getPathParameters();
}</programlisting>
            </example>
        </para>

        <para>For header and cookie parameters the following:</para>

        <para>
            <example>
                <title>Obtaining general map of header parameters</title>
                <programlisting language="java" linenumbering="numbered">@GET
public String get(@Context HttpHeaders hh) {
    MultivaluedMap&lt;String, String&gt; headerParams = hh.getRequestHeaders();
    Map&lt;String, Cookie&gt; pathParams = hh.getCookies();
}</programlisting>
            </example>
        </para>

        <para>In general &jaxrs.core.Context; can be used to obtain contextual Java types related to the request or response.
        </para>

        <para>Because form parameters (unlike others) are part of the message entity, it is possible to do the following:</para>

        <para>
            <example>
                <title>Obtaining general map of form parameters</title>
                <programlisting language="java" linenumbering="numbered">@POST
@Consumes("application/x-www-form-urlencoded")
public void post(MultivaluedMap&lt;String, String&gt; formParams) {
    // Store the message
}</programlisting>
            </example>

            I.e. you don't need to use the &jaxrs.core.Context; annotation.
        </para>
        <para>Another kind of injection is the &jaxrs.BeanParam; which allows to inject the parameters described above into a
            single bean. A bean annotated with &jaxrs.BeanParam; containing any fields and appropriate
            <literal>*param</literal>
            annotation(like &jaxrs.PathParam;) will be initialized with corresponding request values in expected way as if these
            fields were in the resource class. Then instead of injecting request values like path param into a constructor parameters
            or class fields the &jaxrs.BeanParam; can be used to inject such a bean into a resource or resource method. The
            &jaxrs.BeanParam; is used this way to aggregate more request parameters into a single bean.
        </para>
        <example>
            <title>Example of the bean which will be used as &jaxrs.BeanParam;
            </title>
            <programlisting language="java" linenumbering="numbered">public class MyBeanParam {
    @PathParam("p")
    private String pathParam;

    @MatrixParam("m")
    @Encoded
    @DefaultValue("default")
    private String matrixParam;

    @HeaderParam("header")
    private String headerParam;

    private String queryParam;

    public MyBeanParam(@QueryParam("q") String queryParam) {
        this.queryParam = queryParam;
    }

    public String getPathParam() {
        return pathParam;
    }
    ...
}</programlisting>
        </example>
        <example>
            <title>Injection of MyBeanParam as a method parameter:</title>

            <programlisting language="java" linenumbering="numbered">@POST
public void post(@BeanParam MyBeanParam beanParam, String entity) {
    final String pathParam = beanParam.getPathParam(); // contains injected path parameter "p"
    ...
}</programlisting>
        </example>
        <para>The example shows aggregation of injections &jaxrs.PathParam;, &jaxrs.QueryParam; &jaxrs.MatrixParam;
            and &jaxrs.HeaderParam; into one single bean. The rules for injections inside the bean are the same as described above
            for these injections. The &jaxrs.DefaultValue; is used to define the default value for matrix parameter matrixParam.
            Also the &jaxrs.Encoded; annotation has the same behaviour as if it were used for injection in the resource method
            directly. Injecting the bean parameter into @Singleton resource class fields is not allowed (injections into method
            parameter must be used instead).
        </para>
        <para>&jaxrs.BeanParam; can contain all parameters injections
            (&jaxrs.PathParam;, &jaxrs.QueryParam;, &jaxrs.MatrixParam;, &jaxrs.HeaderParam;,
            &jaxrs.CookieParam;, &jaxrs.FormParam;). More
            beans can be injected into one resource or method parameters even if they inject the same request values. For example
            the following is possible:
        </para>
        <example>
            <title>Injection of more beans into one resource methods:</title>

            <programlisting language="java" linenumbering="numbered">@POST
public void post(@BeanParam MyBeanParam beanParam, @BeanParam AnotherBean anotherBean, @PathParam("p") pathParam,
String entity) {
    // beanParam.getPathParam() == pathParam
    ...
}</programlisting>
        </example>

    </section>

    <section>
        <title>Sub-resources</title>

        <para>&jaxrs.Path; may be used on classes and such classes are referred to as root resource classes. &jaxrs.Path;
            may also be used on methods of root resource classes. This enables common functionality for a number of resources
            to be grouped together and potentially reused.
        </para>

        <para>The first way &jaxrs.Path; may be used is on resource methods and such methods are referred to as
            <emphasis>sub-resource methods</emphasis>. The following example shows the method signatures for a root
            resource class from the jmaki-backend sample:
        </para>

        <para>
            <example>
                <title>Sub-resource methods</title>
                <programlisting language="java" linenumbering="numbered">@Singleton
@Path("/printers")
public class PrintersResource {

    @GET
    @Produces({"application/json", "application/xml"})
    public WebResourceList getMyResources() { ... }

    @GET @Path("/list")
    @Produces({"application/json", "application/xml"})
    public WebResourceList getListOfPrinters() { ... }

    @GET @Path("/jMakiTable")
    @Produces("application/json")
    public PrinterTableModel getTable() { ... }

    @GET @Path("/jMakiTree")
    @Produces("application/json")
    public TreeModel getTree() { ... }

    @GET @Path("/ids/{printerid}")
    @Produces({"application/json", "application/xml"})
    public Printer getPrinter(@PathParam("printerid") String printerId) { ... }

    @PUT @Path("/ids/{printerid}")
    @Consumes({"application/json", "application/xml"})
    public void putPrinter(@PathParam("printerid") String printerId, Printer printer) { ... }

    @DELETE @Path("/ids/{printerid}")
    public void deletePrinter(@PathParam("printerid") String printerId) { ... }
}</programlisting>
            </example>
        </para>

        <para>If the path of the request URL is "printers" then the resource methods not annotated with &jaxrs.Path;
            will be selected. If the request path of the request URL is "printers/list" then first the root resource class
            will be matched and then the sub-resource methods that match "list" will be selected, which in this case
            is the sub-resource method<literal>getListOfPrinters</literal>. So, in this example hierarchical matching
            on the path of the request URL is performed.
        </para>

        <para>The second way &jaxrs.Path; may be used is on methods
            <emphasis role="bold">not</emphasis>
            annotated
            with resource method designators such as &jaxrs.GET; or &jaxrs.POST;. Such methods are referred to as
            <emphasis>sub-resource locators</emphasis>. The following example shows the method signatures for
            a root resource class and a resource class from the optimistic-concurrency sample:
        </para>

        <para>
            <example>
                <title>Sub-resource locators</title>
                <programlisting language="java" linenumbering="numbered">@Path("/item")
public class ItemResource {
    @Context UriInfo uriInfo;

    @Path("content")
    public ItemContentResource getItemContentResource() {
        return new ItemContentResource();
    }

    @GET
    @Produces("application/xml")
        public Item get() { ... }
    }
}

public class ItemContentResource {

    @GET
    public Response get() { ... }

    @PUT
    @Path("{version}")
    public void put(@PathParam("version") int version,
                    @Context HttpHeaders headers,
                    byte[] in) {
        ...
    }
}</programlisting>
            </example>
        </para>

        <para>The root resource class
            <literal>ItemResource</literal>
            contains the
            sub-resource locator method
            <literal>getItemContentResource</literal>
            that
            returns a new resource class. If the path of the request URL is
            "item/content" then first of all the root resource will be matched, then
            the sub-resource locator will be matched and invoked, which returns an
            instance of the
            <literal>ItemContentResource</literal>
            resource class.
            Sub-resource locators enable reuse of resource classes. A method can be annotated with the
            &jaxrs.Path; annotation with empty path (<literal>@Path("/")</literal> or <literal>@Path("")</literal>) which
            means that the sub resource locator is matched for the path of the enclosing resource (without sub-resource path).
        </para>
        <para>
            <example>
                <title>Sub-resource locators with empty path</title>
                <programlisting language="java" linenumbering="numbered">@Path("/item")
public class ItemResource {

    @Path("/")
    public ItemContentResource getItemContentResource() {
        return new ItemContentResource();
    }
}</programlisting>
            </example>
        </para>

        <para>In the example above the sub-resource locator method <literal>getItemContentResource</literal>
            is matched for example for request path "/item/locator" or even for only "/item".
        </para>

        <para>In addition the processing of resource classes returned by
            sub-resource locators is performed at runtime thus it is possible to
            support polymorphism. A sub-resource locator may return different
            sub-types depending on the request (for example a sub-resource locator
            could return different sub-types dependent on the role of the principle
            that is authenticated). So for example the following sub resource locator is valid:
        </para>
        <para>
            <example>
                <title>Sub-resource locators returning sub-type</title>
                <programlisting language="java" linenumbering="numbered">@Path("/item")
public class ItemResource {

    @Path("/")
    public Object getItemContentResource() {
        return new AnyResource();
    }
}</programlisting>
            </example>
        </para>


        <para>Note that the runtime will not manage the life-cycle or perform any
            field injection onto instances returned from sub-resource locator methods.
            This is because the runtime does not know what the life-cycle of the
            instance is. If it is required that the runtime manages the sub-resources
            as standard resources the <literal>Class</literal> should be returned
            as shown in the following example:
        </para>
        <para>
            <example>
                <title>Sub-resource locators created from classes</title>
                <programlisting language="java" linenumbering="numbered">import javax.inject.Singleton;

@Path("/item")
public class ItemResource {
    @Path("content")
    public Class&lt;ItemContentSingletonResource&gt; getItemContentResource() {
        return ItemContentSingletonResource.class;
    }
}

@Singleton
public class ItemContentSingletonResource {
    // this class is managed in the singleton life cycle
}</programlisting>
            </example>
        </para>



        <para>JAX-RS resources are managed in per-request scope by default which means that
            new resource is created for each request.
            In this example the <literal>javax.inject.Singleton</literal> annotation says
            that the resource will be managed as singleton and not in request scope.
            The sub-resource locator method returns a class which means that the runtime
            will managed the resource instance and its life-cycle. If the method would return instance instead,
            the <literal>Singleton</literal> annotation would have no effect and the returned instance
            would be used.
        </para>

        <para>The sub resource locator can also return a <emphasis>programmatic resource model</emphasis>. See <link
                linkend="resource-builder">resource builder section</link> for information of how the programmatic resource
            model is constructed. The following example shows very simple resource returned from the sub-resource locator method.
        </para>


        <para>
            <example>
                <title>Sub-resource locators returning resource model</title>
                <programlisting language="java" linenumbering="numbered">import org.glassfish.jersey.server.model.Resource;

@Path("/item")
public class ItemResource {

    @Path("content")
    public Resource getItemContentResource() {
        return Resource.from(ItemContentSingletonResource.class);
    }
}</programlisting>
            </example>
        </para>
        <para>The code above has exactly the same effect as previous example. <literal>Resource</literal> is a resource
            simple resource constructed from <literal>ItemContentSingletonResource</literal>. More complex programmatic
            resource can be returned as long they are valid resources.
        </para>

    </section>


    <section>
        <title>Life-cycle of Root Resource Classes</title>

        <para>By default the life-cycle of root resource classes is per-request which,
            namely that a new instance of a root resource class is created every time
            the request URI path matches the root resource. This makes for a very
            natural programming model where constructors and fields can be utilized
            (as in the previous section showing the constructor of the
            <literal>SparklinesResource</literal>
            class) without concern for multiple
            concurrent requests to the same resource.
        </para>

        <para>In general this is unlikely to be a cause of performance issues.
            Class construction and garbage collection of JVMs has vastly improved over
            the years and many objects will be created and discarded to serve and
            process the HTTP request and return the HTTP response.
        </para>

        <para>Instances of singleton root resource classes can be declared by an instance of &jaxrs.core.Application;.
        </para>



        <para>Jersey supports two further life-cycles using Jersey specific annotations.</para>

        <table frame="all">
            <title>Resource scopes</title>
            <tgroup cols="4">
                <colspec colwidth="1*" />
                <colspec colwidth="1*" />
                <colspec colwidth="2*" />
                <colspec colwidth="5*" />
                <thead>
                    <row>
                        <entry>Scope</entry>
                        <entry>Annotation</entry>
                        <entry>Annotation full class name</entry>
                        <entry>Description</entry>
                    </row>
                </thead>
                <tbody>
                    <row><entry>Request scope</entry><entry>@RequestScoped (or none)</entry>
                        <entry>org.glassfish.jersey.process.internal.RequestScoped</entry>
                        <entry><emphasis>Default lifecycle </emphasis> (applied when no annotation is present). In this scope
                            the resource instance is created for each new request and used for processing of this request. If the
                            resource is used more than one time in the request processing, always the same instance will be used.
                            This can happen when a resource is a sub resource and is returned more times during the matching. In this
                            situation only one instance will serve the requests.</entry></row>
                    <row><entry>Per-lookup scope</entry><entry>@PerLookup</entry>
                        <entry>org.glassfish.hk2.api.PerLookup</entry>
                        <entry>In this scope
                            the resource instance is created every time it is needed for the processing even it handles
                            the same request.</entry></row>
                    <row><entry>Singleton</entry><entry>@Singleton</entry>
                        <entry>javax.inject.Singleton</entry>
                        <entry>In this scope there is only one instance per jax-rs application. Singleton resource can be either
                            annotated with @Singleton and its class can be registered using the instance of
                            &jaxrs.core.Application;. You can also create singletons by registering singleton instances
                            into &jaxrs.core.Application;.</entry></row>
                </tbody>
            </tgroup>
        </table>
    </section>

    <section>
        <title>Rules of Injection</title>

        <para>Previous sections have presented examples of annotated types, mostly
            annotated method parameters but also annotated fields of a class, for the
            injection of values onto those types.
        </para>

        <para>This section presents the rules of injection of values on annotated
            types. Injection can be performed on fields, constructor parameters,
            resource/sub-resource/sub-resource locator method parameters and bean
            setter methods. The following presents an example of all such injection
            cases:
        </para>

        <para>
            <example>
                <title>Injection</title>
                <programlisting language="java" linenumbering="numbered">@Path("{id:\\d+}")
public class InjectedResource {
    // Injection onto field
    @DefaultValue("q") @QueryParam("p")
    private String p;

    // Injection onto constructor parameter
    public InjectedResource(@PathParam("id") int id) { ... }

    // Injection onto resource method parameter
    @GET
    public String get(@Context UriInfo ui) { ... }

    // Injection onto sub-resource resource method parameter
    @Path("sub-id")
    @GET
    public String get(@PathParam("sub-id") String id) { ... }

    // Injection onto sub-resource locator method parameter
    @Path("sub-id")
    public SubResource getSubResource(@PathParam("sub-id") String id) { ... }

    // Injection using bean setter method
    @HeaderParam("X-header")
    public void setHeader(String header) { ... }
}</programlisting>
            </example>
        </para>

        <para>There are some restrictions when injecting on to resource classes
            with a life-cycle of singleton scope. In such cases the class fields or
            constructor parameters cannot be injected with request specific parameters. So, for example
            the following is not allowed.</para>

        <para>
            <example>
                <title>Wrong injection into a singleton scope</title>
                <programlisting language="java" linenumbering="numbered">@Path("resource")
@Singleton
public static class MySingletonResource {

    @QueryParam("query")
    String param; // WRONG: initialization of application will fail as you cannot
                  // inject request specific parameters into a singleton resource.

    @GET
    public String get() {
        return "query param: " + param;
    }
}</programlisting>
            </example>
        </para>
        <para>
            The example above will cause validation failure during application initialization as singleton
            resources cannot inject request specific parameters. The same example would fail if the query
            parameter would be injected into constructor parameter of such a singleton. In other words, if you
            wish one resource instance to server more requests (in the same time) it cannot be bound
            to a specific request parameter.
        </para>
        <para>
            The exception exists for specific request objects which can injected even into
            constructor or class fields. For these objects the runtime will inject proxies
            which are able to simultaneously server more request. These request objects are
            <literal>HttpHeaders</literal>, <literal>Request</literal>, <literal>UriInfo</literal>,
            <literal>SecurityContext</literal>. These proxies can be injected using the &jaxrs.core.Context;
            annotation. The following example shows injection of proxies into the singleton resource class.
        </para>

        <para>
            <example>
                <title>Injection of proxies into singleton</title>
                <programlisting language="java" linenumbering="numbered">@Path("resource")
@Singleton
public static class MySingletonResource {
    @Context
    Request request; // this is ok: the proxy of Request will be injected into this singleton

    public MySingletonResource(@Context SecurityContext securityContext) {
        // this is ok too: the proxy of SecurityContext will be injected
    }

    @GET
    public String get() {
        return "query param: " + param;
    }
}</programlisting>
            </example>
        </para>

        <para>
            To summarize the injection can be done into the following constructs:
        </para>
        <table frame="all">
            <title>Overview of injection types</title>
            <tgroup cols="2">
                <colspec colwidth="1*" />
                <colspec colwidth="5*" />
                <thead>
                    <row>
                        <entry>Java construct</entry>
                        <entry>Description</entry>
                    </row>
                </thead>
                <tbody>
                    <row>
                        <entry>Class fields</entry>
                        <entry>
                            Inject value directly into the field of the class. The field can be private
                            and must not be final. Cannot be used in Singleton scope except proxiable types mentioned above.
                        </entry>
                    </row>
                    <row>
                        <entry>Constructor parameters</entry>
                        <entry>
                            The constructor will be invoked with injected values. If more
                            constructors exists the one with the most injectable parameters will be invoked.
                            Cannot be used in Singleton scope except proxiable types mentioned above.
                        </entry>
                    </row>
                    <row>
                        <entry>Resource methods</entry>
                        <entry>
                            The resource methods (these annotated with @GET, @POST, ...) can contain
                            parameters that can be injected when the resource method is executed.
                            Can be used in any scope.
                        </entry>
                    </row>
                    <row>
                        <entry>Sub resource locators</entry>
                        <entry>
                            The sub resource locators (methods annotated with @Path but not @GET, @POST, ...)
                            can contain parameters that can be injected when the resource method is executed.
                            Can be used in any scope.
                        </entry>
                    </row>
                    <row>
                        <entry>Setter methods</entry>
                        <entry>
                            Instead of injecting values directly into field the value can be injected into the
                            setter method which will initialize the field. This injection can be used only with &jaxrs.core.Context;
                            annotation. This means
                            it cannot be used for example for injecting of query params but it can be used for injections of
                            request. The setters will be called after the object creation and
                            only once. The name of the method does not necessary have a setter pattern. Cannot be used
                            in Singleton scope except proxiable types mentioned above.
                        </entry>
                    </row>
                </tbody>
            </tgroup>
        </table>

        <para>
            The following example shows all possible java constructs into which the values can be injected.

            <example>
                <title>Example of possible injections</title>
                <programlisting language="java" linenumbering="numbered">@Path("resource")
public static class SummaryOfInjectionsResource {
    @QueryParam("query")
    String param; // injection into a class field


    @GET
    public String get(@QueryParam("query") String methodQueryParam) {
        // injection into a resource method parameter
        return "query param: " + param;
    }

    @Path("sub-resource-locator")
    public Class&lt;SubResource&gt; subResourceLocator(@QueryParam("query") String subResourceQueryParam) {
        // injection into a sub resource locator parameter
        return SubResource.class;
    }

    public SummaryOfInjectionsResource(@QueryParam("query") String constructorQueryParam) {
        // injection into a constructor parameter
    }


    @Context
    public void setRequest(Request request) {
        // injection into a setter method
        System.out.println(request != null);
    }
}

public static class SubResource {
    @GET
    public String get() {
        return "sub resource";
    }
}</programlisting>
            </example>
        </para>


        <para>The &jaxrs.FormParam; annotation is special and may only be utilized on resource and sub-resource methods.
            This is because it extracts information from a request entity.
        </para>
    </section>

    <section>
        <title>Use of @Context</title>

        <para>Previous sections have introduced the use of &jaxrs.core.Context;. Chapter "Context" in the JAX-RS
            specification presents all the standard JAX-RS Java types that may be used with &jaxrs.core.Context;.
        </para>

        <para>When deploying a JAX-RS application using servlet then
            <link xlink:href="http://docs.oracle.com/javaee/5/api/javax/servlet/ServletConfig.html">ServletConfig</link>,
            <link xlink:href="http://docs.oracle.com/javaee/5/api/javax/servlet/ServletContext.html">ServletContext</link>,
            <link xlink:href="http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html">HttpServletRequest</link>
            and
            <link xlink:href="http://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletResponse.html">HttpServletResponse</link>
            are available using &jaxrs.core.Context;.
        </para>
    </section>

    <section>
        <title>Programmatic resource model</title>

        <para>Resources can be constructed from classes or instances but also can be constructed from a programmatic resource
            model. Every resource created from resource classes can also
            be constructed using the programmatic resource builder api. See <link
                    linkend="resource-builder">resource builder section</link> for more information.
        </para>
    </section>

</chapter>
