]> git.mxchange.org Git - jjobs-war.git/blob - src/java/org/mxchange/jjobs/beans/user/JobsUserWebSessionBean.java
5c9c1a9ccd21e790e239618f9ec517e57efda0e1
[jjobs-war.git] / src / java / org / mxchange / jjobs / beans / user / JobsUserWebSessionBean.java
1 /*
2  * Copyright (C) 2016, 2017 Roland Häder
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 package org.mxchange.jjobs.beans.user;
18
19 import java.text.MessageFormat;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Locale;
23 import java.util.Objects;
24 import javax.annotation.PostConstruct;
25 import javax.ejb.EJB;
26 import javax.enterprise.context.SessionScoped;
27 import javax.enterprise.event.Event;
28 import javax.enterprise.event.Observes;
29 import javax.enterprise.inject.Any;
30 import javax.faces.context.FacesContext;
31 import javax.faces.view.facelets.FaceletException;
32 import javax.inject.Inject;
33 import javax.inject.Named;
34 import org.mxchange.jcontacts.contact.Contact;
35 import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
36 import org.mxchange.jjobs.beans.BaseJobsController;
37 import org.mxchange.jjobs.beans.contact.JobsContactWebSessionController;
38 import org.mxchange.jjobs.beans.features.JobsFeaturesWebApplicationController;
39 import org.mxchange.jjobs.beans.localization.JobsLocalizationSessionController;
40 import org.mxchange.jjobs.beans.user.login.JobsUserLoginWebSessionController;
41 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
42 import org.mxchange.jusercore.events.user.clear.password.ObservableClearUserPasswordEvent;
43 import org.mxchange.jusercore.events.user.clear.username.ObservableClearUserNameEvent;
44 import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
45 import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
46 import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
47 import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
48 import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
49 import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
50 import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
51 import org.mxchange.jusercore.events.user.update.UpdatedUserPersonalDataEvent;
52 import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
53 import org.mxchange.jusercore.exceptions.UserNotFoundException;
54 import org.mxchange.jusercore.model.user.LoginUser;
55 import org.mxchange.jusercore.model.user.User;
56 import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
57 import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
58 import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
59 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
60 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
61 import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
62 import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
63 import org.mxchange.juserlogincore.login.UserLoginUtils;
64
65 /**
66  * A user controller (bean)
67  * <p>
68  * @author Roland Häder<roland@mxchange.org>
69  */
70 @Named ("userController")
71 @SessionScoped
72 public class JobsUserWebSessionBean extends BaseJobsController implements JobsUserWebSessionController {
73
74         /**
75          * Serial number
76          */
77         private static final long serialVersionUID = 542_145_347_916L;
78
79         /**
80          * General contact controller
81          */
82         @Inject
83         private JobsContactWebSessionController contactController;
84
85         /**
86          * Features controller
87          */
88         @Inject
89         private JobsFeaturesWebApplicationController featureController;
90
91         /**
92          * Locale instance
93          */
94         private Locale locale;
95
96         /**
97          * Localization controller
98          */
99         @Inject
100         private JobsLocalizationSessionController localizationController;
101
102         /**
103          * Event being fired when user updated personal data
104          */
105         @Inject
106         @Any
107         private Event<ObservableUpdatedUserPersonalDataEvent> updatedPersonalDataEvent;
108
109         /**
110          * Remote user bean
111          */
112         @EJB (lookup = "java:global/jjobs-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
113         private UserSessionBeanRemote userBean;
114
115         /**
116          * User id
117          */
118         private Long userId;
119
120         /**
121          * A list of all user profiles
122          */
123         private List<User> userList;
124
125         /**
126          * Login controller (bean)
127          */
128         @Inject
129         private JobsUserLoginWebSessionController userLoginController;
130
131         /**
132          * User name
133          */
134         private String userName;
135
136         /**
137          * User name list
138          */
139         private List<String> userNameList;
140
141         /**
142          * User password (clear-text from web form)
143          */
144         private String userPassword;
145
146         /**
147          * User password repeated (clear-text from web form)
148          */
149         private String userPasswordRepeat;
150
151         /**
152          * Whether the user wants a public profile
153          */
154         private ProfileMode userProfileMode;
155
156         /**
157          * A list of all public user profiles
158          * <p>
159          * @TODO Hmm, makes that sense? Having visible user list in current
160          * (session-scoped) user's visible user list?
161          */
162         private List<User> visibleUserList;
163
164         /**
165          * Default constructor
166          */
167         public JobsUserWebSessionBean () {
168                 // Call super constructor
169                 super();
170         }
171
172         /**
173          * Event observer for newly added users by administrator
174          * <p>
175          * @param event Event being fired
176          */
177         public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
178                 // event should not be null
179                 if (null == event) {
180                         // Throw NPE
181                         throw new NullPointerException("event is null"); //NOI18N
182                 } else if (event.getAddedUser() == null) {
183                         // Throw NPE again
184                         throw new NullPointerException("event.addedUser is null"); //NOI18N
185                 } else if (event.getAddedUser().getUserId() == null) {
186                         // userId is null
187                         throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
188                 } else if (event.getAddedUser().getUserId() < 1) {
189                         // Not avalid id
190                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
191                 }
192
193                 // Update user list
194                 this.updateList(event.getAddedUser());
195
196                 // Clear all data
197                 this.clear();
198
199                 // Set user id again
200                 this.setUserId(event.getAddedUser().getUserId());
201         }
202
203         /**
204          * Event observer for deleted user accounts (by administrator)
205          * <p>
206          * @param event Event being fired
207          */
208         public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
209                 // event should not be null
210                 if (null == event) {
211                         // Throw NPE
212                         throw new NullPointerException("event is null"); //NOI18N
213                 } else if (event.getDeletedUser() == null) {
214                         // Throw NPE again
215                         throw new NullPointerException("event.deletedUser is null"); //NOI18N
216                 } else if (event.getDeletedUser().getUserId() == null) {
217                         // userId is null
218                         throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
219                 } else if (event.getDeletedUser().getUserId() < 1) {
220                         // Not avalid id
221                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
222                 }
223
224                 // Update user list
225                 this.removeFromList(event.getDeletedUser());
226
227                 // Clear all data
228                 this.clear();
229         }
230
231         /**
232          * Event observer for linked users with existing contact data
233          * <p>
234          * @param event Event being fired
235          */
236         public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
237                 // event should not be null
238                 if (null == event) {
239                         // Throw NPE
240                         throw new NullPointerException("event is null"); //NOI18N
241                 } else if (event.getLinkedUser() == null) {
242                         // Throw NPE again
243                         throw new NullPointerException("event.linkedUser is null"); //NOI18N
244                 } else if (event.getLinkedUser().getUserId() == null) {
245                         // userId is null
246                         throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
247                 } else if (event.getLinkedUser().getUserId() < 1) {
248                         // Not avalid id
249                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
250                 }
251
252                 // Update user list
253                 this.updateList(event.getLinkedUser());
254
255                 // Clear all data
256                 this.clear();
257
258                 // Set user id again
259                 this.setUserId(event.getLinkedUser().getUserId());
260         }
261
262         /**
263          * Event observer for locked users
264          * <p>
265          * @param event Event being fired
266          */
267         public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
268                 // event should not be null
269                 if (null == event) {
270                         // Throw NPE
271                         throw new NullPointerException("event is null"); //NOI18N
272                 } else if (event.getLockedUser() == null) {
273                         // Throw NPE again
274                         throw new NullPointerException("event.lockedUser is null"); //NOI18N
275                 } else if (event.getLockedUser().getUserId() == null) {
276                         // userId is null
277                         throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
278                 } else if (event.getLockedUser().getUserId() < 1) {
279                         // Not avalid id
280                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
281                 }
282
283                 // Update user list
284                 this.updateList(event.getLockedUser());
285         }
286
287         /**
288          * Event observer for unlocked users
289          * <p>
290          * @param event Event being fired
291          */
292         public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
293                 // event should not be null
294                 if (null == event) {
295                         // Throw NPE
296                         throw new NullPointerException("event is null"); //NOI18N
297                 } else if (event.getUnlockedUser() == null) {
298                         // Throw NPE again
299                         throw new NullPointerException("event.unlockedUser is null"); //NOI18N
300                 } else if (event.getUnlockedUser().getUserId() == null) {
301                         // userId is null
302                         throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
303                 } else if (event.getUnlockedUser().getUserId() < 1) {
304                         // Not avalid id
305                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
306                 }
307
308                 // Update user list
309                 this.updateList(event.getUnlockedUser());
310         }
311
312         /**
313          * Event observer for updated user data by administrator
314          * <p>
315          * @param event Event being updated
316          */
317         public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
318                 // event should not be null
319                 if (null == event) {
320                         // Throw NPE
321                         throw new NullPointerException("event is null"); //NOI18N
322                 } else if (event.getUpdatedUser() == null) {
323                         // Throw NPE again
324                         throw new NullPointerException("event.updatedUser is null"); //NOI18N
325                 } else if (event.getUpdatedUser().getUserId() == null) {
326                         // userId is null
327                         throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
328                 } else if (event.getUpdatedUser().getUserId() < 1) {
329                         // Not avalid id
330                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
331                 }
332
333                 // Update user list
334                 this.updateList(event.getUpdatedUser());
335
336                 // Clear all data
337                 this.clear();
338         }
339
340         /**
341          * Event observer for when a bean helper has successfully created a user
342          * instance, means the user exists. If the user does not exist, this event
343          * should not fire but instead a proper exception must be thrown.
344          * <p>
345          * @param event User created event
346          */
347         public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
348                 // Is the instance valid?
349                 if (null == event) {
350                         // Throw NPE
351                         throw new NullPointerException("event is null"); //NOI18N
352                 } else if (event.getCreatedUser() == null) {
353                         // Throw NPE again
354                         throw new NullPointerException("event.createdUser is null"); //NOI18N
355                 } else if (event.getCreatedUser().getUserId() == null) {
356                         // Throw NPE again
357                         throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
358                 } else if (event.getCreatedUser().getUserId() < 1) {
359                         // Throw NPE again
360                         throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
361                 }
362
363                 // Get user instance
364                 User user = event.getCreatedUser();
365
366                 // Set all fields here
367                 this.copyUser(user);
368         }
369
370         /**
371          * Observer method for events being fired when the application's locale has
372          * been changed.
373          * <p>
374          * @param event Event being fired
375          */
376         public void afterLocaleChangeEvent (@Observes final ObservableLocaleChangeEvent event) {
377                 // Is the parameter valid?
378                 if (null == event) {
379                         // Throw NPE
380                         throw new NullPointerException("event is null");
381                 } else if (event.getLocale() == null) {
382                         // Throw NPE again
383                         throw new NullPointerException("event.locale is null");
384                 }
385
386                 // Set it here
387                 this.setLocale(event.getLocale());
388         }
389
390         /**
391          * Event observer when user confirmed account.
392          * <p>
393          * @param event Event being fired
394          */
395         public void afterUserConfirmedAccountEvent (@Observes final ObservableUserConfirmedAccountEvent event) {
396                 // event should not be null
397                 if (null == event) {
398                         // Throw NPE
399                         throw new NullPointerException("event is null"); //NOI18N
400                 } else if (event.getConfirmedUser() == null) {
401                         // Throw NPE again
402                         throw new NullPointerException("event.confirmedUser is null"); //NOI18N
403                 } else if (event.getConfirmedUser().getUserId() == null) {
404                         // userId is null
405                         throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N
406                 } else if (event.getConfirmedUser().getUserId() < 1) {
407                         // Not avalid id
408                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N
409                 }
410
411                 // Update user list
412                 this.updateList(event.getConfirmedUser());
413         }
414
415         /**
416          * Event observer for logged-in user
417          * <p>
418          * @param event Event instance
419          */
420         public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
421                 // event should not be null
422                 if (null == event) {
423                         // Throw NPE
424                         throw new NullPointerException("event is null"); //NOI18N
425                 } else if (event.getLoggedInUser() == null) {
426                         // Throw NPE again
427                         throw new NullPointerException("event.registeredUser is null"); //NOI18N
428                 } else if (event.getLoggedInUser().getUserId() == null) {
429                         // userId is null
430                         throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
431                 } else if (event.getLoggedInUser().getUserId() < 1) {
432                         // Not avalid id
433                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
434                 }
435
436                 // "Cache" user instance
437                 User loggedInUser = event.getLoggedInUser();
438
439                 // Copy all data to this bean
440                 this.copyUser(loggedInUser);
441
442                 // Is the user visible?
443                 if (Objects.equals(loggedInUser.getUserProfileMode(), ProfileMode.PUBLIC)) {
444                         // Yes, then add user
445                         this.visibleUserList.add(loggedInUser);
446                 }
447         }
448
449         /**
450          * Event observer for user password changes
451          * <p>
452          * @param event Event being fired
453          */
454         public void afterUserPasswordChangedEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
455                 // Is it valid?
456                 if (null == event) {
457                         // Throw NPE
458                         throw new NullPointerException("event is null"); //NOI18N
459                 } else if (event.getUserPassword() == null) {
460                         // Throw NPE
461                         throw new NullPointerException("event.userPassword is null"); //NOI18N
462                 } else if (event.getUserPassword().isEmpty()) {
463                         // Throw NPE
464                         throw new IllegalArgumentException("event.userPassword is empty"); //NOI18N
465                 }
466
467                 // Set it here
468                 this.setUserPassword(event.getUserPassword());
469                 this.setUserPasswordRepeat(event.getUserPassword());
470         }
471
472         /**
473          * Event observer for new user registrations
474          * <p>
475          * @param event User registration event
476          */
477         public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
478                 // event should not be null
479                 if (null == event) {
480                         // Throw NPE
481                         throw new NullPointerException("event is null"); //NOI18N
482                 } else if (event.getRegisteredUser() == null) {
483                         // Throw NPE again
484                         throw new NullPointerException("event.registeredUser is null"); //NOI18N
485                 } else if (event.getRegisteredUser().getUserId() == null) {
486                         // userId is null
487                         throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
488                 } else if (event.getRegisteredUser().getUserId() < 1) {
489                         // Not avalid id
490                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
491                 }
492
493                 // Get user instance
494                 User registeredUser = event.getRegisteredUser();
495
496                 // Copy all data from registered->user
497                 this.copyUser(registeredUser);
498
499                 // Clear all data
500                 this.clear();
501
502                 // Update user list
503                 this.updateList(registeredUser);
504
505                 // Add user name
506                 this.addUserName(registeredUser);
507
508                 // Is the account public?
509                 if (Objects.equals(registeredUser.getUserProfileMode(), ProfileMode.PUBLIC)) {
510                         // Also add it to this list
511                         this.visibleUserList.add(registeredUser);
512                 }
513
514                 // Set user id again
515                 this.setUserId(registeredUser.getUserId());
516         }
517
518         /**
519          * Method being call after user's password has been updated (and history
520          * entry has been created).
521          * <p>
522          * @param event Event being observed
523          */
524         public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
525                 // Check parameter
526                 if (null == event) {
527                         // Throw NPE
528                         throw new NullPointerException("event is null"); //NOI18N
529                 } else if (event.getPasswordHistory() == null) {
530                         // Throw NPE again
531                         throw new NullPointerException("event.passwordHistory is null"); //NOI18N
532                 } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
533                         // ... and again
534                         throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
535                 } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
536                         // Invalid value
537                         throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
538                 }
539
540                 // Update user list
541                 this.updateList(event.getPasswordHistory().getUserPasswordHistoryUser());
542         }
543
544         /**
545          * Listens to fired event when user updated personal data
546          * <p>
547          * @param event Event being fired
548          */
549         public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
550                 // Check parameter
551                 if (null == event) {
552                         // Throw NPE
553                         throw new NullPointerException("event is null"); //NOI18N
554                 } else if (event.getUpdatedUser() == null) {
555                         // Throw NPE again
556                         throw new NullPointerException("event.updatedUser is null"); //NOI18N
557                 } else if (event.getUpdatedUser().getUserId() == null) {
558                         // ... and again
559                         throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
560                 } else if (event.getUpdatedUser().getUserId() < 1) {
561                         // Invalid value
562                         throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
563                 }
564
565                 // Update user list
566                 this.updateList(event.getUpdatedUser());
567         }
568
569         @Override
570         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
571         public List<User> allUsers () {
572                 // Return it
573                 return this.userList;
574         }
575
576         @Override
577         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
578         public List<User> allVisibleUsers () {
579                 // Return it
580                 return this.visibleUserList;
581         }
582
583         /**
584          * Event observer for when a user name should be cleared
585          * <p>
586          * @param event Event being fired
587          */
588         public void clearUserNameEvent (@Observes final ObservableClearUserNameEvent event) {
589                 // Is it valid?
590                 if (null == event) {
591                         // Throw NPE
592                         throw new NullPointerException("event is null");
593                 }
594
595                 // Clear it
596                 this.clearUserName();
597         }
598
599         /**
600          * Event observer for when both user passwords should be cleared
601          * <p>
602          * @param event Event being fired
603          */
604         public void clearUserPasswordEvent (@Observes final ObservableClearUserPasswordEvent event) {
605                 // Is it valid?
606                 if (null == event) {
607                         // Throw NPE
608                         throw new NullPointerException("event is null");
609                 }
610
611                 // Clear it
612                 this.clearUserPasswords();
613         }
614
615         @Override
616         public User createUserInstance (final boolean createContactData) {
617                 // Trace message
618                 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: CALLED!", this.getClass().getSimpleName()));
619
620                 // Required personal data must be set
621                 assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
622
623                 // Create new user instance
624                 User user = new LoginUser();
625
626                 // Is user name required?
627                 if (!this.isUserNameRequired()) {
628                         // Generate pseudo-random user name
629                         String randomName = this.userBean.generateRandomUserName();
630
631                         // Set it and inivisible profile
632                         this.setUserName(randomName);
633                         this.setUserProfileMode(ProfileMode.INVISIBLE);
634
635                         // Generate random password
636                         String randomPassword = UserLoginUtils.createRandomPassword(JobsUserWebSessionController.MINIMUM_PASSWORD_LENGTH);
637
638                         // Set random password
639                         this.setUserPassword(randomPassword);
640                         this.setUserPasswordRepeat(randomPassword);
641                 }
642
643                 // Set user name profile mode and locale
644                 user.setUserName(this.getUserName());
645                 user.setUserProfileMode(this.getUserProfileMode());
646                 user.setUserLocale(this.getLocale());
647
648                 // Is multiple registration page
649                 if ((createContactData) || (!this.featureController.isFeatureEnabled("user_register_multiple_page"))) { //NOI18N
650                         // Create contact instance
651                         Contact contact = this.contactController.createContactInstance();
652
653                         // Debug message
654                         //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: contact={1}", this.getClass().getSimpleName(), contact));
655                         // Set contact in user
656                         user.setUserContact(contact);
657                 }
658
659                 // Trace message
660                 //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: user={1} - EXIT!", this.getClass().getSimpleName(), user));
661                 // Return it
662                 return user;
663         }
664
665         @Override
666         public User createUserLogin () {
667                 // Trace message
668                 //* NOISY-DEBUG */ System.out.println(MessageFormat.format("{0}.createUserLogin: CALLED!", this.getClass().getSimpleName()));
669
670                 // Is all data set?
671                 if (this.getUserName() == null) {
672                         // Throw NPE
673                         throw new NullPointerException("userName is null"); //NOI18N
674                 } else if (this.getUserName().isEmpty()) {
675                         // Is empty
676                         throw new IllegalStateException("userName is empty."); //NOI18N
677                 }
678
679                 // Create new user instance
680                 User user = new LoginUser();
681
682                 // Update all data ...
683                 user.setUserName(this.getUserName());
684
685                 // Trace message
686                 //* NOISY-DEBUG */ System.out.println(MessageFormat.format("{0}.createUserLogin: user={1} - EXIT!", this.getClass().getSimpleName(), user));
687                 // Return the new instance
688                 return user;
689         }
690
691         @Override
692         public String doChangePersonalData () {
693                 // This method shall only be called if the user is logged-in
694                 if (!this.userLoginController.isUserLoggedIn()) {
695                         // Not logged-in
696                         throw new IllegalStateException("User is not logged-in"); //NOI18N
697                 } else if (!this.isRequiredChangePersonalDataSet()) {
698                         // Not all required fields are set
699                         throw new FaceletException("Not all required fields are set."); //NOI18N
700                 } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
701                         // Password not matching
702                         throw new FaceletException(new UserPasswordMismatchException(this.userLoginController.getLoggedInUser()));
703                 } else if (!this.featureController.isFeatureEnabled("change_user_personal_data")) { //NOI18N
704                         // Editing is not allowed
705                         throw new IllegalStateException("User tried to edit personal data."); //NOI18N
706                 }
707
708                 // Get user instance
709                 User user = this.userLoginController.getLoggedInUser();
710
711                 // Copy contact data to contact instance
712                 this.contactController.updateContactDataFromController(user.getUserContact());
713
714                 // It should be there, so run some tests on it
715                 assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
716                 assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
717                 assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
718                 assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
719                 assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
720                 assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
721
722                 // Update all fields
723                 user.setUserProfileMode(this.getUserProfileMode());
724
725                 // Send it to the EJB
726                 User updatedUser = this.userBean.updateUserPersonalData(user);
727
728                 // Fire event
729                 this.updatedPersonalDataEvent.fire(new UpdatedUserPersonalDataEvent(updatedUser));
730
731                 // All fine
732                 return "user_contact_data_saved"; //NOI18N
733         }
734
735         /**
736          * Getter for user id
737          * <p>
738          * @return User id
739          */
740         public Long getUserId () {
741                 return this.userId;
742         }
743
744         /**
745          * Setter for user id
746          * <p>
747          * @param userId User id
748          */
749         public void setUserId (final Long userId) {
750                 this.userId = userId;
751         }
752
753         /**
754          * Getter for user name
755          * <p>
756          * @return User name
757          */
758         public String getUserName () {
759                 return this.userName;
760         }
761
762         /**
763          * Setter for user name
764          * <p>
765          * @param userName User name
766          */
767         public void setUserName (final String userName) {
768                 this.userName = userName;
769         }
770
771         @Override
772         public String getUserPassword () {
773                 return this.userPassword;
774         }
775
776         /**
777          * Setter for clear-text user password
778          * <p>
779          * @param userPassword Clear-text user password
780          */
781         public void setUserPassword (final String userPassword) {
782                 this.userPassword = userPassword;
783         }
784
785         /**
786          * Getter for clear-text user password repeated
787          * <p>
788          * @return Clear-text user password repeated
789          */
790         public String getUserPasswordRepeat () {
791                 return this.userPasswordRepeat;
792         }
793
794         /**
795          * Setter for clear-text user password repeated
796          * <p>
797          * @param userPasswordRepeat Clear-text user password repeated
798          */
799         public void setUserPasswordRepeat (final String userPasswordRepeat) {
800                 this.userPasswordRepeat = userPasswordRepeat;
801         }
802
803         /**
804          * Getter for user profile mode
805          * <p>
806          * @return User profile mode
807          */
808         public ProfileMode getUserProfileMode () {
809                 return this.userProfileMode;
810         }
811
812         /**
813          * Setter for user profile mode
814          * <p>
815          * @param userProfileMode User profile mode
816          */
817         public void setUserProfileMode (final ProfileMode userProfileMode) {
818                 this.userProfileMode = userProfileMode;
819         }
820
821         @Override
822         public boolean ifBothPasswordsEmptyAllowed () {
823                 // Check feature first
824                 return ((this.featureController.isFeatureEnabled("allow_user_registration_empty_password")) && //NOI18N
825                                 ((this.getUserPassword() == null) || (this.getUserPassword().isEmpty())) &&
826                                 ((this.getUserPasswordRepeat() == null) || (this.getUserPasswordRepeat().isEmpty())));
827         }
828
829         /**
830          * Post-initialization of this class
831          */
832         @PostConstruct
833         public void init () {
834                 // Initialize user list
835                 this.userList = this.userBean.allUsers();
836
837                 // Get full user name list for reducing EJB calls
838                 this.userNameList = this.userBean.getUserNameList();
839
840                 // Is the user logged-in?
841                 if (this.userLoginController.isUserLoggedIn()) {
842                         // Is logged-in, so load also users visible to memebers
843                         this.visibleUserList = this.userBean.allMemberPublicVisibleUsers();
844                 } else {
845                         // Initialize user list
846                         this.visibleUserList = this.userBean.allPublicUsers();
847                 }
848         }
849
850         @Override
851         public boolean isContactFound (final Contact contact) {
852                 // The contact must be valid
853                 if (null == contact) {
854                         // Throw NPE
855                         throw new NullPointerException("contact is null"); //NOI18N
856                 } else if (contact.getContactId() == null) {
857                         // Throw again ...
858                         throw new NullPointerException("contact.contactId is null"); //NOI18N
859                 } else if (contact.getContactId() < 1) {
860                         // Not valid
861                         throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid", contact.getContactId())); //NOI18N
862                 }
863
864                 // Default is not found
865                 boolean isFound = false;
866
867                 // Get iterator
868                 Iterator<User> iterator = this.allUsers().iterator();
869
870                 // Loop through all entries
871                 while (iterator.hasNext()) {
872                         // Get user
873                         User next = iterator.next();
874
875                         // Compare both objects
876                         if (Objects.equals(contact, next.getUserContact())) {
877                                 // Found it
878                                 isFound = true;
879                                 break;
880                         }
881                 }
882
883                 // Return status
884                 return isFound;
885         }
886
887         @Override
888         public boolean isPublicUserProfileEnabled () {
889                 // Get context parameter
890                 String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_public_profile_enabled"); //NOI18N
891
892                 // Is it set?
893                 boolean isEnabled = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
894
895                 // This requires user names being enabled, too.
896                 if ((isEnabled) && (!this.isUserNameRequired())) {
897                         // Not valid state, users must be able to modify their profile, especially when it is public
898                         throw new IllegalStateException("Public user profiles are enabled but user name requirement is disabled, this is not possible."); //NOI18N
899                 }
900
901                 // Return value
902                 return isEnabled;
903         }
904
905         @Override
906         public boolean isRequiredChangePersonalDataSet () {
907                 return ((this.getUserProfileMode() != null) &&
908                                 (this.getUserName() != null) && (!this.getUserName().isEmpty()) &&
909                                 (this.contactController.isRequiredChangePersonalDataSet()));
910         }
911
912         @Override
913         public boolean isRequiredPersonalDataSet () {
914                 if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
915                         // Multiple registration page
916                         return this.contactController.isRequiredPersonalDataSet();
917                 } else {
918                         // Single registration page
919                         return (((this.getUserName() != null) || (!this.isUserNameRequired())) &&
920                                         (this.getUserProfileMode() != null) &&
921                                         (this.contactController.isRequiredPersonalDataSet()) &&
922                                         (this.getUserPassword() != null) &&
923                                         (this.getUserPasswordRepeat() != null));
924                 }
925         }
926
927         @Override
928         public boolean isSamePasswordEntered () {
929                 return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
930         }
931
932         @Override
933         public boolean isUserIdEmpty () {
934                 return ((this.getUserId() == null) || (this.getUserId() == 0));
935         }
936
937         @Override
938         public boolean isUserNameRegistered (final User user) {
939                 return ((this.userNameList instanceof List) && (this.userNameList.contains(user.getUserName())));
940         }
941
942         @Override
943         public boolean isUserNameRequired () {
944                 // Get context parameter
945                 String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_user_login_require_user_name"); //NOI18N
946
947                 // Is it set?
948                 boolean isRequired = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
949
950                 // Return value
951                 return isRequired;
952         }
953
954         @Override
955         public boolean isVisibleUserFound () {
956                 return ((this.visibleUserList instanceof List) && (this.visibleUserList.size() > 0));
957         }
958
959         @Override
960         public User lookupUserByEmailAddress (final String emailAddress) throws UserEmailAddressNotFoundException {
961                 // Parameter must be valid
962                 if (null == emailAddress) {
963                         // Throw NPE
964                         throw new NullPointerException("emailAddress is null"); //NOI18N
965                 } else if (emailAddress.isEmpty()) {
966                         // Not valid
967                         throw new IllegalArgumentException("emailAddress is empty"); //NOI18N
968                 }
969
970                 // Init variable
971                 User user = null;
972
973                 // Try to lookup it in visible user list
974                 for (final Iterator<User> iterator = this.userList.iterator(); iterator.hasNext();) {
975                         // Get next user
976                         User next = iterator.next();
977
978                         // Contact should be set
979                         if (next.getUserContact() == null) {
980                                 // Contact is null
981                                 throw new NullPointerException(MessageFormat.format("next.userContact is null for user id {0}", next.getUserId())); //NOI18N
982                         } else if (next.getUserContact().getContactEmailAddress() == null) {
983                                 // Email address should be set
984                                 throw new NullPointerException(MessageFormat.format("next.userContact.contactEmailAddress is null for user id {0}", next.getUserId())); //NOI18N
985                         }
986
987                         // Is the email address found?
988                         if (Objects.equals(next.getUserContact().getContactEmailAddress(), emailAddress)) {
989                                 // Copy to other variable
990                                 user = next;
991                                 break;
992                         }
993                 }
994
995                 // Is it still null?
996                 if (null == user) {
997                         // Not visible for the current user
998                         throw new UserEmailAddressNotFoundException(emailAddress);
999                 }
1000
1001                 // Return it
1002                 return user;
1003         }
1004
1005         @Override
1006         public User lookupUserById (final Long userId) throws UserNotFoundException {
1007                 // Parameter must be valid
1008                 if (null == userId) {
1009                         // Throw NPE
1010                         throw new NullPointerException("userId is null"); //NOI18N
1011                 } else if (userId < 1) {
1012                         // Not valid
1013                         throw new IllegalArgumentException(MessageFormat.format("userId={0} is not valid.", userId)); //NOI18N
1014                 }
1015
1016                 // Init variable
1017                 User user = null;
1018
1019                 // Try to lookup it in visible user list
1020                 for (final Iterator<User> iterator = this.userList.iterator(); iterator.hasNext();) {
1021                         // Get next user
1022                         User next = iterator.next();
1023
1024                         // Is the user id found?
1025                         if (Objects.equals(next.getUserId(), userId)) {
1026                                 // Copy to other variable
1027                                 user = next;
1028                                 break;
1029                         }
1030                 }
1031
1032                 // Is it still null?
1033                 if (null == user) {
1034                         // Not visible for the current user
1035                         throw new UserNotFoundException(userId);
1036                 }
1037
1038                 // Return it
1039                 return user;
1040         }
1041
1042         /**
1043          * Adds user's name to bean's internal list. It also updates the public user
1044          * list if the user has decided to have a public account,
1045          * <p>
1046          * @param user User instance
1047          */
1048         private void addUserName (final User user) {
1049                 // Make sure the entry is not added yet
1050                 if (this.userNameList.contains(user.getUserName())) {
1051                         // Abort here
1052                         throw new IllegalArgumentException(MessageFormat.format("User name {0} already added.", user.getUserName())); //NOI18N
1053                 }
1054
1055                 // Add user name
1056                 this.userNameList.add(user.getUserName());
1057         }
1058
1059         /**
1060          * Clears this bean
1061          */
1062         private void clear () {
1063                 // Clear all data
1064                 // - personal data
1065                 this.setUserId(null);
1066                 this.setUserProfileMode(null);
1067
1068                 // - other data
1069                 this.clearUserName();
1070                 this.clearUserPasswords();
1071                 this.setLocale(null);
1072         }
1073
1074         /**
1075          * Clears user name
1076          */
1077         private void clearUserName () {
1078                 // Clear it
1079                 this.setUserName(null);
1080         }
1081
1082         /**
1083          * Clears both user passwords
1084          */
1085         private void clearUserPasswords () {
1086                 // Clear both
1087                 this.setUserPassword(null);
1088                 this.setUserPasswordRepeat(null);
1089         }
1090
1091         /**
1092          * Copies given user into the controller
1093          * <p>
1094          * @param user User instance
1095          */
1096         private void copyUser (final User user) {
1097                 // Make sure the instance is valid
1098                 if (null == user) {
1099                         // Throw NPE
1100                         throw new NullPointerException("user is null"); //NOI18N
1101                 } else if (user.getUserContact() == null) {
1102                         // Throw again ...
1103                         throw new NullPointerException("user.userContact is null"); //NOI18N
1104                 }
1105
1106                 // Copy all fields:
1107                 // - base data
1108                 this.setUserId(user.getUserId());
1109                 this.setUserProfileMode(user.getUserProfileMode());
1110         }
1111
1112         /**
1113          * Getter for locale instance
1114          * <p>
1115          * @return Locale instance
1116          */
1117         private Locale getLocale () {
1118                 return this.locale;
1119         }
1120
1121         /**
1122          * Setter for locale instance
1123          * <p>
1124          * @param locale Locale instance
1125          */
1126         private void setLocale (final Locale locale) {
1127                 this.locale = locale;
1128         }
1129
1130         /**
1131          * Removes user from all lists
1132          * <p>
1133          * @param user User to remove
1134          */
1135         private void removeFromList (final User user) {
1136                 // The user should be valid
1137                 if (null == user) {
1138                         // Throw NPE
1139                         throw new NullPointerException("user is null"); //NOI18N
1140                 } else if (user.getUserId() == null) {
1141                         // ... again NPE
1142                         throw new NullPointerException("user.userId is null"); //NOI18N
1143                 } else if (user.getUserId() < 1) {
1144                         // Invalid id
1145                         throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
1146                 }
1147
1148                 // Remove it from lists
1149                 this.userList.remove(user);
1150                 this.visibleUserList.remove(user);
1151
1152                 // Remove name from list
1153                 this.userNameList.remove(user.getUserName());
1154         }
1155
1156         /**
1157          * Updates list with given user instance
1158          * <p>
1159          * @param user User instance
1160          */
1161         private void updateList (final User user) {
1162                 // The user should be valid
1163                 if (null == user) {
1164                         // Throw NPE
1165                         throw new NullPointerException("user is null"); //NOI18N
1166                 } else if (user.getUserId() == null) {
1167                         // ... again NPE
1168                         throw new NullPointerException("user.userId is null"); //NOI18N
1169                 } else if (user.getUserId() < 1) {
1170                         // Invalid id
1171                         throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
1172                 } else if (user.getUserContact() == null) {
1173                         // Throw again ...
1174                         throw new NullPointerException("user.userContact is null"); //NOI18N
1175                 } else if (user.getUserContact().getContactId() == null) {
1176                         // Throw again ...
1177                         throw new NullPointerException("user.userContact.contactId is null"); //NOI18N
1178                 } else if (user.getUserContact().getContactId() < 1) {
1179                         // Throw again ...
1180                         throw new NullPointerException(MessageFormat.format("user.userContact.contactId={0} is invalid.", user.getUserContact().getContactId())); //NOI18N
1181                 }
1182
1183                 // Get iterator from list
1184                 Iterator<User> iterator = this.userList.iterator();
1185
1186                 // "Walk" through all entries
1187                 while (iterator.hasNext()) {
1188                         // Get next element
1189                         User next = iterator.next();
1190
1191                         // Is user id number the same?
1192                         if (Objects.equals(user.getUserId(), next.getUserId())) {
1193                                 // Found entry, so remove it and abort
1194                                 this.userList.remove(next);
1195                                 break;
1196                         }
1197                 }
1198
1199                 // Re-add user
1200                 this.userList.add(user);
1201         }
1202
1203 }