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 package org.apache.http.nio.protocol;
28
29 import java.io.IOException;
30 import java.util.concurrent.atomic.AtomicBoolean;
31
32 import org.apache.http.HttpEntity;
33 import org.apache.http.HttpException;
34 import org.apache.http.HttpResponse;
35 import org.apache.http.entity.ContentType;
36 import org.apache.http.nio.ContentDecoder;
37 import org.apache.http.nio.IOControl;
38 import org.apache.http.protocol.HttpContext;
39
40
41
42
43
44
45
46
47 public abstract class AbstractAsyncResponseConsumer<T> implements HttpAsyncResponseConsumer<T> {
48
49 private final AtomicBoolean completed;
50
51 private volatile T result;
52 private volatile Exception ex;
53
54 public AbstractAsyncResponseConsumer() {
55 super();
56 this.completed = new AtomicBoolean(false);
57 }
58
59
60
61
62
63
64
65
66
67
68
69 protected abstract void onResponseReceived(
70 HttpResponse response) throws HttpException, IOException;
71
72
73
74
75
76
77
78
79
80
81
82
83
84 protected abstract void onContentReceived(
85 ContentDecoder decoder, IOControl ioControl) throws IOException;
86
87
88
89
90
91
92
93
94 protected abstract void onEntityEnclosed(
95 HttpEntity entity, ContentType contentType) throws IOException;
96
97
98
99
100
101
102
103
104
105 protected abstract T buildResult(HttpContext context) throws Exception;
106
107
108
109
110 protected abstract void releaseResources();
111
112
113
114
115
116
117
118 protected void onClose() throws IOException {
119 }
120
121
122
123
124 protected ContentType getContentType(final HttpEntity entity) {
125 return entity != null ? ContentType.getOrDefault(entity) : null;
126 }
127
128
129
130
131 @Override
132 public final void responseReceived(
133 final HttpResponse response) throws IOException, HttpException {
134 onResponseReceived(response);
135 final HttpEntity entity = response.getEntity();
136 if (entity != null) {
137 onEntityEnclosed(entity, getContentType(entity));
138 }
139 }
140
141
142
143
144 @Override
145 public final void consumeContent(
146 final ContentDecoder decoder, final IOControl ioControl) throws IOException {
147 onContentReceived(decoder, ioControl);
148 }
149
150
151
152
153 @Override
154 public final void responseCompleted(final HttpContext context) {
155 if (this.completed.compareAndSet(false, true)) {
156 try {
157 this.result = buildResult(context);
158 } catch (final Exception ex) {
159 this.ex = ex;
160 } finally {
161 releaseResources();
162 }
163 }
164 }
165
166 @Override
167 public final boolean cancel() {
168 if (this.completed.compareAndSet(false, true)) {
169 releaseResources();
170 return true;
171 }
172 return false;
173 }
174
175 @Override
176 public final void failed(final Exception ex) {
177 if (this.completed.compareAndSet(false, true)) {
178 this.ex = ex;
179 releaseResources();
180 }
181 }
182
183 @Override
184 public final void close() throws IOException {
185 if (this.completed.compareAndSet(false, true)) {
186 releaseResources();
187 onClose();
188 }
189 }
190
191 @Override
192 public Exception getException() {
193 return this.ex;
194 }
195
196 @Override
197 public T getResult() {
198 return this.result;
199 }
200
201 @Override
202 public boolean isDone() {
203 return this.completed.get();
204 }
205
206 }