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     public void close() throws IOException {
118         releaseResources();
119         if (!this.future.isDone()) {
120             this.future.cancel();
121         }
122     }
123 
124     public HttpHost getTarget() {
125         return this.requestProducer.getTarget();
126     }
127 
128     public HttpRequest generateRequest() throws IOException, HttpException {
129         return this.requestProducer.generateRequest();
130     }
131 
132     public void produceContent(
133             final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
134         this.requestProducer.produceContent(encoder, ioctrl);
135     }
136 
137     public void requestCompleted(final HttpContext context) {
138         this.requestProducer.requestCompleted(context);
139         this.requestSent = true;
140     }
141 
142     public boolean isRepeatable() {
143         return false;
144     }
145 
146     public void resetRequest() {
147     }
148 
149     public void responseReceived(final HttpResponse response) throws IOException, HttpException {
150         this.responseConsumer.responseReceived(response);
151     }
152 
153     public void consumeContent(
154             final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
155         this.responseConsumer.consumeContent(decoder, ioctrl);
156     }
157 
158     public void failed(final Exception ex) {
159         try {
160             if (!this.requestSent) {
161                 this.requestProducer.failed(ex);
162             }
163             this.responseConsumer.failed(ex);
164         } finally {
165             try {
166                 this.future.failed(ex);
167             } finally {
168                 releaseResources();
169             }
170         }
171     }
172 
173     public boolean cancel() {
174         try {
175             final boolean cancelled = this.responseConsumer.cancel();
176             this.future.cancel();
177             releaseResources();
178             return cancelled;
179         } catch (final RuntimeException ex) {
180             failed(ex);
181             throw ex;
182         }
183     }
184 
185     public void responseCompleted(final HttpContext context) {
186         try {
187             this.responseConsumer.responseCompleted(context);
188             final T result = this.responseConsumer.getResult();
189             final Exception ex = this.responseConsumer.getException();
190             if (ex == null) {
191                 this.future.completed(result);
192             } else {
193                 this.future.failed(ex);
194             }
195             releaseResources();
196         } catch (final RuntimeException ex) {
197             failed(ex);
198             throw ex;
199         }
200     }
201 
202     public T getResult() {
203         return this.responseConsumer.getResult();
204     }
205 
206     public Exception getException() {
207         return this.responseConsumer.getException();
208     }
209 
210     public HttpContext getContext() {
211         return this.localContext;
212     }
213 
214     public HttpProcessor getHttpProcessor() {
215         return this.httppocessor;
216     }
217 
218     public ConnectionReuseStrategy getConnectionReuseStrategy() {
219         return this.reuseStrategy;
220     }
221 
222     public boolean isDone() {
223         return this.responseConsumer.isDone();
224     }
225 
226 }