1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.client;
20
21 import java.nio.ByteBuffer;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import org.eclipse.jetty.client.api.ContentResponse;
26 import org.eclipse.jetty.client.api.Request;
27 import org.eclipse.jetty.client.api.Response;
28 import org.eclipse.jetty.client.api.Result;
29 import org.eclipse.jetty.http.HttpField;
30 import org.eclipse.jetty.util.Callback;
31 import org.eclipse.jetty.util.IteratingNestedCallback;
32 import org.eclipse.jetty.util.log.Log;
33 import org.eclipse.jetty.util.log.Logger;
34
35 public class ResponseNotifier
36 {
37 private static final Logger LOG = Log.getLogger(ResponseNotifier.class);
38
39 public void notifyBegin(List<Response.ResponseListener> listeners, Response response)
40 {
41
42 for (int i = 0; i < listeners.size(); ++i)
43 {
44 Response.ResponseListener listener = listeners.get(i);
45 if (listener instanceof Response.BeginListener)
46 notifyBegin((Response.BeginListener)listener, response);
47 }
48 }
49
50 private void notifyBegin(Response.BeginListener listener, Response response)
51 {
52 try
53 {
54 listener.onBegin(response);
55 }
56 catch (Throwable x)
57 {
58 LOG.info("Exception while notifying listener " + listener, x);
59 }
60 }
61
62 public boolean notifyHeader(List<Response.ResponseListener> listeners, Response response, HttpField field)
63 {
64 boolean result = true;
65
66 for (int i = 0; i < listeners.size(); ++i)
67 {
68 Response.ResponseListener listener = listeners.get(i);
69 if (listener instanceof Response.HeaderListener)
70 result &= notifyHeader((Response.HeaderListener)listener, response, field);
71 }
72 return result;
73 }
74
75 private boolean notifyHeader(Response.HeaderListener listener, Response response, HttpField field)
76 {
77 try
78 {
79 return listener.onHeader(response, field);
80 }
81 catch (Throwable x)
82 {
83 LOG.info("Exception while notifying listener " + listener, x);
84 return false;
85 }
86 }
87
88 public void notifyHeaders(List<Response.ResponseListener> listeners, Response response)
89 {
90
91 for (int i = 0; i < listeners.size(); ++i)
92 {
93 Response.ResponseListener listener = listeners.get(i);
94 if (listener instanceof Response.HeadersListener)
95 notifyHeaders((Response.HeadersListener)listener, response);
96 }
97 }
98
99 private void notifyHeaders(Response.HeadersListener listener, Response response)
100 {
101 try
102 {
103 listener.onHeaders(response);
104 }
105 catch (Throwable x)
106 {
107 LOG.info("Exception while notifying listener " + listener, x);
108 }
109 }
110
111 public void notifyContent(List<Response.ResponseListener> listeners, Response response, ByteBuffer buffer, Callback callback)
112 {
113
114
115
116 ContentCallback contentCallback = new ContentCallback(listeners, response, buffer, callback);
117 contentCallback.iterate();
118 }
119
120 private void notifyContent(Response.AsyncContentListener listener, Response response, ByteBuffer buffer, Callback callback)
121 {
122 try
123 {
124 listener.onContent(response, buffer, callback);
125 }
126 catch (Throwable x)
127 {
128 LOG.info("Exception while notifying listener " + listener, x);
129 }
130 }
131
132 public void notifySuccess(List<Response.ResponseListener> listeners, Response response)
133 {
134
135 for (int i = 0; i < listeners.size(); ++i)
136 {
137 Response.ResponseListener listener = listeners.get(i);
138 if (listener instanceof Response.SuccessListener)
139 notifySuccess((Response.SuccessListener)listener, response);
140 }
141 }
142
143 private void notifySuccess(Response.SuccessListener listener, Response response)
144 {
145 try
146 {
147 listener.onSuccess(response);
148 }
149 catch (Throwable x)
150 {
151 LOG.info("Exception while notifying listener " + listener, x);
152 }
153 }
154
155 public void notifyFailure(List<Response.ResponseListener> listeners, Response response, Throwable failure)
156 {
157
158 for (int i = 0; i < listeners.size(); ++i)
159 {
160 Response.ResponseListener listener = listeners.get(i);
161 if (listener instanceof Response.FailureListener)
162 notifyFailure((Response.FailureListener)listener, response, failure);
163 }
164 }
165
166 private void notifyFailure(Response.FailureListener listener, Response response, Throwable failure)
167 {
168 try
169 {
170 listener.onFailure(response, failure);
171 }
172 catch (Throwable x)
173 {
174 LOG.info("Exception while notifying listener " + listener, x);
175 }
176 }
177
178 public void notifyComplete(List<Response.ResponseListener> listeners, Result result)
179 {
180
181 for (int i = 0; i < listeners.size(); ++i)
182 {
183 Response.ResponseListener listener = listeners.get(i);
184 if (listener instanceof Response.CompleteListener)
185 notifyComplete((Response.CompleteListener)listener, result);
186 }
187 }
188
189 private void notifyComplete(Response.CompleteListener listener, Result result)
190 {
191 try
192 {
193 listener.onComplete(result);
194 }
195 catch (Throwable x)
196 {
197 LOG.info("Exception while notifying listener " + listener, x);
198 }
199 }
200
201 public void forwardSuccess(List<Response.ResponseListener> listeners, Response response)
202 {
203 notifyBegin(listeners, response);
204 for (Iterator<HttpField> iterator = response.getHeaders().iterator(); iterator.hasNext();)
205 {
206 HttpField field = iterator.next();
207 if (!notifyHeader(listeners, response, field))
208 iterator.remove();
209 }
210 notifyHeaders(listeners, response);
211 if (response instanceof ContentResponse)
212 notifyContent(listeners, response, ByteBuffer.wrap(((ContentResponse)response).getContent()), Callback.NOOP);
213 notifySuccess(listeners, response);
214 }
215
216 public void forwardSuccessComplete(List<Response.ResponseListener> listeners, Request request, Response response)
217 {
218 forwardSuccess(listeners, response);
219 notifyComplete(listeners, new Result(request, response));
220 }
221
222 public void forwardFailure(List<Response.ResponseListener> listeners, Response response, Throwable failure)
223 {
224 notifyBegin(listeners, response);
225 for (Iterator<HttpField> iterator = response.getHeaders().iterator(); iterator.hasNext();)
226 {
227 HttpField field = iterator.next();
228 if (!notifyHeader(listeners, response, field))
229 iterator.remove();
230 }
231 notifyHeaders(listeners, response);
232 if (response instanceof ContentResponse)
233 notifyContent(listeners, response, ByteBuffer.wrap(((ContentResponse)response).getContent()), Callback.NOOP);
234 notifyFailure(listeners, response, failure);
235 }
236
237 public void forwardFailureComplete(List<Response.ResponseListener> listeners, Request request, Throwable requestFailure, Response response, Throwable responseFailure)
238 {
239 forwardFailure(listeners, response, responseFailure);
240 notifyComplete(listeners, new Result(request, requestFailure, response, responseFailure));
241 }
242
243 private class ContentCallback extends IteratingNestedCallback
244 {
245 private final List<Response.ResponseListener> listeners;
246 private final Response response;
247 private final ByteBuffer buffer;
248 private int index;
249
250 private ContentCallback(List<Response.ResponseListener> listeners, Response response, ByteBuffer buffer, Callback callback)
251 {
252 super(callback);
253 this.listeners = listeners;
254 this.response = response;
255
256 this.buffer = buffer.slice();
257 }
258
259 @Override
260 protected Action process() throws Exception
261 {
262 if (index == listeners.size())
263 return Action.SUCCEEDED;
264
265 Response.ResponseListener listener = listeners.get(index);
266 if (listener instanceof Response.AsyncContentListener)
267 {
268
269
270
271 buffer.clear();
272 ResponseNotifier.this.notifyContent((Response.AsyncContentListener)listener, response, buffer, this);
273 return Action.SCHEDULED;
274 }
275 else
276 {
277 succeeded();
278 return Action.SCHEDULED;
279 }
280 }
281
282 @Override
283 public void succeeded()
284 {
285 ++index;
286 super.succeeded();
287 }
288 }
289 }