2 * Copyright (C) 2016 Roland Haeder
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.jjobs.beans.user;
19 import java.text.MessageFormat;
20 import java.util.Collections;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Objects;
24 import javax.annotation.PostConstruct;
25 import javax.enterprise.context.SessionScoped;
26 import javax.enterprise.event.Event;
27 import javax.enterprise.event.Observes;
28 import javax.enterprise.inject.Any;
29 import javax.faces.context.FacesContext;
30 import javax.faces.view.facelets.FaceletException;
31 import javax.inject.Inject;
32 import javax.inject.Named;
33 import javax.naming.Context;
34 import javax.naming.InitialContext;
35 import javax.naming.NamingException;
36 import org.mxchange.jcontacts.contact.Contact;
37 import org.mxchange.jcontacts.contact.ContactSessionBeanRemote;
38 import org.mxchange.jcontacts.events.contact.add.AdminAddedContactEvent;
39 import org.mxchange.jjobs.beans.BaseJobsController;
40 import org.mxchange.jjobs.beans.contact.JobsContactWebSessionController;
41 import org.mxchange.jjobs.beans.login.JobsUserLoginWebSessionController;
42 import org.mxchange.jjobs.beans.register.JobsUserRegisterWebSessionController;
43 import org.mxchange.jusercore.events.login.UserLoggedInEvent;
44 import org.mxchange.jusercore.events.registration.UserRegisteredEvent;
45 import org.mxchange.jusercore.events.user.add.AdminAddedUserEvent;
46 import org.mxchange.jusercore.events.user.update.AdminUpdatedUserDataEvent;
47 import org.mxchange.jusercore.events.user.update.UpdatedUserPersonalDataEvent;
48 import org.mxchange.jusercore.events.user.update.UserUpdatedPersonalDataEvent;
49 import org.mxchange.jusercore.exceptions.UserNotFoundException;
50 import org.mxchange.jusercore.exceptions.UserPasswordMismatchException;
51 import org.mxchange.jusercore.model.user.LoginUser;
52 import org.mxchange.jusercore.model.user.User;
53 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
54 import org.mxchange.jusercore.model.user.UserUtils;
55 import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
58 * A user bean (controller)
60 * @author Roland Haeder<roland@mxchange.org>
62 @Named ("userController")
64 public class JobsUserWebSessionBean extends BaseJobsController implements JobsUserWebSessionController {
69 private static final long serialVersionUID = 542_145_347_916L;
74 private ContactSessionBeanRemote contactBean;
77 * General contact controller
80 private JobsContactWebSessionController contactController;
83 * Registration controller
86 private JobsUserRegisterWebSessionController registerController;
89 * A list of all selectable contacts
91 private List<Contact> selectableContacts;
94 * Event being fired when user updated personal data
98 private Event<UpdatedUserPersonalDataEvent> updatedPersonalDataEvent;
103 private final UserSessionBeanRemote userBean;
111 * A list of all user profiles
113 private List<User> userList;
116 * Login bean (controller)
119 private JobsUserLoginWebSessionController userLoginController;
124 private String userName;
129 private List<String> userNameList;
132 * User password (unencrypted from web form)
134 private String userPassword;
137 * User password repeated (unencrypted from web form)
139 private String userPasswordRepeat;
142 * Whether the user wants a public profile
144 private ProfileMode userProfileMode;
147 * A list of all public user profiles
149 private List<User> visibleUserList;
152 * Default constructor
154 public JobsUserWebSessionBean () {
157 // Get initial context
158 Context context = new InitialContext();
161 this.userBean = (UserSessionBeanRemote) context.lookup("java:global/jjobs-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote"); //NOI18N
164 this.contactBean = (ContactSessionBeanRemote) context.lookup("java:global/jjobs-ejb/contact!org.mxchange.jcontacts.contact.ContactSessionBeanRemote"); //NOI18N
165 } catch (final NamingException e) {
167 throw new FaceletException(e);
172 public void afterAdminAddedContact (@Observes final AdminAddedContactEvent event) {
173 // The event must be valid
176 throw new NullPointerException("event is null"); //NOI18N
177 } else if (event.getAddedContact() == null) {
179 throw new NullPointerException("event.addedContact is null"); //NOI18N
180 } else if (event.getAddedContact().getContactId() == null) {
182 throw new NullPointerException("event.addedContact.customerId is null"); //NOI18N
183 } else if (event.getAddedContact().getContactId() < 1) {
185 throw new IllegalArgumentException(MessageFormat.format("event.addedContact.customerId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N //NOI18N
189 this.selectableContacts.add(event.getAddedContact());
193 public void afterAdminAddedUserEvent (@Observes final AdminAddedUserEvent event) {
195 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("UserWebBean:afterAdminAddedUserEvent: event={0} - CALLED!", event)); //NOI18N
197 // event should not be null
200 throw new NullPointerException("event is null"); //NOI18N
201 } else if (event.getAddedUser() == null) {
203 throw new NullPointerException("event.addedUser is null"); //NOI18N
204 } else if (event.getAddedUser().getUserId() == null) {
206 throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
207 } else if (event.getAddedUser().getUserId() < 1) {
209 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
212 // Add user to local list
213 this.userList.add(event.getAddedUser());
219 this.setUserId(event.getAddedUser().getUserId());
222 //* NOISY-DEBUG: */ System.out.println("UserWebBean:afterAdminAddedUserEvent: EXIT!"); //NOI18N
226 public void afterAdminUpdatedUserDataEvent (@Observes final AdminUpdatedUserDataEvent event) {
228 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("UserWebBean:afterAdminUpdatedUserEvent: event={0} - CALLED!", event)); //NOI18N
230 // event should not be null
233 throw new NullPointerException("event is null"); //NOI18N
234 } else if (event.getUpdatedUser() == null) {
236 throw new NullPointerException("event.updatedUser is null"); //NOI18N
237 } else if (event.getUpdatedUser().getUserId() == null) {
239 throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
240 } else if (event.getUpdatedUser().getUserId() < 1) {
242 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
246 this.updateList(event.getUpdatedUser());
252 //* NOISY-DEBUG: */ System.out.println("UserWebBean:afterAdminUpdatedUserEvent: EXIT!"); //NOI18N
256 public void afterRegistrationEvent (@Observes final UserRegisteredEvent event) {
258 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("UserWebBean:afterRegistration: event={0} - CALLED!", event)); //NOI18N
260 // event should not be null
263 throw new NullPointerException("event is null"); //NOI18N
264 } else if (event.getRegisteredUser() == null) {
266 throw new NullPointerException("event.registeredUser is null"); //NOI18N
267 } else if (event.getRegisteredUser().getUserId() == null) {
269 throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
270 } else if (event.getRegisteredUser().getUserId() < 1) {
272 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
276 User registeredUser = event.getRegisteredUser();
279 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("UserWebBean:afterRegistration: registeredUser={0}", registeredUser)); //NOI18N
281 // Copy all data from registered->user
282 this.copyUser(registeredUser);
287 // Add user to local list
288 this.userList.add(registeredUser);
291 this.addUserName(registeredUser);
293 // Is the account public?
294 if (Objects.equals(registeredUser.getUserProfileMode(), ProfileMode.PUBLIC)) {
295 // Also add it to this list
296 this.visibleUserList.add(registeredUser);
300 this.setUserId(registeredUser.getUserId());
303 //* NOISY-DEBUG: */ System.out.println("UserWebBean:afterRegistration: EXIT!"); //NOI18N
307 public void afterUserLogin (final @Observes UserLoggedInEvent event) {
309 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("UserWebBean:afterUserLogin: event={0} - CALLED!", event)); //NOI18N
311 // event should not be null
314 throw new NullPointerException("event is null"); //NOI18N
315 } else if (event.getLoggedInUser() == null) {
317 throw new NullPointerException("event.registeredUser is null"); //NOI18N
318 } else if (event.getLoggedInUser().getUserId() == null) {
320 throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
321 } else if (event.getLoggedInUser().getUserId() < 1) {
323 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
326 // Copy all data to this bean
327 this.copyUser(event.getLoggedInUser());
329 // Re-initialize list
330 this.visibleUserList = this.userBean.allMemberPublicVisibleUsers();
333 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("UserWebBean:afterUserLogin: this.visibleUserList.size()={0} - EXIT!", this.visibleUserList.size())); //NOI18N
337 public void afterUserUpdatedPersonalData (@Observes final UpdatedUserPersonalDataEvent event) {
341 throw new NullPointerException("event is null"); //NOI18N
342 } else if (event.getUpdatedUser() == null) {
344 throw new NullPointerException("event.updatedUser is null"); //NOI18N
345 } else if (event.getUpdatedUser().getUserId() == null) {
347 throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
348 } else if (event.getUpdatedUser().getUserId() < 1) {
350 throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
353 // All fine, so update list
354 this.updateList(event.getUpdatedUser());
358 public List<User> allUsers () {
360 return Collections.unmodifiableList(this.userList);
364 public List<User> allVisibleUsers () {
366 return Collections.unmodifiableList(this.visibleUserList);
370 public User createUserInstance () {
372 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: CALLED!", this.getClass().getSimpleName()));
374 // Required personal data must be set
375 assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
377 // Create new user instance
378 User localUser = new LoginUser();
380 // Is user name required?
381 if (!this.isUserNameRequired()) {
382 // Generate pseudo-random user name
383 String randomName = this.userBean.generateRandomUserName();
385 // Set it and inivisible profile
386 this.setUserName(randomName);
387 this.setUserProfileMode(ProfileMode.INVISIBLE);
389 // Generate random password
390 String randomPassword = UserUtils.createRandomPassword(JobsUserWebSessionController.MINIMUM_PASSWORD_LENGTH);
392 // Set random password
393 this.setUserPassword(randomPassword);
394 this.setUserPasswordRepeat(randomPassword);
397 // Set user name and mode
398 localUser.setUserName(this.getUserName());
399 localUser.setUserProfileMode(this.getUserProfileMode());
401 // Create contact instance
402 Contact contact = this.contactController.createContactInstance();
405 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: contact={1}", this.getClass().getSimpleName(), contact));
407 // Set contact in user
408 localUser.setUserContact(contact);
411 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: user={1} - EXIT!", this.getClass().getSimpleName(), user));
418 public User createUserLogin () {
420 //* NOISY-DEBUG */ System.out.println(MessageFormat.format("{0}.createUserLogin: CALLED!", this.getClass().getSimpleName()));
423 if (this.getUserName() == null) {
425 throw new NullPointerException("recruiterName is null"); //NOI18N
426 } else if (this.getUserName().isEmpty()) {
428 throw new IllegalStateException("recruiterName is empty."); //NOI18N
431 // Create new recruiter instance
432 User recruiter = new LoginUser();
434 // Update all data ...
435 recruiter.setUserName(this.getUserName());
438 //* NOISY-DEBUG */ System.out.println(MessageFormat.format("{0}.createUserLogin: recruiter={1} - EXIT!", this.getClass().getSimpleName(), recruiter));
440 // Return the new instance
445 public String doChangePersonalData () {
446 // This method shall only be called if the user is logged-in
447 if (!this.userLoginController.isUserLoggedIn()) {
449 throw new IllegalStateException("User is not logged-in"); //NOI18N
450 } else if (!this.isRequiredChangePersonalDataSet()) {
451 // Not all required fields are set
452 throw new FaceletException("Not all required fields are set."); //NOI18N
453 } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
454 // Password not matching
455 throw new FaceletException(new UserPasswordMismatchException(this.userLoginController.getLoggedInUser()));
459 User user = this.userLoginController.getLoggedInUser();
461 // Copy contact data to contact instance
462 this.contactController.updateContactDataFromController(user.getUserContact());
464 // It should be there, so run some tests on it
465 assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
466 assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
467 assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
468 assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
469 assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
470 assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
473 user.setUserProfileMode(this.getUserProfileMode());
475 // Send it to the EJB
476 User updatedUser = this.userBean.updateUserPersonalData(user);
479 this.updatedPersonalDataEvent.fire(new UserUpdatedPersonalDataEvent(updatedUser));
482 return "user_data_saved"; //NOI18N
486 public Long getUserId () {
491 public void setUserId (final Long userId) {
492 this.userId = userId;
496 public String getUserName () {
497 return this.userName;
501 public void setUserName (final String userName) {
502 this.userName = userName;
506 public String getUserPassword () {
507 return this.userPassword;
511 public void setUserPassword (final String userPassword) {
512 this.userPassword = userPassword;
516 public String getUserPasswordRepeat () {
517 return this.userPasswordRepeat;
521 public void setUserPasswordRepeat (final String userPasswordRepeat) {
522 this.userPasswordRepeat = userPasswordRepeat;
526 public ProfileMode getUserProfileMode () {
527 return this.userProfileMode;
531 public void setUserProfileMode (final ProfileMode userProfileMode) {
532 this.userProfileMode = userProfileMode;
536 public boolean hasUsers () {
537 return (!this.allUsers().isEmpty());
541 * Post-initialization of this class
544 public void init () {
545 // Initialize user list
546 this.userList = this.userBean.allUsers();
548 // Get full user name list for reducing EJB calls
549 this.userNameList = this.userBean.getUserNameList();
551 // Is the user logged-in?
552 if (this.userLoginController.isUserLoggedIn()) {
553 // Is logged-in, so load also users visible to memebers
554 this.visibleUserList = this.userBean.allMemberPublicVisibleUsers();
556 // Initialize user list
557 this.visibleUserList = this.userBean.allPublicUsers();
561 List<User> allUsers = this.allUsers();
564 List<Contact> allContacts = this.contactBean.getAllContacts();
567 Iterator<Contact> iterator = allContacts.iterator();
570 while (iterator.hasNext()) {
572 Contact next = iterator.next();
575 Iterator<User> userIterator = allUsers.iterator();
577 // Loop through all users
578 while (userIterator.hasNext()) {
580 User nextUser = userIterator.next();
583 if (Objects.equals(next, nextUser.getUserContact())) {
592 this.selectableContacts = allContacts;
596 public boolean isContactFound (final Contact contact) {
597 // The contact must be valid
598 if (null == contact) {
600 throw new NullPointerException("contact is null"); //NOI18N
601 } else if (contact.getContactId() == null) {
603 throw new NullPointerException("contact.contactId is null"); //NOI18N
604 } else if (contact.getContactId() < 1) {
606 throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid", contact.getContactId())); //NOI18N
609 // Default is not found
610 boolean isFound = false;
613 Iterator<User> iterator = this.allUsers().iterator();
615 // Loop through all entries
616 while (iterator.hasNext()) {
618 User next = iterator.next();
620 // Compare both objects
621 if (Objects.equals(contact, next.getUserContact())) {
633 public boolean isPublicUserProfileEnabled () {
634 // Get context parameter
635 String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_public_profile_enabled"); //NOI18N
638 boolean isPublicUserProfileEnabled = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
640 // This requires user names being enabled, too.
641 if ((isPublicUserProfileEnabled) && (!this.isUserNameRequired())) {
642 // Not valid state, users must be able to modify their profile, especially when it is public
643 throw new IllegalStateException("Public user profiles are enabled but user name requirement is disabled, this is not possible."); //NOI18N
647 return isPublicUserProfileEnabled;
651 public boolean isRequiredChangePersonalDataSet () {
652 return ((this.getUserProfileMode() != null) &&
653 (this.getUserName() != null) && (!this.getUserName().isEmpty()) &&
654 (this.contactController.isRequiredChangePersonalDataSet()));
658 public boolean isRequiredPersonalDataSet () {
659 if (this.registerController.isMultiplePageEnabled()) {
660 // Multiple registration page
661 return this.contactController.isRequiredPersonalDataSet();
663 // Single registration page
664 return (((this.getUserName() != null) || (!this.isUserNameRequired())) &&
665 (this.getUserProfileMode() != null) &&
666 (this.contactController.isRequiredPersonalDataSet()) &&
667 (this.getUserPassword() != null) &&
668 (this.getUserPasswordRepeat() != null));
673 public boolean isSamePasswordEntered () {
674 return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
678 public boolean isUserIdEmpty () {
679 return ((this.getUserId() == null) || (this.getUserId() == 0));
683 public boolean isUserNameRegistered (final User user) {
684 return ((this.userNameList instanceof List) && (this.userNameList.contains(user.getUserName())));
688 public boolean isUserNameRequired () {
689 // Get context parameter
690 String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_user_name_required"); //NOI18N
693 boolean isUserNameRequired = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
696 return isUserNameRequired;
700 public boolean isVisibleUserFound () {
701 return ((this.visibleUserList instanceof List) && (this.visibleUserList.size() > 0));
705 public User lookupUserById (final Long userId) throws UserNotFoundException {
706 // Parameter must be valid
707 if (null == userId) {
709 throw new NullPointerException("userId is null"); //NOI18N
710 } else if (userId < 1) {
712 throw new IllegalArgumentException(MessageFormat.format("userId={0} is not valid.", userId)); //NOI18N
718 // Try to lookup it in visible user list
719 for (final Iterator<User> iterator = this.userList.iterator(); iterator.hasNext();) {
721 User next = iterator.next();
723 // Is the user id found?
724 if (Objects.equals(next.getUserId(), userId)) {
725 // Copy to other variable
733 // Not visible for the current user
734 throw new UserNotFoundException(userId);
742 public List<Contact> selectableContacts () {
743 return Collections.unmodifiableList(this.selectableContacts);
747 * Adds user's name to bean's internal list. It also updates the public user
748 * list if the user has decided to have a public account,
750 * @param user User instance
752 private void addUserName (final User user) {
753 // Make sure the entry is not added yet
754 if (this.userNameList.contains(user.getUserName())) {
756 throw new IllegalArgumentException(MessageFormat.format("User name {0} already added.", user.getUserName())); //NOI18N
757 } else if (this.contactController.isEmailAddressRegistered(user.getUserContact())) {
759 throw new IllegalArgumentException(MessageFormat.format("Email address {0} already added.", user.getUserContact().getContactEmailAddress())); //NOI18N
763 this.userNameList.add(user.getUserName());
769 private void clear () {
772 this.setUserId(null);
773 this.setUserProfileMode(null);
776 this.setUserName(null);
777 this.setUserPassword(null);
778 this.setUserPasswordRepeat(null);
782 * Copies given user into the controller
784 * @param user User instance
786 private void copyUser (final User user) {
787 // Make sure the instance is valid
790 throw new NullPointerException("user is null"); //NOI18N
791 } else if (user.getUserContact() == null) {
793 throw new NullPointerException("user.userContact is null"); //NOI18N
798 this.setUserId(user.getUserId());
799 this.setUserProfileMode(user.getUserProfileMode());
803 * Updates list with given user instance
805 * @param user User instance
807 private void updateList (final User user) {
808 // The user should be valid
811 throw new NullPointerException("user is null"); //NOI18N
812 } else if (user.getUserId() == null) {
814 throw new NullPointerException("user.userId is null"); //NOI18N
815 } else if (user.getUserId() < 1) {
817 throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
821 Iterator<User> iterator = this.userList.iterator();
824 while (iterator.hasNext()) {
826 User next = iterator.next();
828 // Is the same user id?
829 if (Objects.equals(user.getUserId(), next.getUserId())) {
830 // Found it, so remove it
831 this.userList.remove(next);
837 this.userList.add(user);