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

    Copyright (c) 2010, 2021 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="https://jakarta.ee/specifications/restful-ws/3.0/jakarta-restful-ws-spec-3.0.pdf">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="https://repo1.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 jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.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="https://javaee.github.io/wadl/">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>jakarta.ws.rs.ext.ParamConverterProvider</literal> JAX-RS
                    extension SPI that returns a <literal>jakarta.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 jakarta.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>jakarta.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>jakarta.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="https://jakarta.ee/specifications/servlet/5.0/apidocs/jakarta/servlet/ServletConfig.html">ServletConfig</link>,
            <link xlink:href="https://jakarta.ee/specifications/servlet/5.0/apidocs/jakarta/servlet/ServletContext.html">ServletContext</link>,
            <link xlink:href="https://jakarta.ee/specifications/servlet/5.0/apidocs/jakarta/servlet/http/HttpServletRequest.html">HttpServletRequest</link>
            and
            <link xlink:href="https://jakarta.ee/specifications/servlet/5.0/apidocs/jakarta/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>
