View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
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.HttpParams;
44  import org.apache.http.protocol.HttpContext;
45  import org.apache.http.protocol.HttpProcessor;
46  import org.apache.http.util.Args;
47  
48  /**
49   * Basic implementation of {@link HttpAsyncRequestExecutionHandler} that executes
50   * a single HTTP request / response exchange.
51   *
52   * @param <T> the result type of request execution.
53   * @since 4.2
54   *
55   * @deprecated (4.3) use {@link BasicAsyncClientExchangeHandler}.
56   */
57  @Deprecated
58  public class BasicAsyncRequestExecutionHandler<T> implements HttpAsyncRequestExecutionHandler<T> {
59  
60      private final HttpAsyncRequestProducer requestProducer;
61      private final HttpAsyncResponseConsumer<T> responseConsumer;
62      private final BasicFuture<T> future;
63      private final HttpContext localContext;
64      private final HttpProcessor httpPocessor;
65      private final ConnectionReuseStrategy reuseStrategy;
66  
67      private volatile boolean requestSent;
68  
69      public BasicAsyncRequestExecutionHandler(
70              final HttpAsyncRequestProducer requestProducer,
71              final HttpAsyncResponseConsumer<T> responseConsumer,
72              final FutureCallback<T> callback,
73              final HttpContext localContext,
74              final HttpProcessor httpPocessor,
75              final ConnectionReuseStrategy reuseStrategy,
76              final HttpParams params) {
77          super();
78          Args.notNull(requestProducer, "Request producer");
79          Args.notNull(responseConsumer, "Response consumer");
80          Args.notNull(localContext, "HTTP context");
81          Args.notNull(httpPocessor, "HTTP processor");
82          Args.notNull(reuseStrategy, "Connection reuse strategy");
83          Args.notNull(params, "HTTP parameters");
84          this.requestProducer = requestProducer;
85          this.responseConsumer = responseConsumer;
86          this.future = new BasicFuture<T>(callback);
87          this.localContext = localContext;
88          this.httpPocessor = httpPocessor;
89          this.reuseStrategy = reuseStrategy;
90      }
91  
92      public BasicAsyncRequestExecutionHandler(
93              final HttpAsyncRequestProducer requestProducer,
94              final HttpAsyncResponseConsumer<T> responseConsumer,
95              final HttpContext localContext,
96              final HttpProcessor httpPocessor,
97              final ConnectionReuseStrategy reuseStrategy,
98              final HttpParams params) {
99          this(requestProducer, responseConsumer, null, localContext, httpPocessor, reuseStrategy, params);
100     }
101 
102     public Future<T> getFuture() {
103         return this.future;
104     }
105 
106     private void releaseResources() {
107         try {
108             this.responseConsumer.close();
109         } catch (final IOException ex) {
110         }
111         try {
112             this.requestProducer.close();
113         } catch (final IOException ex) {
114         }
115     }
116 
117     @Override
118     public void close() throws IOException {
119         releaseResources();
120         if (!this.future.isDone()) {
121             this.future.cancel();
122         }
123     }
124 
125     @Override
126     public HttpHost getTarget() {
127         return this.requestProducer.getTarget();
128     }
129 
130     @Override
131     public HttpRequest generateRequest() throws IOException, HttpException {
132         return this.requestProducer.generateRequest();
133     }
134 
135     @Override
136     public void produceContent(
137             final ContentEncoder encoder, final IOControl ioControl) throws IOException {
138         this.requestProducer.produceContent(encoder, ioControl);
139     }
140 
141     @Override
142     public void requestCompleted(final HttpContext context) {
143         this.requestProducer.requestCompleted(context);
144         this.requestSent = true;
145     }
146 
147     @Override
148     public boolean isRepeatable() {
149         return false;
150     }
151 
152     @Override
153     public void resetRequest() {
154     }
155 
156     @Override
157     public void responseReceived(final HttpResponse response) throws IOException, HttpException {
158         this.responseConsumer.responseReceived(response);
159     }
160 
161     @Override
162     public void consumeContent(
163             final ContentDecoder decoder, final IOControl ioControl) throws IOException {
164         this.responseConsumer.consumeContent(decoder, ioControl);
165     }
166 
167     @Override
168     public void failed(final Exception ex) {
169         try {
170             if (!this.requestSent) {
171                 this.requestProducer.failed(ex);
172             }
173             this.responseConsumer.failed(ex);
174         } finally {
175             try {
176                 this.future.failed(ex);
177             } finally {
178                 releaseResources();
179             }
180         }
181     }
182 
183     @Override
184     public boolean cancel() {
185         try {
186             final boolean cancelled = this.responseConsumer.cancel();
187             this.future.cancel();
188             releaseResources();
189             return cancelled;
190         } catch (final RuntimeException ex) {
191             failed(ex);
192             throw ex;
193         }
194     }
195 
196     @Override
197     public void responseCompleted(final HttpContext context) {
198         try {
199             this.responseConsumer.responseCompleted(context);
200             final T result = this.responseConsumer.getResult();
201             final Exception ex = this.responseConsumer.getException();
202             if (ex == null) {
203                 this.future.completed(result);
204             } else {
205                 this.future.failed(ex);
206             }
207             releaseResources();
208         } catch (final RuntimeException ex) {
209             failed(ex);
210             throw ex;
211         }
212     }
213 
214     @Override
215     public T getResult() {
216         return this.responseConsumer.getResult();
217     }
218 
219     @Override
220     public Exception getException() {
221         return this.responseConsumer.getException();
222     }
223 
224     @Override
225     public HttpContext getContext() {
226         return this.localContext;
227     }
228 
229     @Override
230     public HttpProcessor getHttpProcessor() {
231         return this.httpPocessor;
232     }
233 
234     @Override
235     public ConnectionReuseStrategy getConnectionReuseStrategy() {
236         return this.reuseStrategy;
237     }
238 
239     @Override
240     public boolean isDone() {
241         return this.responseConsumer.isDone();
242     }
243 
244 }