    001// Licensed under the Apache License, Version 2.0 (the "License");
    002// you may not use this file except in compliance with the License.
    003// You may obtain a copy of the License at
    004//
    005// http://www.apache.org/licenses/LICENSE-2.0
    006//
    007// Unless required by applicable law or agreed to in writing, software
    008// distributed under the License is distributed on an "AS IS" BASIS,
    009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    010// See the License for the specific language governing permissions and
    011// limitations under the License.
    012package org.apache.tapestry5.http;
    013
    014import java.util.Objects;
    015import java.util.concurrent.Executor;
    016
    017import javax.servlet.AsyncListener;
    018import javax.servlet.http.HttpServletRequest;
    019import javax.servlet.http.HttpServletResponse;
    020
    021/**
    022 * Class used by {@linkplain AsyncRequestHandler} to return information on how to handle
    023 * a request.
    024 * @see AsyncRequestHandler
    025 */
    026public class AsyncRequestHandlerResponse
    027{
    028
    029    private static final AsyncRequestHandlerResponse NOT_HANDLED =
    030            new AsyncRequestHandlerResponse(false);
    031
    032    final private boolean async;
    033
    034    final private Executor executor;
    035
    036    private HttpServletRequest request;
    037
    038    private HttpServletResponse response;
    039
    040    private AsyncListener listener;
    041
    042    private long timeout;
    043
    044    /**
    045     * Creates an instance with a given {@link Executor}. It cannot be null.
    046     * If you want an instance with a non-async response, use {@link #notHandled()} instead.
    047     * @param executor a non-null {@link Executor}.
    048     */
    049    public AsyncRequestHandlerResponse(Executor executor)
    050    {
    051        this(true, executor);
    052    }
    053
    054    private AsyncRequestHandlerResponse(boolean async, Executor executor)
    055    {
    056        Objects.requireNonNull(executor, "Parameter executor cannot be null");
    057        this.async = async;
    058        this.executor = executor;
    059    }
    060
    061    private AsyncRequestHandlerResponse(boolean async)
    062    {
    063        this.async = async;
    064        executor = null;
    065    }
    066
    067    /**
    068     * Defines a different request and response to be passed to {@link HttpServletRequest#startAsync(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}.
    069     * Both cannot be null.
    070     */
    071    public AsyncRequestHandlerResponse with(HttpServletRequest request, HttpServletResponse response)
    072    {
    073        Objects.requireNonNull(request, "Parameter request cannot be null");
    074        Objects.requireNonNull(response, "Parameter response cannot be null");
    075        this.request = request;
    076        this.response = response;
    077        return this;
    078    }
    079
    080    /**
    081     * Defines a listener to be added to the asynchronous request. It cannot be null.
    082     */
    083    public AsyncRequestHandlerResponse with(AsyncListener listener)
    084    {
    085        Objects.requireNonNull(listener, "Parameter listener cannot be null");
    086        this.listener = listener;
    087        return this;
    088    }
    089
    090    /**
    091     * Sets the timeout for this asynchronous request in milliseconds.
    092     */
    093    public AsyncRequestHandlerResponse withTimeout(long timeout)
    094    {
    095        this.timeout = timeout;
    096        return this;
    097    }
    098
    099    /**
    100     * Returns a response saying this {@linkplain AsyncRequestHandler} doesn't handle this request.
    101     * @return an {@link AsyncRequestHandlerResponse}.
    102     */
    103    public static AsyncRequestHandlerResponse notHandled()
    104    {
    105        return NOT_HANDLED;
    106    }
    107
    108    /**
    109     * Returns whether the request should be processed asynchronously or not.
    110     */
    111    public boolean isAsync()
    112    {
    113        return async;
    114    }
    115
    116    /**
    117     * Returns the {@link Executor} to be used to process the request.
    118     */
    119    public Executor getExecutor()
    120    {
    121        return executor;
    122    }
    123
    124    /**
    125     * Returns the request to be used with {@link HttpServletRequest#startAsync()} or null.
    126     */
    127    public HttpServletRequest getRequest()
    128    {
    129        return request;
    130    }
    131
    132    /**
    133     * Returns the response to be used with {@link HttpServletRequest#startAsync()} or null.
    134     */
    135    public HttpServletResponse getResponse()
    136    {
    137        return response;
    138    }
    139
    140    /**
    141     * Returns the listener to be added to the asynchronous request or null.
    142     */
    143    public AsyncListener getListener()
    144    {
    145        return listener;
    146    }
    147
    148    /**
    149     * Returns whether a request and a response were set in this object.
    150     */
    151    public boolean isHasRequestAndResponse()
    152    {
    153        return request != null && response != null;
    154    }
    155
    156    /**
    157     * Returns the timeout, in milliseconds, for the asynchronous request. Any value
    158     * less than or equal zero is considered not having set a timeout.
    159     */
    160    public long getTimeout() {
    161        return timeout;
    162    }
    163
    164    @Override
    165    public String toString()
    166    {
    167        return "AsyncRequestHandlerResponse [async=" + async + ", executor=" + executor + ", request=" + request + ", response=" + response + ", listener="
    168                + listener + "]";
    169    }
    170
    171}