1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.rribbit;
17  
18  import org.rribbit.dispatching.RequestDispatcher;
19  import org.slf4j.Logger;
20  import org.slf4j.LoggerFactory;
21  
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Collection;
25  import java.util.List;
26  import java.util.concurrent.CopyOnWriteArrayList;
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.getFirst();
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.getFirst();
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.getFirst();
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 }