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

    Copyright (c) 2010, 2020 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>
