2 * Copyright (C) 2016, 2017 Roland Häder
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
14 * You should have received a copy of the GNU Affero General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.addressbook.beans.user.activity;
19 import java.text.MessageFormat;
20 import java.util.Collections;
21 import java.util.GregorianCalendar;
22 import java.util.LinkedHashMap;
23 import java.util.LinkedList;
24 import java.util.List;
26 import javax.annotation.PostConstruct;
27 import javax.enterprise.context.ApplicationScoped;
28 import javax.enterprise.event.Observes;
29 import javax.faces.view.facelets.FaceletException;
30 import javax.inject.Inject;
31 import javax.inject.Named;
32 import javax.naming.Context;
33 import javax.naming.InitialContext;
34 import javax.naming.NamingException;
35 import org.mxchange.addressbook.beans.BaseAddressbookController;
36 import org.mxchange.addressbook.beans.helper.AddressbookWebRequestHelperController;
37 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
38 import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
39 import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
40 import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
41 import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
42 import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
43 import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
44 import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
45 import org.mxchange.jusercore.model.user.User;
46 import org.mxchange.jusercore.model.user.activity.LogableUserActivity;
47 import org.mxchange.jusercore.model.user.activity.UserActivityLog;
48 import org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote;
49 import org.mxchange.jusercore.model.user.activity.comparator.UserActivityLogTimestampComparator;
50 import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
51 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
52 import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
53 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
54 import org.mxchange.juserlogincore.events.resendlink.ObservableUserResendLinkAccountEvent;
55 import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
58 * A controller (bean) for user activity log
60 * @author Roland Häder<roland@mxchange.org>
62 @Named ("userActivityController")
64 public class AddressbookUserActivityWebApplicationBean extends BaseAddressbookController implements AddressbookUserActivityWebApplicationController {
69 private static final long serialVersionUID = 192_586_376_717_856_904L;
75 private AddressbookWebRequestHelperController beanHelper;
83 * EJB for user activity log
85 private UserActivityLogSessionBeanRemote userActivityBean;
88 * "Cache" for activity log per user
90 private final Map<User, List<LogableUserActivity>> usersActivity;
95 @SuppressWarnings ("CollectionWithoutInitialCapacity")
96 public AddressbookUserActivityWebApplicationBean () {
98 this.usersActivity = new LinkedHashMap<>();
102 * Event observer for newly added users by administrator
104 * @param event Event being fired
106 public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
107 // event should not be null
110 throw new NullPointerException("event is null"); //NOI18N
111 } else if (event.getAddedUser() == null) {
113 throw new NullPointerException("event.addedUser is null"); //NOI18N
114 } else if (event.getAddedUser().getUserId() == null) {
116 throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
117 } else if (event.getAddedUser().getUserId() < 1) {
119 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
123 this.addUserActivity(event.getAddedUser(), "ADMIN_ADDED_USER_ACCOUNT"); //NOI18N
127 * Event observer for deleted user accounts (by administrator)
129 * @param event Event being fired
131 public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
132 // event should not be null
135 throw new NullPointerException("event is null"); //NOI18N
136 } else if (event.getDeletedUser() == null) {
138 throw new NullPointerException("event.deletedUser is null"); //NOI18N
139 } else if (event.getDeletedUser().getUserId() == null) {
141 throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
142 } else if (event.getDeletedUser().getUserId() < 1) {
144 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
148 this.addUserActivity(event.getDeletedUser(), "ADMIN_DELETED_USER_ACCOUNT", event.getUserDeleteReason()); //NOI18N
152 * Event observer for linked users with existing contact data
154 * @param event Event being fired
156 public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
157 // event should not be null
160 throw new NullPointerException("event is null"); //NOI18N
161 } else if (event.getLinkedUser() == null) {
163 throw new NullPointerException("event.linkedUser is null"); //NOI18N
164 } else if (event.getLinkedUser().getUserId() == null) {
166 throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
167 } else if (event.getLinkedUser().getUserId() < 1) {
169 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
173 this.addUserActivity(event.getLinkedUser(), "ADMIN_LINKED_USER_ACCOUNT"); //NOI18N
177 * Event observer for locked users
179 * @param event Event being fired
181 public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
182 // event should not be null
185 throw new NullPointerException("event is null"); //NOI18N
186 } else if (event.getLockedUser() == null) {
188 throw new NullPointerException("event.lockedUser is null"); //NOI18N
189 } else if (event.getLockedUser().getUserId() == null) {
191 throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
192 } else if (event.getLockedUser().getUserId() < 1) {
194 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
198 this.addUserActivity(event.getLockedUser(), "ADMIN_LOCKED_USER_ACCOUNT", event.getLockedUser().getUserLastLockedReason()); //NOI18N
202 * Event observer for unlocked users
204 * @param event Event being fired
206 public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
207 // event should not be null
210 throw new NullPointerException("event is null"); //NOI18N
211 } else if (event.getUnlockedUser() == null) {
213 throw new NullPointerException("event.unlockedUser is null"); //NOI18N
214 } else if (event.getUnlockedUser().getUserId() == null) {
216 throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
217 } else if (event.getUnlockedUser().getUserId() < 1) {
219 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
223 this.addUserActivity(event.getUnlockedUser(), "ADMIN_UNLOCKED_USER_ACCOUNT"); //NOI18N
227 * Event observer for updated user data by administrator
229 * @param event Event being updated
231 public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
232 // event should not be null
235 throw new NullPointerException("event is null"); //NOI18N
236 } else if (event.getUpdatedUser() == null) {
238 throw new NullPointerException("event.updatedUser is null"); //NOI18N
239 } else if (event.getUpdatedUser().getUserId() == null) {
241 throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
242 } else if (event.getUpdatedUser().getUserId() < 1) {
244 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
248 this.addUserActivity(event.getUpdatedUser(), "ADMIN_UPDATED_USER_PERSONAL_DATA"); //NOI18N
252 * Event observer for when a bean helper has successfully created a user
253 * instance, means the user exists. If the user does not exist, this event
254 * should not fire but instead a proper exception must be thrown.
256 * @param event User created event
258 public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
259 // Is the instance valid?
262 throw new NullPointerException("event is null"); //NOI18N
263 } else if (event.getCreatedUser() == null) {
265 throw new NullPointerException("event.createdUser is null"); //NOI18N
266 } else if (event.getCreatedUser().getUserId() == null) {
268 throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
269 } else if (event.getCreatedUser().getUserId() < 1) {
271 throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
275 this.setUser(event.getCreatedUser());
279 * Event observer when user confirmed account.
281 * @param event Event being fired
283 public void afterUserConfirmedAccountEvent (@Observes final ObservableUserConfirmedAccountEvent event) {
284 // event should not be null
287 throw new NullPointerException("event is null"); //NOI18N
288 } else if (event.getConfirmedUser() == null) {
290 throw new NullPointerException("event.confirmedUser is null"); //NOI18N
291 } else if (event.getConfirmedUser().getUserId() == null) {
293 throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N
294 } else if (event.getConfirmedUser().getUserId() < 1) {
296 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N
300 this.addUserActivity(event.getConfirmedUser(), "USER_CONFIRMED_ACCOUNT"); //NOI18N
304 * Event observer for logged-in user
306 * @param event Event being fired
308 public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
309 // event should not be null
312 throw new NullPointerException("event is null"); //NOI18N
313 } else if (event.getLoggedInUser() == null) {
315 throw new NullPointerException("event.registeredUser is null"); //NOI18N
316 } else if (event.getLoggedInUser().getUserId() == null) {
318 throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
319 } else if (event.getLoggedInUser().getUserId() < 1) {
321 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
324 // Copy all data to this bean
325 this.addUserActivity(event.getLoggedInUser(), "USER_LOGGED_IN"); //NOI18N
329 * Event observer for logged-out user
331 * @param event Event instance
333 public void afterUserLogoutEvent (@Observes final ObservableUserLogoutEvent event) {
334 // event should not be null
337 throw new NullPointerException("event is null"); //NOI18N
338 } else if (event.getLoggedOutUser() == null) {
340 throw new NullPointerException("event.loggedOutUser is null"); //NOI18N
341 } else if (event.getLoggedOutUser().getUserId() == null) {
343 throw new NullPointerException("event.loggedOutUser.userId is null"); //NOI18N
344 } else if (event.getLoggedOutUser().getUserId() < 1) {
346 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedOutUser(), event.getLoggedOutUser().getUserId())); //NOI18N
350 this.addUserActivity(event.getLoggedOutUser(), "USER_LOGGED_OUT"); //NOI18N
354 * Event observer for new user registrations
356 * @param event Event being fired
358 public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
359 // event should not be null
362 throw new NullPointerException("event is null"); //NOI18N
363 } else if (event.getRegisteredUser() == null) {
365 throw new NullPointerException("event.registeredUser is null"); //NOI18N
366 } else if (event.getRegisteredUser().getUserId() == null) {
368 throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
369 } else if (event.getRegisteredUser().getUserId() < 1) {
371 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
375 this.addUserActivity(event.getRegisteredUser(), "USER_REGISTERED_NEW_ACCOUNT"); //NOI18N
379 * Event observer for users resending their confirmation link
381 * @param event Event being fired
383 public void afterUserResendConfirmationLinkEvent (@Observes final ObservableUserResendLinkAccountEvent event) {
384 // event should not be null
387 throw new NullPointerException("event is null"); //NOI18N
388 } else if (event.getResendLinkUser() == null) {
390 throw new NullPointerException("event.resendLinkUser is null"); //NOI18N
391 } else if (event.getResendLinkUser().getUserId() == null) {
393 throw new NullPointerException("event.resendLinkUser.userId is null"); //NOI18N
394 } else if (event.getResendLinkUser().getUserId() < 1) {
396 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getResendLinkUser(), event.getResendLinkUser().getUserId())); //NOI18N
399 // Copy all data to this bean
400 this.addUserActivity(event.getResendLinkUser(), "USER_RESEND_CONFIRMATION_LINK"); //NOI18N
404 * Method being call after user's password has been updated (and history
405 * entry has been created).
407 * @param event Event being observed
409 public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
413 throw new NullPointerException("event is null"); //NOI18N
414 } else if (event.getPasswordHistory() == null) {
416 throw new NullPointerException("event.passwordHistory is null"); //NOI18N
417 } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
419 throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
420 } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
422 throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
426 this.addUserActivity(event.getPasswordHistory().getUserPasswordHistoryUser(), "USER_UPDATED_PASSWORD"); //NOI18N
430 * Listens to fired event when user updated personal data
432 * @param event Event being fired
434 public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
438 throw new NullPointerException("event is null"); //NOI18N
439 } else if (event.getUpdatedUser() == null) {
441 throw new NullPointerException("event.updatedUser is null"); //NOI18N
442 } else if (event.getUpdatedUser().getUserId() == null) {
444 throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
445 } else if (event.getUpdatedUser().getUserId() < 1) {
447 throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
451 this.addUserActivity(event.getUpdatedUser(), "USER_UPDATED_PERSONAL_DATA"); //NOI18N
455 * Expands given activity type into a i18n string for administrators
457 * @param activityType Activity type
459 * @return Expanded i18n string
461 public String expandAdminActivityType (final String activityType) {
463 if (null == activityType) {
465 throw new NullPointerException("activityType is null"); //NOI18N
466 } else if (activityType.isEmpty()) {
468 throw new IllegalArgumentException("activityType is empty"); //NOI18N
472 return "ADMIN_ACTIVITY_" + activityType; //NOI18N
476 * Expands given activity type into a i18n string for users
478 * @param activityType Activity type
480 * @return Expanded i18n string
482 public String expandUserActivityType (final String activityType) {
484 if (null == activityType) {
486 throw new NullPointerException("activityType is null"); //NOI18N
487 } else if (activityType.isEmpty()) {
489 throw new IllegalArgumentException("activityType is empty"); //NOI18N
493 return "USER_ACTIVITY_" + activityType; //NOI18N
497 * Returns a list of in beanHelper set user instance's activity log
499 * @return List of user's activity log
501 public List<LogableUserActivity> fetchCurrentUsersActivityLog () {
502 // beanHelper.user should be set and valid
503 if (this.getUser() == null) {
505 throw new NullPointerException("this.beanHelper.user is null"); //NOI18N
506 } else if (this.getUser().getUserId() == null) {
508 throw new NullPointerException("this.beanHelper.user.userId is null"); //NOI18N
509 } else if (this.getUser().getUserId() < 1) {
511 throw new IllegalArgumentException(MessageFormat.format("this.beanHelper.user.userId={0} is not valid", this.getUser().getUserId())); //NOI18N
515 List<LogableUserActivity> list = new LinkedList<>();
518 if (this.usersActivity.containsKey(this.getUser())) {
520 list.addAll(this.usersActivity.get(this.getUser()));
522 // Sort list and reverse it
523 Collections.sort(list, new UserActivityLogTimestampComparator());
524 Collections.reverse(list);
532 * Getter for user instance
534 * @return User instance
536 public User getUser () {
541 * Setter for user instance
543 * @param user User instance
545 public void setUser (final User user) {
550 * Post-constructor method
553 public void init () {
554 // Try to get EJB instance
556 // Get initial context
557 Context context = new InitialContext();
560 this.userActivityBean = (UserActivityLogSessionBeanRemote) context.lookup("java:global/addressbook-ejb/userActivity!org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote"); //NOI18N
561 } catch (final NamingException e) {
563 throw new FaceletException(e);
567 List<LogableUserActivity> list = this.userActivityBean.fetchAllUserActivityLog();
569 // Put all in map, per-user
570 for (final LogableUserActivity userActivity : list) {
571 // Is the list there?
572 if (!this.usersActivity.containsKey(userActivity.getActivityUser())) {
574 this.usersActivity.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
577 // Add by user instance
578 boolean added = this.usersActivity.get(userActivity.getActivityUser()).add(userActivity);
581 assert (added) : "Activity log not added"; //NOI18N
586 * Adds user activity entry with given type
588 * @param user User instance
589 * @param activityType Activity type
591 private void addUserActivity (final User user, final String activityType) {
592 // Better re-validate
595 throw new NullPointerException("user is null"); //NOI18N
596 } else if (user.getUserId() == null) {
598 throw new NullPointerException("user.userId is null"); //NOI18N
599 } else if (user.getUserId() < 1) {
601 throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
602 } else if (null == activityType) {
604 throw new NullPointerException("activityType is null"); //NOI18N
605 } else if (activityType.isEmpty()) {
607 throw new IllegalArgumentException("activityType is empty"); //NOI18N
610 // Create new activity object
611 LogableUserActivity userActivity = new UserActivityLog(activityType, user, new GregorianCalendar(), this.determinePrincipalName());
613 // Call bean to add it
614 this.userActivityBean.addUserActivityLog(userActivity);
617 this.addUserActivityToCache(userActivity);
621 * Adds user activity log with type and message
623 * @param user User instance
624 * @param activityType Activity type
625 * @param message Activity message
627 private void addUserActivity (final User user, final String activityType, final String message) {
628 // Better re-validate
631 throw new NullPointerException("user is null"); //NOI18N
632 } else if (user.getUserId() == null) {
634 throw new NullPointerException("user.userId is null"); //NOI18N
635 } else if (user.getUserId() < 1) {
637 throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
638 } else if (null == activityType) {
640 throw new NullPointerException("activityType is null"); //NOI18N
641 } else if (activityType.isEmpty()) {
643 throw new IllegalArgumentException("activityType is empty"); //NOI18N
644 } else if (null == message) {
646 throw new NullPointerException("message is null"); //NOI18N
647 } else if (message.isEmpty()) {
649 throw new IllegalArgumentException("message is empty"); //NOI18N
652 // Create new activity object
653 LogableUserActivity userActivity = new UserActivityLog(message, activityType, user, new GregorianCalendar(), this.determinePrincipalName());
655 // Call bean to add it
656 this.userActivityBean.addUserActivityLog(userActivity);
659 this.addUserActivityToCache(userActivity);
663 * Adds given user activity instance to "cache" (local map)
665 * @param userActivity User activity instance
667 private void addUserActivityToCache (final LogableUserActivity userActivity) {
668 // Is the instance valid
669 if (null == userActivity) {
671 throw new NullPointerException("userActivity is null");
672 } else if (userActivity.getActivityId() instanceof Long) {
674 throw new IllegalArgumentException("userActivity.activityId=" + userActivity.getActivityId() + " is not null");
675 } else if (userActivity.getActivityUser() == null) {
677 throw new NullPointerException("userActivity.activityUser is null");
678 } else if (userActivity.getActivityUser().getUserId() == null) {
680 throw new NullPointerException("userActivity.activityUser.userId is null");
681 } else if (userActivity.getActivityUser().getUserId() < 1) {
683 throw new IllegalArgumentException("userActivity.activityUser.userId=" + userActivity.getActivityUser().getUserId() + " is not valid");
687 if (!this.usersActivity.containsKey(userActivity.getActivityUser())) {
689 this.usersActivity.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
692 // Add activity to log
693 this.usersActivity.get(userActivity.getActivityUser()).add(userActivity);