1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.nio.protocol;
29
30 import java.io.IOException;
31 import java.util.concurrent.Future;
32
33 import org.apache.http.ConnectionReuseStrategy;
34 import org.apache.http.HttpException;
35 import org.apache.http.HttpHost;
36 import org.apache.http.HttpRequest;
37 import org.apache.http.HttpResponse;
38 import org.apache.http.concurrent.BasicFuture;
39 import org.apache.http.concurrent.FutureCallback;
40 import org.apache.http.nio.ContentDecoder;
41 import org.apache.http.nio.ContentEncoder;
42 import org.apache.http.nio.IOControl;
43 import org.apache.http.params.DefaultedHttpParams;
44 import org.apache.http.params.HttpParams;
45 import org.apache.http.protocol.HttpContext;
46 import org.apache.http.protocol.HttpProcessor;
47
48
49
50
51
52
53
54
55 public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExecutionHandler<T> {
56
57 private final HttpAsyncRequestProducer requestProducer;
58 private final HttpAsyncResponseConsumer<T> responseConsumer;
59 private final BasicFuture<T> future;
60 private final HttpContext localContext;
61 private final HttpProcessor httppocessor;
62 private final ConnectionReuseStrategy reuseStrategy;
63 private final HttpParams params;
64
65 private volatile boolean requestSent;
66
67 public BasicAsyncRequestExecutionHandler(
68 final HttpAsyncRequestProducer requestProducer,
69 final HttpAsyncResponseConsumer<T> responseConsumer,
70 final FutureCallback<T> callback,
71 final HttpContext localContext,
72 final HttpProcessor httppocessor,
73 final ConnectionReuseStrategy reuseStrategy,
74 final HttpParams params) {
75 super();
76 if (requestProducer == null) {
77 throw new IllegalArgumentException("Request producer may not be null");
78 }
79 if (responseConsumer == null) {
80 throw new IllegalArgumentException("Response consumer may not be null");
81 }
82 if (localContext == null) {
83 throw new IllegalArgumentException("HTTP context may not be null");
84 }
85 if (httppocessor == null) {
86 throw new IllegalArgumentException("HTTP processor may not be null");
87 }
88 if (reuseStrategy == null) {
89 throw new IllegalArgumentException("Connection reuse strategy may not be null");
90 }
91 if (params == null) {
92 throw new IllegalArgumentException("HTTP parameters may not be null");
93 }
94 this.requestProducer = requestProducer;
95 this.responseConsumer = responseConsumer;
96 this.future = new BasicFuture<T>(callback);
97 this.localContext = localContext;
98 this.httppocessor = httppocessor;
99 this.reuseStrategy = reuseStrategy;
100 this.params = params;
101 }
102
103 public BasicAsyncRequestExecutionHandler(
104 final HttpAsyncRequestProducer requestProducer,
105 final HttpAsyncResponseConsumer<T> responseConsumer,
106 final HttpContext localContext,
107 final HttpProcessor httppocessor,
108 final ConnectionReuseStrategy reuseStrategy,
109 final HttpParams params) {
110 this(requestProducer, responseConsumer, null, localContext, httppocessor, reuseStrategy, params);
111 }
112
113 public Future<T> getFuture() {
114 return this.future;
115 }
116
117 private void releaseResources() {
118 try {
119 this.responseConsumer.close();
120 } catch (IOException ex) {
121 }
122 try {
123 this.requestProducer.close();
124 } catch (IOException ex) {
125 }
126 }
127
128 public void close() throws IOException {
129 releaseResources();
130 if (!this.future.isDone()) {
131 this.future.cancel();
132 }
133 }
134
135 public HttpHost getTarget() {
136 return this.requestProducer.getTarget();
137 }
138
139 public HttpRequest generateRequest() throws IOException, HttpException {
140 HttpRequest request = this.requestProducer.generateRequest();
141 request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
142 return request;
143 }
144
145 public void produceContent(
146 final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
147 this.requestProducer.produceContent(encoder, ioctrl);
148 }
149
150 public void requestCompleted(final HttpContext context) {
151 this.requestProducer.requestCompleted(context);
152 this.requestSent = true;
153 }
154
155 public boolean isRepeatable() {
156 return false;
157 }
158
159 public void resetRequest() {
160 }
161
162 public void responseReceived(final HttpResponse response) throws IOException, HttpException {
163 response.setParams(new DefaultedHttpParams(response.getParams(), this.params));
164 this.responseConsumer.responseReceived(response);
165 }
166
167 public void consumeContent(
168 final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
169 this.responseConsumer.consumeContent(decoder, ioctrl);
170 }
171
172 public void failed(final Exception ex) {
173 try {
174 if (!this.requestSent) {
175 this.requestProducer.failed(ex);
176 }
177 this.responseConsumer.failed(ex);
178 } finally {
179 try {
180 this.future.failed(ex);
181 } finally {
182 releaseResources();
183 }
184 }
185 }
186
187 public boolean cancel() {
188 try {
189 boolean cancelled = this.responseConsumer.cancel();
190 this.future.cancel();
191 releaseResources();
192 return cancelled;
193 } catch (RuntimeException ex) {
194 failed(ex);
195 throw ex;
196 }
197 }
198
199 public void responseCompleted(final HttpContext context) {
200 try {
201 this.responseConsumer.responseCompleted(context);
202 T result = this.responseConsumer.getResult();
203 Exception ex = this.responseConsumer.getException();
204 if (ex == null) {
205 this.future.completed(result);
206 } else {
207 this.future.failed(ex);
208 }
209 releaseResources();
210 } catch (RuntimeException ex) {
211 failed(ex);
212 throw ex;
213 }
214 }
215
216 public T getResult() {
217 return this.responseConsumer.getResult();
218 }
219
220 public Exception getException() {
221 return this.responseConsumer.getException();
222 }
223
224 public HttpContext getContext() {
225 return this.localContext;
226 }
227
228 public HttpProcessor getHttpProcessor() {
229 return this.httppocessor;
230 }
231
232 public ConnectionReuseStrategy getConnectionReuseStrategy() {
233 return this.reuseStrategy;
234 }
235
236 public boolean isDone() {
237 return this.responseConsumer.isDone();
238 }
239
240 }