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.hc.client5.http.impl.classic;
29  
30  import java.io.IOException;
31  import java.util.Iterator;
32  import java.util.Locale;
33  
34  import org.apache.hc.client5.http.classic.ExecRuntime;
35  import org.apache.hc.core5.annotation.Internal;
36  import org.apache.hc.core5.http.ClassicHttpResponse;
37  import org.apache.hc.core5.http.Header;
38  import org.apache.hc.core5.http.HttpEntity;
39  import org.apache.hc.core5.http.ProtocolException;
40  import org.apache.hc.core5.http.ProtocolVersion;
41  import org.apache.hc.core5.io.CloseMode;
42  import org.apache.hc.core5.io.ModalCloseable;
43  import org.apache.hc.core5.util.Args;
44  
45  /**
46   * Provided for backward compatibility with HttpClient 4.x.
47   *
48   * @since 4.3
49   */
50  public final class CloseableHttpResponse implements ClassicHttpResponse, ModalCloseable {
51  
52      private final ClassicHttpResponse response;
53      private final CloseableDelegate closeableDelegate;
54  
55      /**
56       * @since 5.4
57       */
58      @Internal
59      public static CloseableHttpResponse adapt(final ClassicHttpResponse response) {
60          if (response == null) {
61              return null;
62          }
63          return response instanceof CloseableHttpResponse ?
64                  (CloseableHttpResponse) response :
65                  new CloseableHttpResponse(response);
66      }
67  
68      /**
69       * @since 5.5
70       */
71      @Internal
72      public static CloseableHttpResponse create(final ClassicHttpResponse response,
73                                                 final CloseableDelegate closeableDelegate) {
74          if (response == null) {
75              return null;
76          }
77          return new CloseableHttpResponse(response, closeableDelegate);
78      }
79  
80      CloseableHttpResponse(final ClassicHttpResponse response) {
81          this.response = Args.notNull(response, "Response");
82          this.closeableDelegate = null;
83      }
84  
85      CloseableHttpResponse(final ClassicHttpResponse response, final CloseableDelegate closeableDelegate) {
86          this.response = Args.notNull(response, "Response");
87          this.closeableDelegate = closeableDelegate;
88      }
89  
90      CloseableHttpResponse(final ClassicHttpResponse response, final ExecRuntime execRuntime) {
91          this.response = Args.notNull(response, "Response");
92          this.closeableDelegate = (closeable, closeMode) -> {
93              try {
94                  if (closeMode == CloseMode.GRACEFUL) {
95                      response.close();
96                  }
97                  execRuntime.disconnectEndpoint();
98              } finally {
99                  execRuntime.discardEndpoint();
100             }
101         };
102     }
103 
104     @Override
105     public int getCode() {
106         return response.getCode();
107     }
108 
109     @Override
110     public HttpEntity getEntity() {
111         return response.getEntity();
112     }
113 
114     @Override
115     public boolean containsHeader(final String name) {
116         return response.containsHeader(name);
117     }
118 
119     @Override
120     public void setVersion(final ProtocolVersion version) {
121         response.setVersion(version);
122     }
123 
124     @Override
125     public void setCode(final int code) {
126         response.setCode(code);
127     }
128 
129     @Override
130     public String getReasonPhrase() {
131         return response.getReasonPhrase();
132     }
133 
134     @Override
135     public int countHeaders(final String name) {
136         return response.countHeaders(name);
137     }
138 
139     @Override
140     public void setEntity(final HttpEntity entity) {
141         response.setEntity(entity);
142     }
143 
144     @Override
145     public ProtocolVersion getVersion() {
146         return response.getVersion();
147     }
148 
149     @Override
150     public void setReasonPhrase(final String reason) {
151         response.setReasonPhrase(reason);
152     }
153 
154     @Override
155     public Header[] getHeaders(final String name) {
156         return response.getHeaders(name);
157     }
158 
159     @Override
160     public void addHeader(final Header header) {
161         response.addHeader(header);
162     }
163 
164     @Override
165     public Locale getLocale() {
166         return response.getLocale();
167     }
168 
169     @Override
170     public void addHeader(final String name, final Object value) {
171         response.addHeader(name, value);
172     }
173 
174     @Override
175     public void setLocale(final Locale loc) {
176         response.setLocale(loc);
177     }
178 
179     @Override
180     public Header getHeader(final String name) throws ProtocolException {
181         return response.getHeader(name);
182     }
183 
184     @Override
185     public void setHeader(final Header header) {
186         response.setHeader(header);
187     }
188 
189     @Override
190     public Header getFirstHeader(final String name) {
191         return response.getFirstHeader(name);
192     }
193 
194     @Override
195     public void setHeader(final String name, final Object value) {
196         response.setHeader(name, value);
197     }
198 
199     @Override
200     public void setHeaders(final Header... headers) {
201         response.setHeaders(headers);
202     }
203 
204     @Override
205     public boolean removeHeader(final Header header) {
206         return response.removeHeader(header);
207     }
208 
209     @Override
210     public boolean removeHeaders(final String name) {
211         return response.removeHeaders(name);
212     }
213 
214     @Override
215     public Header getLastHeader(final String name) {
216         return response.getLastHeader(name);
217     }
218 
219     @Override
220     public Header[] getHeaders() {
221         return response.getHeaders();
222     }
223 
224     @Override
225     public Iterator<Header> headerIterator() {
226         return response.headerIterator();
227     }
228 
229     @Override
230     public Iterator<Header> headerIterator(final String name) {
231         return response.headerIterator(name);
232     }
233 
234     private void doClose(final CloseMode closeMode) throws IOException {
235         if (closeableDelegate != null) {
236             closeableDelegate.close(response, closeMode);
237         } else {
238             response.close();
239         }
240     }
241 
242     @Override
243     public void close(final CloseMode closeMode) {
244         try {
245             doClose(closeMode);
246         } catch (final IOException ignore) {
247         }
248     }
249 
250     @Override
251     public void close() throws IOException {
252         doClose(CloseMode.GRACEFUL);
253     }
254 
255     @Override
256     public String toString() {
257         return response.toString();
258     }
259 
260 }