From 760433bc1a6db91e8504b89137d7ee509a62b4ca Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Sun, 29 Mar 2020 21:00:35 +0200 Subject: [PATCH] Please cherry-pick/repeat: - rewrote "contacts-list view" into modern approach, with filters and sorting - in the progress a ViewScoped backing bean has been added which needs to duplicated to all other projects, that handles "jcontacts-core data" MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Roland Häder --- .../FinancialsAdminContactWebRequestBean.java | 47 +- .../FinancialsContactWebRequestBean.java | 368 +-------------- ...FinancialsContactWebRequestController.java | 20 - .../FinancialsContactListWebViewBean.java | 429 ++++++++++++++++++ ...inancialsContactListWebViewController.java | 59 +++ .../FinancialsContactPhoneWebRequestBean.java | 14 +- .../contact/FinancialsContactConverter.java | 12 +- web/admin/contact/admin_contact_list.xhtml | 161 +++++-- web/admin/fax/admin_fax_show.xhtml | 2 +- web/admin/user/admin_user_list.xhtml | 2 +- 10 files changed, 657 insertions(+), 457 deletions(-) create mode 100644 src/java/org/mxchange/jfinancials/beans/contact/list/FinancialsContactListWebViewBean.java create mode 100644 src/java/org/mxchange/jfinancials/beans/contact/list/FinancialsContactListWebViewController.java diff --git a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsAdminContactWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsAdminContactWebRequestBean.java index eb2c579a..cca45e73 100644 --- a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsAdminContactWebRequestBean.java +++ b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsAdminContactWebRequestBean.java @@ -18,7 +18,6 @@ package org.mxchange.jfinancials.beans.contact; import java.text.MessageFormat; import java.util.Date; -import java.util.Iterator; import javax.ejb.EJB; import javax.enterprise.context.RequestScoped; import javax.enterprise.event.Event; @@ -41,6 +40,7 @@ import org.mxchange.jcontacts.model.contact.UserContact; import org.mxchange.jcontacts.model.contact.title.PersonalTitle; import org.mxchange.jcountry.model.data.Country; import org.mxchange.jfinancials.beans.BaseFinancialsBean; +import org.mxchange.jfinancials.beans.contact.list.FinancialsContactListWebViewController; import org.mxchange.jphone.model.phonenumbers.DialableNumber; import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber; import org.mxchange.jphone.model.phonenumbers.fax.FaxNumber; @@ -103,12 +103,6 @@ public class FinancialsAdminContactWebRequestBean extends BaseFinancialsBean imp @EJB (lookup = "java:global/jfinancials-ejb/contact!org.mxchange.jcontacts.model.contact.ContactSessionBeanRemote") private ContactSessionBeanRemote contactBean; - /** - * General contact controller - */ - @Inject - private FinancialsContactWebRequestController contactController; - /** * Country instance */ @@ -119,6 +113,12 @@ public class FinancialsAdminContactWebRequestBean extends BaseFinancialsBean imp */ private Long contactId; + /** + * An instance of a contact list controller + */ + @Inject + private FinancialsContactListWebViewController contactListController; + /** * Email address */ @@ -271,7 +271,7 @@ public class FinancialsAdminContactWebRequestBean extends BaseFinancialsBean imp final Contact contact = this.createContactInstance(); // Default is not same contact - if (this.isSameContactFound(contact)) { + if (this.contactListController.isSameContactFound(contact)) { // Already registered throw new FaceletException(new ContactAlreadyAddedException(contact)); } @@ -1086,37 +1086,6 @@ public class FinancialsAdminContactWebRequestBean extends BaseFinancialsBean imp this.setComment(null); } - /** - * Checks whether the given contact is found - *

- * @param contact Contact instance - * - * @return Whether contact has been found - */ - private boolean isSameContactFound (final Contact contact) { - // Default is not found - boolean IsFound = false; - - // Get iterator - final Iterator iterator = this.contactController.allContacts().iterator(); - - // Loop through all - while (iterator.hasNext()) { - // Get next contact - final Contact next = iterator.next(); - - // Is the same? - if (Contacts.isSameContact(contact, next)) { - // Yes, then abort loop - IsFound = false; - break; - } - } - - // Return status - return IsFound; - } - /** * Updates all data in contact instance. *

diff --git a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestBean.java index 4ca78d27..dbb4ade8 100644 --- a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestBean.java +++ b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestBean.java @@ -16,24 +16,15 @@ */ package org.mxchange.jfinancials.beans.contact; -import fish.payara.cdi.jsr107.impl.NamedCache; import java.text.MessageFormat; import java.util.Date; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; import java.util.Objects; -import javax.annotation.PostConstruct; -import javax.cache.Cache; import javax.ejb.EJB; import javax.enterprise.context.RequestScoped; import javax.enterprise.event.Observes; import javax.faces.view.facelets.FaceletException; import javax.inject.Inject; import javax.inject.Named; -import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent; -import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent; -import org.mxchange.jcontacts.exceptions.ContactNotFoundException; import org.mxchange.jcontacts.model.contact.Contact; import org.mxchange.jcontacts.model.contact.ContactSessionBeanRemote; import org.mxchange.jcontacts.model.contact.Contacts; @@ -41,7 +32,7 @@ import org.mxchange.jcontacts.model.contact.UserContact; import org.mxchange.jcontacts.model.contact.title.PersonalTitle; import org.mxchange.jcountry.model.data.Country; import org.mxchange.jfinancials.beans.BaseFinancialsBean; -import org.mxchange.jfinancials.beans.user.FinancialsUserWebRequestController; +import org.mxchange.jfinancials.beans.contact.list.FinancialsContactListWebViewController; import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController; import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber; import org.mxchange.jphone.model.phonenumbers.fax.FaxNumber; @@ -52,10 +43,7 @@ import org.mxchange.jphone.model.phonenumbers.mobile.MobileNumber; import org.mxchange.jphone.model.phonenumbers.mobileprovider.MobileProvider; import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent; import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent; -import org.mxchange.jusercore.model.user.User; -import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent; import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent; -import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent; import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException; /** @@ -99,11 +87,9 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen private ContactSessionBeanRemote contactBean; /** - * Contact list + * An instance of a contact-list backing bean */ - @Inject - @NamedCache (cacheName = "contactCache") - private Cache contactCache; + private FinancialsContactListWebViewController contactListController; /** * Country instance @@ -115,13 +101,6 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen */ private String emailAddress; - /** - * Email address list - */ - @Inject - @NamedCache (cacheName = "emailAddressCache") - private Cache emailAddressCache; - /** * Email address repeated */ @@ -207,24 +186,11 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen */ private PersonalTitle personalTitle; - /** - * A list of all selectable contacts - */ - @Inject - @NamedCache (cacheName = "selectableContactsCache") - private Cache selectableContactsCache; - /** * Street */ private String street; - /** - * Regular user controller - */ - @Inject - private FinancialsUserWebRequestController userController; - /** * Login bean (controller) */ @@ -244,38 +210,6 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen super(); } - /** - * Observes events being fired when an administrator has added a new - * contact. - *

- * @param event Event being fired - */ - public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) { - // The event must be valid - if (null == event) { - // Throw NPE - throw new NullPointerException("event is null"); //NOI18N - } else if (event.getAddedContact() == null) { - // Throw again ... - throw new NullPointerException("event.addedContact is null"); //NOI18N - } else if (event.getAddedContact().getContactId() == null) { - // ... and again - throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N - } else if (event.getAddedContact().getContactId() < 1) { - // Not valid - throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N //NOI18N - } - - // Clear this bean - this.clear(); - - // Call other method - this.uniqueAddContact(event.getAddedContact()); - - // Add to selectable contacts - this.selectableContactsCache.put(event.getAddedContact().getContactId(), event.getAddedContact()); - } - /** * Event observer for newly added users by administrator *

@@ -326,66 +260,10 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserContact().getContactId())); //NOI18N } - // Remove contact from list available contacts list - this.selectableContactsCache.remove(event.getLinkedUser().getUserContact().getContactId()); - // Clear all data this.clear(); } - /** - * Event observer for updated contact data by administrators - *

- * @param event Updated contact data event - */ - public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) { - // event should not be null - if (null == event) { - // Throw NPE - throw new NullPointerException("event is null"); //NOI18N - } else if (event.getUpdatedContact() == null) { - // Throw NPE again - throw new NullPointerException("event.updatedContact is null"); //NOI18N - } else if (event.getUpdatedContact().getContactId() == null) { - // userId is null - throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N - } else if (event.getUpdatedContact().getContactId() < 1) { - // Not avalid id - throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N - } - - // Add contact instance only once - this.uniqueAddContact(event.getUpdatedContact()); - - // Add email address to list - this.emailAddressCache.put(event.getUpdatedContact().getContactId(), event.getUpdatedContact().getContactEmailAddress()); - } - - /** - * Event observer when user confirmed account. - *

- * @param event Event being fired - */ - public void afterUserConfirmedAccount (@Observes final ObservableUserConfirmedAccountEvent event) { - // event should not be null - if (null == event) { - // Throw NPE - throw new NullPointerException("event is null"); //NOI18N - } else if (event.getConfirmedUser() == null) { - // Throw NPE again - throw new NullPointerException("event.confirmedUser is null"); //NOI18N - } else if (event.getConfirmedUser().getUserId() == null) { - // userId is null - throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N - } else if (event.getConfirmedUser().getUserId() < 1) { - // Not avalid id - throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N - } - - // Add contact instance only once - this.uniqueAddContact(event.getConfirmedUser().getUserContact()); - } - /** * Event observer for logged-in user *

@@ -411,65 +289,6 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen this.copyContact(event.getLoggedInUser().getUserContact()); } - /** - * Event observer for new user registrations - *

- * @param event User registration event - */ - public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) { - // event should not be null - if (null == event) { - // Throw NPE - throw new NullPointerException("event is null"); //NOI18N - } else if (event.getRegisteredUser() == null) { - // Throw NPE again - throw new NullPointerException("event.registeredUser is null"); //NOI18N - } else if (event.getRegisteredUser().getUserId() == null) { - // userId is null - throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N - } else if (event.getRegisteredUser().getUserId() < 1) { - // Not avalid id - throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N - } - - // Get user instance - final Contact registeredContact = event.getRegisteredUser().getUserContact(); - - // Copy all data from registered->user - this.copyContact(registeredContact); - - // Add contact instance only once - this.uniqueAddContact(registeredContact); - - // Add user name and email address - this.addUserNameEmailAddress(registeredContact); - - // Clear all data - this.clear(); - } - - @Override - @SuppressWarnings ("ReturnOfCollectionOrArrayField") - public List allContacts () { - // Init list - final List list = new LinkedList<>(); - - // Get iterator - final Iterator> iterator = this.contactCache.iterator(); - - // Loop over all - while (iterator.hasNext()) { - // Get next entry - final Cache.Entry next = iterator.next(); - - // Add value to list - list.add(next.getValue()); - } - - // Return it - return list; - } - @Override public void clearEmailAddresses () { // Clear both @@ -616,27 +435,6 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen return "contact_data_saved"; //NOI18N } - @Override - public Contact findContactById (final Long contactId) throws ContactNotFoundException { - // Validate parameter - if (null == contactId) { - // Throw NPE - throw new NullPointerException("contactId is null"); //NOI18N - } else if (contactId < 1) { - // Throw IAE - throw new IllegalArgumentException("contactId=" + contactId + " is invalid"); //NOI18N - } else if (!this.contactCache.containsKey(contactId)) { - // Not found - throw new ContactNotFoundException(contactId); - } - - // Get it from cache - final Contact contact = this.contactCache.get(contactId); - - // Return it - return contact; - } - /** * Getter for academic title *

@@ -1043,64 +841,6 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen this.zipCode = zipCode; } - /** - * Post-construction method - */ - @PostConstruct - public void init () { - // Is cache there? - if (!this.contactCache.iterator().hasNext()) { - // Get whole list from EJB - final List contacts = this.contactBean.allContacts(); - - // Add all - for (final Contact contact : contacts) { - // Add it to cache - this.contactCache.put(contact.getContactId(), contact); - - // Is email address given? - if (contact.getContactEmailAddress() != null) { - // Set it, too - this.emailAddressCache.put(contact.getContactId(), contact.getContactEmailAddress()); - } - } - } else if (this.selectableContactsCache.iterator().hasNext()) { - // Has already entries, avoid executing below code - return; - } - - // Get all users - final List allUsers = this.userController.allUsers(); - - // Get iterator from contacts cache - final Iterator> iterator = this.contactCache.iterator(); - - // Loop through all contacts - while (iterator.hasNext()) { - // Get next element - final Cache.Entry next = iterator.next(); - - // Default is not found - boolean isFound = false; - - // User list is not empty, check each entry, if contact is found - for (final User user : allUsers) { - // Is the contact the same? - if (Objects.equals(user.getUserContact(), next.getValue())) { - // Found one - isFound = true; - break; - } - } - - // Is contact not found? - if (!isFound) { - // Add it as selectable - this.selectableContactsCache.put(next.getKey(), next.getValue()); - } - } - } - @Override public boolean isEmailAddressRegistered (final Contact contact) { // Cherck parameter @@ -1115,8 +855,23 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen throw new IllegalArgumentException("contact.contactEmailAddress is empty."); //NOI18N } + // Default is not registered + boolean isRegistered = false; + // Determine it - return ((this.emailAddressCache instanceof List) && (this.emailAddressCache.containsKey(contact.getContactId()))); + for (final Contact currentContact : this.contactListController.getAllContacts()) { + // Is same contact found? + if (currentContact.getContactEmailAddress().equals(contact.getContactEmailAddress())) { + // Found same email address + isRegistered = true; + + // Skipp further iterations + break; + } + } + + // Return status + return isRegistered; } @Override @@ -1153,32 +908,6 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen return (Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat())); } - /** - * Returns a list of all selectable contacts for user creation. Contacts - * from already existing users are excluded in this list. - *

- * @return A list of all selectable contacts - */ - public List selectableContacts () { - // Init list - final List selectableContacts = new LinkedList<>(); - - // Get iterator from cache - final Iterator> iterator = this.contactCache.iterator(); - - // Loop through all contacts - while (iterator.hasNext()) { - // Get next element - final Cache.Entry next = iterator.next(); - - // Add entry's value to list - selectableContacts.add(next.getValue()); - } - - // Return list - return selectableContacts; - } - @Override public void updateContactDataFromController (final Contact contact) { // Is the instance valid? @@ -1197,22 +926,6 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen this.copyContact(contact); } - /** - * Adds email address to bean's internal list. - *

- * @param contact Contact instance - */ - private void addUserNameEmailAddress (final Contact contact) { - // Make sure the entry is not added yet - if (this.emailAddressCache.containsKey(contact.getContactId())) { - // Already added - throw new IllegalArgumentException(MessageFormat.format("Email address {0} already added.", contact.getContactEmailAddress())); //NOI18N - } - - // Add email addres - this.emailAddressCache.put(contact.getContactId(), contact.getContactEmailAddress()); - } - /** * Clears this bean */ @@ -1292,47 +1005,4 @@ public class FinancialsContactWebRequestBean extends BaseFinancialsBean implemen } } - /** - * Removes given contact from all lists - *

- * @param contact Contact instance to remove - */ - private void removeContact (final Contact contact) { - // Remove from general list - if (!this.contactCache.remove(contact.getContactId())) { - // Did not remove contact - throw new IllegalStateException(MessageFormat.format("contact {0} was not removed.", contact.getContactId())); //NOI18N - } - - // Remove from other lists - this.emailAddressCache.remove(contact.getContactId()); - } - - /** - * Adds unique instance to contact list. First any existing instance is - * being removed, then the new instance is added. - *

- * @param contact Contact instance to add uniquely - */ - private void uniqueAddContact (final Contact contact) { - // Get iterator from list - final Iterator> iterator = this.contactCache.iterator(); - - // "Walk" through all entries - while (iterator.hasNext()) { - // Get next element - final Cache.Entry next = iterator.next(); - - // Is id number the same? - if (Objects.equals(contact.getContactId(), next.getKey())) { - // Found entry, so remove it and abort - this.removeContact(next.getValue()); - break; - } - } - - // Add contact to list - this.contactCache.put(contact.getContactId(), contact); - } - } diff --git a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestController.java index b5003108..a164d115 100644 --- a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestController.java +++ b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestController.java @@ -17,8 +17,6 @@ package org.mxchange.jfinancials.beans.contact; import java.io.Serializable; -import java.util.List; -import org.mxchange.jcontacts.exceptions.ContactNotFoundException; import org.mxchange.jcontacts.model.contact.Contact; /** @@ -45,13 +43,6 @@ public interface FinancialsContactWebRequestController extends Serializable { */ void clearEmailAddresses (); - /** - * Returns a list of all found contacts - *

- * @return A list of all contacts. - */ - List allContacts (); - /** * Updates all data from bean in given contact instance *

@@ -121,17 +112,6 @@ public interface FinancialsContactWebRequestController extends Serializable { */ String doChangePersonalContactData (); - /** - * Returns a contact instance which has the given id number. - *

- * @param contactId Contact id - *

- * @return Contact instance - *

- * @throws ContactNotFoundException If the contact was not found - */ - Contact findContactById (final Long contactId) throws ContactNotFoundException; - /** * Checks whether the given email address is already registered. The email * address should be validated by EmailAddressValidator before calling this diff --git a/src/java/org/mxchange/jfinancials/beans/contact/list/FinancialsContactListWebViewBean.java b/src/java/org/mxchange/jfinancials/beans/contact/list/FinancialsContactListWebViewBean.java new file mode 100644 index 00000000..d4edde22 --- /dev/null +++ b/src/java/org/mxchange/jfinancials/beans/contact/list/FinancialsContactListWebViewBean.java @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2016 - 2020 Free Software Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.mxchange.jfinancials.beans.contact.list; + +import fish.payara.cdi.jsr107.impl.NamedCache; +import java.text.MessageFormat; +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; +import javax.annotation.PostConstruct; +import javax.cache.Cache; +import javax.ejb.EJB; +import javax.enterprise.event.Observes; +import javax.faces.view.ViewScoped; +import javax.inject.Inject; +import javax.inject.Named; +import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent; +import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent; +import org.mxchange.jcontacts.exceptions.ContactNotFoundException; +import org.mxchange.jcontacts.model.contact.Contact; +import org.mxchange.jcontacts.model.contact.ContactSessionBeanRemote; +import org.mxchange.jcontacts.model.contact.Contacts; +import org.mxchange.jfinancials.beans.BaseFinancialsBean; +import org.mxchange.jphone.model.phonenumbers.DialableNumber; +import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber; +import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent; +import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent; + +/** + * A regular contact list bean (controller) + *

+ * @author Roland Häder + */ +@Named ("contactListController") +@ViewScoped +public class FinancialsContactListWebViewBean extends BaseFinancialsBean implements FinancialsContactListWebViewController { + + /** + * Serial number + */ + private static final long serialVersionUID = 542_145_347_917L; + + /** + * All contacts + */ + private final List allContacts; + + /** + * Administrative contact EJB + */ + @EJB (lookup = "java:global/jfinancials-ejb/contact!org.mxchange.jcontacts.model.contact.ContactSessionBeanRemote") + private ContactSessionBeanRemote contactBean; + + /** + * Contact list + */ + @Inject + @NamedCache (cacheName = "contactCache") + private transient Cache contactCache; + + /** + * A list of filtered contacts + */ + private List filteredContacts; + + /** + * Current selected contact + */ + private Contact selectedContact; + + /** + * Default constructor + */ + public FinancialsContactListWebViewBean () { + // Call super constructor + super(); + + // Init list + this.allContacts = new LinkedList<>(); + } + + /** + * Observes events being fired when an administrator has added a new + * contact. + *

+ * @param event Event being fired + */ + public void afterAdminAddedContactEvent (@Observes final ObservableAdminAddedContactEvent event) { + // The event must be valid + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getAddedContact() == null) { + // Throw again ... + throw new NullPointerException("event.addedContact is null"); //NOI18N + } else if (event.getAddedContact().getContactId() == null) { + // ... and again + throw new NullPointerException("event.addedContact.contactId is null"); //NOI18N + } else if (event.getAddedContact().getContactId() < 1) { + // Not valid + throw new IllegalArgumentException(MessageFormat.format("event.addedContact.contactId={0} is not valid", event.getAddedContact().getContactId())); //NOI18N //NOI18N + } + + // Call other method + this.uniqueAddContact(event.getAddedContact()); + } + + /** + * Event observer for updated contact data by administrators + *

+ * @param event Updated contact data event + */ + public void afterAdminUpdatedContactDataEvent (@Observes final ObservableAdminUpdatedContactEvent event) { + // event should not be null + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getUpdatedContact() == null) { + // Throw NPE again + throw new NullPointerException("event.updatedContact is null"); //NOI18N + } else if (event.getUpdatedContact().getContactId() == null) { + // userId is null + throw new NullPointerException("event.updatedContact.contactId is null"); //NOI18N + } else if (event.getUpdatedContact().getContactId() < 1) { + // Not avalid id + throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N + } + + // Add contact instance only once + this.uniqueAddContact(event.getUpdatedContact()); + } + + /** + * Event observer when user confirmed account. + *

+ * @param event Event being fired + */ + public void afterUserConfirmedAccount (@Observes final ObservableUserConfirmedAccountEvent event) { + // event should not be null + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getConfirmedUser() == null) { + // Throw NPE again + throw new NullPointerException("event.confirmedUser is null"); //NOI18N + } else if (event.getConfirmedUser().getUserId() == null) { + // userId is null + throw new NullPointerException("event.confirmedUser.userId is null"); //NOI18N + } else if (event.getConfirmedUser().getUserId() < 1) { + // Not avalid id + throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getConfirmedUser(), event.getConfirmedUser().getUserId())); //NOI18N + } + + // Add contact instance only once + this.uniqueAddContact(event.getConfirmedUser().getUserContact()); + } + + /** + * Event observer for new user registrations + *

+ * @param event User registration event + */ + public void afterUserRegistrationEvent (@Observes final ObservableUserRegisteredEvent event) { + // event should not be null + if (null == event) { + // Throw NPE + throw new NullPointerException("event is null"); //NOI18N + } else if (event.getRegisteredUser() == null) { + // Throw NPE again + throw new NullPointerException("event.registeredUser is null"); //NOI18N + } else if (event.getRegisteredUser().getUserId() == null) { + // userId is null + throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N + } else if (event.getRegisteredUser().getUserId() < 1) { + // Not avalid id + throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getRegisteredUser(), event.getRegisteredUser().getUserId())); //NOI18N + } + + // Get user instance + final Contact registeredContact = event.getRegisteredUser().getUserContact(); + + // Add contact instance only once + this.uniqueAddContact(registeredContact); + } + + @Override + public Contact findContactById (final Long contactId) throws ContactNotFoundException { + // Validate parameter + if (null == contactId) { + // Throw NPE + throw new NullPointerException("contactId is null"); //NOI18N + } else if (contactId < 1) { + // Throw IAE + throw new IllegalArgumentException("contactId=" + contactId + " is invalid"); //NOI18N + } else if (!this.contactCache.containsKey(contactId)) { + // Not found + throw new ContactNotFoundException(contactId); + } + + // Get it from cache + final Contact contact = this.contactCache.get(contactId); + + // Return it + return contact; + } + + /** + * Returns a text representation of given mobile number or null if not set. + *

+ * @param mobileNumber Mobile number + *

+ * @return Text representation or null + */ + public String generateMobileNumber (final DialableMobileNumber mobileNumber) { + // Is it null? + if (null == mobileNumber) { + // Return null + return null; + } + + // Get all data + final String number = String.format( + "%s%d%d", //NOI18N + mobileNumber.getMobileProvider().getProviderCountry().getCountryExternalDialPrefix(), + mobileNumber.getMobileProvider().getProviderDialPrefix(), + mobileNumber.getPhoneNumber() + ); + + // Return it + return number; + } + + /** + * Returns a text representation of given land-line or fax number or null if + * not set. + *

+ * @param phoneNumber Land-line or fax number + *

+ * @return Text representation or null + */ + public String generatePhoneNumber (final DialableNumber phoneNumber) { + // Is it null? + if (null == phoneNumber) { + // Return null + return null; + } + + // Generate it + final String number = String.format( + "%s%d%d", //NOI18N + phoneNumber.getPhoneCountry().getCountryExternalDialPrefix(), + phoneNumber.getPhoneAreaCode(), + phoneNumber.getPhoneNumber() + ); + + // Return it + return number; + } + + @Override + @SuppressWarnings ("ReturnOfCollectionOrArrayField") + public List getAllContacts () { + return this.allContacts; + } + + /** + * Getter for filtered contacts + *

+ * @return + */ + @SuppressWarnings ("ReturnOfCollectionOrArrayField") + public List getFilteredContacts () { + return this.filteredContacts; + } + + /** + * Setter for filtered contacts + *

+ * @param filteredContacts Filtered contacts list + */ + @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter") + public void setFilteredContacts (final List filteredContacts) { + this.filteredContacts = filteredContacts; + } + + /** + * Getter for selected contact + *

+ * @return Selected Contact instance + */ + public Contact getSelectedContact () { + return this.selectedContact; + } + + /** + * Setter for selected contact + *

+ * @param selectedContact + */ + public void setSelectedContact (final Contact selectedContact) { + this.selectedContact = selectedContact; + } + + /** + * Post-construction method + */ + @PostConstruct + public void init () { + // Is cache there? + if (!this.contactCache.iterator().hasNext()) { + // Get whole list from EJB + final List contacts = this.contactBean.allContacts(); + + // Add all + for (final Contact contact : contacts) { + // Add it to cache + this.contactCache.put(contact.getContactId(), contact); + } + } + + // Is cache there and list is not full? + if ((this.getAllContacts().isEmpty()) && (this.contactCache.iterator().hasNext())) { + // Get iterator + final Iterator> iterator = this.contactCache.iterator(); + + // Build up list + while (iterator.hasNext()) { + // GEt next element + final Cache.Entry next = iterator.next(); + + // Add to list + this.getAllContacts().add(next.getValue()); + } + + // Sort list + this.getAllContacts().sort(new Comparator() { + @Override + public int compare (final Contact o1, final Contact o2) { + return o1.getContactId() > o2.getContactId() ? 1 : o1.getContactId() < o2.getContactId() ? -1 : 0; + } + }); + + // Set full list + this.setFilteredContacts(this.getAllContacts()); + } + } + + @Override + public boolean isSameContactFound (final Contact contact) { + // Default is not found + boolean IsFound = false; + + // Get iterator + final Iterator iterator = this.getAllContacts().iterator(); + + // Loop through all + while (iterator.hasNext()) { + // Get next contact + final Contact next = iterator.next(); + + // Is the same? + if (Contacts.isSameContact(contact, next)) { + // Yes, then abort loop + IsFound = false; + break; + } + } + + // Return status + return IsFound; + } + + /** + * Removes given contact from all lists + *

+ * @param contact Contact instance to remove + */ + private void removeContact (final Contact contact) { + // Remove from general list + if (!this.contactCache.remove(contact.getContactId())) { + // Did not remove contact + throw new IllegalStateException(MessageFormat.format("contact {0} was not removed.", contact.getContactId())); //NOI18N + } + } + + /** + * Adds unique instance to contact list. First any existing instance is + * being removed, then the new instance is added. + *

+ * @param contact Contact instance to add uniquely + */ + private void uniqueAddContact (final Contact contact) { + // Get iterator from list + final Iterator> iterator = this.contactCache.iterator(); + + // "Walk" through all entries + while (iterator.hasNext()) { + // Get next element + final Cache.Entry next = iterator.next(); + + // Is id number the same? + if (Objects.equals(contact.getContactId(), next.getKey())) { + // Found entry, so remove it and abort + this.removeContact(next.getValue()); + break; + } + } + + // Add contact to list + this.contactCache.put(contact.getContactId(), contact); + } + +} diff --git a/src/java/org/mxchange/jfinancials/beans/contact/list/FinancialsContactListWebViewController.java b/src/java/org/mxchange/jfinancials/beans/contact/list/FinancialsContactListWebViewController.java new file mode 100644 index 00000000..51d3346e --- /dev/null +++ b/src/java/org/mxchange/jfinancials/beans/contact/list/FinancialsContactListWebViewController.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 - 2020 Free Software Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.mxchange.jfinancials.beans.contact.list; + +import java.io.Serializable; +import java.util.List; +import org.mxchange.jcontacts.exceptions.ContactNotFoundException; +import org.mxchange.jcontacts.model.contact.Contact; + +/** + * An administrative interface for user beans + *

+ * @author Roland Häder + */ +public interface FinancialsContactListWebViewController extends Serializable { + + /** + * Returns a contact instance which has the given id number. + *

+ * @param contactId Contact id + *

+ * @return Contact instance + *

+ * @throws ContactNotFoundException If the contact was not found + */ + Contact findContactById (final Long contactId) throws ContactNotFoundException; + + /** + * Checks whether the given contact is found + *

+ * @param contact Contact instance + * + * @return Whether contact has been found + */ + boolean isSameContactFound (final Contact contact); + + /** + * Getter for all contacts + * + * @return All contact + */ + @SuppressWarnings ("ReturnOfCollectionOrArrayField") + List getAllContacts (); + +} diff --git a/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestBean.java index 54805fe2..1be5d85e 100644 --- a/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestBean.java +++ b/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestBean.java @@ -33,7 +33,7 @@ import org.mxchange.jcontacts.events.landline.unlinked.ObservableAdminUnlinkedLa import org.mxchange.jcontacts.events.mobile.unlinked.ObservableAdminUnlinkedMobileNumberEvent; import org.mxchange.jcontacts.model.contact.Contact; import org.mxchange.jfinancials.beans.BaseFinancialsBean; -import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestController; +import org.mxchange.jfinancials.beans.contact.list.FinancialsContactListWebViewController; import org.mxchange.jphone.events.fax.created.ObservableCreatedFaxNumberEvent; import org.mxchange.jphone.events.landline.created.ObservableCreatedLandLineNumberEvent; import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent; @@ -58,10 +58,10 @@ public class FinancialsContactPhoneWebRequestBean extends BaseFinancialsBean imp private static final long serialVersionUID = 542_145_347_916L; /** - * General contact controller + * An instance of a contact-list controller */ @Inject - private FinancialsContactWebRequestController contactController; + private FinancialsContactListWebViewController contactListController; /** * "Cache" for contact's mobile, land-line and fax numbers. Currently one @@ -338,7 +338,7 @@ public class FinancialsContactPhoneWebRequestBean extends BaseFinancialsBean imp *

* @return List of all linked contacts */ - public List allCurrentFaxNumberContacts () { + public List getAllCurrentFaxNumberContacts () { // Get id final DialableFaxNumber number = this.getFaxNumber(); @@ -351,7 +351,7 @@ public class FinancialsContactPhoneWebRequestBean extends BaseFinancialsBean imp final List list = new LinkedList<>(); // "Walk" through all contacts - for (final Contact contact : this.contactController.allContacts()) { + for (final Contact contact : this.contactListController.getAllContacts()) { // Is mobile instance the same? if (Objects.equals(contact.getContactFaxNumber(), number)) { // Found one @@ -385,7 +385,7 @@ public class FinancialsContactPhoneWebRequestBean extends BaseFinancialsBean imp final List list = new LinkedList<>(); // "Walk" through all contacts - for (final Contact contact : this.contactController.allContacts()) { + for (final Contact contact : this.contactListController.getAllContacts()) { // Is mobile instance the same? if (Objects.equals(contact.getContactLandLineNumber(), number)) { // Found one @@ -419,7 +419,7 @@ public class FinancialsContactPhoneWebRequestBean extends BaseFinancialsBean imp final List list = new LinkedList<>(); // "Walk" through all contacts - for (final Contact contact : this.contactController.allContacts()) { + for (final Contact contact : this.contactListController.getAllContacts()) { // Is mobile instance the same? if (Objects.equals(contact.getContactMobileNumber(), number)) { // Found one diff --git a/src/java/org/mxchange/jfinancials/converter/contact/FinancialsContactConverter.java b/src/java/org/mxchange/jfinancials/converter/contact/FinancialsContactConverter.java index e619ea31..75248375 100644 --- a/src/java/org/mxchange/jfinancials/converter/contact/FinancialsContactConverter.java +++ b/src/java/org/mxchange/jfinancials/converter/contact/FinancialsContactConverter.java @@ -24,8 +24,8 @@ import javax.faces.convert.ConverterException; import javax.faces.convert.FacesConverter; import org.mxchange.jcontacts.exceptions.ContactNotFoundException; import org.mxchange.jcontacts.model.contact.Contact; -import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestBean; -import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestController; +import org.mxchange.jfinancials.beans.contact.list.FinancialsContactListWebViewBean; +import org.mxchange.jfinancials.beans.contact.list.FinancialsContactListWebViewController; /** * Converter for contact id <-> valid contact instance @@ -38,14 +38,14 @@ public class FinancialsContactConverter implements Converter { /** * Contact EJB */ - private static FinancialsContactWebRequestController CONTACT_CONTROLLER; + private static FinancialsContactListWebViewController CONTACT_LIST_CONTROLLER; @Override public Contact getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) { // Is the instance there? - if (null == CONTACT_CONTROLLER) { + if (null == CONTACT_LIST_CONTROLLER) { // Get bean from CDI directly - CONTACT_CONTROLLER = CDI.current().select(FinancialsContactWebRequestBean.class).get(); + CONTACT_LIST_CONTROLLER = CDI.current().select(FinancialsContactListWebViewBean.class).get(); } // Is the value null or empty? @@ -65,7 +65,7 @@ public class FinancialsContactConverter implements Converter { final Long contactId = Long.valueOf(submittedValue); // Try to get user instance from it - contact = CONTACT_CONTROLLER.findContactById(contactId); + contact = CONTACT_LIST_CONTROLLER.findContactById(contactId); } catch (final NumberFormatException ex) { // Throw again throw new ConverterException(ex); diff --git a/web/admin/contact/admin_contact_list.xhtml b/web/admin/contact/admin_contact_list.xhtml index eec56139..15ce9664 100644 --- a/web/admin/contact/admin_contact_list.xhtml +++ b/web/admin/contact/admin_contact_list.xhtml @@ -23,18 +23,68 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + - - - - - - + - - - - - + - - - - - + - - - - - + - - - - - + + + + + + + + + + + + + + + + + diff --git a/web/admin/fax/admin_fax_show.xhtml b/web/admin/fax/admin_fax_show.xhtml index 32e13320..1c52c3ed 100644 --- a/web/admin/fax/admin_fax_show.xhtml +++ b/web/admin/fax/admin_fax_show.xhtml @@ -30,7 +30,7 @@ diff --git a/web/admin/user/admin_user_list.xhtml b/web/admin/user/admin_user_list.xhtml index eeda9a55..f99488b0 100644 --- a/web/admin/user/admin_user_list.xhtml +++ b/web/admin/user/admin_user_list.xhtml @@ -226,7 +226,7 @@