]> git.mxchange.org Git - jjobs-war.git/blob - src/java/org/mxchange/jjobs/beans/phone/JobsPhoneWebApplicationBean.java
Please cherry-pick:
[jjobs-war.git] / src / java / org / mxchange / jjobs / beans / phone / JobsPhoneWebApplicationBean.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.phone;
18
19 import java.text.MessageFormat;
20 import java.util.LinkedList;
21 import java.util.List;
22 import java.util.Locale;
23 import java.util.MissingResourceException;
24 import java.util.Objects;
25 import java.util.ResourceBundle;
26 import javax.annotation.PostConstruct;
27 import javax.enterprise.context.ApplicationScoped;
28 import javax.enterprise.event.Observes;
29 import javax.faces.application.FacesMessage;
30 import javax.faces.context.FacesContext;
31 import javax.faces.view.facelets.FaceletException;
32 import javax.inject.Named;
33 import javax.naming.Context;
34 import javax.naming.InitialContext;
35 import javax.naming.NamingException;
36 import org.mxchange.jcontacts.contact.Contact;
37 import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
38 import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
39 import org.mxchange.jcontacts.events.fax.linked.ObservableAdminLinkedFaxNumberEvent;
40 import org.mxchange.jcontacts.events.landline.linked.ObservableAdminLinkedLandLineNumberEvent;
41 import org.mxchange.jcontacts.events.mobile.linked.ObservableAdminLinkedMobileNumberEvent;
42 import org.mxchange.jjobs.beans.BaseJobsController;
43 import org.mxchange.jphone.events.fax.deleted.AdminDeletedFaxNumberEvent;
44 import org.mxchange.jphone.events.fax.updated.AdminUpdatedFaxNumberEvent;
45 import org.mxchange.jphone.events.landline.deleted.AdminDeletedLandLineNumberEvent;
46 import org.mxchange.jphone.events.landline.updated.AdminUpdatedLandLineNumberEvent;
47 import org.mxchange.jphone.events.mobile.deleted.AdminDeletedMobileNumberEvent;
48 import org.mxchange.jphone.events.mobile.updated.AdminUpdatedMobileNumberEvent;
49 import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
50 import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
51 import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
52 import org.mxchange.jphone.phonenumbers.phone.PhoneSessionBeanRemote;
53 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
54
55 /**
56  * Regular controller (bean) for phone numbers
57  * <p>
58  * @author Roland Häder<roland@mxchange.org>
59  */
60 @Named ("phoneController")
61 @ApplicationScoped
62 public abstract class JobsPhoneWebApplicationBean extends BaseJobsController implements JobsPhoneWebApplicationController {
63
64         /**
65          * Serial number
66          */
67         private static final long serialVersionUID = 491_058_674_675_690_105L;
68
69         /**
70          * All fax numbers
71          */
72         private final List<DialableFaxNumber> faxNumbers;
73
74         /**
75          * All land-line numbers
76          */
77         private final List<DialableLandLineNumber> landLineNumbers;
78
79         /**
80          * All mobile numbers
81          */
82         private final List<DialableMobileNumber> mobileNumbers;
83
84         /**
85          * General EJB for phone numbers
86          */
87         private PhoneSessionBeanRemote phoneBean;
88
89         /**
90          * Default constructor
91          */
92         public JobsPhoneWebApplicationBean () {
93                 // Call super constructor
94                 super();
95
96                 // Init all lists
97                 this.mobileNumbers = new LinkedList<>();
98                 this.faxNumbers = new LinkedList<>();
99                 this.landLineNumbers = new LinkedList<>();
100         }
101
102         /**
103          * Observes events being fired when an administrator has added a new
104          * contact.
105          * <p>
106          * @param event Event being fired
107          */
108         public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) {
109                 // The event must be valid
110                 if (null == event) {
111                         // Throw NPE
112                         throw new NullPointerException("event is null"); //NOI18N
113                 } else if (event.getAddedContact() == null) {
114                         // Throw again ...
115                         throw new NullPointerException("event.addedContact is null"); //NOI18N
116                 } else if (event.getAddedContact().getContactId() == null) {
117                         // ... and again
118                         throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N
119                 } else if (event.getAddedContact().getContactId() < 1) {
120                         // Not valid
121                         throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N
122                 }
123
124                 // Update contact's mobile, land-line and fax number
125                 this.updateContactPhoneNumbers(event.getAddedContact());
126
127                 // Clear this bean
128                 this.clear();
129         }
130
131         /**
132          * Event observer for newly added users by administrator
133          * <p>
134          * @param event Event being fired
135          */
136         public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
137                 // event should not be null
138                 if (null == event) {
139                         // Throw NPE
140                         throw new NullPointerException("event is null"); //NOI18N
141                 } else if (event.getAddedUser() == null) {
142                         // Throw NPE again
143                         throw new NullPointerException("event.addedUser is null"); //NOI18N
144                 } else if (event.getAddedUser().getUserId() == null) {
145                         // userId is null
146                         throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
147                 } else if (event.getAddedUser().getUserId() < 1) {
148                         // Not avalid id
149                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
150                 }
151
152                 // Update contact's mobile, land-line and fax number
153                 this.updateContactPhoneNumbers(event.getAddedUser().getUserContact());
154
155                 // Clear all data
156                 this.clear();
157         }
158
159         /**
160          * Observes events being fired when an administrator has deleted a fax
161          * number
162          * <p>
163          * @param event Event being fired
164          */
165         public void afterAdminDeletedFaxNumberEvent (@Observes final AdminDeletedFaxNumberEvent event) {
166                 // event should not be null
167                 if (null == event) {
168                         // Throw NPE
169                         throw new NullPointerException("event is null"); //NOI18N
170                 } else if (event.getDeletedFaxNumber() == null) {
171                         // Throw NPE again
172                         throw new NullPointerException("event.deletedFaxNumber is null"); //NOI18N
173                 } else if (event.getDeletedFaxNumber().getPhoneId() == null) {
174                         // userId is null
175                         throw new NullPointerException("event.deletedFaxNumber.phoneId is null"); //NOI18N
176                 } else if (event.getDeletedFaxNumber().getPhoneId() < 1) {
177                         // Not avalid id
178                         throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedFaxNumber(), event.getDeletedFaxNumber().getPhoneId())); //NOI18N
179                 }
180
181                 // Update contact's mobile, land-line and fax number
182                 this.allFaxNumbers().remove(event.getDeletedFaxNumber());
183
184                 // Clear all data
185                 this.clear();
186         }
187
188         /**
189          * Observes events being fired when an administrator has deleted a land-line
190          * number
191          * <p>
192          * @param event Event being fired
193          */
194         public void afterAdminDeletedLandLineNumberEvent (@Observes final AdminDeletedLandLineNumberEvent event) {
195                 // event should not be null
196                 if (null == event) {
197                         // Throw NPE
198                         throw new NullPointerException("event is null"); //NOI18N
199                 } else if (event.getDeletedLandLineNumber() == null) {
200                         // Throw NPE again
201                         throw new NullPointerException("event.deletedLandLineNumber is null"); //NOI18N
202                 } else if (event.getDeletedLandLineNumber().getPhoneId() == null) {
203                         // userId is null
204                         throw new NullPointerException("event.deletedLandLineNumber.phoneId is null"); //NOI18N
205                 } else if (event.getDeletedLandLineNumber().getPhoneId() < 1) {
206                         // Not avalid id
207                         throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedLandLineNumber(), event.getDeletedLandLineNumber().getPhoneId())); //NOI18N
208                 }
209
210                 // Update contact's mobile, land-line and fax number
211                 this.allLandLineNumbers().remove(event.getDeletedLandLineNumber());
212
213                 // Clear all data
214                 this.clear();
215         }
216
217         /**
218          * Observes events being fired when an administrator has deleted a mobile
219          * number
220          * <p>
221          * @param event Event being fired
222          */
223         public void afterAdminDeletedMobileNumberEvent (@Observes final AdminDeletedMobileNumberEvent event) {
224                 // event should not be null
225                 if (null == event) {
226                         // Throw NPE
227                         throw new NullPointerException("event is null"); //NOI18N
228                 } else if (event.getDeletedMobileNumber() == null) {
229                         // Throw NPE again
230                         throw new NullPointerException("event.deletedMobileNumber is null"); //NOI18N
231                 } else if (event.getDeletedMobileNumber().getPhoneId() == null) {
232                         // userId is null
233                         throw new NullPointerException("event.deletedMobileNumber.phoneId is null"); //NOI18N
234                 } else if (event.getDeletedMobileNumber().getPhoneId() < 1) {
235                         // Not avalid id
236                         throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedMobileNumber(), event.getDeletedMobileNumber().getPhoneId())); //NOI18N
237                 }
238
239                 // Update contact's mobile, land-line and fax number
240                 this.allMobileNumbers().remove(event.getDeletedMobileNumber());
241
242                 // Clear all data
243                 this.clear();
244         }
245
246         /**
247          * Observes events being fired when an administrator has a linked a fax
248          * number
249          * <p>
250          * @param event Event being fired
251          */
252         public void afterAdminLinkedFaxNumberEvent (@Observes final ObservableAdminLinkedFaxNumberEvent event) {
253                 // Is the event fine?
254                 if (event == null) {
255                         // Throw NPE
256                         throw new NullPointerException("event is null"); //NOI18N
257                 } else if (event.getContact() == null) {
258                         // Throw again ...
259                         throw new NullPointerException("event.contact is null");
260                 } else if (event.getContact().getContactId() == null) {
261                         // Throw again ...
262                         throw new NullPointerException("event.contact.contactId is null");
263                 } else if (event.getContact().getContactId() < 1) {
264                         // Throw again ...
265                         throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
266                 } else if (event.getContact().getContactFaxNumber() == null) {
267                         // Throw again ...
268                         throw new NullPointerException("event.contact.contactFaxNumber is null");
269                 } else if (event.getContact().getContactFaxNumber().getPhoneId() == null) {
270                         // Throw again ...
271                         throw new NullPointerException("event.contact.contactFaxNumber.phoneId is null");
272                 } else if (event.getContact().getContactFaxNumber().getPhoneId() < 1) {
273                         // Throw again ...
274                         throw new NullPointerException("event.contact.contactFaxNumber.phoneId=" + event.getContact().getContactFaxNumber().getPhoneId() + " is invalid");
275                 } else if (event.getLinkedFaxNumber() == null) {
276                         // Throw again ...
277                         throw new NullPointerException("event.linkedFaxNumer is null");
278                 }
279
280                 // Is the id number in linked number not set?
281                 if (event.getLinkedFaxNumber().getPhoneId() == null) {
282                         // Then it is a new number, so add it from contact as there the id number has been set
283                         this.uniqueAddFaxNumber(event.getContact().getContactFaxNumber());
284                 }
285         }
286
287         /**
288          * Observes events being fired when an administrator has a linked a
289          * land-line number
290          * <p>
291          * @param event Event being fired
292          */
293         public void afterAdminLinkedLandLineNumberEvent (@Observes final ObservableAdminLinkedLandLineNumberEvent event) {
294                 // Is the event fine?
295                 if (event == null) {
296                         // Throw NPE
297                         throw new NullPointerException("event is null"); //NOI18N
298                 } else if (event.getContact() == null) {
299                         // Throw again ...
300                         throw new NullPointerException("event.contact is null");
301                 } else if (event.getContact().getContactId() == null) {
302                         // Throw again ...
303                         throw new NullPointerException("event.contact.contactId is null");
304                 } else if (event.getContact().getContactId() < 1) {
305                         // Throw again ...
306                         throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
307                 } else if (event.getContact().getContactLandLineNumber() == null) {
308                         // Throw again ...
309                         throw new NullPointerException("event.contact.contactLandLineNumber is null");
310                 } else if (event.getContact().getContactLandLineNumber().getPhoneId() == null) {
311                         // Throw again ...
312                         throw new NullPointerException("event.contact.contactLandLineNumber.phoneId is null");
313                 } else if (event.getContact().getContactLandLineNumber().getPhoneId() < 1) {
314                         // Throw again ...
315                         throw new NullPointerException("event.contact.contactLandLineNumber.phoneId=" + event.getContact().getContactLandLineNumber().getPhoneId() + " is invalid");
316                 } else if (event.getLinkedLandLineNumber() == null) {
317                         // Throw again ...
318                         throw new NullPointerException("event.linkedLandLineNumer is null");
319                 }
320
321                 // Is the id number in linked number not set?
322                 if (event.getLinkedLandLineNumber().getPhoneId() == null) {
323                         // Then it is a new number, so add it from contact as there the id number has been set
324                         this.uniqueAddLandLineNumber(event.getContact().getContactLandLineNumber());
325                 }
326         }
327
328         /**
329          * Observes events being fired when an administrator has a linked a mobile
330          * number
331          * <p>
332          * @param event Event being fired
333          */
334         public void afterAdminLinkedMobileNumberEvent (@Observes final ObservableAdminLinkedMobileNumberEvent event) {
335                 // Is the event fine?
336                 if (event == null) {
337                         // Throw NPE
338                         throw new NullPointerException("event is null"); //NOI18N
339                 } else if (event.getContact() == null) {
340                         // Throw again ...
341                         throw new NullPointerException("event.contact is null");
342                 } else if (event.getContact().getContactId() == null) {
343                         // Throw again ...
344                         throw new NullPointerException("event.contact.contactId is null");
345                 } else if (event.getContact().getContactId() < 1) {
346                         // Throw again ...
347                         throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
348                 } else if (event.getContact().getContactMobileNumber() == null) {
349                         // Throw again ...
350                         throw new NullPointerException("event.contact.contactMobileNumber is null");
351                 } else if (event.getContact().getContactMobileNumber().getPhoneId() == null) {
352                         // Throw again ...
353                         throw new NullPointerException("event.contact.contactMobileNumber.phoneId is null");
354                 } else if (event.getContact().getContactMobileNumber().getPhoneId() < 1) {
355                         // Throw again ...
356                         throw new NullPointerException("event.contact.contactMobileNumber.phoneId=" + event.getContact().getContactMobileNumber().getPhoneId() + " is invalid");
357                 } else if (event.getLinkedMobileNumber() == null) {
358                         // Throw again ...
359                         throw new NullPointerException("event.linkedMobileNumer is null");
360                 }
361
362                 // Is the id number in linked number not set?
363                 if (event.getLinkedMobileNumber().getPhoneId() == null) {
364                         // Then it is a new number, so add it from contact as there the id number has been set
365                         this.uniqueAddMobileNumber(event.getContact().getContactMobileNumber());
366                 }
367         }
368
369         /**
370          * Observes events being fired when an administrator has updated contact
371          * data.
372          * <p>
373          * @param event Event being fired
374          */
375         public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) {
376                 // event should not be null
377                 if (null == event) {
378                         // Throw NPE
379                         throw new NullPointerException("event is null"); //NOI18N
380                 } else if (event.getUpdatedContact() == null) {
381                         // Throw NPE again
382                         throw new NullPointerException("event.updatedContact is null"); //NOI18N
383                 } else if (event.getUpdatedContact().getContactId() == null) {
384                         // userId is null
385                         throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
386                 } else if (event.getUpdatedContact().getContactId() < 1) {
387                         // Not avalid id
388                         throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
389                 }
390
391                 // Update contact's mobile, land-line and fax number
392                 this.updateContactPhoneNumbers(event.getUpdatedContact());
393
394                 // Clear all data
395                 this.clear();
396         }
397
398         /**
399          * Observes events being fired when an administrator has updated a fax
400          * number.
401          * <p>
402          * @param event Event being fired
403          */
404         public void afterAdminUpdatedFaxNumberEvent (@Observes final AdminUpdatedFaxNumberEvent event) {
405                 // event should not be null
406                 if (null == event) {
407                         // Throw NPE
408                         throw new NullPointerException("event is null"); //NOI18N
409                 } else if (event.getUpdatedFaxNumber() == null) {
410                         // Throw NPE again
411                         throw new NullPointerException("event.updatedFaxNumber is null"); //NOI18N
412                 } else if (event.getUpdatedFaxNumber().getPhoneId() == null) {
413                         // userId is null
414                         throw new NullPointerException("event.updatedFaxNumber.phoneId is null"); //NOI18N
415                 } else if (event.getUpdatedFaxNumber().getPhoneId() < 1) {
416                         // Not avalid id
417                         throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedFaxNumber(), event.getUpdatedFaxNumber().getPhoneId())); //NOI18N
418                 }
419
420                 // Uniquely add it
421                 this.uniqueAddFaxNumber(event.getUpdatedFaxNumber());
422
423                 // Clear it
424                 this.clear();
425         }
426
427         /**
428          * Observes events being fired when an administrator has updated a land-line
429          * number.
430          * <p>
431          * @param event Event being fired
432          */
433         public void afterAdminUpdatedLandLineNumberEvent (@Observes final AdminUpdatedLandLineNumberEvent event) {
434                 // event should not be null
435                 if (null == event) {
436                         // Throw NPE
437                         throw new NullPointerException("event is null"); //NOI18N
438                 } else if (event.getUpdatedLandLineNumber() == null) {
439                         // Throw NPE again
440                         throw new NullPointerException("event.updatedLandLineNumber is null"); //NOI18N
441                 } else if (event.getUpdatedLandLineNumber().getPhoneId() == null) {
442                         // userId is null
443                         throw new NullPointerException("event.updatedLandLineNumber.phoneId is null"); //NOI18N
444                 } else if (event.getUpdatedLandLineNumber().getPhoneId() < 1) {
445                         // Not avalid id
446                         throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedLandLineNumber(), event.getUpdatedLandLineNumber().getPhoneId())); //NOI18N
447                 }
448
449                 // Uniquely add it
450                 this.uniqueAddLandLineNumber(event.getUpdatedLandLineNumber());
451
452                 // Clear it
453                 this.clear();
454         }
455
456         /**
457          * Observes events being fired when an administrator has updated a mobile
458          * number.
459          * <p>
460          * @param event Event being fired
461          */
462         public void afterAdminUpdatedMobileNumberEvent (@Observes final AdminUpdatedMobileNumberEvent event) {
463                 // event should not be null
464                 if (null == event) {
465                         // Throw NPE
466                         throw new NullPointerException("event is null"); //NOI18N
467                 } else if (event.getUpdatedMobileNumber() == null) {
468                         // Throw NPE again
469                         throw new NullPointerException("event.updatedMobileNumber is null"); //NOI18N
470                 } else if (event.getUpdatedMobileNumber().getPhoneId() == null) {
471                         // userId is null
472                         throw new NullPointerException("event.updatedMobileNumber.phoneId is null"); //NOI18N
473                 } else if (event.getUpdatedMobileNumber().getPhoneId() < 1) {
474                         // Not avalid id
475                         throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedMobileNumber(), event.getUpdatedMobileNumber().getPhoneId())); //NOI18N
476                 }
477
478                 // Uniquely add it
479                 this.uniqueAddMobileNumber(event.getUpdatedMobileNumber());
480
481                 // Clear it
482                 this.clear();
483         }
484
485         @Override
486         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
487         public List<DialableFaxNumber> allFaxNumbers () {
488                 return this.faxNumbers;
489         }
490
491         @Override
492         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
493         public List<DialableLandLineNumber> allLandLineNumbers () {
494                 return this.landLineNumbers;
495         }
496
497         @Override
498         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
499         public List<DialableMobileNumber> allMobileNumbers () {
500                 return this.mobileNumbers;
501         }
502
503         /**
504          * Post-construction method
505          */
506         @PostConstruct
507         public void init () {
508                 // Try it
509                 try {
510                         // Get initial context
511                         Context context = new InitialContext();
512
513                         // Try to lookup the beans
514                         this.phoneBean = (PhoneSessionBeanRemote) context.lookup("java:global/jjobs-ejb/phone!org.mxchange.jphone.phonenumbers.phone.PhoneSessionBeanRemote"); //NOI18N
515                 } catch (final NamingException e) {
516                         // Throw it again
517                         throw new FaceletException(e);
518                 }
519
520                 // All phone numbers
521                 this.allMobileNumbers().addAll(this.phoneBean.allMobileNumbers());
522                 this.allFaxNumbers().addAll(this.phoneBean.allFaxNumbers());
523                 this.allLandLineNumbers().addAll(this.phoneBean.allLandLineNumbers());
524         }
525
526         /**
527          * Clears this bean
528          */
529         private void clear () {
530                 // Clear all data
531         }
532
533         /**
534          * Uniquely add given fax number to this bean's list. First remove the old
535          * instance (by id number), then re-add it again.
536          * <p>
537          * @param faxNumber number to add
538          */
539         private void uniqueAddFaxNumber (final DialableFaxNumber faxNumber) {
540                 // Make sure the parameter is valid
541                 if (null == faxNumber) {
542                         // Throw NPE
543                         throw new NullPointerException("faxNumber is null");
544                 } else if (faxNumber.getPhoneId() == null) {
545                         // Throw again ...
546                         throw new NullPointerException("faxNumber.phoneId is null");
547                 } else if (faxNumber.getPhoneId() < 1) {
548                         // Not valid
549                         throw new IllegalArgumentException(MessageFormat.format("faxNumber.phoneId={0} is not valid.", faxNumber.getPhoneId()));
550                 }
551
552                 // First remove it
553                 if (!this.allFaxNumbers().remove(faxNumber)) {
554                         // Did not work, try by id number
555                         for (final DialableFaxNumber fax : this.allFaxNumbers()) {
556                                 // Is id number the same?
557                                 if (Objects.equals(fax.getPhoneId(), faxNumber.getPhoneId())) {
558                                         // Found it
559                                         this.allFaxNumbers().remove(fax);
560                                         break;
561                                 }
562                         }
563                 }
564
565                 // ... then add it
566                 this.allFaxNumbers().add(faxNumber);
567         }
568
569         /**
570          * Uniquely add given land-line number to this bean's list. First remove the
571          * old instance (by id number), then re-add it again.
572          * <p>
573          * @param landLineNumber Land-line number to add
574          */
575         private void uniqueAddLandLineNumber (final DialableLandLineNumber landLineNumber) {
576                 // Make sure the parameter is valid
577                 if (null == landLineNumber) {
578                         // Throw NPE
579                         throw new NullPointerException("landLineNumber is null");
580                 } else if (landLineNumber.getPhoneId() == null) {
581                         // Throw again ...
582                         throw new NullPointerException("landLineNumber.phoneId is null");
583                 } else if (landLineNumber.getPhoneId() < 1) {
584                         // Not valid
585                         throw new IllegalArgumentException(MessageFormat.format("landLineNumber.phoneId={0} is not valid.", landLineNumber.getPhoneId()));
586                 }
587
588                 // First remove it
589                 if (!this.allLandLineNumbers().remove(landLineNumber)) {
590                         // Did not work, try by id number
591                         for (final DialableLandLineNumber landLine : this.allLandLineNumbers()) {
592                                 // Is id number the same?
593                                 if (Objects.equals(landLine.getPhoneId(), landLineNumber.getPhoneId())) {
594                                         // Found it
595                                         this.allLandLineNumbers().remove(landLine);
596                                         break;
597                                 }
598                         }
599                 }
600
601                 // ... then add it
602                 this.allLandLineNumbers().add(landLineNumber);
603         }
604
605         /**
606          * Uniquely add given mobile number to this bean's list. First remove the
607          * old instance (by id number), then re-add it again.
608          * <p>
609          * @param mobileNumber Mobile number to add
610          */
611         private void uniqueAddMobileNumber (final DialableMobileNumber mobileNumber) {
612                 // Make sure the parameter is valid
613                 if (null == mobileNumber) {
614                         // Throw NPE
615                         throw new NullPointerException("mobileNumber is null");
616                 } else if (mobileNumber.getPhoneId() == null) {
617                         // Throw again ...
618                         throw new NullPointerException("mobileNumber.phoneId is null");
619                 } else if (mobileNumber.getPhoneId() < 1) {
620                         // Not valid
621                         throw new IllegalArgumentException(MessageFormat.format("mobileNumber.phoneId={0} is not valid.", mobileNumber.getPhoneId()));
622                 }
623
624                 // First remove it by object
625                 if (!this.allMobileNumbers().remove(mobileNumber)) {
626                         // Did not work, try by id number
627                         for (final DialableMobileNumber cell : this.allMobileNumbers()) {
628                                 // Is id number the same?
629                                 if (Objects.equals(cell.getPhoneId(), mobileNumber.getPhoneId())) {
630                                         // Found it
631                                         this.allMobileNumbers().remove(cell);
632                                         break;
633                                 }
634                         }
635                 }
636
637                 // ... then add it
638                 this.allMobileNumbers().add(mobileNumber);
639         }
640
641         /**
642          * Updates given contact's mobile, land-line and fax number
643          * <p>
644          * @param contact Contact instance
645          */
646         private void updateContactPhoneNumbers (final Contact contact) {
647                 // Parameter must be valid
648                 if (null == contact) {
649                         // Throw NPE
650                         throw new NullPointerException("contact is null");
651                 } else if (contact.getContactId() == null) {
652                         // Throw again
653                         throw new NullPointerException("contact.contactId is null");
654                 } else if (contact.getContactId() < 1) {
655                         // Id number is not valid
656                 }
657
658                 // Is mobile set?
659                 if (contact.getContactMobileNumber() instanceof DialableMobileNumber) {
660                         // Unique-add it
661                         this.uniqueAddMobileNumber(contact.getContactMobileNumber());
662                 }
663
664                 // Is land-line set?
665                 if (contact.getContactLandLineNumber() instanceof DialableLandLineNumber) {
666                         // Unique-add it
667                         this.uniqueAddLandLineNumber(contact.getContactLandLineNumber());
668                 }
669
670                 // Is fax set?
671                 if (contact.getContactFaxNumber() instanceof DialableFaxNumber) {
672                         // Unique-add it
673                         this.uniqueAddFaxNumber(contact.getContactFaxNumber());
674                 }
675         }
676
677         /**
678          * Returns given property key or throws an exception if not found.
679          * <p>
680          * @param parameterKey Property key
681          * <p>
682          * @return Property value
683          * <p>
684          * @throws NullPointerException If given key is not found
685          * @throws NumberFormatException If no number is given in context parameter
686          */
687         protected int getIntegerContextParameter (final String parameterKey) throws NullPointerException, NumberFormatException {
688                 // Get context parameter
689                 Integer contextValue = Integer.parseInt(this.getStringContextParameter(parameterKey));
690                 // Return it
691                 return contextValue;
692         }
693
694         /**
695          * Returns given property key or throws an exception if not found.
696          * <p>
697          * @param parameterKey Property key
698          * <p>
699          * @return Property value
700          * <p>
701          * @throws NullPointerException If given key is not found
702          */
703         protected String getStringContextParameter (final String parameterKey) throws NullPointerException {
704                 // Get context parameter
705                 String contextValue = FacesContext.getCurrentInstance().getExternalContext().getInitParameter(parameterKey);
706                 // Is it null?
707                 if (null == contextValue) {
708                         // Throw NPE
709                         throw new NullPointerException(MessageFormat.format("parameterKey={0} is not set.", parameterKey)); //NOI18N
710                 }
711                 // Return it
712                 return contextValue;
713         }
714
715         /**
716          * Checks whether debug mode is enabled for given controller
717          * <p>
718          * @param controllerName Name of controller
719          * <p>
720          * @return Whether debug mode is enabled
721          */
722         protected boolean isDebugModeEnabled (final String controllerName) {
723                 // Parameters should be valid
724                 if (null == controllerName) {
725                         // Throw NPE
726                         throw new NullPointerException("controllerName is null"); //NOI18N
727                 } else if (controllerName.isEmpty()) {
728                         // Is empty
729                         throw new IllegalArgumentException("controllerName is empty"); //NOI18N
730                 }
731                 // Try to get context parameter
732                 String contextParameter = this.getStringContextParameter(String.format("is_debug_%s_enabled", controllerName)); //NOI18N
733                 // Is it set and true?
734                 boolean isEnabled = Boolean.parseBoolean(contextParameter) == Boolean.TRUE;
735                 // Return it
736                 return isEnabled;
737         }
738
739         /**
740          * Loads resource bundle for given locale. This must be implemented per
741          * project so all projects can still customize their methods. Calling
742          * ResourceBundleloadBundle() in this class means that also the bundle files
743          * must be present here.
744          * <p>
745          * @param locale Locale from e.g. FacesContext
746          * <p>
747          * @return Initialized and loaded resource bundle
748          */
749         protected abstract ResourceBundle loadResourceBundle (final Locale locale);
750
751         /**
752          * Shows a faces message for given causing exception. The message from the
753          * exception is being inserted into the message.
754          * <p>
755          * @param clientId Client id to send message to
756          * @param cause    Causing exception
757          */
758         protected void showFacesMessage (final String clientId, final Throwable cause) {
759                 // Get context and add message
760                 this.showFacesMessage(clientId, cause.getMessage());
761         }
762
763         /**
764          * Shows a faces message with given message (i18n) key.
765          * <p>
766          * @param clientId Client id to send message to
767          * @param i18nKey  Message key
768          * <p>
769          * @throws NullPointerException If clientId or i18nKey is null
770          * @throws IllegalArgumentException If clientId or i18nKey is empty
771          */
772         protected void showFacesMessage (final String clientId, final String i18nKey) throws NullPointerException, IllegalArgumentException {
773                 // Both parameter must be valid
774                 if (null == clientId) {
775                         // Throw NPE
776                         throw new NullPointerException("clientId is null"); //NOI18N
777                 } else if (clientId.isEmpty()) {
778                         // Is empty
779                         throw new IllegalArgumentException("clientId is null"); //NOI18N
780                 } else if (null == i18nKey) {
781                         // Throw NPE
782                         throw new NullPointerException("i18nKey is null"); //NOI18N
783                 } else if (i18nKey.isEmpty()) {
784                         // Is empty
785                         throw new IllegalArgumentException("i18nKey is null"); //NOI18N
786                 }
787                 // Get current locale
788                 Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
789                 // Get bundle bundle
790                 ResourceBundle bundle = this.loadResourceBundle(locale);
791                 // Default is i18nKey
792                 String message = MessageFormat.format("!{0}!", i18nKey); //NOI18N
793                 // Try it
794                 try {
795                         // Get message
796                         message = bundle.getString(i18nKey);
797                 } catch (final MissingResourceException ex) {
798                         // Did not find it, ignored
799                 }
800                 // Get context and add message
801                 FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(message));
802         }
803
804 }