]> git.mxchange.org Git - addressbook-war.git/commitdiff
Please maybe cherry-pick:
authorRoland Häder <roland@mxchange.org>
Sat, 5 Aug 2017 19:11:00 +0000 (21:11 +0200)
committerRoland Häder <roland@mxchange.org>
Sat, 5 Aug 2017 19:32:50 +0000 (21:32 +0200)
- added missing backing bean + interface for user acitity
- added dependency to juser-acitivty-core|lib

Signed-off-by: Roland Häder <roland@mxchange.org>
nbproject/project.properties
nbproject/project.xml
src/java/org/mxchange/addressbook/beans/user/activity/AddressbookUserActivityWebApplicationBean.java [new file with mode: 0644]
src/java/org/mxchange/addressbook/beans/user/activity/AddressbookUserActivityWebApplicationController.java [new file with mode: 0644]

index 560a980e0a09c9575b52b5f1ed4a65dac545a8a0..b13c987a217914b76e5188be2f7141f112a2ee7e 100644 (file)
@@ -51,6 +51,8 @@ file.reference.jcountry-core.jar=lib/jcountry-core.jar
 file.reference.jcountry-lib.jar=lib/jcountry-lib.jar
 file.reference.jphone-core.jar=lib/jphone-core.jar
 file.reference.jphone-lib.jar=lib/jphone-lib.jar
+file.reference.juser-activity-core.jar=lib/juser-activity-core.jar
+file.reference.juser-activity-lib.jar=lib/juser-activity-lib.jar
 file.reference.juser-core.jar=lib/juser-core.jar
 file.reference.juser-lib.jar=lib/juser-lib.jar
 file.reference.juser-login-core.jar=lib/juser-login-core.jar
@@ -81,6 +83,8 @@ javac.classpath=\
     ${file.reference.jphone-lib.jar}:\
     ${file.reference.juser-core.jar}:\
     ${file.reference.juser-lib.jar}:\
+    ${file.reference.juser-activity-core.jar}:\
+    ${file.reference.juser-activity-lib.jar}:\
     ${file.reference.juser-login-core.jar}:\
     ${file.reference.juser-login-lib.jar}:\
     ${file.reference.jaddressbook-core.jar}:\
@@ -149,6 +153,8 @@ source.reference.jcountry-core.jar=../jcountry-core/src/
 source.reference.jcountry-lib.jar=../jcountry-lib/src/
 source.reference.jphone-core.jar=../jphone-core/src/
 source.reference.jphone-lib.jar=../jphone-lib/src/
+source.reference.juser-activity-core.jar=../juser-activity-core/src/
+source.reference.juser-activity-lib.jar=../juser-activity-lib/src/
 source.reference.juser-core.jar=../juser-core/src/
 source.reference.juser-lib.jar=../juser-lib/src/
 source.reference.juser-login-core.jar=../juser-login-core/src/
index c7466fb8f81aaee3f8d3b5526682c483f880a49d..d82f1652e1691b31f0cd4f57c5a4e98d9dfd14ab 100644 (file)
                 <library dirs="200">
                     <file>${file.reference.juser-lib.jar}</file>
                 </library>
+                <library dirs="200">
+                    <file>${file.reference.juser-activity-core.jar}</file>
+                </library>
+                <library dirs="200">
+                    <file>${file.reference.juser-activity-lib.jar}</file>
+                </library>
                 <library dirs="200">
                     <file>${file.reference.juser-login-core.jar}</file>
                 </library>
diff --git a/src/java/org/mxchange/addressbook/beans/user/activity/AddressbookUserActivityWebApplicationBean.java b/src/java/org/mxchange/addressbook/beans/user/activity/AddressbookUserActivityWebApplicationBean.java
new file mode 100644 (file)
index 0000000..59eb590
--- /dev/null
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.addressbook.beans.user.activity;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.GregorianCalendar;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.addressbook.beans.BaseAddressbookController;
+import org.mxchange.addressbook.beans.helper.AddressbookWebRequestHelperController;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
+import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
+import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
+import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
+import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
+import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
+import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.activity.LogableUserActivity;
+import org.mxchange.jusercore.model.user.activity.UserActivityLog;
+import org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote;
+import org.mxchange.jusercore.model.user.activity.comparator.UserActivityLogTimestampComparator;
+import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
+import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
+import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
+import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
+import org.mxchange.juserlogincore.events.resendlink.ObservableUserResendLinkAccountEvent;
+import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
+
+/**
+ * A controller (bean) for user activity log
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("userActivityController")
+@ApplicationScoped
+public class AddressbookUserActivityWebApplicationBean extends BaseAddressbookController implements AddressbookUserActivityWebApplicationController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 192_586_376_717_856_904L;
+
+       /**
+        * Bean helper
+        */
+       @Inject
+       private AddressbookWebRequestHelperController beanHelper;
+
+       /**
+        * User instance
+        */
+       private User user;
+
+       /**
+        * EJB for user activity log
+        */
+       private UserActivityLogSessionBeanRemote userActivityBean;
+
+       /**
+        * "Cache" for activity log per user
+        */
+       private final Map<User, List<LogableUserActivity>> usersActivity;
+
+       /**
+        * Default constructor
+        */
+       @SuppressWarnings ("CollectionWithoutInitialCapacity")
+       public AddressbookUserActivityWebApplicationBean () {
+               // Try to get EJB instance
+               try {
+                       // Get initial context
+                       Context context = new InitialContext();
+
+                       // Try to lookup
+                       this.userActivityBean = (UserActivityLogSessionBeanRemote) context.lookup("java:global/addressbook-ejb/userActivity!org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote"); //NOI18N
+               } catch (final NamingException e) {
+                       // Throw again
+                       throw new FaceletException(e);
+               }
+
+               // Init cache
+               this.usersActivity = new LinkedHashMap<>();
+       }
+
+       /**
+        * Adds user activity entry with given type
+        * <p>
+        * @param user User instance
+        * @param activityType Activity type
+        */
+       private void addUserActivity (final User user, final String activityType) {
+               // Better re-validate
+               if (null == user) {
+                       // Throw NPE
+                       throw new NullPointerException("user is null"); //NOI18N
+               } else if (user.getUserId() == null) {
+                       // Throw again
+                       throw new NullPointerException("user.userId is null"); //NOI18N
+               } else if (user.getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
+               } else if (null == activityType) {
+                       // Throw NPE again
+                       throw new NullPointerException("activityType is null"); //NOI18N
+               } else if (activityType.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
+               }
+
+               // Create new activity object
+               LogableUserActivity userActivity = new UserActivityLog(activityType, user, new GregorianCalendar(), this.determinePrincipalName());
+
+               // Call bean to add it
+               this.userActivityBean.addUserActivityLog(userActivity);
+
+               // Add to cache, too
+               this.addUserActivityToCache(userActivity);
+       }
+
+       /**
+        * Adds user activity log with type and message
+        * <p>
+        * @param user User instance
+        * @param activityType Activity type
+        * @param message Activity message
+        */
+       private void addUserActivity (final User user, final String activityType, final String message) {
+               // Better re-validate
+               if (null == user) {
+                       // Throw NPE
+                       throw new NullPointerException("user is null"); //NOI18N
+               } else if (user.getUserId() == null) {
+                       // Throw again
+                       throw new NullPointerException("user.userId is null"); //NOI18N
+               } else if (user.getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
+               } else if (null == activityType) {
+                       // Throw NPE again
+                       throw new NullPointerException("activityType is null"); //NOI18N
+               } else if (activityType.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
+               } else if (null == message) {
+                       // Throw NPE again
+                       throw new NullPointerException("message is null"); //NOI18N
+               } else if (message.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("message is empty"); //NOI18N
+               }
+
+               // Create new activity object
+               LogableUserActivity userActivity = new UserActivityLog(message, activityType, user, new GregorianCalendar(), this.determinePrincipalName());
+
+               // Call bean to add it
+               this.userActivityBean.addUserActivityLog(userActivity);
+
+               // Add to cache, too
+               this.addUserActivityToCache(userActivity);
+       }
+
+       /**
+        * Event observer for newly added users by administrator
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getAddedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.addedUser is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getAddedUser(), "ADMIN_ADDED_USER_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for deleted user accounts (by administrator)
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getDeletedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.deletedUser is null"); //NOI18N
+               } else if (event.getDeletedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
+               } else if (event.getDeletedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
+               }
+
+               // Add acitivity
+               this.addUserActivity(event.getDeletedUser(), "ADMIN_DELETED_USER_ACCOUNT", event.getUserDeleteReason()); //NOI18N
+       }
+
+       /**
+        * Event observer for linked users with existing contact data
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLinkedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.linkedUser is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getLinkedUser(), "ADMIN_LINKED_USER_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for locked users
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLockedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.lockedUser is null"); //NOI18N
+               } else if (event.getLockedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
+               } else if (event.getLockedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getLockedUser(), "ADMIN_LOCKED_USER_ACCOUNT", event.getLockedUser().getUserLastLockedReason()); //NOI18N
+       }
+
+       /**
+        * Event observer for unlocked users
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUnlockedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.unlockedUser is null"); //NOI18N
+               } else if (event.getUnlockedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
+               } else if (event.getUnlockedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getUnlockedUser(), "ADMIN_UNLOCKED_USER_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for updated user data by administrator
+        * <p>
+        * @param event Event being updated
+        */
+       public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getUpdatedUser(), "ADMIN_UPDATED_USER_PERSONAL_DATA"); //NOI18N
+       }
+
+       /**
+        * Event observer for when a bean helper has successfully created a user
+        * instance, means the user exists. If the user does not exist, this event
+        * should not fire but instead a proper exception must be thrown.
+        * <p>
+        * @param event User created event
+        */
+       public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
+               // Is the instance valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getCreatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.createdUser is null"); //NOI18N
+               } else if (event.getCreatedUser().getUserId() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
+               } else if (event.getCreatedUser().getUserId() < 1) {
+                       // Throw NPE again
+                       throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
+               }
+
+               // Set whole user
+               this.setUser(event.getCreatedUser());
+       }
+
+       /**
+        * Event observer when user confirmed account.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserConfirmedAccountEvent (@Observes final ObservableUserConfirmedAccountEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getConfirmedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.confirmedUser is null"); //NOI18N
+               } else if (event.getConfirmedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N
+               } else if (event.getConfirmedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getConfirmedUser(), "USER_CONFIRMED_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for logged-in user
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLoggedInUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.registeredUser is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
+               }
+
+               // Copy all data to this bean
+               this.addUserActivity(event.getLoggedInUser(), "USER_LOGGED_IN"); //NOI18N
+       }
+
+       /**
+        * Event observer for logged-out user
+        * <p>
+        * @param event Event instance
+        */
+       public void afterUserLogoutEvent (@Observes final ObservableUserLogoutEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLoggedOutUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.loggedOutUser is null"); //NOI18N
+               } else if (event.getLoggedOutUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.loggedOutUser.userId is null"); //NOI18N
+               } else if (event.getLoggedOutUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedOutUser(), event.getLoggedOutUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getLoggedOutUser(), "USER_LOGGED_OUT"); //NOI18N
+       }
+
+       /**
+        * Event observer for new user registrations
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getRegisteredUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.registeredUser is null"); //NOI18N
+               } else if (event.getRegisteredUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
+               } else if (event.getRegisteredUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getRegisteredUser(), "USER_REGISTERED_NEW_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for users resending their confirmation link
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserResendConfirmationLinkEvent (@Observes final ObservableUserResendLinkAccountEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getResendLinkUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.resendLinkUser is null"); //NOI18N
+               } else if (event.getResendLinkUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.resendLinkUser.userId is null"); //NOI18N
+               } else if (event.getResendLinkUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getResendLinkUser(), event.getResendLinkUser().getUserId())); //NOI18N
+               }
+
+               // Copy all data to this bean
+               this.addUserActivity(event.getResendLinkUser(), "USER_RESEND_CONFIRMATION_LINK"); //NOI18N
+       }
+
+       /**
+        * Method being call after user's password has been updated (and history
+        * entry has been created).
+        * <p>
+        * @param event Event being observed
+        */
+       public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
+               // Check parameter
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getPasswordHistory() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.passwordHistory is null"); //NOI18N
+               } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
+                       // ... and again
+                       throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
+               } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
+                       // Invalid value
+                       throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getPasswordHistory().getUserPasswordHistoryUser(), "USER_UPDATED_PASSWORD"); //NOI18N
+       }
+
+       /**
+        * Listens to fired event when user updated personal data
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
+               // Check parameter
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() == null) {
+                       // ... and again
+                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() < 1) {
+                       // Invalid value
+                       throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getUpdatedUser(), "USER_UPDATED_PERSONAL_DATA"); //NOI18N
+       }
+
+       /**
+        * Expands given activity type into a i18n string for administrators
+        * <p>
+        * @param activityType Activity type
+        * <p>
+        * @return Expanded i18n string
+        */
+       public String expandAdminActivityType (final String activityType) {
+               // Is it valid?
+               if (null == activityType) {
+                       // Throw NPE
+                       throw new NullPointerException("activityType is null"); //NOI18N
+               } else if (activityType.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
+               }
+
+               // Expand it
+               return "ADMIN_ACTIVITY_" + activityType; //NOI18N
+       }
+
+       /**
+        * Expands given activity type into a i18n string for users
+        * <p>
+        * @param activityType Activity type
+        * <p>
+        * @return Expanded i18n string
+        */
+       public String expandUserActivityType (final String activityType) {
+               // Is it valid?
+               if (null == activityType) {
+                       // Throw NPE
+                       throw new NullPointerException("activityType is null"); //NOI18N
+               } else if (activityType.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
+               }
+
+               // Expand it
+               return "USER_ACTIVITY_" + activityType; //NOI18N
+       }
+
+       /**
+        * Returns a list of in beanHelper set user instance's activity log
+        * <p>
+        * @return List of user's activity log
+        */
+       public List<LogableUserActivity> fetchCurrentUsersActivityLog () {
+               // beanHelper.user should be set and valid
+               if (this.getUser() == null) {
+                       // Is not set
+                       throw new NullPointerException("this.beanHelper.user is null"); //NOI18N
+               } else if (this.getUser().getUserId() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("this.beanHelper.user.userId is null"); //NOI18N
+               } else if (this.getUser().getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalArgumentException(MessageFormat.format("this.beanHelper.user.userId={0} is not valid", this.getUser().getUserId())); //NOI18N
+               }
+
+               // Init list
+               List<LogableUserActivity> list = new LinkedList<>();
+
+               // Is the user set?
+               if (this.usersActivity.containsKey(this.getUser())) {
+                       // Return it
+                       list.addAll(this.usersActivity.get(this.getUser()));
+
+                       // Sort list and reverse it
+                       Collections.sort(list, new UserActivityLogTimestampComparator());
+                       Collections.reverse(list);
+               }
+
+               // Return it
+               return list;
+       }
+
+       /**
+        * Getter for user instance
+        * <p>
+        * @return User instance
+        */
+       public User getUser () {
+               return this.user;
+       }
+
+       /**
+        * Setter for user instance
+        * <p>
+        * @param user User instance
+        */
+       public void setUser (final User user) {
+               this.user = user;
+       }
+
+       /**
+        * Post-constructor method
+        */
+       @PostConstruct
+       public void init () {
+               // Get whole list
+               List<LogableUserActivity> list = this.userActivityBean.fetchAllUserActivityLog();
+
+               // Put all in map, per-user
+               for (final LogableUserActivity userActivity : list) {
+                       // Is the list there?
+                       if (!this.usersActivity.containsKey(userActivity.getActivityUser())) {
+                               // Init list
+                               this.usersActivity.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
+                       }
+
+                       // Add by user instance
+                       boolean added = this.usersActivity.get(userActivity.getActivityUser()).add(userActivity);
+
+                       // Should be added
+                       assert (added) : "Activity log not added"; //NOI18N
+               }
+       }
+
+       /**
+        * Adds given user activity instance to "cache" (local map)
+        * <p>
+        * @param userActivity User activity instance
+        */
+       private void addUserActivityToCache (final LogableUserActivity userActivity) {
+               // Is the instance valid
+               if (null == userActivity) {
+                       // Throw NPE again
+                       throw new NullPointerException("userActivity is null");
+               } else if (userActivity.getActivityId() instanceof Long) {
+                       // Is not null
+                       throw new IllegalArgumentException("userActivity.activityId=" + userActivity.getActivityId() + " is not null");
+               } else if (userActivity.getActivityUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("userActivity.activityUser is null");
+               } else if (userActivity.getActivityUser().getUserId() == null) {
+                       // Throw it again
+                       throw new NullPointerException("userActivity.activityUser.userId is null");
+               } else if (userActivity.getActivityUser().getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalArgumentException("userActivity.activityUser.userId=" + userActivity.getActivityUser().getUserId() + " is not valid");
+               }
+
+               // Is it there?
+               if (!this.usersActivity.containsKey(userActivity.getActivityUser())) {
+                       // Init it
+                       this.usersActivity.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
+               }
+
+               // Add activity to log
+               this.usersActivity.get(userActivity.getActivityUser()).add(userActivity);
+       }
+
+}
diff --git a/src/java/org/mxchange/addressbook/beans/user/activity/AddressbookUserActivityWebApplicationController.java b/src/java/org/mxchange/addressbook/beans/user/activity/AddressbookUserActivityWebApplicationController.java
new file mode 100644 (file)
index 0000000..e048d81
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.addressbook.beans.user.activity;
+
+import java.io.Serializable;
+
+/**
+ * A controller (bean) interface for user activity log
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface AddressbookUserActivityWebApplicationController extends Serializable {
+
+}