Class Request

All Implemented Interfaces:
SharedResource

public class Request extends AbstractResource

This class represents a single request (which may have any content model that a ServerProvider chooses to implement). The URI is used by the Container to route it to the appropriate RequestHandler, which in turn will provide a ContentChannel to write content to.

To ensure application consistency throughout the lifetime of a Request, the Request itself holds an active reference to the Container for which it was created. This has the unfortunate side-effect of requiring the creator of a Request to do explicit reference counting during the setup of a content stream.

For every successfully dispatched Request (i.e. a non-null ContentChannel has been retrieved), there will be exactly one Response returned to the provided ResponseHandler.

Author:
Simon Thoresen Hult
See Also:
  • Constructor Details

    • Request

      public Request(CurrentContainer current, URI uri)

      Creates a new instance of this class. As a ServerProvider you need to inject a CurrentContainer instance at construction time and use that as argument to this method. As a RequestHandler that needs to spawn child Requests, use the other constructor.

      Because a Request holds an active reference to the owning Container, it is necessary to call AbstractResource.release() once a ContentChannel has been established. Suggested usage:

       Request request = null;
       ContentChannel content = null;
       try {
           request = new Request(currentContainer, uri);
           (...)
           content = request.connect(responseHandler);
       } finally {
          if (request != null) request.release();
       }
       content.write(...);
       
      Parameters:
      current - The CurrentContainer for which this Request is created.
      uri - The identifier of this request.
    • Request

      public Request(CurrentContainer current, URI uri, boolean isServerRequest)
    • Request

      public Request(CurrentContainer current, URI uri, boolean isServerRequest, long creationTime)
    • Request

      public Request(Request parent, URI uri)

      Creates a new instance of this class. As a RequestHandler you should use this method to spawn child Requests of another. As a ServerProvider that needs to spawn new Requests, us the other constructor.

      Because a Request holds an active reference to the owning Container, it is necessary to call AbstractResource.release() once a ContentChannel has been established. Suggested usage:

       Request request = null;
       ContentChannel content = null;
       try {
           request = new Request(parentRequest, uri);
           (...)
           content = request.connect(responseHandler);
       } finally {
          if (request != null) request.release();
       }
       content.write(...);
       
      Parameters:
      parent - The parent Request of this.
      uri - The identifier of this request.
  • Method Details

    • container

      public Container container()
      Returns the Container for which this Request was created
    • getUri

      public URI getUri()
      Returns the Uniform Resource Identifier used by the Container to resolve the appropriate RequestHandler for this Request.
    • isServerRequest

      public boolean isServerRequest()
      Returns whether this Request was created by a ServerProvider. The value of this is used by Container.resolveHandler(Request) to decide whether to match against server- or client-bindings.
      Returns:
      true, if this is a server request
    • getBindingMatch

      public BindingMatch<RequestHandler> getBindingMatch()
      Returns the last resolved BindingMatch, or null if none has been resolved yet. This is set automatically when calling the Container.resolveHandler(Request) method. The BindingMatch object holds information about the match of this Request's URI to the UriPattern of the resolved RequestHandler. It allows you to reflect on the parts of the URI that were matched by wildcards in the UriPattern.
      Returns:
      the last resolved BindingMatch, or null
      See Also:
    • setBindingMatch

      public Request setBindingMatch(BindingMatch<RequestHandler> bindingMatch)

      Sets the last resolved BindingMatch of this Request. This is called by the Container.resolveHandler(Request) method.

      Parameters:
      bindingMatch - The BindingMatch to set.
      Returns:
      This, to allow chaining.
      See Also:
    • context

      public Map<String,Object> context()

      Returns the named application context objects. This data is not intended for network transport, rather they are intended for passing shared data between components of an Application.

      Returns:
      The context map.
    • headers

      public HeaderFields headers()

      Returns the set of header fields of this Request. These are the meta-data of the Request, and are not applied to any internal Container logic. As opposed to the context(), the headers ARE intended for network transport. Modifying headers is a thread-unsafe operation -- any changes made after calling connect(ResponseHandler) might never become visible to other threads, and might throw ConcurrentModificationExceptions in other threads.

      Returns:
      The header fields.
    • setTimeoutManager

      public void setTimeoutManager(TimeoutManager timeoutManager)

      Sets a TimeoutManager to be called when setTimeout(long, TimeUnit) is invoked. If a timeout has already been set for this Request, the TimeoutManager is called before returning. This method will throw an IllegalStateException if it has already been called.

      NOTE: This is used by the default timeout management implementation, so unless you are replacing that mechanism you should avoid calling this method. If you do want to replace that mechanism, you need to call this method prior to calling the target RequestHandler (since that injects the default manager).

      Parameters:
      timeoutManager - The manager to set.
      Throws:
      NullPointerException - If the TimeoutManager is null.
      IllegalStateException - If another TimeoutManager has already been set.
      See Also:
    • getTimeoutManager

      public TimeoutManager getTimeoutManager()

      Returns the TimeoutManager of this request, or null if none has been assigned.

      Returns:
      The TimeoutManager of this Request.
      See Also:
    • setTimeout

      public void setTimeout(long timeout, TimeUnit unit)

      Sets the allocated time that this Request is allowed to exist before the corresponding call to ResponseHandler.handleResponse(Response) must have been made. If no timeout value is assigned to a Request, there will be no timeout.

      Once the allocated time has expired, unless the ResponseHandler has already been called, the RequestHandler.handleTimeout(Request, ResponseHandler) method is invoked.

      Calls to isCancelled() return true if timeout has been exceeded.

      Parameters:
      timeout - The allocated amount of time.
      unit - The time unit of the timeout argument.
      See Also:
    • getTimeout

      public Long getTimeout(TimeUnit unit)

      Returns the allocated number of time units that this Request is allowed to exist. If no timeout has been set for this Request, this method returns null.

      Parameters:
      unit - The unit to return the timeout in.
      Returns:
      The timeout of this Request.
      See Also:
    • timeRemaining

      public Long timeRemaining(TimeUnit unit)

      Returns the time that this Request is allowed to exist. If no timeout has been set, this method will return null.

      Parameters:
      unit - The unit to return the time in.
      Returns:
      The number of time units left until this Request times out, or null.
    • timeElapsed

      public long timeElapsed(TimeUnit unit)

      Returns the time that this Request has existed so far.

      Parameters:
      unit - The unit to return the time in.
      Returns:
      The number of time units elapsed since this Request was created.
    • creationTime

      public long creationTime(TimeUnit unit)

      Returns the time at which this Request was created. This is whatever value was returned by Timer.currentTimeMillis() when constructing this.

      Parameters:
      unit - The unit to return the time in.
      Returns:
      The creation time of this Request.
    • isCancelled

      public boolean isCancelled()

      Returns whether or not this Request has been cancelled. This can be thought of as the Thread.isInterrupted() of Requests - it does not enforce anything in ways of blocking the Request, it is simply a signal to allow the developer to break early if the Request has already been dropped.

      This method will also return true if the Request has a non-null timeout, and that timeout has expired.

      Finally, this method will also return true if this Request has a parent Request that has been cancelled.

      Returns:
      True if this Request has timed out or been cancelled.
      See Also:
    • cancel

      public void cancel()

      Mark this request as cancelled and frees any resources held by the request if possible. All subsequent calls to isCancelled() on this Request return true.

      See Also:
    • connect

      public ContentChannel connect(ResponseHandler responseHandler)

      Attempts to resolve and connect to the RequestHandler appropriate for the URI of this Request. An exception is thrown if this operation fails at any point. This method is exception-safe.

      Parameters:
      responseHandler - The handler to pass the corresponding Response to.
      Returns:
      The ContentChannel to write the Request content to.
      Throws:
      NullPointerException - If the ResponseHandler is null.
      BindingNotFoundException - If the corresponding call to Container.resolveHandler(Request) returns null.
    • destroy

      protected void destroy()
      Description copied from class: AbstractResource

      This method signals that this AbstractResource can dispose of any internal resources, and commence with shut down of any internal threads. This will be called once the reference count of this resource reaches zero.

      Overrides:
      destroy in class AbstractResource