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

    DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.

    Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.

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

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

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

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

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

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

    <title>Programmatic API for Building Resources</title>

    <section>
        <title>Introduction</title>
        <para>A standard approach of developing JAX-RS application is to implement resource classes annotated with &jaxrs.Path;
            with resource methods annotated with HTTP method annotations like &jaxrs.GET; or &jaxrs.POST; and
            implement needed functionality. This approach is described in the chapter
            <link xlink:href="jaxrs-resources.html">JAX-RS Application, Resources and Sub-Resources</link>. Besides this standard
            JAX-RS approach, Jersey offers an API for constructing resources programmatically.
            </para>

        <para>
            Imagine a situation where a deployed JAX-RS application consists of many resource classes. These resources implement
            standard HTTP methods like  &jaxrs.GET;, &jaxrs.POST;, &jaxrs.DELETE;. In some situations it would be useful to add
            an &jaxrs.OPTIONS; method which would return some kind of meta data about the deployed resource. Ideally, you would
            want to expose the functionality as an additional feature and you want to decide at the deploy time whether you want
            to add your custom &lit.http.OPTIONS; method. However, when custom &lit.http.OPTIONS; method are not
            enabled you would like to be &lit.http.OPTIONS; requests handled in the standard way by JAX-RS runtime. To
            achieve this you would need to modify the code to add or remove custom &lit.http.OPTIONS; methods before
            deployment. Another way would be to use programmatic API to build resource according to your needs.
        </para>
        <para>
            Another use case of programmatic resource builder API is when you build any generic RESTful interface which
            depends on lot of configuration parameters or for example database structure. Your resource classes would
            need to have different methods, different structure for every new application deploy. You could use more solutions
            including approaches where your resource classes would be built using Java byte code manipulation.
            However, this is exactly the case when you can solve the problem cleanly with the programmatic resource builder API.
            Let's have a closer look at how the API can be utilized.
        </para>
    </section>

    <section>
        <title>Programmatic Hello World example</title>
        <para>
            Jersey Programmatic API was designed to fully support JAX-RS resource model. In other words, every resource that can
            be designed using standard JAX-RS approach via annotated resource classes can be also modelled using Jersey
            programmatic API. Let's try to build simple hello world resource using standard approach first and
            then using the Jersey programmatic resource builder API.
        </para>
        <para>
            The following example shows standard JAX-RS "Hello world!" resource class.
            <example>
                <title>A standard resource class</title>
                <programlisting language="java" linenumbering="numbered">
                    @Path("helloworld")
                    public class HelloWorldResource {

                        @GET
                        @Produces("text/plain")
                        public String getHello() {
                            return "Hello World!";
                        }
                    }
                </programlisting>
            </example>
            This is just a simple resource class with one GET method returning "Hello World!" string that will be serialized
            as text/plain media type.
        </para>

        <para>
            Now we will design this simple resource using programmatic API.
            <example>
                <title>A programmatic resource</title>
                <programlisting language="java" linenumbering="numbered">
                    package org.glassfish.jersey.examples.helloworld;

                    import javax.ws.rs.container.ContainerRequestContext;
                    import javax.ws.rs.core.Application;
                    import javax.ws.rs.core.Response;
                    import org.glassfish.jersey.process.Inflector;
                    import org.glassfish.jersey.server.ResourceConfig;
                    import org.glassfish.jersey.server.model.Resource;
                    import org.glassfish.jersey.server.model.ResourceMethod;


                    public static class MyResourceConfig extends ResourceConfig {

                        public MyResourceConfig() {
                            final Resource.Builder resourceBuilder = Resource.builder();
                            resourceBuilder.path("helloworld");

                            final ResourceMethod.Builder methodBuilder = resourceBuilder.addMethod("GET");
                            methodBuilder.produces(MediaType.TEXT_PLAIN_TYPE)
                                    .handledBy(new Inflector&lt;ContainerRequestContext, String>() {

                                @Override
                                public String apply(ContainerRequestContext containerRequestContext) {
                                    return "Hello World!";
                                }
                            });

                            final Resource resource = resourceBuilder.build();
                            registerResources(resource);
                        }
                    }
                </programlisting>
            </example>
            First, focus on the content of the <literal>MyResourceConfig</literal> constructor in the example.
            The Jersey programmatic resource model is constructed from <literal>Resource</literal>s that contain
            <literal>ResourceMethod</literal>s. In the example, a single resource would be constructed from a
            <literal>Resource</literal> containing one &lit.http.GET; resource method that returns "Hello World!".
            The main entry point for building programmatic resources in Jersey is the
            <emphasis><literal>Resource.Builder</literal></emphasis> class. <literal>Resource.Builder</literal> contains just
            a few methods like the <literal>path</literal> method used in the example, which sets the name of the path. Another
            useful method is a <literal>addMethod(String path)</literal> which adds a new method to the resource builder and
            returns a resource method builder for the new method. Resource method builder contains methods which
            set consumed and produced media type, define name bindings, timeout for asynchronous executions, etc. It is always
            necessary to define a resource method handler (i.e. the code of the resource method that will return "Hello World!").
            There are more options how a resource method can be handled. In the example the implementation of
            <literal>Inflector</literal> is used. The Jersey <literal>Inflector</literal> interface defines a simple contract for
            transformation of a request into a response. An inflector can either return a &jaxrs.core.Response; or directly
            an entity object, the way it is shown in the example. Another option is to setup a Java method handler using
            <literal>handledBy(Class&lt;?&gt; handlerClass, Method method)</literal> and pass it the chosen
            <literal>java.lang.reflect.Method</literal> instance together with the enclosing class.
        </para>
        <para>
            A resource method model construction can be explicitly completed by invoking <literal>build()</literal> on the
            resource method builder. It is however not necessary to do so as the new resource method model will be built
            automatically once the parent resource is built. Once a resource model is built, it is registered
            into the resource config at the last line of the <literal>MyResourceConfig</literal> constructor in the example.
        </para>

        <section>
            <title>Deployment of programmatic resources</title>

            <para>
                Let's now look at how a programmatic resources are deployed.
                The easiest way to setup your application as well as register any programmatic resources in Jersey
                is to use a Jersey &lit.jersey.server.ResourceConfig; utility class, an extension of &jaxrs.core.Application;
                class.
                If you deploy your Jersey application into a Servlet container you will need to provide a &jaxrs.core.Application;
                subclass that will be used for configuration. You may use a <literal>web.xml</literal> where you would define a
                <literal>org.glassfish.jersey.servlet.ServletContainer</literal> Servlet entry there and specify initial parameter
                <literal>javax.ws.rs.Application</literal> with the class name of your JAX-RS Application that you
                wish to deploy. In the example above, this application will be <literal>MyResourceConfig</literal> class. This is
                the reason why <literal>MyResourceConfig</literal> extends the &lit.jersey.server.ResourceConfig; (which, if you
                remember extends the <literal>javax.ws.rs.Application</literal>).
            </para>
            <para>
                The following example shows a fragment of <literal>web.xml</literal> that can be used to deploy the
                &lit.jersey.server.ResourceConfig; JAX-RS application.
                <example>
                    <title>A programmatic resource</title>
                    <programlisting language="xml" linenumbering="numbered">
                        ...
                        &lt;servlet&gt;
                            &lt;servlet-name&gt;org.glassfish.jersey.examples.helloworld.MyApplication&lt;/servlet-name&gt;
                            &lt;servlet-class&gt;org.glassfish.jersey.servlet.ServletContainer&lt;/servlet-class&gt;
                            &lt;init-param&gt;
                                &lt;param-name&gt;javax.ws.rs.Application&lt;/param-name&gt;
                                &lt;param-value&gt;org.glassfish.jersey.examples.helloworld.MyResourceConfig&lt;/param-value&gt;
                            &lt;/init-param&gt;
                            &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
                        &lt;/servlet&gt;
                        &lt;servlet-mapping&gt;
                            &lt;servlet-name&gt;org.glassfish.jersey.examples.helloworld.MyApplication&lt;/servlet-name&gt;
                            &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
                        &lt;/servlet-mapping&gt;
                        ...
                    </programlisting>
                </example>
            </para>
            <para>
                If you use another deployment options and you have accessible instance of ResourceConfig which you use
                for configuration, you can register programmatic resources directly by <literal>registerResources()</literal>
                method called on the ResourceConfig. Please note that the method registerResources() replaces all the previously
                registered resources.
            </para>
            <para>
                Because Jersey programmatic API is not a standard JAX-RS feature the &lit.jersey.server.ResourceConfig; must be
                used to register programmatic resources as shown above. See <link linkend="deployment">deployment chapter</link>
                for more information.
            </para>
        </section>
    </section>

    <section>
        <title>Additional examples</title>
        <para>
            <example>
                <title>A programmatic resource</title>
                <programlisting language="java" linenumbering="numbered">
                    final Resource.Builder resourceBuilder = Resource.builder(HelloWorldResource.class);
                    resourceBuilder.addMethod("OPTIONS")
                        .handledBy(new Inflector&lt;ContainerRequestContext, Response&gt;() {
                            @Override
                            public Response apply(ContainerRequestContext containerRequestContext) {
                                return Response.ok("This is a response to an OPTIONS method.").build();
                            }
                        });
                    final Resource resource = resourceBuilder.build();
                </programlisting>
            </example>
        </para>
        <para>
            In the example above the <literal>Resource</literal> is built from
            a <literal>HelloWorldResource</literal> resource class. The resource model built this way
            contains a &lit.http.GET; method producing <literal>'text/plain'</literal> responses with "Hello World!" entity.
            This is quite important as it allows you to whatever Resource objects based on introspecting
            existing JAX-RS resources and use builder API to enhance such these standard resources.
            In the example we used already implemented <literal>HelloWorldResource</literal> resource class
            and enhanced it by &lit.http.OPTIONS; method. The &lit.http.OPTIONS; method is handled by an Inflector which
            returns &jaxrs.core.Response;.
         </para>

        <para>
            The following sample shows how to define sub-resource methods (methods that contains sub-path).
        </para>
        <para>
            <example>
                <title>A programmatic resource</title>
                <programlisting language="java" linenumbering="numbered">
                    final Resource.Builder resourceBuilder = Resource.builder("helloworld");

                    final Resource.Builder childResource = resourceBuilder.addChildResource("subresource");
                    childResource.addMethod("GET").handledBy(new GetInflector());

                    final Resource resource = resourceBuilder.build();
                </programlisting>
            </example>
        </para>
        <para>
            Sub-resource methods are defined using so called <emphasis>child resource models</emphasis>. Child
            resource models (or child resources) are programmatic resources build in the same way as any other
            programmatic resource but they are registered as a child resource of a parent resource. The child resource
            in the example is build directly from the parent builder using method
            <literal>addChildResource(String path)</literal>.
            However, there is also an option to build a child resource model separately as a standard resource and then
            add it as a child resource to a selected parent resource. This means that child resource objects
            can be reused to define child resources in different parent resources (you just build a single child resource
            and then register it in multiple parent resources). Each child resource groups methods with the same sub-resource
            path. Note that a child resource cannot have any child resources as there is nothing like sub-sub-resource
            method concept in JAX-RS. For example if a sub resource method contains more path segments in its path
            (e.g. "/root/sub/resource/method" where "root" is a path of the resource and "sub/resource/method" is the sub
            resource method path) then parent resource will have path "root" and child resource will have path
            "sub/resource/method" (so, there will not be any separate nested sub-resources for "sub", "resource" and "method").
        </para>
        <para>
            See the javadocs of the resource builder API for more information.
            <!--TODO javadoc link-->
        </para>
    </section>
    <section>
        <title>Model processors</title>
        <para>
            Jersey gives you an option to register so called <emphasis>model processor providers</emphasis>. These providers
            are able to modify or enhance the application resource model during application deployment. This is an advanced
            feature and will not be needed in most use cases. However, imagine you would like to add &lit.http.OPTIONS; resource
            method to each deployed resource as it is described at the top of this chapter. You would want to do it for every
            programmatic resource that is registered as well as for all standard JAX-RS resources.
        </para>
        <para>
            To do that, you first need to register a model processor provider in your application, which implements
            <literal>org.glassfish.jersey.server.model.ModelProcessor</literal> extension contract. An example of
            a model processor implementation is shown here:
            <example>
                <title>A programmatic resource</title>
                <programlisting language="java" linenumbering="numbered">
                    import javax.ws.rs.GET;
                    import javax.ws.rs.Path;
                    import javax.ws.rs.Produces;
                    import javax.ws.rs.container.ContainerRequestContext;
                    import javax.ws.rs.core.Application;
                    import javax.ws.rs.core.Configuration;
                    import javax.ws.rs.core.MediaType;
                    import javax.ws.rs.core.Response;
                    import javax.ws.rs.ext.Provider;

                    import org.glassfish.jersey.process.Inflector;
                    import org.glassfish.jersey.server.model.ModelProcessor;
                    import org.glassfish.jersey.server.model.Resource;
                    import org.glassfish.jersey.server.model.ResourceMethod;
                    import org.glassfish.jersey.server.model.ResourceModel;

                    @Provider
                    public static class MyOptionsModelProcessor implements ModelProcessor {

                        @Override
                        public ResourceModel processResourceModel(ResourceModel resourceModel, Configuration configuration) {
                            // we get the resource model and we want to enhance each resource by OPTIONS method
                            ResourceModel.Builder newResourceModelBuilder = new ResourceModel.Builder(false);
                            for (final Resource resource : resourceModel.getResources()) {
                                // for each resource in the resource model we create a new builder which is based on the old resource
                                final Resource.Builder resourceBuilder = Resource.builder(resource);

                                // we add a new OPTIONS method to each resource
                                // note that we should check whether the method does not yet exist to avoid failures
                                resourceBuilder.addMethod("OPTIONS")
                                    .handledBy(new Inflector&lt;ContainerRequestContext, String&gt;() {
                                        @Override
                                        public String apply(ContainerRequestContext containerRequestContext) {
                                            return "On this path the resource with " + resource.getResourceMethods().size()
                                                + " methods is deployed.";
                                        }
                                        }).produces(MediaType.TEXT_PLAIN)
                                          .extended(true); // extended means: not part of core RESTful API

                                // we add to the model new resource which is a combination of the old resource enhanced
                                // by the OPTIONS method
                                newResourceModelBuilder.addResource(resourceBuilder.build());
                            }

                            final ResourceModel newResourceModel = newResourceModelBuilder.build();
                            // and we return new model
                            return newResourceModel;
                        };

                        @Override
                        public ResourceModel processSubResource(ResourceModel subResourceModel, Configuration configuration) {
                            // we just return the original subResourceModel which means we do not want to do any modification
                            return subResourceModel;
                        }
                    }
                </programlisting>
            </example>
            The <literal>MyOptionsModelProcessor</literal> from the example is a relatively simple model processor which
            iterates over all registered resources and for all of them builds a new resource that is equal to the old resource
            except it is enhanced with a new &lit.http.OPTIONS; method.
        </para>
        <para>
            Note that you only need to register such a ModelProcessor as your custom extension provider in the same way as you
            would register any standard JAX-RS extension provider. During an application deployment, Jersey will look for any
            registered model processor and execute them. As you can seem, model processors are very powerful as they can do
            whatever manipulation with the resource model they like. A model processor can even, for example, completely ignore
            the old resource model and return a new custom resource model with a single "Hello world!" resource, which would
            result in only the "Hello world!" resource being deployed in your application. Of course, it would not not make
            much sense to implement such model processor, but the scenario demonstrates how powerful the model processor concept
            is. A better, real-life use case scenario would, for example, be to always add some custom new resource to each
            application that might return additional metadata about the deployed application. Or, you might want to
            filter out particular resources or resource methods, which is another situation where a model processor could
            be used successfully.
        </para>
        <para>
            Also note that <literal>processSubResource(ResourceModel subResourceModel, Configuration configuration)</literal>
            method is executed for each sub resource returned from the sub resource locator. The example is simplified and does
            not do any manipulation but probably in such a case you would want to enhance all sub resources with
            a new &lit.http.OPTIONS; method handlers too.
        </para>
        <para>
            It is important to remember that any model processor must always return valid resource model. As you might have
            already noticed, in the example above this important rule is not followed. If any of the resources in the original
            resource model would already have an &lit.http.OPTIONS; method handler defined, adding another handler would cause
            the application fail during the deployment in the resource model validation phase. In order to retain the consistency
            of the final model, a model processor implementation would have to be more robust than what is shown in the example.
        </para>
    </section>
</chapter>
