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.Named;
31 import javax.naming.Context;
32 import javax.naming.InitialContext;
33 import javax.naming.NamingException;
34 import org.mxchange.addressbook.beans.BaseAddressbookController;
35 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
36 import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
37 import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
38 import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
39 import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
40 import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
41 import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
42 import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
43 import org.mxchange.jusercore.model.user.User;
44 import org.mxchange.jusercore.model.user.activity.LogableUserActivity;
45 import org.mxchange.jusercore.model.user.activity.UserActivityLog;
46 import org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote;
47 import org.mxchange.jusercore.model.user.activity.comparator.UserActivityLogTimestampComparator;
48 import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
49 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
50 import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
51 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
52 import org.mxchange.juserlogincore.events.resendlink.ObservableUserResendLinkAccountEvent;
53 import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
56 * A controller (bean) for user activity log
58 * @author Roland Häder<roland@mxchange.org>
60 @Named ("userActivityController")
62 public class AddressbookUserActivityWebApplicationBean extends BaseAddressbookController implements AddressbookUserActivityWebApplicationController {
67 private static final long serialVersionUID = 192_586_376_717_856_904L;
75 * EJB for user activity log
77 private UserActivityLogSessionBeanRemote userActivityBean;
80 * "Cache" for activity log per user
82 private final Map<User, List<LogableUserActivity>> usersActivity;
87 @SuppressWarnings ("CollectionWithoutInitialCapacity")
88 public AddressbookUserActivityWebApplicationBean () {
90 this.usersActivity = new LinkedHashMap<>();
94 * Event observer for newly added users by administrator
96 * @param event Event being fired
98 public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
99 // event should not be null
102 throw new NullPointerException("event is null"); //NOI18N
103 } else if (event.getAddedUser() == null) {
105 throw new NullPointerException("event.addedUser is null"); //NOI18N
106 } else if (event.getAddedUser().getUserId() == null) {
108 throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
109 } else if (event.getAddedUser().getUserId() < 1) {
111 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
115 this.addUserActivity(event.getAddedUser(), "ADMIN_ADDED_USER_ACCOUNT"); //NOI18N
119 * Event observer for deleted user accounts (by administrator)
121 * @param event Event being fired
123 public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
124 // event should not be null
127 throw new NullPointerException("event is null"); //NOI18N
128 } else if (event.getDeletedUser() == null) {
130 throw new NullPointerException("event.deletedUser is null"); //NOI18N
131 } else if (event.getDeletedUser().getUserId() == null) {
133 throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
134 } else if (event.getDeletedUser().getUserId() < 1) {
136 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
140 this.addUserActivity(event.getDeletedUser(), "ADMIN_DELETED_USER_ACCOUNT", event.getUserDeleteReason()); //NOI18N
144 * Event observer for linked users with existing contact data
146 * @param event Event being fired
148 public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
149 // event should not be null
152 throw new NullPointerException("event is null"); //NOI18N
153 } else if (event.getLinkedUser() == null) {
155 throw new NullPointerException("event.linkedUser is null"); //NOI18N
156 } else if (event.getLinkedUser().getUserId() == null) {
158 throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
159 } else if (event.getLinkedUser().getUserId() < 1) {
161 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
165 this.addUserActivity(event.getLinkedUser(), "ADMIN_LINKED_USER_ACCOUNT"); //NOI18N
169 * Event observer for locked users
171 * @param event Event being fired
173 public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
174 // event should not be null
177 throw new NullPointerException("event is null"); //NOI18N
178 } else if (event.getLockedUser() == null) {
180 throw new NullPointerException("event.lockedUser is null"); //NOI18N
181 } else if (event.getLockedUser().getUserId() == null) {
183 throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
184 } else if (event.getLockedUser().getUserId() < 1) {
186 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
190 this.addUserActivity(event.getLockedUser(), "ADMIN_LOCKED_USER_ACCOUNT", event.getLockedUser().getUserLastLockedReason()); //NOI18N
194 * Event observer for unlocked users
196 * @param event Event being fired
198 public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
199 // event should not be null
202 throw new NullPointerException("event is null"); //NOI18N
203 } else if (event.getUnlockedUser() == null) {
205 throw new NullPointerException("event.unlockedUser is null"); //NOI18N
206 } else if (event.getUnlockedUser().getUserId() == null) {
208 throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
209 } else if (event.getUnlockedUser().getUserId() < 1) {
211 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
215 this.addUserActivity(event.getUnlockedUser(), "ADMIN_UNLOCKED_USER_ACCOUNT"); //NOI18N
219 * Event observer for updated user data by administrator
221 * @param event Event being updated
223 public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
224 // event should not be null
227 throw new NullPointerException("event is null"); //NOI18N
228 } else if (event.getUpdatedUser() == null) {
230 throw new NullPointerException("event.updatedUser is null"); //NOI18N
231 } else if (event.getUpdatedUser().getUserId() == null) {
233 throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
234 } else if (event.getUpdatedUser().getUserId() < 1) {
236 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
240 this.addUserActivity(event.getUpdatedUser(), "ADMIN_UPDATED_USER_PERSONAL_DATA"); //NOI18N
244 * Event observer for when a bean helper has successfully created a user
245 * instance, means the user exists. If the user does not exist, this event
246 * should not fire but instead a proper exception must be thrown.
248 * @param event User created event
250 public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
251 // Is the instance valid?
254 throw new NullPointerException("event is null"); //NOI18N
255 } else if (event.getCreatedUser() == null) {
257 throw new NullPointerException("event.createdUser is null"); //NOI18N
258 } else if (event.getCreatedUser().getUserId() == null) {
260 throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
261 } else if (event.getCreatedUser().getUserId() < 1) {
263 throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
267 this.setUser(event.getCreatedUser());
271 * Event observer when user confirmed account.
273 * @param event Event being fired
275 public void afterUserConfirmedAccountEvent (@Observes final ObservableUserConfirmedAccountEvent event) {
276 // event should not be null
279 throw new NullPointerException("event is null"); //NOI18N
280 } else if (event.getConfirmedUser() == null) {
282 throw new NullPointerException("event.confirmedUser is null"); //NOI18N
283 } else if (event.getConfirmedUser().getUserId() == null) {
285 throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N
286 } else if (event.getConfirmedUser().getUserId() < 1) {
288 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N
292 this.addUserActivity(event.getConfirmedUser(), "USER_CONFIRMED_ACCOUNT"); //NOI18N
296 * Event observer for logged-in user
298 * @param event Event being fired
300 public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
301 // event should not be null
304 throw new NullPointerException("event is null"); //NOI18N
305 } else if (event.getLoggedInUser() == null) {
307 throw new NullPointerException("event.registeredUser is null"); //NOI18N
308 } else if (event.getLoggedInUser().getUserId() == null) {
310 throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
311 } else if (event.getLoggedInUser().getUserId() < 1) {
313 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
316 // Copy all data to this bean
317 this.addUserActivity(event.getLoggedInUser(), "USER_LOGGED_IN"); //NOI18N
321 * Event observer for logged-out user
323 * @param event Event instance
325 public void afterUserLogoutEvent (@Observes final ObservableUserLogoutEvent event) {
326 // event should not be null
329 throw new NullPointerException("event is null"); //NOI18N
330 } else if (event.getLoggedOutUser() == null) {
332 throw new NullPointerException("event.loggedOutUser is null"); //NOI18N
333 } else if (event.getLoggedOutUser().getUserId() == null) {
335 throw new NullPointerException("event.loggedOutUser.userId is null"); //NOI18N
336 } else if (event.getLoggedOutUser().getUserId() < 1) {
338 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedOutUser(), event.getLoggedOutUser().getUserId())); //NOI18N
342 this.addUserActivity(event.getLoggedOutUser(), "USER_LOGGED_OUT"); //NOI18N
346 * Event observer for new user registrations
348 * @param event Event being fired
350 public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
351 // event should not be null
354 throw new NullPointerException("event is null"); //NOI18N
355 } else if (event.getRegisteredUser() == null) {
357 throw new NullPointerException("event.registeredUser is null"); //NOI18N
358 } else if (event.getRegisteredUser().getUserId() == null) {
360 throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
361 } else if (event.getRegisteredUser().getUserId() < 1) {
363 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
367 this.addUserActivity(event.getRegisteredUser(), "USER_REGISTERED_NEW_ACCOUNT"); //NOI18N
371 * Event observer for users resending their confirmation link
373 * @param event Event being fired
375 public void afterUserResendConfirmationLinkEvent (@Observes final ObservableUserResendLinkAccountEvent event) {
376 // event should not be null
379 throw new NullPointerException("event is null"); //NOI18N
380 } else if (event.getResendLinkUser() == null) {
382 throw new NullPointerException("event.resendLinkUser is null"); //NOI18N
383 } else if (event.getResendLinkUser().getUserId() == null) {
385 throw new NullPointerException("event.resendLinkUser.userId is null"); //NOI18N
386 } else if (event.getResendLinkUser().getUserId() < 1) {
388 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getResendLinkUser(), event.getResendLinkUser().getUserId())); //NOI18N
391 // Copy all data to this bean
392 this.addUserActivity(event.getResendLinkUser(), "USER_RESEND_CONFIRMATION_LINK"); //NOI18N
396 * Method being call after user's password has been updated (and history
397 * entry has been created).
399 * @param event Event being observed
401 public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
405 throw new NullPointerException("event is null"); //NOI18N
406 } else if (event.getPasswordHistory() == null) {
408 throw new NullPointerException("event.passwordHistory is null"); //NOI18N
409 } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
411 throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
412 } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
414 throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
418 this.addUserActivity(event.getPasswordHistory().getUserPasswordHistoryUser(), "USER_UPDATED_PASSWORD"); //NOI18N
422 * Listens to fired event when user updated personal data
424 * @param event Event being fired
426 public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
430 throw new NullPointerException("event is null"); //NOI18N
431 } else if (event.getUpdatedUser() == null) {
433 throw new NullPointerException("event.updatedUser is null"); //NOI18N
434 } else if (event.getUpdatedUser().getUserId() == null) {
436 throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
437 } else if (event.getUpdatedUser().getUserId() < 1) {
439 throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
443 this.addUserActivity(event.getUpdatedUser(), "USER_UPDATED_PERSONAL_DATA"); //NOI18N
447 * Expands given activity type into a i18n string for administrators
449 * @param activityType Activity type
451 * @return Expanded i18n string
453 public String expandAdminActivityType (final String activityType) {
455 if (null == activityType) {
457 throw new NullPointerException("activityType is null"); //NOI18N
458 } else if (activityType.isEmpty()) {
460 throw new IllegalArgumentException("activityType is empty"); //NOI18N
464 return "ADMIN_ACTIVITY_" + activityType; //NOI18N
468 * Expands given activity type into a i18n string for users
470 * @param activityType Activity type
472 * @return Expanded i18n string
474 public String expandUserActivityType (final String activityType) {
476 if (null == activityType) {
478 throw new NullPointerException("activityType is null"); //NOI18N
479 } else if (activityType.isEmpty()) {
481 throw new IllegalArgumentException("activityType is empty"); //NOI18N
485 return "USER_ACTIVITY_" + activityType; //NOI18N
489 * Returns a list of in beanHelper set user instance's activity log
491 * @return List of user's activity log
493 public List<LogableUserActivity> fetchCurrentUsersActivityLog () {
494 // beanHelper.user should be set and valid
495 if (this.getUser() == null) {
497 throw new NullPointerException("this.beanHelper.user is null"); //NOI18N
498 } else if (this.getUser().getUserId() == null) {
500 throw new NullPointerException("this.beanHelper.user.userId is null"); //NOI18N
501 } else if (this.getUser().getUserId() < 1) {
503 throw new IllegalArgumentException(MessageFormat.format("this.beanHelper.user.userId={0} is not valid", this.getUser().getUserId())); //NOI18N
507 List<LogableUserActivity> list = new LinkedList<>();
510 if (this.usersActivity.containsKey(this.getUser())) {
512 list.addAll(this.usersActivity.get(this.getUser()));
514 // Sort list and reverse it
515 Collections.sort(list, new UserActivityLogTimestampComparator());
516 Collections.reverse(list);
524 * Getter for user instance
526 * @return User instance
528 public User getUser () {
533 * Setter for user instance
535 * @param user User instance
537 public void setUser (final User user) {
542 * Post-constructor method
545 public void init () {
546 // Try to get EJB instance
548 // Get initial context
549 Context context = new InitialContext();
552 this.userActivityBean = (UserActivityLogSessionBeanRemote) context.lookup("java:global/addressbook-ejb/userActivity!org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote"); //NOI18N
553 } catch (final NamingException e) {
555 throw new FaceletException(e);
559 List<LogableUserActivity> list = this.userActivityBean.fetchAllUserActivityLog();
561 // Put all in map, per-user
562 for (final LogableUserActivity userActivity : list) {
563 // Is the list there?
564 if (!this.usersActivity.containsKey(userActivity.getActivityUser())) {
566 this.usersActivity.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
569 // Add by user instance
570 boolean added = this.usersActivity.get(userActivity.getActivityUser()).add(userActivity);
573 assert (added) : "Activity log not added"; //NOI18N
578 * Adds user activity entry with given type
580 * @param user User instance
581 * @param activityType Activity type
583 private void addUserActivity (final User user, final String activityType) {
584 // Better re-validate
587 throw new NullPointerException("user is null"); //NOI18N
588 } else if (user.getUserId() == null) {
590 throw new NullPointerException("user.userId is null"); //NOI18N
591 } else if (user.getUserId() < 1) {
593 throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
594 } else if (null == activityType) {
596 throw new NullPointerException("activityType is null"); //NOI18N
597 } else if (activityType.isEmpty()) {
599 throw new IllegalArgumentException("activityType is empty"); //NOI18N
602 // Create new activity object
603 LogableUserActivity userActivity = new UserActivityLog(activityType, user, new GregorianCalendar(), this.determinePrincipalName());
605 // Call bean to add it
606 this.userActivityBean.addUserActivityLog(userActivity);
609 this.addUserActivityToCache(userActivity);
613 * Adds user activity log with type and message
615 * @param user User instance
616 * @param activityType Activity type
617 * @param message Activity message
619 private void addUserActivity (final User user, final String activityType, final String message) {
620 // Better re-validate
623 throw new NullPointerException("user is null"); //NOI18N
624 } else if (user.getUserId() == null) {
626 throw new NullPointerException("user.userId is null"); //NOI18N
627 } else if (user.getUserId() < 1) {
629 throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
630 } else if (null == activityType) {
632 throw new NullPointerException("activityType is null"); //NOI18N
633 } else if (activityType.isEmpty()) {
635 throw new IllegalArgumentException("activityType is empty"); //NOI18N
636 } else if (null == message) {
638 throw new NullPointerException("message is null"); //NOI18N
639 } else if (message.isEmpty()) {
641 throw new IllegalArgumentException("message is empty"); //NOI18N
644 // Create new activity object
645 LogableUserActivity userActivity = new UserActivityLog(message, activityType, user, new GregorianCalendar(), this.determinePrincipalName());
647 // Call bean to add it
648 this.userActivityBean.addUserActivityLog(userActivity);
651 this.addUserActivityToCache(userActivity);
655 * Adds given user activity instance to "cache" (local map)
657 * @param userActivity User activity instance
659 private void addUserActivityToCache (final LogableUserActivity userActivity) {
660 // Is the instance valid
661 if (null == userActivity) {
663 throw new NullPointerException("userActivity is null");
664 } else if (userActivity.getActivityId() instanceof Long) {
666 throw new IllegalArgumentException("userActivity.activityId=" + userActivity.getActivityId() + " is not null");
667 } else if (userActivity.getActivityUser() == null) {
669 throw new NullPointerException("userActivity.activityUser is null");
670 } else if (userActivity.getActivityUser().getUserId() == null) {
672 throw new NullPointerException("userActivity.activityUser.userId is null");
673 } else if (userActivity.getActivityUser().getUserId() < 1) {
675 throw new IllegalArgumentException("userActivity.activityUser.userId=" + userActivity.getActivityUser().getUserId() + " is not valid");
679 if (!this.usersActivity.containsKey(userActivity.getActivityUser())) {
681 this.usersActivity.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
684 // Add activity to log
685 this.usersActivity.get(userActivity.getActivityUser()).add(userActivity);