2 * Copyright (C) 2016 - 2022 Free Software Foundation
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation, either version 3 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
14 * You should have received a copy of the GNU Affero General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.addressbook.beans.phone.list;
19 import fish.payara.cdi.jsr107.impl.NamedCache;
20 import java.text.MessageFormat;
21 import java.util.Comparator;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.Objects;
25 import javax.annotation.PostConstruct;
26 import javax.cache.Cache;
28 import javax.enterprise.event.Observes;
29 import javax.faces.view.ViewScoped;
30 import javax.inject.Inject;
31 import javax.inject.Named;
32 import org.mxchange.addressbook.beans.BaseAddressbookBean;
33 import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
34 import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
35 import org.mxchange.jcontacts.events.contact.update.ObservableUpdatedContactEvent;
36 import org.mxchange.jcontacts.events.fax.linked.ObservableAdminLinkedFaxNumberEvent;
37 import org.mxchange.jcontacts.events.landline.linked.ObservableAdminLinkedLandLineNumberEvent;
38 import org.mxchange.jcontacts.model.contact.Contact;
39 import org.mxchange.jphone.events.fax.deleted.AdminDeletedFaxNumberEvent;
40 import org.mxchange.jphone.events.fax.updated.AdminUpdatedFaxNumberEvent;
41 import org.mxchange.jphone.events.landline.deleted.AdminDeletedLandLineNumberEvent;
42 import org.mxchange.jphone.events.landline.updated.AdminUpdatedLandLineNumberEvent;
43 import org.mxchange.jphone.exceptions.phone.PhoneEntityNotFoundException;
44 import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber;
45 import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber;
46 import org.mxchange.jphone.model.phonenumbers.phone.PhoneSessionBeanRemote;
49 * Administrative listing controller (bean) for phone numbers
51 * @author Roland Häder<roland@mxchange.org>
53 @Named ("phoneListController")
55 public class AddressbookPhoneListWebViewBean extends BaseAddressbookBean implements AddressbookPhoneListWebViewController {
60 private static final long serialVersionUID = 491_058_674_675_690_107L;
63 * A list of all fax numbers
65 private final List<DialableFaxNumber> allFaxNumbers;
68 * A list of all land-line numbers
70 private final List<DialableLandLineNumber> allLandLineNumbers;
76 @NamedCache (cacheName = "faxNumberCache")
77 private transient Cache<Long, DialableFaxNumber> faxNumberCache;
80 * A list of filtered fax numbers
82 private List<DialableFaxNumber> filteredFaxNumbers;
85 * A list of filtered land-line numbers
87 private List<DialableLandLineNumber> filteredLandLineNumbers;
90 * All land-line numbers
93 @NamedCache (cacheName = "landLineNumberCache")
94 private transient Cache<Long, DialableLandLineNumber> landLineNumberCache;
97 * General EJB for phone numbers
99 @EJB (lookup = "java:global/addressbook-ejb/phone!org.mxchange.jphone.model.phonenumbers.phone.PhoneSessionBeanRemote")
100 private PhoneSessionBeanRemote phoneBean;
103 * Default constructor
105 public AddressbookPhoneListWebViewBean () {
106 // Call super constructor
110 this.allFaxNumbers = new LinkedList<>();
111 this.allLandLineNumbers = new LinkedList<>();
115 * Observes events being fired when an administrator has added a new
118 * @param event Event being fired
120 public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) {
121 // The event must be valid
124 throw new NullPointerException("event is null"); //NOI18N
125 } else if (event.getAddedContact() == null) {
127 throw new NullPointerException("event.addedContact is null"); //NOI18N
128 } else if (event.getAddedContact().getContactId() == null) {
130 throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N
131 } else if (event.getAddedContact().getContactId() < 1) {
133 throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N
136 // Update contact's mobile, land-line and fax number
137 this.updateContactPhoneNumbers(event.getAddedContact());
144 * Observes events being fired when an administrator has deleted a fax
147 * @param event Event being fired
149 public void afterAdminDeletedFaxNumberEvent (@Observes final AdminDeletedFaxNumberEvent event) {
150 // Event and contained entity instance should not be null
153 throw new NullPointerException("event is null"); //NOI18N
154 } else if (event.getDeletedFaxNumber() == null) {
156 throw new NullPointerException("event.deletedFaxNumber is null"); //NOI18N
157 } else if (event.getDeletedFaxNumber().getPhoneId() == null) {
159 throw new NullPointerException("event.deletedFaxNumber.phoneId is null"); //NOI18N
160 } else if (event.getDeletedFaxNumber().getPhoneId() < 1) {
162 throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedFaxNumber(), event.getDeletedFaxNumber().getPhoneId())); //NOI18N
165 // Update contact's mobile, land-line and fax number
166 this.getAllFaxNumbers().remove(event.getDeletedFaxNumber());
173 * Observes events being fired when an administrator has deleted a land-line
176 * @param event Event being fired
178 public void afterAdminDeletedLandLineNumberEvent (@Observes final AdminDeletedLandLineNumberEvent event) {
179 // Event and contained entity instance should not be null
182 throw new NullPointerException("event is null"); //NOI18N
183 } else if (event.getDeletedLandLineNumber() == null) {
185 throw new NullPointerException("event.deletedLandLineNumber is null"); //NOI18N
186 } else if (event.getDeletedLandLineNumber().getPhoneId() == null) {
188 throw new NullPointerException("event.deletedLandLineNumber.phoneId is null"); //NOI18N
189 } else if (event.getDeletedLandLineNumber().getPhoneId() < 1) {
191 throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedLandLineNumber(), event.getDeletedLandLineNumber().getPhoneId())); //NOI18N
194 // Update contact's mobile, land-line and fax number
195 this.getAllLandLineNumbers().remove(event.getDeletedLandLineNumber());
202 * Observes events being fired when an administrator has a linked a fax
205 * @param event Event being fired
207 public void afterAdminLinkedFaxNumberEvent (@Observes final ObservableAdminLinkedFaxNumberEvent event) {
208 // Is the event fine?
211 throw new NullPointerException("event is null"); //NOI18N
212 } else if (event.getContact() == null) {
214 throw new NullPointerException("event.contact is null"); //NOI18N
215 } else if (event.getContact().getContactId() == null) {
217 throw new NullPointerException("event.contact.contactId is null"); //NOI18N
218 } else if (event.getContact().getContactId() < 1) {
220 throw new NullPointerException(MessageFormat.format("event.contact.contactId={0} is invalid", event.getContact().getContactId())); //NOI18N
221 } else if (event.getContact().getContactFaxNumber() == null) {
223 throw new NullPointerException("event.contact.contactFaxNumber is null"); //NOI18N
224 } else if (event.getContact().getContactFaxNumber().getPhoneId() == null) {
226 throw new NullPointerException("event.contact.contactFaxNumber.phoneId is null"); //NOI18N
227 } else if (event.getContact().getContactFaxNumber().getPhoneId() < 1) {
229 throw new NullPointerException(MessageFormat.format("event.contact.contactFaxNumber.phoneId={0} is invalid", event.getContact().getContactFaxNumber().getPhoneId())); //NOI18N
230 } else if (event.getLinkedFaxNumber() == null) {
232 throw new NullPointerException("event.linkedFaxNumer is null"); //NOI18N
235 // Is the id number in linked number not set?
236 if (event.getLinkedFaxNumber().getPhoneId() == null) {
237 // Then it is a new number, so add it from contact as there the id number has been set
238 this.uniqueAddFaxNumber(event.getContact().getContactFaxNumber());
243 * Observes events being fired when an administrator has a linked a
246 * @param event Event being fired
248 public void afterAdminLinkedLandLineNumberEvent (@Observes final ObservableAdminLinkedLandLineNumberEvent event) {
249 // Is the event fine?
252 throw new NullPointerException("event is null"); //NOI18N
253 } else if (event.getContact() == null) {
255 throw new NullPointerException("event.contact is null"); //NOI18N
256 } else if (event.getContact().getContactId() == null) {
258 throw new NullPointerException("event.contact.contactId is null"); //NOI18N
259 } else if (event.getContact().getContactId() < 1) {
261 throw new NullPointerException(MessageFormat.format("event.contact.contactId={0} is invalid", event.getContact().getContactId())); //NOI18N
262 } else if (event.getContact().getContactLandLineNumber() == null) {
264 throw new NullPointerException("event.contact.contactLandLineNumber is null"); //NOI18N
265 } else if (event.getContact().getContactLandLineNumber().getPhoneId() == null) {
267 throw new NullPointerException("event.contact.contactLandLineNumber.phoneId is null"); //NOI18N
268 } else if (event.getContact().getContactLandLineNumber().getPhoneId() < 1) {
270 throw new NullPointerException(MessageFormat.format("event.contact.contactLandLineNumber.phoneId={0} is invalid", event.getContact().getContactLandLineNumber().getPhoneId())); //NOI18N
271 } else if (event.getLinkedLandLineNumber() == null) {
273 throw new NullPointerException("event.linkedLandLineNumer is null"); //NOI18N
276 // Is the id number in linked number not set?
277 if (event.getLinkedLandLineNumber().getPhoneId() == null) {
278 // Then it is a new number, so add it from contact as there the id number has been set
279 this.uniqueAddLandLineNumber(event.getContact().getContactLandLineNumber());
284 * Observes events being fired when an administrator has updated contact
287 * @param event Event being fired
289 public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) {
290 // Event and contained entity instance should not be null
293 throw new NullPointerException("event is null"); //NOI18N
294 } else if (event.getUpdatedContact() == null) {
296 throw new NullPointerException("event.updatedContact is null"); //NOI18N
297 } else if (event.getUpdatedContact().getContactId() == null) {
299 throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
300 } else if (event.getUpdatedContact().getContactId() < 1) {
302 throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
305 // Update contact's mobile, land-line and fax number
306 this.updateContactPhoneNumbers(event.getUpdatedContact());
313 * Observes events being fired when an administrator has updated a fax
316 * @param event Event being fired
318 public void afterAdminUpdatedFaxNumberEvent (@Observes final AdminUpdatedFaxNumberEvent event) {
319 // Event and contained entity instance should not be null
322 throw new NullPointerException("event is null"); //NOI18N
323 } else if (event.getUpdatedFaxNumber() == null) {
325 throw new NullPointerException("event.updatedFaxNumber is null"); //NOI18N
326 } else if (event.getUpdatedFaxNumber().getPhoneId() == null) {
328 throw new NullPointerException("event.updatedFaxNumber.phoneId is null"); //NOI18N
329 } else if (event.getUpdatedFaxNumber().getPhoneId() < 1) {
331 throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedFaxNumber(), event.getUpdatedFaxNumber().getPhoneId())); //NOI18N
335 this.uniqueAddFaxNumber(event.getUpdatedFaxNumber());
342 * Observes events being fired when an administrator has updated a land-line
345 * @param event Event being fired
347 public void afterAdminUpdatedLandLineNumberEvent (@Observes final AdminUpdatedLandLineNumberEvent event) {
348 // Event and contained entity instance should not be null
351 throw new NullPointerException("event is null"); //NOI18N
352 } else if (event.getUpdatedLandLineNumber() == null) {
354 throw new NullPointerException("event.updatedLandLineNumber is null"); //NOI18N
355 } else if (event.getUpdatedLandLineNumber().getPhoneId() == null) {
357 throw new NullPointerException("event.updatedLandLineNumber.phoneId is null"); //NOI18N
358 } else if (event.getUpdatedLandLineNumber().getPhoneId() < 1) {
360 throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedLandLineNumber(), event.getUpdatedLandLineNumber().getPhoneId())); //NOI18N
364 this.uniqueAddLandLineNumber(event.getUpdatedLandLineNumber());
371 * Observes events being fired when an user has updated contact data.
373 * @param event Event being fired
375 public void afterUpdatedContactDataEvent (@Observes final ObservableUpdatedContactEvent event) {
376 // Event and contained entity instance should not be null
379 throw new NullPointerException("event is null"); //NOI18N
380 } else if (event.getUpdatedContact() == null) {
382 throw new NullPointerException("event.updatedContact is null"); //NOI18N
383 } else if (event.getUpdatedContact().getContactId() == null) {
385 throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
386 } else if (event.getUpdatedContact().getContactId() < 1) {
388 throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
391 // Update contact's mobile, land-line and fax number
392 this.updateContactPhoneNumbers(event.getUpdatedContact());
399 public DialableFaxNumber findFaxNumberById (final Long phoneId) throws PhoneEntityNotFoundException {
401 if (null == phoneId) {
403 throw new NullPointerException("phoneId is null"); //NOI18N
404 } else if (phoneId < 1) {
406 throw new IllegalArgumentException("phoneId=" + phoneId + " is invalid."); //NOI18N
407 } else if (!this.faxNumberCache.containsKey(phoneId)) {
409 throw new PhoneEntityNotFoundException(phoneId);
413 final DialableFaxNumber faxNumber = this.faxNumberCache.get(phoneId);
420 public DialableLandLineNumber findLandLineNumberById (final Long landLineNumberId) throws PhoneEntityNotFoundException {
422 if (null == landLineNumberId) {
424 throw new NullPointerException("landLineNumberId is null"); //NOI18N
425 } else if (landLineNumberId < 1) {
427 throw new IllegalArgumentException(MessageFormat.format("landLineNumberId={0} is invalid.", landLineNumberId)); //NOI18N
428 } else if (!this.landLineNumberCache.containsKey(landLineNumberId)) {
430 throw new PhoneEntityNotFoundException(landLineNumberId);
434 final DialableLandLineNumber landLineNumber = this.landLineNumberCache.get(landLineNumberId);
437 return landLineNumber;
441 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
442 public List<DialableFaxNumber> getAllFaxNumbers () {
443 return this.allFaxNumbers;
447 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
448 public List<DialableLandLineNumber> getAllLandLineNumbers () {
449 return this.allLandLineNumbers;
453 * Getter for filtered fax number list
455 * @return Filtered fax number list
457 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
458 public List<DialableFaxNumber> getFilteredFaxNumbers () {
459 return this.filteredFaxNumbers;
463 * Setter for filtered fax number list
465 * @param filteredFaxNumbers Filtered fax number list
467 @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
468 public void setFilteredFaxNumbers (final List<DialableFaxNumber> filteredFaxNumbers) {
469 this.filteredFaxNumbers = filteredFaxNumbers;
473 * Getter for filtered land-line number list
475 * @return Filtered land-line number list
477 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
478 public List<DialableLandLineNumber> getFilteredLandLineNumbers () {
479 return this.filteredLandLineNumbers;
483 * Setter for filtered land-line number list
485 * @param filteredLandLineNumbers Filtered land-line number list
487 @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
488 public void setFilteredLandLineNumbers (final List<DialableLandLineNumber> filteredLandLineNumbers) {
489 this.filteredLandLineNumbers = filteredLandLineNumbers;
493 * Post-construction method
496 public void initializeList () {
498 if (!this.faxNumberCache.iterator().hasNext()) {
500 for (final DialableFaxNumber currentNumber : this.phoneBean.fetchAllFaxNumbers()) {
502 this.faxNumberCache.put(currentNumber.getPhoneId(), currentNumber);
507 if (!this.landLineNumberCache.iterator().hasNext()) {
509 for (final DialableLandLineNumber currentNumber : this.phoneBean.fetchAllLandLineNumbers()) {
511 this.landLineNumberCache.put(currentNumber.getPhoneId(), currentNumber);
515 // Is cache filled and list is empty
516 if ((this.faxNumberCache.iterator().hasNext()) && (this.getAllFaxNumbers().isEmpty())) {
518 for (final Cache.Entry<Long, DialableFaxNumber> currentEntry : this.faxNumberCache) {
520 this.getAllFaxNumbers().add(currentEntry.getValue());
524 this.getAllFaxNumbers().sort(new Comparator<DialableFaxNumber>() {
526 public int compare (final DialableFaxNumber faxNumber1, final DialableFaxNumber faxNumber2) {
527 return faxNumber1.getPhoneId() > faxNumber2.getPhoneId() ? 1 : faxNumber1.getPhoneId() < faxNumber2.getPhoneId() ? -1 : 0;
532 this.setFilteredFaxNumbers(this.getAllFaxNumbers());
535 // Is cache filled and list is empty
536 if ((this.landLineNumberCache.iterator().hasNext()) && (this.getAllLandLineNumbers().isEmpty())) {
538 for (final Cache.Entry<Long, DialableLandLineNumber> currentEntry : this.landLineNumberCache) {
540 this.getAllLandLineNumbers().add(currentEntry.getValue());
544 this.getAllLandLineNumbers().sort(new Comparator<DialableLandLineNumber>() {
546 public int compare (final DialableLandLineNumber landLineNumber1, final DialableLandLineNumber landLineNumber2) {
547 return landLineNumber1.getPhoneId() > landLineNumber2.getPhoneId() ? 1 : landLineNumber1.getPhoneId() < landLineNumber2.getPhoneId() ? -1 : 0;
552 this.setFilteredLandLineNumbers(this.getAllLandLineNumbers());
559 private void clear () {
564 * Uniquely add given fax number to this bean's list. First remove the old
565 * instance (by id number), then re-add it again.
567 * @param faxNumber number to add
569 private void uniqueAddFaxNumber (final DialableFaxNumber faxNumber) {
570 // Make sure the parameter is valid
571 if (null == faxNumber) {
573 throw new NullPointerException("faxNumber is null"); //NOI18N
574 } else if (faxNumber.getPhoneId() == null) {
576 throw new NullPointerException("faxNumber.phoneId is null"); //NOI18N
577 } else if (faxNumber.getPhoneId() < 1) {
579 throw new IllegalArgumentException(MessageFormat.format("faxNumber.phoneId={0} is not valid.", faxNumber.getPhoneId())); //NOI18N
583 if (!this.getAllFaxNumbers().remove(faxNumber)) {
584 // Did not work, try by id number
585 for (final DialableFaxNumber currentNumber : this.getAllFaxNumbers()) {
586 // Is id number the same?
587 if (Objects.equals(currentNumber.getPhoneId(), faxNumber.getPhoneId())) {
589 this.getAllFaxNumbers().remove(currentNumber);
596 this.getAllFaxNumbers().add(faxNumber);
600 * Uniquely add given land-line number to this bean's list. First remove the
601 * old instance (by id number), then re-add it again.
603 * @param landLineNumber Land-line number to add
605 private void uniqueAddLandLineNumber (final DialableLandLineNumber landLineNumber) {
606 // Make sure the parameter is valid
607 if (null == landLineNumber) {
609 throw new NullPointerException("landLineNumber is null"); //NOI18N
610 } else if (landLineNumber.getPhoneId() == null) {
612 throw new NullPointerException("landLineNumber.phoneId is null"); //NOI18N
613 } else if (landLineNumber.getPhoneId() < 1) {
615 throw new IllegalArgumentException(MessageFormat.format("landLineNumber.phoneId={0} is not valid.", landLineNumber.getPhoneId())); //NOI18N
619 if (!this.getAllLandLineNumbers().remove(landLineNumber)) {
620 // Did not work, try by id number
621 for (final DialableLandLineNumber currentNumber : this.getAllLandLineNumbers()) {
622 // Is id number the same?
623 if (Objects.equals(currentNumber.getPhoneId(), landLineNumber.getPhoneId())) {
625 this.getAllLandLineNumbers().remove(currentNumber);
632 this.getAllLandLineNumbers().add(landLineNumber);
636 * Updates given contact's mobile, land-line and fax number
638 * @param contact Contact instance
640 private void updateContactPhoneNumbers (final Contact contact) {
641 // Parameter must be valid
642 if (null == contact) {
644 throw new NullPointerException("contact is null"); //NOI18N
645 } else if (contact.getContactId() == null) {
647 throw new NullPointerException("contact.contactId is null"); //NOI18N
648 } else if (contact.getContactId() < 1) {
649 // Id number is not valid
653 if (contact.getContactLandLineNumber() instanceof DialableLandLineNumber) {
655 this.uniqueAddLandLineNumber(contact.getContactLandLineNumber());
659 if (contact.getContactFaxNumber() instanceof DialableFaxNumber) {
661 this.uniqueAddFaxNumber(contact.getContactFaxNumber());