Package oracle.dbtools.plugin.api.http.annotations

## Annotation Type Dispatches

-     @Retention(RUNTIME)
      @Target(TYPE)
      @Documented
      public @interface Dispatches

  Annotation that should be applied to sub-types of HttpServlet to describe the URI patterns that the servlet can dispatch. These patterns are termed Route patterns and have a specific syntax.

  ### Basic Example

       @Dispatches(@PathTemplate("some/resource"))
       @Provides
       class ExampleServlet extends HttpServlet {

        @Inject ExampleServlet(Logger log) {
         super();
         this.log = log;
        }

        public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
          response.setContentType("text/plain");
          response.getWriter().append("Hello World");
          response.flushBuffer();
          log.fine("Generated Resource");
        }

        private final Logger log;
       }

  - This servlet dispatches the `some/resource` path.

  - The servlet must have the `Provides` annotation to be discoverable. The class must extend `HttpServlet` directly, or directly implement the `Servlet` interface.

    If the class does not directly extend `HttpServlet` or directly implement the `Servlet` interface, then it must express that it provides the `Servlet` service via the `Provides` annotation. For example: `@Provides(HttpServlet.class)` or `@Provides(Servlet.class)`.

  - The servlet can express any dependencies using a Constructor annotated with the `Inject` annotation. This servlet injects the `Log` service.

  - The set of HTTP methods that the servlet supports is inferred by examining which of the `HttpServlet` methods the class overrides. This example overrides `HttpServlet#doGet(HttpServletRequest,HttpServletResponse)`.

    The override may be `public` or `protected`.

  ### Dispatching multiple paths

       @Dispatches({@PathTemplate(name="collection", value="/some/collection/",methods={"GET","POST"),
                         @PathTemplate(name="item", value="/some/collection/:id",methods={"GET","PUT","DELETE")})
       @Provides
       class ExampleCollectionServlet extends HttpServlet {

        @Inject ExampleServlet(PathTemplates pathTemplates,Logger log) {
         super();
         this.pathTemplates = pathTemplates;
         this.log = log;
        }

        public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
          final PathTemplateMatch matched = pathTemplates.matchedTemplate(request);
          switch ( matched.name() ) {
          case "collection":
           // generate resource for some/collection/ path
           ...
           log.fine("Generated Collection Resource");
           break;
          default:
           // generate resource for some/collection/:id path
           final String id = matched.parameters().get("id");
           ...
           log.fine("Generated Resource for: " +id );
          }
        }

        public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
          // can only be a POST on the collection resource
          ...
        }

        public void doPut(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
          // can only be a PUT on an individual resource
          final String id = pathTemplates.matchedTemplate(request).parameters().get("id");
          ...
        }

        public void doDelete(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
          // can only be a DELETE on an individual resource
          final String id = pathTemplates.matchedTemplate(request).parameters().get("id");
          ...
        }

        private final Logger log;
        private final PathTemplates pathTemplates;

       }

  - A servlet can dispatch for multiple paths by specifying multiple `PathTemplate` annotations. This example shows a common pattern, consisting of one pattern for a collection resource, and another pattern for individual resources within the collection.

  - The HTTP methods that a particular pattern supports can be specified via the `PathTemplate.methods()` property.

    In this example the collection resource supports GET for retrieving an enumeration of all resources in the collection, and POST for adding new resources to the collection.

    The individual resource supports GET for retrieving the resource, PUT for updating the resource, and DELETE for removing the resource.

  ### Dispatching custom HTTP methods

  Name your handler method after the HTTP method, e.g: `GET` is handled by `doGet(HttpServletRequest,HttpServletResponse)`. For example, to handle the `PATCH` method, define a `doPatch(HttpServletRequest,HttpServletResponse)` method. Note that you must override the `service(HttpServletRequest,HttpServletResponse)` method to cause it to dispatch to the `doPatch` method, as shown below:

       @Provides
       @Dispatches(@PathTemplate("/examples/custom"))
       class SupportsPatchExample extends HttpServlet {

         @Inject
         SupportsPathExample() {
         }

         protected void service(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
           final String method = req.getMethod();
           // dispatch to doPatch() method
           if ("PATCH".equalsIgnoreCase(method)) {
             doPatch(req, resp);
           } else {
             super.service(req, resp);
           }
         }

         private void doPatch(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
           // handle PATCH ...
         }
       }

  ### Explicitly stating supported HTTP methods

  As shown above, supported HTTP methods are discovered by looking for methods starting with `do` and taking `(HttpServletRequest,HttpServletResponse)` arguments.

  If you prefer you can explicitly enumerate the methods that are supported via the `PathTemplate.methods()` property:

       @Provides
       @Dispatches(@PathTemplate(value = "/examples/explicit", methods = { "GET",
           "PATCH" }))
       class ExplicitHttpMethods extends HttpServlet {

         protected void service(HttpServletRequest req, HttpServletResponse resp)
             throws ServletException, IOException {
           final String method = req.getMethod();
           // dispatch to doPatch() method
           if ("PATCH".equalsIgnoreCase(method)) {
             // handle PATCH
             ...
           } else if ("GET".equalsIgnoreCase(method)) {
             // handle GET
           } else {
             super.service(req, resp);
           }
         }
       }

  Author:
    cdivilly
  See Also:
    Route Pattern Syntax

- - ### Required Element Summary

    Required Elements
    Modifier and Type | Required Element | Description
    --- | --- | ---
    `PathTemplate[]` | `value` | Identifies the URI patterns that a type can dispatch:

- - ### Element Detail

    - #### value

          PathTemplate[] value

      Identifies the URI patterns that a type can dispatch:

           @Dispatches(@PathTemplate("some/collection/:id")

           @Dispatches({@PathTemplate(value="some/collection/",methods={"GET","POST"),
                           @PathTemplate(value="some/collection/:id",methods={"GET","PUT","DELETE")})

      Returns:
        The `PathTemplate`s for this servlet