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
213 notifyContent(listeners, response, ByteBuffer.wrap(((ContentResponse)response).getContent()), new Callback.Adapter());
214 notifySuccess(listeners, response);
215 }
216
217 public void forwardSuccessComplete(List<Response.ResponseListener> listeners, Request request, Response response)
218 {
219 forwardSuccess(listeners, response);
220 notifyComplete(listeners, new Result(request, response));
221 }
222
223 public void forwardFailure(List<Response.ResponseListener> listeners, Response response, Throwable failure)
224 {
225 notifyBegin(listeners, response);
226 for (Iterator<HttpField> iterator = response.getHeaders().iterator(); iterator.hasNext();)
227 {
228 HttpField field = iterator.next();
229 if (!notifyHeader(listeners, response, field))
230 iterator.remove();
231 }
232 notifyHeaders(listeners, response);
233 if (response instanceof ContentResponse)
234
235 notifyContent(listeners, response, ByteBuffer.wrap(((ContentResponse)response).getContent()), new Callback.Adapter());
236 notifyFailure(listeners, response, failure);
237 }
238
239 public void forwardFailureComplete(List<Response.ResponseListener> listeners, Request request, Throwable requestFailure, Response response, Throwable responseFailure)
240 {
241 forwardFailure(listeners, response, responseFailure);
242 notifyComplete(listeners, new Result(request, requestFailure, response, responseFailure));
243 }
244
245 private class ContentCallback extends IteratingNestedCallback
246 {
247 private final List<Response.ResponseListener> listeners;
248 private final Response response;
249 private final ByteBuffer buffer;
250 private int index;
251
252 private ContentCallback(List<Response.ResponseListener> listeners, Response response, ByteBuffer buffer, Callback callback)
253 {
254 super(callback);
255 this.listeners = listeners;
256 this.response = response;
257
258 this.buffer = buffer.slice();
259 }
260
261 @Override
262 protected Action process() throws Exception
263 {
264 if (index == listeners.size())
265 return Action.SUCCEEDED;
266
267 Response.ResponseListener listener = listeners.get(index);
268 if (listener instanceof Response.AsyncContentListener)
269 {
270
271
272
273 buffer.clear();
274 ResponseNotifier.this.notifyContent((Response.AsyncContentListener)listener, response, buffer, this);
275 return Action.SCHEDULED;
276 }
277 else
278 {
279 succeeded();
280 return Action.SCHEDULED;
281 }
282 }
283
284 @Override
285 public void succeeded()
286 {
287 ++index;
288 super.succeeded();
289 }
290 }
291 }