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