2 * Copyright (C) 2016 - 2020 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.jfinancials.beans.contact.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.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
33 import org.mxchange.jcontacts.events.contact.deleted.ObservableAdminDeletedContactEvent;
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.unlinked.ObservableAdminUnlinkedFaxNumberEvent;
37 import org.mxchange.jcontacts.events.landline.unlinked.ObservableAdminUnlinkedLandLineNumberEvent;
38 import org.mxchange.jcontacts.events.mobile.unlinked.ObservableAdminUnlinkedMobileNumberEvent;
39 import org.mxchange.jcontacts.exceptions.ContactNotFoundException;
40 import org.mxchange.jcontacts.model.contact.Contact;
41 import org.mxchange.jcontacts.model.contact.ContactSessionBeanRemote;
42 import org.mxchange.jcontacts.model.contact.Contacts;
43 import org.mxchange.jfinancials.beans.BaseFinancialsBean;
44 import org.mxchange.jphone.model.phonenumbers.DialableNumber;
45 import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber;
46 import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
47 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
50 * A regular contact list bean (controller)
52 * @author Roland Häder<roland@mxchange.org>
54 @Named ("contactListController")
56 public class FinancialsContactListWebViewBean extends BaseFinancialsBean implements FinancialsContactListWebViewController {
61 private static final long serialVersionUID = 542_145_347_917L;
66 private final List<Contact> allContacts;
69 * Administrative contact EJB
71 @EJB (lookup = "java:global/jfinancials-ejb/contact!org.mxchange.jcontacts.model.contact.ContactSessionBeanRemote")
72 private ContactSessionBeanRemote contactBean;
78 @NamedCache (cacheName = "contactCache")
79 private transient Cache<Long, Contact> contactCache;
82 * A list of filtered contacts
84 private List<Contact> filteredContacts;
87 * Current selected contact
89 private Contact selectedContact;
94 public FinancialsContactListWebViewBean () {
95 // Call super constructor
99 this.allContacts = new LinkedList<>();
103 * Observes events being fired when an administrator has added a new
106 * @param event Event being fired
108 public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) {
109 // The event must be valid
112 throw new NullPointerException("event is null"); //NOI18N
113 } else if (event.getAddedContact() == null) {
115 throw new NullPointerException("event.addedContact is null"); //NOI18N
116 } else if (event.getAddedContact().getContactId() == null) {
118 throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N
119 } else if (event.getAddedContact().getContactId() < 1) {
121 throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N
125 this.uniqueAddContact(event.getAddedContact());
129 * Event observer for when an administrator has deleted a contact
131 * @param event Event being fired
133 public void afterAdminDeletedContactEvent (@Observes final ObservableAdminDeletedContactEvent event) {
134 // Validate parameter
137 throw new NullPointerException("event is null"); //NOI18N
138 } else if (event.getDeletedContact() == null) {
140 throw new NullPointerException("event.deletedContact is null"); //NOI18N
141 } else if (event.getDeletedContact().getContactId() == null) {
143 throw new NullPointerException("event.deletedContact.contactId is null"); //NOI18N
144 } else if (event.getDeletedContact().getContactId() < 1) {
146 throw new IllegalArgumentException(MessageFormat.format("event.deletedContact.contactId={0} is not valid.", event.getDeletedContact().getContactId())); //NOI18N
149 // Delete from cache and list
150 this.contactCache.remove(event.getDeletedContact().getContactId());
151 this.getAllContacts().remove(event.getDeletedContact());
155 * Event observer for unlinked fax contact by administrators
157 * @param event Unlinked fax contact event
159 public void afterAdminUnlinkedFaxContactDataEvent (@Observes final ObservableAdminUnlinkedFaxNumberEvent event) {
160 // Event and contained entity instance should not be null
163 throw new NullPointerException("event is null"); //NOI18N
164 } else if (event.getUnlinkedFaxNumber() == null) {
166 throw new NullPointerException("event.unlinkedFaxNumber is null"); //NOI18N
167 } else if (event.getUnlinkedFaxNumber().getPhoneId() == null) {
169 throw new NullPointerException("event.unlinkedFaxNumber.contactId is null"); //NOI18N
170 } else if (event.getUnlinkedFaxNumber().getPhoneId() < 1) {
172 throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedFaxNumber(), event.getUnlinkedFaxNumber().getPhoneId())); //NOI18N
175 // Remove it from any entry
176 for (final Cache.Entry<Long, Contact> entry : this.contactCache) {
177 // Get contact instance from it
178 final Contact contact = entry.getValue();
180 // Is the number matching?
181 if (Objects.equals(event.getUnlinkedFaxNumber(), contact.getContactFaxNumber())) {
182 // Yes, then unset it
183 contact.setContactFaxNumber(null);
189 * Event observer for unlinked land-line contact by administrators
191 * @param event Unlinked land-line contact event
193 public void afterAdminUnlinkedLandLineContactDataEvent (@Observes final ObservableAdminUnlinkedLandLineNumberEvent event) {
194 // Event and contained entity instance should not be null
197 throw new NullPointerException("event is null"); //NOI18N
198 } else if (event.getUnlinkedLandLineNumber() == null) {
200 throw new NullPointerException("event.unlinkedLandLineNumber is null"); //NOI18N
201 } else if (event.getUnlinkedLandLineNumber().getPhoneId() == null) {
203 throw new NullPointerException("event.unlinkedLandLineNumber.contactId is null"); //NOI18N
204 } else if (event.getUnlinkedLandLineNumber().getPhoneId() < 1) {
206 throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedLandLineNumber(), event.getUnlinkedLandLineNumber().getPhoneId())); //NOI18N
209 // Remove it from any entry
210 for (final Cache.Entry<Long, Contact> entry : this.contactCache) {
211 // Get contact instance from it
212 final Contact contact = entry.getValue();
214 // Is the number matching?
215 if (Objects.equals(event.getUnlinkedLandLineNumber(), contact.getContactLandLineNumber())) {
216 // Yes, then unset it
217 contact.setContactLandLineNumber(null);
223 * Event observer for unlinked mobile contact by administrators
225 * @param event Unlinked mobile contact event
227 public void afterAdminUnlinkedMobileContactDataEvent (@Observes final ObservableAdminUnlinkedMobileNumberEvent event) {
228 // Event and contained entity instance should not be null
231 throw new NullPointerException("event is null"); //NOI18N
232 } else if (event.getUnlinkedMobileNumber() == null) {
234 throw new NullPointerException("event.unlinkedMobileNumber is null"); //NOI18N
235 } else if (event.getUnlinkedMobileNumber().getMobileId() == null) {
237 throw new NullPointerException("event.unlinkedMobileNumber.contactId is null"); //NOI18N
238 } else if (event.getUnlinkedMobileNumber().getMobileId() < 1) {
240 throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedMobileNumber(), event.getUnlinkedMobileNumber().getMobileId())); //NOI18N
243 // Remove it from any entry
244 for (final Cache.Entry<Long, Contact> entry : this.contactCache) {
245 // Get contact instance from it
246 final Contact contact = entry.getValue();
248 // Is the number matching?
249 if (Objects.equals(event.getUnlinkedMobileNumber(), contact.getContactMobileNumber())) {
250 // Yes, then unset it
251 contact.setContactMobileNumber(null);
257 * Event observer for updated contact data by administrators
259 * @param event Updated contact data event
261 public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) {
262 // Event and contained entity instance should not be null
265 throw new NullPointerException("event is null"); //NOI18N
266 } else if (event.getUpdatedContact() == null) {
268 throw new NullPointerException("event.updatedContact is null"); //NOI18N
269 } else if (event.getUpdatedContact().getContactId() == null) {
271 throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
272 } else if (event.getUpdatedContact().getContactId() < 1) {
274 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
277 // Add contact instance only once
278 this.uniqueAddContact(event.getUpdatedContact());
282 * Event observer for updated contact data by the user
284 * @param event Updated contact data event
286 public void afterUpdatedContactDataEvent (@Observes final ObservableUpdatedContactEvent event) {
287 // Event and contained entity instance should not be null
290 throw new NullPointerException("event is null"); //NOI18N
291 } else if (event.getUpdatedContact() == null) {
293 throw new NullPointerException("event.updatedContact is null"); //NOI18N
294 } else if (event.getUpdatedContact().getContactId() == null) {
296 throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N
297 } else if (event.getUpdatedContact().getContactId() < 1) {
299 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
302 // Add contact instance only once
303 this.uniqueAddContact(event.getUpdatedContact());
307 * Event observer when user confirmed account.
309 * @param event Event being fired
311 public void afterUserConfirmedAccount (@Observes final ObservableUserConfirmedAccountEvent event) {
312 // Event and contained entity instance should not be null
315 throw new NullPointerException("event is null"); //NOI18N
316 } else if (event.getConfirmedUser() == null) {
318 throw new NullPointerException("event.confirmedUser is null"); //NOI18N
319 } else if (event.getConfirmedUser().getUserId() == null) {
321 throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N
322 } else if (event.getConfirmedUser().getUserId() < 1) {
324 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N
327 // Add contact instance only once
328 this.uniqueAddContact(event.getConfirmedUser().getUserContact());
332 * Event observer for new user registrations
334 * @param event User registration event
336 public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) {
337 // Event and contained entity instance should not be null
340 throw new NullPointerException("event is null"); //NOI18N
341 } else if (event.getRegisteredUser() == null) {
343 throw new NullPointerException("event.registeredUser is null"); //NOI18N
344 } else if (event.getRegisteredUser().getUserId() == null) {
346 throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
347 } else if (event.getRegisteredUser().getUserId() < 1) {
349 throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N
353 final Contact registeredContact = event.getRegisteredUser().getUserContact();
355 // Add contact instance only once
356 this.uniqueAddContact(registeredContact);
360 public Contact findContactById (final Long contactId) throws ContactNotFoundException {
361 // Validate parameter
362 if (null == contactId) {
364 throw new NullPointerException("contactId is null"); //NOI18N
365 } else if (contactId < 1) {
367 throw new IllegalArgumentException(MessageFormat.format("contactId={0} is invalid", contactId)); //NOI18N
368 } else if (!this.contactCache.containsKey(contactId)) {
370 throw new ContactNotFoundException(contactId);
374 final Contact contact = this.contactCache.get(contactId);
381 * Returns a text representation of given mobile number or null if not set.
383 * @param mobileNumber Mobile number
385 * @return Text representation or null
387 public String generateMobileNumber (final DialableMobileNumber mobileNumber) {
389 if (null == mobileNumber) {
395 final String number = String.format(
397 mobileNumber.getMobileProvider().getProviderCountry().getCountryExternalDialPrefix(),
398 mobileNumber.getMobileProvider().getProviderDialPrefix(),
399 mobileNumber.getMobileNumber()
407 * Returns a text representation of given land-line or fax number or null if
410 * @param phoneNumber Land-line or fax number
412 * @return Text representation or null
414 public String generatePhoneNumber (final DialableNumber phoneNumber) {
416 if (null == phoneNumber) {
422 final String number = String.format(
424 phoneNumber.getPhoneCountry().getCountryExternalDialPrefix(),
425 phoneNumber.getPhoneAreaCode(),
426 phoneNumber.getPhoneNumber()
434 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
435 public List<Contact> getAllContacts () {
436 return this.allContacts;
440 * Getter for filtered contacts
444 @SuppressWarnings ("ReturnOfCollectionOrArrayField")
445 public List<Contact> getFilteredContacts () {
446 return this.filteredContacts;
450 * Setter for filtered contacts
452 * @param filteredContacts Filtered contacts list
454 @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter")
455 public void setFilteredContacts (final List<Contact> filteredContacts) {
456 this.filteredContacts = filteredContacts;
460 * Getter for selected contact
462 * @return Selected Contact instance
464 public Contact getSelectedContact () {
465 return this.selectedContact;
469 * Setter for selected contact
471 * @param selectedContact
473 public void setSelectedContact (final Contact selectedContact) {
474 this.selectedContact = selectedContact;
478 * Post-construction method
481 public void initializeList () {
483 if (!this.contactCache.iterator().hasNext()) {
485 for (final Contact contact : this.contactBean.fetchAllContacts()) {
487 this.contactCache.put(contact.getContactId(), contact);
491 // Is cache there and list is not full?
492 if ((this.getAllContacts().isEmpty()) && (this.contactCache.iterator().hasNext())) {
494 for (final Cache.Entry<Long, Contact> currentEntry : this.contactCache) {
496 this.getAllContacts().add(currentEntry.getValue());
500 this.getAllContacts().sort(new Comparator<Contact>() {
502 public int compare (final Contact contact1, final Contact contact2) {
503 return contact1.getContactId() > contact2.getContactId() ? 1 : contact1.getContactId() < contact2.getContactId() ? -1 : 0;
508 this.setFilteredContacts(this.getAllContacts());
513 public boolean isContactFound (final Contact contact) {
514 // Default is not found
515 boolean IsFound = false;
518 for (final Contact currentContact : this.getAllContacts()) {
520 if (Contacts.isSameContact(contact, currentContact)) {
521 // Yes, then abort loop
532 * Removes given contact from all lists
534 * @param contact Contact instance to remove
536 private void removeContact (final Contact contact) {
537 // Remove from general list
538 this.contactCache.remove(contact.getContactId());
542 * Adds unique instance to contact list. First any existing instance is
543 * being removed, then the new instance is added.
545 * @param contact Contact instance to add uniquely
547 private void uniqueAddContact (final Contact contact) {
548 // "Walk" through all entries
549 for (final Cache.Entry<Long, Contact> currentEntry : this.contactCache) {
550 // Is id number the same?
551 if (Objects.equals(contact.getContactId(), currentEntry.getKey())) {
552 // Found entry, so remove it and abort
553 this.removeContact(currentEntry.getValue());
558 // Add contact to list
559 this.contactCache.put(contact.getContactId(), contact);