1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.rribbit;
17
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.concurrent.CopyOnWriteArrayList;
23
24 import org.rribbit.dispatching.RequestDispatcher;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class DefaultRequestResponseBus implements RequestResponseBus {
43
44 private static final Logger log = LoggerFactory.getLogger(DefaultRequestResponseBus.class);
45
46 protected List<RequestDispatcher> requestDispatchers;
47
48
49
50
51
52 public DefaultRequestResponseBus() {
53 requestDispatchers = new CopyOnWriteArrayList<>();
54 }
55
56
57
58
59
60
61
62 public DefaultRequestResponseBus(RequestDispatcher... requestDispatchers) {
63 this();
64 this.requestDispatchers.addAll(Arrays.asList(requestDispatchers));
65 }
66
67 @Override
68 public <T> T sendForSingleOfClass(Class<T> returnType, Object... parameters) {
69
70 log.info("Sending request for single object of class: '{}'", returnType.getName());
71
72 log.debug("Creating Request object");
73 Request request = new Request(returnType, null, parameters);
74
75 log.debug("Dispatching Request");
76 List<T> returnValues = this.dispatchRequestAndProcessResponse(request);
77 return returnValues.isEmpty() ? null : returnValues.get(0);
78 }
79
80 @Override
81 public <T> Collection<T> sendForMultipleOfClass(Class<T> returnType, Object... parameters) {
82
83 log.info("Sending request for multiple objects of class: '{}'", returnType.getName());
84
85 log.debug("Creating Request object");
86 Request request = new Request(returnType, null, parameters);
87
88 log.debug("Dispatching Request");
89 return this.dispatchRequestAndProcessResponse(request);
90 }
91
92 @Override
93 public void sendForNothing(Object... parameters) {
94
95 log.info("Sending request for nothing");
96
97 log.debug("Creating Request object");
98 Request request = new Request(null, null, parameters);
99
100 log.debug("Dispatching Request");
101 this.dispatchRequestAndProcessResponse(request);
102 }
103
104 @Override
105 public <T> T sendForSingleWithHint(String hint, Object... parameters) {
106
107 log.info("Sending request for single object with hint '{}'", hint);
108
109 log.debug("Creating Request object");
110 Request request = new Request(null, hint, parameters);
111
112 log.debug("Dispatching Request");
113 List<T> returnValues = this.dispatchRequestAndProcessResponse(request);
114 return returnValues.isEmpty() ? null : returnValues.get(0);
115 }
116
117 @Override
118 public <T> Collection<T> sendForMultipleWithHint(String hint, Object... parameters) {
119
120 log.info("Sending request for multiple objects with hint '{}'", hint);
121
122 log.debug("Creating Request object");
123 Request request = new Request(null, hint, parameters);
124
125 log.debug("Dispatching Request");
126 return this.dispatchRequestAndProcessResponse(request);
127 }
128
129 @Override
130 public void sendForNothingWithHint(String hint, Object... parameters) {
131
132 log.info("Sending request for nothing with hint '{}'", hint);
133
134 log.debug("Creating Request object");
135 Request request = new Request(null, hint, parameters);
136
137 log.debug("Dispatching Request");
138 this.dispatchRequestAndProcessResponse(request);
139 }
140
141 @Override
142 public <T> T sendForSingleOfClassWithHint(Class<T> returnType, String hint, Object... parameters) {
143
144 log.info("Sending request for single object of class '{}' and with hint '{}'", returnType.getName(), hint);
145
146 log.debug("Creating Request object");
147 Request request = new Request(returnType, hint, parameters);
148
149 log.debug("Dispatching Request");
150 List<T> returnValues = this.dispatchRequestAndProcessResponse(request);
151 return returnValues.isEmpty() ? null : returnValues.get(0);
152 }
153
154 @Override
155 public <T> Collection<T> sendForMultipleOfClassWithHint(Class<T> returnType, String hint, Object... parameters) {
156
157 log.info("Sending request for multiple objects of class '{}' and with hint '{}'", returnType.getName(), hint);
158
159 log.debug("Creating Request object");
160 Request request = new Request(returnType, hint, parameters);
161
162 log.debug("Dispatching Request");
163 return this.dispatchRequestAndProcessResponse(request);
164 }
165
166 @Override
167 public <T> T send(String hint, Object... parameters) {
168
169 return this.sendForSingleWithHint(hint, parameters);
170 }
171
172
173
174
175
176
177
178
179 protected <T> List<T> dispatchRequestAndProcessResponse(Request request) {
180
181
182 List<T> returnValues = new ArrayList<>();
183 Collection<Throwable> throwables = new ArrayList<>();
184 for(RequestDispatcher requestDispatcher : requestDispatchers) {
185 Response<T> response = requestDispatcher.dispatchRequest(request);
186 returnValues.addAll(response.getReturnValues());
187 throwables.addAll(response.getThrowables());
188 }
189
190
191 log.debug("Processing Responses");
192 if(throwables.size() == 1) {
193 this.throwAny(throwables.iterator().next());
194 } else if(!throwables.isEmpty()) {
195 throw new MultipleThrowablesOccurredException(throwables);
196 }
197
198
199 return returnValues;
200 }
201
202
203
204
205
206
207
208
209 private <E extends Throwable> void throwAny(Throwable e) throws E {
210 throw (E) e;
211 }
212
213
214
215
216
217
218 public List<RequestDispatcher> getRequestDispatchers() {
219 return requestDispatchers;
220 }
221
222
223
224
225
226
227 public void addRequestDispatcher(RequestDispatcher requestDispatcher) {
228 requestDispatchers.add(requestDispatcher);
229 }
230
231
232
233
234
235
236
237 public void setRequestDispatcher(RequestDispatcher requestDispatcher) {
238 requestDispatchers.clear();
239 requestDispatchers.add(requestDispatcher);
240 }
241 }