View Javadoc
1   package net.avcompris.examples.users3.web;
2   
3   import static com.google.common.base.Preconditions.checkNotNull;
4   import static net.avcompris.commons3.databeans.DataBeans.instantiate;
5   import static net.avcompris.examples.users3.web.Application.API;
6   import static org.springframework.web.bind.annotation.RequestMethod.DELETE;
7   import static org.springframework.web.bind.annotation.RequestMethod.GET;
8   import static org.springframework.web.bind.annotation.RequestMethod.POST;
9   import static org.springframework.web.bind.annotation.RequestMethod.PUT;
10  
11  import javax.servlet.http.HttpServletRequest;
12  import javax.servlet.http.HttpServletResponse;
13  
14  import org.apache.commons.logging.Log;
15  import org.springframework.beans.factory.annotation.Autowired;
16  import org.springframework.http.HttpStatus;
17  import org.springframework.http.ResponseEntity;
18  import org.springframework.web.bind.annotation.PathVariable;
19  import org.springframework.web.bind.annotation.RequestBody;
20  import org.springframework.web.bind.annotation.RequestMapping;
21  import org.springframework.web.bind.annotation.RequestParam;
22  import org.springframework.web.bind.annotation.RestController;
23  
24  import net.avcompris.commons3.api.EntitiesQueryRaw;
25  import net.avcompris.commons3.api.exception.ServiceException;
26  import net.avcompris.commons3.client.SessionPropagator;
27  import net.avcompris.commons3.core.AuthService;
28  import net.avcompris.commons3.core.CorrelationService;
29  import net.avcompris.commons3.utils.Clock;
30  import net.avcompris.commons3.utils.LogFactory;
31  import net.avcompris.examples.users3.api.PreferredLang;
32  import net.avcompris.examples.users3.api.PreferredTimeZone;
33  import net.avcompris.examples.users3.api.UserCreate;
34  import net.avcompris.examples.users3.api.UserInfo;
35  import net.avcompris.examples.users3.api.UserUpdate;
36  import net.avcompris.examples.users3.api.UsersInfo;
37  import net.avcompris.examples.users3.api.UsersQuery;
38  import net.avcompris.examples.users3.core.api.UsersService;
39  import net.avcompris.examples.users3.query.UserFiltering;
40  
41  @RestController
42  public final class UsersController extends MyAbstractController {
43  
44  	private static final Log logger = LogFactory.getLog(UsersController.class);
45  
46  	private final AuthService authService;
47  	private final UsersService usersService;
48  
49  	@Autowired
50  	public UsersController(final CorrelationService correlationService, final AuthService authService,
51  			final UsersService usersService, //
52  			final SessionPropagator sessionPropagator, //
53  			final Clock clock) {
54  
55  		super(correlationService, sessionPropagator, clock);
56  
57  		this.authService = checkNotNull(authService, "authService");
58  		this.usersService = checkNotNull(usersService, "usersService");
59  	}
60  
61  	@RequestMapping(value = API + "/users", method = GET)
62  	public ResponseEntity<UsersInfo> getUsers(final HttpServletRequest request, //
63  			final HttpServletResponse response, //
64  			@RequestParam(name = "q", required = false) final String q, //
65  			@RequestParam(name = "sort", required = false) final String sort, //
66  			@RequestParam(name = "start", required = false) final Integer start, //
67  			@RequestParam(name = "limit", required = false) final Integer limit, //
68  			@RequestParam(name = "expand", required = false) final String expand //
69  	) throws ServiceException {
70  
71  		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
72  
73  			final UsersQuery query = usersService.validateUsersQuery(correlationId, user, q, sort, start, limit,
74  					expand);
75  
76  			final UsersInfo users = usersService.getUsers(correlationId, user, query);
77  
78  			return ResponseEntity.status(HttpStatus.OK) //
79  					.body(users);
80  		});
81  	}
82  
83  	@RequestMapping(value = API + "/users", method = POST)
84  	public ResponseEntity<UsersInfo> getUsers(final HttpServletRequest request, //
85  			final HttpServletResponse response, //
86  			@RequestBody(required = true) final EntitiesQueryRaw<UserFiltering, UserFiltering.Field> raw //
87  	) throws ServiceException {
88  
89  		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
90  
91  			final UsersQuery query = usersService.validateUsersQuery(correlationId, user, raw.getQ(), raw.getSort(),
92  					raw.getStart(), raw.getLimit(), raw.getExpand());
93  
94  			final UsersInfo users = usersService.getUsers(correlationId, user, query);
95  
96  			return ResponseEntity.status(HttpStatus.OK) //
97  					.body(users);
98  		});
99  	}
100 
101 	@RequestMapping(value = API + "/users/{username}", method = POST)
102 	public ResponseEntity<UserInfo> createUser(final HttpServletRequest request, //
103 			final HttpServletResponse response, //
104 			@PathVariable(name = "username", required = true) final String username, //
105 			@RequestBody(required = true) final UserCreate create //
106 	) throws ServiceException {
107 
108 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
109 
110 			final UserInfo userInfo = usersService.createUser(correlationId, user, username, create);
111 
112 			return ResponseEntity.status(HttpStatus.CREATED) //
113 					.body(userInfo);
114 		});
115 	}
116 
117 	@RequestMapping(value = API + "/users/me", method = GET)
118 	public ResponseEntity<UserInfo> getUserMe(final HttpServletRequest request, //
119 			final HttpServletResponse response //
120 	) throws ServiceException {
121 
122 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
123 
124 			final UserInfo userInfo = usersService.getUserMe(correlationId, user);
125 
126 			return ResponseEntity.status(HttpStatus.OK) //
127 					.body(userInfo);
128 		});
129 	}
130 
131 	@RequestMapping(value = API + "/users/{username}", method = GET)
132 	public ResponseEntity<UserInfo> getUser(final HttpServletRequest request, //
133 			final HttpServletResponse response, //
134 			@PathVariable(name = "username", required = true) final String username //
135 	) throws ServiceException {
136 
137 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
138 
139 			final UserInfo userInfo;
140 
141 			if (username.contentEquals(user.getUsername())) {
142 
143 				userInfo = usersService.getUserMe(correlationId, user);
144 
145 			} else {
146 
147 				userInfo = usersService.getUser(correlationId, user, username);
148 			}
149 
150 			return ResponseEntity.status(HttpStatus.OK) //
151 					.body(userInfo);
152 		});
153 	}
154 
155 	@RequestMapping(value = API + "/users/me/preferredLang", method = GET)
156 	public ResponseEntity<String> getUserMePreferredLang(final HttpServletRequest request, //
157 			final HttpServletResponse response //
158 	) throws ServiceException {
159 
160 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
161 
162 			final UserInfo userInfo = usersService.getUserMe(correlationId, user);
163 
164 			final String lang = userInfo.getPreferredLang();
165 
166 			return ResponseEntity.status(lang != null //
167 					? HttpStatus.OK //
168 					: HttpStatus.NO_CONTENT) //
169 					.body(lang);
170 		});
171 	}
172 
173 	@RequestMapping(value = API + "/users/me/preferredLang", method = { PUT, POST })
174 	public ResponseEntity<String> setUserMePreferredLang(final HttpServletRequest request, //
175 			final HttpServletResponse response, //
176 			@RequestBody(required = false) final PreferredLang preferredLang, //
177 			@RequestParam(name = "preferredLang", required = false) final String preferredLangParam //
178 	) throws ServiceException {
179 
180 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
181 
182 			if (logger.isDebugEnabled()) {
183 				logger.debug("setUserMePreferredLang(), user: " + user.getUsername() + ", preferredLang: " + preferredLang
184 						+ ", preferredLangParam: " + preferredLangParam);
185 			}
186 
187 			final String lang;
188 
189 			if (preferredLangParam != null) {
190 
191 				lang = preferredLangParam;
192 
193 			} else if (preferredLang == null) {
194 
195 				throw new IllegalArgumentException("lang should be set");
196 
197 			} else {
198 
199 				lang = preferredLang.getLang();
200 			}
201 
202 			final int fromRevision = usersService.getUserMe(correlationId, user).getRevision();
203 
204 			usersService.updateUserMe(correlationId, user, instantiate(UserUpdate.class) //
205 					.setPreferredLang(lang) //
206 					.setFromRevision(fromRevision));
207 
208 			final UserInfo userInfo = usersService.getUserMe(correlationId, user);
209 
210 			return ResponseEntity.status(HttpStatus.OK) //
211 					.body(userInfo.getPreferredLang());
212 		});
213 	}
214 
215 	@RequestMapping(value = API + "/users/{username}/preferredLang", method = GET)
216 	public ResponseEntity<String> getUserPreferredLang(final HttpServletRequest request, //
217 			final HttpServletResponse response, //
218 			@PathVariable(name = "username", required = true) final String username //
219 	) throws ServiceException {
220 
221 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
222 
223 			final UserInfo userInfo;
224 
225 			if (username.contentEquals(user.getUsername())) {
226 
227 				userInfo = usersService.getUserMe(correlationId, user);
228 
229 			} else {
230 
231 				userInfo = usersService.getUser(correlationId, user, username);
232 			}
233 
234 			final String lang = userInfo.getPreferredLang();
235 
236 			return ResponseEntity.status(lang != null //
237 					? HttpStatus.OK //
238 					: HttpStatus.NO_CONTENT) //
239 					.body(lang);
240 		});
241 	}
242 
243 	@RequestMapping(value = API + "/users/{username}/preferredLang", method = { POST, PUT })
244 	public ResponseEntity<String> setUserPreferredLang(final HttpServletRequest request, //
245 			final HttpServletResponse response, //
246 			@PathVariable(name = "username", required = true) final String username, //
247 			@RequestBody(required = false) final PreferredLang preferredLang, //
248 			@RequestParam(name = "preferredLang", required = false) final String preferredLangParam //
249 	) throws ServiceException {
250 
251 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
252 
253 			final String lang;
254 
255 			if (preferredLangParam != null) {
256 
257 				lang = preferredLangParam;
258 
259 			} else if (preferredLang == null) {
260 
261 				throw new IllegalArgumentException("lang should be set");
262 
263 			} else {
264 
265 				lang = preferredLang.getLang();
266 			}
267 
268 			final UserInfo userInfo;
269 
270 			if (username.contentEquals(user.getUsername())) {
271 
272 				final int fromRevision = usersService.getUserMe(correlationId, user).getRevision();
273 
274 				usersService.updateUserMe(correlationId, user, instantiate(UserUpdate.class) //
275 						.setPreferredLang(lang) //
276 						.setFromRevision(fromRevision));
277 
278 				userInfo = usersService.getUserMe(correlationId, user);
279 
280 			} else {
281 
282 				final int fromRevision = usersService.getUser(correlationId, user, username).getRevision();
283 
284 				usersService.updateUser(correlationId, user, username, instantiate(UserUpdate.class) //
285 						.setPreferredLang(lang) //
286 						.setFromRevision(fromRevision));
287 
288 				userInfo = usersService.getUser(correlationId, user, username);
289 			}
290 
291 			return ResponseEntity.status(HttpStatus.OK) //
292 					.body(userInfo.getPreferredLang());
293 		});
294 	}
295 
296 	@RequestMapping(value = API + "/users/me/preferredTimeZone", method = GET)
297 	public ResponseEntity<String> getUserMePreferredTimeZone(final HttpServletRequest request, //
298 			final HttpServletResponse response //
299 	) throws ServiceException {
300 
301 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
302 
303 			final UserInfo userInfo = usersService.getUserMe(correlationId, user);
304 
305 			final String timeZone = userInfo.getPreferredTimeZone();
306 
307 			return ResponseEntity.status(timeZone != null //
308 					? HttpStatus.OK //
309 					: HttpStatus.NO_CONTENT) //
310 					.body(timeZone);
311 		});
312 	}
313 
314 	@RequestMapping(value = API + "/users/me/preferredTimeZone", method = { PUT, POST })
315 	public ResponseEntity<String> setUserMePreferredTimeZone(final HttpServletRequest request, //
316 			final HttpServletResponse response, //
317 			@RequestBody(required = false) final PreferredTimeZone preferredTimeZone, //
318 			@RequestParam(required = false) final String timeZoneParam //
319 	) throws ServiceException {
320 
321 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
322 
323 			final String timeZone;
324 
325 			if (timeZoneParam != null) {
326 
327 				timeZone = timeZoneParam;
328 
329 			} else if (preferredTimeZone == null) {
330 
331 				throw new IllegalArgumentException("timeZone should be set");
332 
333 			} else {
334 
335 				timeZone = preferredTimeZone.getTimeZone();
336 			}
337 
338 			final int fromRevision = usersService.getUserMe(correlationId, user).getRevision();
339 
340 			usersService.updateUserMe(correlationId, user, instantiate(UserUpdate.class) //
341 					.setPreferredTimeZone(timeZone) //
342 					.setFromRevision(fromRevision));
343 
344 			final UserInfo userInfo = usersService.getUserMe(correlationId, user);
345 
346 			return ResponseEntity.status(HttpStatus.OK) //
347 					.body(userInfo.getPreferredTimeZone());
348 		});
349 	}
350 
351 	@RequestMapping(value = API + "/users/{username}", method = PUT)
352 	public ResponseEntity<UserInfo> updateUser(final HttpServletRequest request, //
353 			final HttpServletResponse response, //
354 			@PathVariable(name = "username", required = true) final String username, //
355 			@RequestBody(required = true) final UserUpdate update //
356 	) throws ServiceException {
357 
358 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
359 
360 			final UserInfo userInfo = usersService.updateUser(correlationId, user, username, update);
361 
362 			return ResponseEntity.status(HttpStatus.OK) //
363 					.body(userInfo);
364 		});
365 	}
366 
367 	@RequestMapping(value = API + "/users/{username}", method = DELETE)
368 	public ResponseEntity<String> deleteUser(final HttpServletRequest request, //
369 			final HttpServletResponse response, //
370 			@PathVariable(name = "username", required = true) final String username //
371 	) throws ServiceException {
372 
373 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
374 
375 			usersService.deleteUser(correlationId, user, username);
376 
377 			return ResponseEntity.status(HttpStatus.NO_CONTENT) //
378 					.body(null);
379 		});
380 	}
381 
382 	@RequestMapping(value = API + "/users/{username}/preferredTimeZone", method = GET)
383 	public ResponseEntity<String> getUserPreferredTimeZone(final HttpServletRequest request, //
384 			final HttpServletResponse response, //
385 			@PathVariable(name = "username", required = true) final String username //
386 	) throws ServiceException {
387 
388 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
389 
390 			final UserInfo userInfo;
391 
392 			if (username.contentEquals(user.getUsername())) {
393 
394 				userInfo = usersService.getUserMe(correlationId, user);
395 
396 			} else {
397 
398 				userInfo = usersService.getUser(correlationId, user, username);
399 			}
400 
401 			final String timeZone = userInfo.getPreferredTimeZone();
402 
403 			return ResponseEntity.status(timeZone != null //
404 					? HttpStatus.OK //
405 					: HttpStatus.NO_CONTENT) //
406 					.body(timeZone);
407 		});
408 	}
409 
410 	@RequestMapping(value = API + "/users/{username}/preferredTimeZone", method = { POST, PUT })
411 	public ResponseEntity<String> setUserPreferredTimeZone(final HttpServletRequest request, //
412 			final HttpServletResponse response, //
413 			@PathVariable(name = "username", required = true) final String username, //
414 			@RequestBody(required = false) final PreferredTimeZone preferredTimeZone, //
415 			@RequestParam(name = "preferredTimeZone", required = false) final String preferredTimeZoneParam //
416 	) throws ServiceException {
417 
418 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
419 
420 			final String timeZone;
421 
422 			if (preferredTimeZoneParam != null) {
423 
424 				timeZone = preferredTimeZoneParam;
425 
426 			} else if (preferredTimeZone == null) {
427 
428 				throw new IllegalArgumentException("timeZone should be set");
429 
430 			} else {
431 
432 				timeZone = preferredTimeZone.getTimeZone();
433 			}
434 
435 			final UserInfo userInfo;
436 
437 			if (username.contentEquals(user.getUsername())) {
438 
439 				final int fromRevision = usersService.getUserMe(correlationId, user).getRevision();
440 
441 				usersService.updateUserMe(correlationId, user, instantiate(UserUpdate.class) //
442 						.setPreferredTimeZone(timeZone) //
443 						.setFromRevision(fromRevision));
444 
445 				userInfo = usersService.getUserMe(correlationId, user);
446 
447 			} else {
448 
449 				final int fromRevision = usersService.getUser(correlationId, user, username).getRevision();
450 
451 				usersService.updateUser(correlationId, user, username, instantiate(UserUpdate.class) //
452 						.setPreferredTimeZone(timeZone) //
453 						.setFromRevision(fromRevision));
454 
455 				userInfo = usersService.getUser(correlationId, user, username);
456 			}
457 
458 			return ResponseEntity.status(HttpStatus.OK) //
459 					.body(userInfo.getPreferredTimeZone());
460 		});
461 	}
462 }