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}