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