]> git.mxchange.org Git - jfinancials-war.git/commitdiff
Please rename/cherry-pick:
authorRoland Häder <roland@mxchange.org>
Sat, 2 Sep 2017 19:52:41 +0000 (21:52 +0200)
committerRoland Häder <roland@mxchange.org>
Sat, 2 Sep 2017 19:52:41 +0000 (21:52 +0200)
- having to much session-scoped beans was a bad design idea anyway
- on each new session, "tons" of EJB (JNDI lookup + business method invocation)
  will occur which will overrun the EJB container soon or later
- also having JNDI lookup in PostConstruct-annotated methods was bad, too
  because it "confuses" the web container
- while it is building proxy objects arround every managed class (like also now
  converters, JSF 2.3.x only) especially backing beans, there should be no JNDI
  lookup hapening
- but initializing some lists for performance reasons is the right thing to do
- maybe later some other annotation will be used instead, but for now it is fine
- so let's make this painless and rename all session-scoped backing beans and
  re-annotate them with RequestScoped for now as this is also reduces memory
  foot-print

Signed-off-by: Roland Häder <roland@mxchange.org>
58 files changed:
src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebSessionBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/business/employee/FinancialsCompanyEmployeeWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/business/employee/FinancialsCompanyEmployeeWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/business/employee/FinancialsCompanyEmployeeWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/contact/FinancialsAdminContactWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebSessionBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebSessionBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/country/FinancialsAdminCountryWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebApplicationBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebApplicationController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebSessionBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/helper/FinancialsWebRequestHelperBean.java
src/java/org/mxchange/jfinancials/beans/mobileprovider/FinancialsMobileProviderWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/phone/FinancialsAdminPhoneWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebApplicationBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebApplicationController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/profile/FinancialsUserProfileWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/user/FinancialsAdminUserWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebSessionBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebApplicationBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebApplicationController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/confirmlink/FinancialsConfirmationLinkWebRequestBean.java
src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebSessionBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/login/FinancialsUserLoginWebSessionBean.java
src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebSessionBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebRequestBean.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebRequestController.java [new file with mode: 0644]
src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebSessionBean.java [deleted file]
src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebSessionController.java [deleted file]
src/java/org/mxchange/jfinancials/converter/mobileprovider/FinancialsMobileProviderConverter.java
web/guest/user/user_list.xhtml

diff --git a/src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebRequestBean.java
new file mode 100644 (file)
index 0000000..ea14c63
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.business.basicdata;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontactsbusiness.basicdata.AdminBusinessDataSessionBeanRemote;
+import org.mxchange.jcontactsbusiness.basicdata.BusinessBasicData;
+import org.mxchange.jcontactsbusiness.basicdata.BusinessDataSessionBeanRemote;
+import org.mxchange.jcontactsbusiness.events.basicdata.added.ObservableAdminAddedBusinessBasicDataEvent;
+import org.mxchange.jcoreee.jcache.Cached;
+import org.mxchange.jcountry.data.Country;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
+
+/**
+ * A business contact bean (controller)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("companyDataController")
+@RequestScoped
+public class FinancialsBusinessDataWebRequestBean extends BaseFinancialsController implements FinancialsBusinessDataWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 56_189_028_928_371L;
+
+       /**
+        * EJB for administrative basic business data purposes
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/adminBusinessData!org.mxchange.jcontactsbusiness.basicdata.AdminBusinessDataSessionBeanRemote", description = "A stateless session bean for administrative purposes.")
+       private AdminBusinessDataSessionBeanRemote adminBusinessDataBean;
+
+       /**
+        * A list of all registered companies (globally)
+        */
+       @Inject
+       @Cached (cacheName = "basicDataCache")
+       private transient Cache<Long, BusinessBasicData> basicDataCache;
+
+       /**
+        * EJB for general basic business data purposes
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/businessData!org.mxchange.jcontactsbusiness.basicdata.BusinessDataSessionBeanRemote", description = "A stateless session bean for general purposes.")
+       private BusinessDataSessionBeanRemote businessDataBean;
+
+       /**
+        * Comments for this company
+        */
+       private String companyComments;
+
+       /**
+        * Companies (main) email address (example: info@company.example)
+        */
+       private String companyEmailAddress;
+
+       /**
+        * Company cacheName
+        */
+       private String companyName;
+
+       /**
+        * Area code for fax number
+        */
+       private Integer faxAreaCode;
+
+       /**
+        * Country for fax number
+        */
+       private Country faxCountry;
+
+       /**
+        * Dial number for fax number
+        */
+       private Long faxNumber;
+
+       /**
+        * Area code for land-line number
+        */
+       private Integer landLineAreaCode;
+
+       /**
+        * Country for land-line number
+        */
+       private Country landLineCountry;
+
+       /**
+        * Dial number for land-line number
+        */
+       private Long landLineNumber;
+
+       /**
+        * User instance
+        */
+       @Inject
+       private FinancialsUserLoginWebSessionController userLoginController;
+
+       /**
+        * Constructor
+        */
+       public FinancialsBusinessDataWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Observers events being fired when an administrator has added company
+        * basic data.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminAddedBasicCompanyDataEvent (@Observes final ObservableAdminAddedBusinessBasicDataEvent event) {
+               // Is the parameter valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null");
+               } else if (event.getBasicData() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.basicData is null");
+               } else if (event.getBasicData().getCompanyDataId() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.basicData.companyDataId is null");
+               } else if (event.getBasicData().getCompanyDataId() < 1) {
+                       // Throw IAE
+                       throw new IllegalArgumentException(MessageFormat.format("event.basicData.companyDataId={0} is invalid", event.getBasicData().getCompanyDataId()));
+               } else if (event.getBasicData().getCompanyName() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.basicData.companyName is null");
+               } else if (event.getBasicData().getCompanyName().isEmpty()) {
+                       // Throw IAE again
+                       throw new IllegalArgumentException("event.basicData.companyName is empty");
+               }
+
+               // Add it to list
+               this.basicDataCache.put(event.getBasicData().getCompanyDataId(), event.getBasicData());
+       }
+
+       /**
+        * Returns a list of all business contacts
+        * <p>
+        * @return A list of all business contacts
+        */
+       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+       public List<BusinessBasicData> allCompanyBasicData () {
+               // Init list
+               List<BusinessBasicData> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, BusinessBasicData>> iterator = this.basicDataCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, BusinessBasicData> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
+       }
+
+       /**
+        * Getter for comments
+        * <p>
+        * @return Comments
+        */
+       public String getCompanyComments () {
+               return this.companyComments;
+       }
+
+       /**
+        * Setter for comments
+        * <p>
+        * @param companyComments Comments
+        */
+       public void setCompanyComments (final String companyComments) {
+               this.companyComments = companyComments;
+       }
+
+       /**
+        * Getter for company's (main) email address
+        * <p>
+        * @return Company's (main) email address
+        */
+       public String getCompanyEmailAddress () {
+               return this.companyEmailAddress;
+       }
+
+       /**
+        * Setter for company's (main) email address
+        * <p>
+        * @param companyEmailAddress Company's (main) email address
+        */
+       public void setCompanyEmailAddress (final String companyEmailAddress) {
+               this.companyEmailAddress = companyEmailAddress;
+       }
+
+       /**
+        * Getter for company cacheName
+        * <p>
+        * @return Company cacheName
+        */
+       public String getCompanyName () {
+               return this.companyName;
+       }
+
+       /**
+        * Setter for company cacheName
+        * <p>
+        * @param companyName Company cacheName
+        */
+       public void setCompanyName (final String companyName) {
+               this.companyName = companyName;
+       }
+
+       /**
+        * Getter for fax number's area code
+        * <p>
+        * @return Fax number's area code
+        */
+       public Integer getFaxAreaCode () {
+               return this.faxAreaCode;
+       }
+
+       /**
+        * Setter for fax number's area code
+        * <p>
+        * @param faxAreaCode Fax number's area code
+        */
+       public void setFaxAreaCode (final Integer faxAreaCode) {
+               this.faxAreaCode = faxAreaCode;
+       }
+
+       /**
+        * Getter for fax's country instance
+        * <p>
+        * @return Fax' country instance
+        */
+       public Country getFaxCountry () {
+               return this.faxCountry;
+       }
+
+       /**
+        * Setter for fax's country instance
+        * <p>
+        * @param faxCountry Fax' country instance
+        */
+       public void setFaxCountry (final Country faxCountry) {
+               this.faxCountry = faxCountry;
+       }
+
+       /**
+        * Getter for fax number
+        * <p>
+        * @return Fax number
+        */
+       public Long getFaxNumber () {
+               return this.faxNumber;
+       }
+
+       /**
+        * Setter for fax number
+        * <p>
+        * @param faxNumber Fax number
+        */
+       public void setFaxNumber (final Long faxNumber) {
+               this.faxNumber = faxNumber;
+       }
+
+       /**
+        * Getter for land-line number's area code
+        * <p>
+        * @return Land-line number's area code
+        */
+       public Integer getLandLineAreaCode () {
+               return this.landLineAreaCode;
+       }
+
+       /**
+        * Setter for land-line number's area code
+        * <p>
+        * @param landLineAreaCode Land-line number's area code
+        */
+       public void setLandLineAreaCode (final Integer landLineAreaCode) {
+               this.landLineAreaCode = landLineAreaCode;
+       }
+
+       /**
+        * Getter for land-line number's country instance
+        * <p>
+        * @return Land-line number's country instance
+        */
+       public Country getLandLineCountry () {
+               return this.landLineCountry;
+       }
+
+       /**
+        * Setter for land-line number's country instance
+        * <p>
+        * @param landLineCountry Land-line number's country instance
+        */
+       public void setLandLineCountry (final Country landLineCountry) {
+               this.landLineCountry = landLineCountry;
+       }
+
+       /**
+        * Getter for land-line number
+        * <p>
+        * @return Land-line number
+        */
+       public Long getLandLineNumber () {
+               return this.landLineNumber;
+       }
+
+       /**
+        * Setter for land-line number
+        * <p>
+        * @param landLineNumber Land-line number
+        */
+       public void setLandLineNumber (final Long landLineNumber) {
+               this.landLineNumber = landLineNumber;
+       }
+
+       /**
+        * Initializer method
+        */
+       @PostConstruct
+       public void initializeList () {
+               // Is cache there?
+               if (!this.basicDataCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<BusinessBasicData> list = this.businessDataBean.allCompanyBasicData();
+
+                       // Add all
+                       for (final Iterator<BusinessBasicData> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final BusinessBasicData next = iterator.next();
+
+                               // Add it to cache
+                               this.basicDataCache.put(next.getCompanyDataId(), next);
+                       }
+               }
+       }
+
+       /**
+        * Clears this bean
+        */
+       private void clear () {
+               // Clear all data:
+               this.setCompanyComments(null);
+               this.setCompanyEmailAddress(null);
+               this.setCompanyName(null);
+               this.setFaxAreaCode(null);
+               this.setFaxCountry(null);
+               this.setFaxNumber(null);
+               this.setLandLineAreaCode(null);
+               this.setLandLineCountry(null);
+               this.setLandLineNumber(null);
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebRequestController.java
new file mode 100644 (file)
index 0000000..990aa91
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.business.basicdata;
+
+import java.io.Serializable;
+
+/**
+ * An interface for session-scoped financial controller
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsBusinessDataWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebSessionBean.java b/src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebSessionBean.java
deleted file mode 100644 (file)
index f0505ce..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.business.basicdata;
-
-import java.text.MessageFormat;
-import java.util.LinkedList;
-import java.util.List;
-import javax.annotation.PostConstruct;
-import javax.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jcontactsbusiness.basicdata.AdminBusinessDataSessionBeanRemote;
-import org.mxchange.jcontactsbusiness.basicdata.BusinessBasicData;
-import org.mxchange.jcontactsbusiness.basicdata.BusinessDataSessionBeanRemote;
-import org.mxchange.jcontactsbusiness.events.basicdata.added.ObservableAdminAddedBusinessBasicDataEvent;
-import org.mxchange.jcountry.data.Country;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
-
-/**
- * A business contact bean (controller)
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("companyDataController")
-@SessionScoped
-public class FinancialsBusinessDataWebSessionBean extends BaseFinancialsController implements FinancialsBusinessDataWebSessionController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 56_189_028_928_371L;
-
-       /**
-        * EJB for administrative basic business data purposes
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/adminBusinessData!org.mxchange.jcontactsbusiness.basicdata.AdminBusinessDataSessionBeanRemote", description = "A stateless session bean for administrative purposes.")
-       private AdminBusinessDataSessionBeanRemote adminBusinessDataBean;
-
-       /**
-        * A list of all registered companies (globally)
-        */
-       private final List<BusinessBasicData> businessContacts;
-
-       /**
-        * EJB for general basic business data purposes
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/businessData!org.mxchange.jcontactsbusiness.basicdata.BusinessDataSessionBeanRemote", description = "A stateless session bean for general purposes.")
-       private BusinessDataSessionBeanRemote businessDataBean;
-
-       /**
-        * Comments for this company
-        */
-       private String companyComments;
-
-       /**
-        * Companies (main) email address (example: info@company.example)
-        */
-       private String companyEmailAddress;
-
-       /**
-        * Company name
-        */
-       private String companyName;
-
-       /**
-        * Area code for fax number
-        */
-       private Integer faxAreaCode;
-
-       /**
-        * Country for fax number
-        */
-       private Country faxCountry;
-
-       /**
-        * Dial number for fax number
-        */
-       private Long faxNumber;
-
-       /**
-        * Area code for land-line number
-        */
-       private Integer landLineAreaCode;
-
-       /**
-        * Country for land-line number
-        */
-       private Country landLineCountry;
-
-       /**
-        * Dial number for land-line number
-        */
-       private Long landLineNumber;
-
-       /**
-        * User instance
-        */
-       @Inject
-       private FinancialsUserLoginWebSessionController userLoginController;
-
-       /**
-        * Constructor
-        */
-       public FinancialsBusinessDataWebSessionBean () {
-               // Call super constructor
-               super();
-
-               // Init list
-               this.businessContacts = new LinkedList<>();
-       }
-
-       /**
-        * Observers events being fired when an administrator has added company
-        * basic data.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminAddedBasicCompanyDataEvent (@Observes final ObservableAdminAddedBusinessBasicDataEvent event) {
-               // Is the parameter valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null");
-               } else if (event.getBasicData() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.basicData is null");
-               } else if (event.getBasicData().getCompanyDataId() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.basicData.companyDataId is null");
-               } else if (event.getBasicData().getCompanyDataId() < 1) {
-                       // Throw IAE
-                       throw new IllegalArgumentException(MessageFormat.format("event.basicData.companyDataId={0} is invalid", event.getBasicData().getCompanyDataId()));
-               } else if (event.getBasicData().getCompanyName() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.basicData.companyName is null");
-               } else if (event.getBasicData().getCompanyName().isEmpty()) {
-                       // Throw IAE again
-                       throw new IllegalArgumentException("event.basicData.companyName is empty");
-               }
-
-               // Add it to list
-               this.businessContacts.add(event.getBasicData());
-       }
-
-       /**
-        * Returns a list of all business contacts
-        * <p>
-        * @return A list of all business contacts
-        */
-       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
-       public List<BusinessBasicData> allCompanyBasicData () {
-               // Return it
-               return this.businessContacts;
-       }
-
-       /**
-        * Getter for comments
-        * <p>
-        * @return Comments
-        */
-       public String getCompanyComments () {
-               return this.companyComments;
-       }
-
-       /**
-        * Setter for comments
-        * <p>
-        * @param companyComments Comments
-        */
-       public void setCompanyComments (final String companyComments) {
-               this.companyComments = companyComments;
-       }
-
-       /**
-        * Getter for company's (main) email address
-        * <p>
-        * @return Company's (main) email address
-        */
-       public String getCompanyEmailAddress () {
-               return this.companyEmailAddress;
-       }
-
-       /**
-        * Setter for company's (main) email address
-        * <p>
-        * @param companyEmailAddress Company's (main) email address
-        */
-       public void setCompanyEmailAddress (final String companyEmailAddress) {
-               this.companyEmailAddress = companyEmailAddress;
-       }
-
-       /**
-        * Getter for company name
-        * <p>
-        * @return Company name
-        */
-       public String getCompanyName () {
-               return this.companyName;
-       }
-
-       /**
-        * Setter for company name
-        * <p>
-        * @param companyName Company name
-        */
-       public void setCompanyName (final String companyName) {
-               this.companyName = companyName;
-       }
-
-       /**
-        * Getter for fax number's area code
-        * <p>
-        * @return Fax number's area code
-        */
-       public Integer getFaxAreaCode () {
-               return this.faxAreaCode;
-       }
-
-       /**
-        * Setter for fax number's area code
-        * <p>
-        * @param faxAreaCode Fax number's area code
-        */
-       public void setFaxAreaCode (final Integer faxAreaCode) {
-               this.faxAreaCode = faxAreaCode;
-       }
-
-       /**
-        * Getter for fax's country instance
-        * <p>
-        * @return Fax' country instance
-        */
-       public Country getFaxCountry () {
-               return this.faxCountry;
-       }
-
-       /**
-        * Setter for fax's country instance
-        * <p>
-        * @param faxCountry Fax' country instance
-        */
-       public void setFaxCountry (final Country faxCountry) {
-               this.faxCountry = faxCountry;
-       }
-
-       /**
-        * Getter for fax number
-        * <p>
-        * @return Fax number
-        */
-       public Long getFaxNumber () {
-               return this.faxNumber;
-       }
-
-       /**
-        * Setter for fax number
-        * <p>
-        * @param faxNumber Fax number
-        */
-       public void setFaxNumber (final Long faxNumber) {
-               this.faxNumber = faxNumber;
-       }
-
-       /**
-        * Getter for land-line number's area code
-        * <p>
-        * @return Land-line number's area code
-        */
-       public Integer getLandLineAreaCode () {
-               return this.landLineAreaCode;
-       }
-
-       /**
-        * Setter for land-line number's area code
-        * <p>
-        * @param landLineAreaCode Land-line number's area code
-        */
-       public void setLandLineAreaCode (final Integer landLineAreaCode) {
-               this.landLineAreaCode = landLineAreaCode;
-       }
-
-       /**
-        * Getter for land-line number's country instance
-        * <p>
-        * @return Land-line number's country instance
-        */
-       public Country getLandLineCountry () {
-               return this.landLineCountry;
-       }
-
-       /**
-        * Setter for land-line number's country instance
-        * <p>
-        * @param landLineCountry Land-line number's country instance
-        */
-       public void setLandLineCountry (final Country landLineCountry) {
-               this.landLineCountry = landLineCountry;
-       }
-
-       /**
-        * Getter for land-line number
-        * <p>
-        * @return Land-line number
-        */
-       public Long getLandLineNumber () {
-               return this.landLineNumber;
-       }
-
-       /**
-        * Setter for land-line number
-        * <p>
-        * @param landLineNumber Land-line number
-        */
-       public void setLandLineNumber (final Long landLineNumber) {
-               this.landLineNumber = landLineNumber;
-       }
-
-       /**
-        * Initializer method
-        */
-       @PostConstruct
-       public void initializeList () {
-               // Init user's contact list
-               this.businessContacts.addAll(this.adminBusinessDataBean.allCompanyBasicData());
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/business/basicdata/FinancialsBusinessDataWebSessionController.java
deleted file mode 100644 (file)
index 60b1397..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.business.basicdata;
-
-import java.io.Serializable;
-
-/**
- * An interface for session-scoped financial controller
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsBusinessDataWebSessionController extends Serializable {
-
-}
index 8d8307a28a5ab57ca2ed7cc7385f14f525a484a0..9b00752df139eb81bcd78f5d3b6dd8889c4ed5d8 100644 (file)
  */
 package org.mxchange.jfinancials.beans.business.employee;
 
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import javax.annotation.PostConstruct;
+import javax.cache.Cache;
 import javax.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
 import javax.inject.Named;
 import org.mxchange.jcontactsbusiness.employee.CompanyEmployeeSessionBeanRemote;
 import org.mxchange.jcontactsbusiness.employee.Employee;
+import org.mxchange.jcoreee.jcache.Cached;
 import org.mxchange.jfinancials.beans.BaseFinancialsController;
 
 /**
@@ -32,8 +36,8 @@ import org.mxchange.jfinancials.beans.BaseFinancialsController;
  * @author Roland Häder<roland@mxchange.org>
  */
 @Named ("companyEmployeeController")
-@SessionScoped
-public class FinancialsCompanyEmployeeWebRequestBean extends BaseFinancialsController implements FinancialsCompanyEmployeeWebSessionController {
+@RequestScoped
+public class FinancialsCompanyEmployeeWebRequestBean extends BaseFinancialsController implements FinancialsCompanyEmployeeWebRequestController {
 
        /**
         * Serial number
@@ -49,7 +53,9 @@ public class FinancialsCompanyEmployeeWebRequestBean extends BaseFinancialsContr
        /**
         * List of all company employees
         */
-       private final List<Employee> companyEmployees;
+       @Inject
+       @Cached(cacheName = "companyEmployeeCache")
+       private transient Cache<Long, Employee> companyEmployeeCache;
 
        /**
         * Default constructor
@@ -57,9 +63,6 @@ public class FinancialsCompanyEmployeeWebRequestBean extends BaseFinancialsContr
        public FinancialsCompanyEmployeeWebRequestBean () {
                // Call super constructor
                super();
-
-               // Init list instance
-               this.companyEmployees = new LinkedList<>();
        }
 
        /**
@@ -69,7 +72,23 @@ public class FinancialsCompanyEmployeeWebRequestBean extends BaseFinancialsContr
         */
        @SuppressWarnings ("ReturnOfCollectionOrArrayField")
        public List<Employee> allCompanyEmployees () {
-               return this.companyEmployees;
+               // Init list
+               List<Employee> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, Employee>> iterator = this.companyEmployeeCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, Employee> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
        }
 
        /**
@@ -77,11 +96,20 @@ public class FinancialsCompanyEmployeeWebRequestBean extends BaseFinancialsContr
         */
        @PostConstruct
        public void init () {
-               // Get all entries from remote bean
-               List<Employee> employees = this.companyEmployeeBean.allCompanyEmployees();
+               // Is cache there?
+               if (!this.companyEmployeeCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<Employee> list = this.companyEmployeeBean.allCompanyEmployees();
+
+                       // Add all
+                       for (final Iterator<Employee> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final Employee next = iterator.next();
 
-               // Copy it to main list
-               this.companyEmployees.addAll(employees);
+                               // Add it to cache
+                               this.companyEmployeeCache.put(next.getEmployeeId(), next);
+                       }
+               }
        }
 
 }
diff --git a/src/java/org/mxchange/jfinancials/beans/business/employee/FinancialsCompanyEmployeeWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/business/employee/FinancialsCompanyEmployeeWebRequestController.java
new file mode 100644 (file)
index 0000000..ef6bd14
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.business.employee;
+
+import java.io.Serializable;
+
+/**
+ * An interface for request-scoped general company employee beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsCompanyEmployeeWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/business/employee/FinancialsCompanyEmployeeWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/business/employee/FinancialsCompanyEmployeeWebSessionController.java
deleted file mode 100644 (file)
index 80e14ad..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.business.employee;
-
-import java.io.Serializable;
-
-/**
- * An interface for request-scoped general company employee beans
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsCompanyEmployeeWebSessionController extends Serializable {
-
-}
index a5f3d1aa0de3f7de1ba051e0ffb0de0c906ce145..7f5c540057455ba217d3f04b253abc8297091ae3 100644 (file)
@@ -107,7 +107,7 @@ public class FinancialsAdminContactWebRequestBean extends BaseFinancialsControll
         * General contact controller
         */
        @Inject
-       private FinancialsContactWebSessionController contactController;
+       private FinancialsContactWebRequestController contactController;
 
        /**
         * Country instance
diff --git a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebRequestBean.java
new file mode 100644 (file)
index 0000000..8d47e2b
--- /dev/null
@@ -0,0 +1,1329 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.contact;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+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.contact.Contact;
+import org.mxchange.jcontacts.contact.ContactSessionBeanRemote;
+import org.mxchange.jcontacts.contact.ContactUtils;
+import org.mxchange.jcontacts.contact.UserContact;
+import org.mxchange.jcontacts.contact.title.PersonalTitle;
+import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
+import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
+import org.mxchange.jcoreee.jcache.Cached;
+import org.mxchange.jcountry.data.Country;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
+import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
+import org.mxchange.jphone.phonenumbers.fax.FaxNumber;
+import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
+import org.mxchange.jphone.phonenumbers.landline.LandLineNumber;
+import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
+import org.mxchange.jphone.phonenumbers.mobile.MobileNumber;
+import org.mxchange.jphone.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;
+import org.mxchange.jfinancials.beans.user.FinancialsUserWebRequestController;
+
+/**
+ * A general contact bean (controller)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("contactController")
+@RequestScoped
+public class FinancialsContactWebRequestBean extends BaseFinancialsController implements FinancialsContactWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 542_145_347_916L;
+
+       /**
+        * Academic academicTitle
+        */
+       private String academicTitle;
+
+       /**
+        * Birth day
+        */
+       private Date birthday;
+
+       /**
+        * City
+        */
+       private String city;
+
+       /**
+        * Optional comments
+        */
+       private String comment;
+
+       /**
+        * EJB for general contact purposes
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/contact!org.mxchange.jcontacts.contact.ContactSessionBeanRemote")
+       private ContactSessionBeanRemote contactBean;
+
+       /**
+        * Contact list
+        */
+       @Inject
+       @Cached (cacheName = "contactsCache")
+       private transient Cache<Long, Contact> contactsCache;
+
+       /**
+        * Country instance
+        */
+       private Country country;
+
+       /**
+        * Email address
+        */
+       private String emailAddress;
+
+       /**
+        * Email address list
+        */
+       @Inject
+       @Cached (cacheName = "emailAddressCache")
+       private transient Cache<Long, String> emailAddressCache;
+
+       /**
+        * Email address repeated
+        */
+       private String emailAddressRepeat;
+
+       /**
+        * Family name
+        */
+       private String familyName;
+
+       /**
+        * Fax number's area code
+        */
+       private Integer faxAreaCode;
+
+       /**
+        * Country instance for fax number
+        */
+       private Country faxCountry;
+
+       /**
+        * Fax number
+        */
+       private Long faxNumber;
+
+       /**
+        * First name
+        */
+       private String firstName;
+
+       /**
+        * House number
+        */
+       private Short houseNumber;
+
+       /**
+        * House number extension
+        */
+       private String houseNumberExtension;
+
+       /**
+        * Whether a fax entry has been unlinked
+        */
+       private boolean isFaxUnlinked;
+
+       /**
+        * Whether a land-line number has been unlinked
+        */
+       private boolean isLandLineUnlinked;
+
+       /**
+        * Whether a mobile entry has been unlinked
+        */
+       private boolean isMobileUnlinked;
+
+       /**
+        * Phone number area code
+        */
+       private Integer landLineAreaCode;
+
+       /**
+        * Country instance for phone number
+        */
+       private Country landLineCountry;
+
+       /**
+        * Phone number
+        */
+       private Long landLineNumber;
+
+       /**
+        * Mobile number
+        */
+       private Long mobileNumber;
+
+       /**
+        * Mobile number's carrier
+        */
+       private MobileProvider mobileProvider;
+
+       /**
+        * Personal academicTitle
+        */
+       private PersonalTitle personalTitle;
+
+       /**
+        * A list of all selectable contacts
+        */
+       private List<Contact> selectableContacts;
+
+       /**
+        * Street
+        */
+       private String street;
+
+       /**
+        * Regular user controller
+        */
+       @Inject
+       private FinancialsUserWebRequestController userController;
+
+       /**
+        * Login bean (controller)
+        */
+       @Inject
+       private FinancialsUserLoginWebSessionController userLoginController;
+
+       /**
+        * ZIP code
+        */
+       private Integer zipCode;
+
+       /**
+        * Default constructor
+        */
+       public FinancialsContactWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Observes events being fired when an administrator has added a new
+        * contact.
+        * <p>
+        * @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.selectableContacts.add(event.getAddedContact());
+       }
+
+       /**
+        * Event observer for newly added users by administrator
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getAddedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.addedUser is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+               }
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when an administrator has linked a new user
+        * with existing contact data.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLinkedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.linkedUser is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserContact() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.linkedUser.userContact is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserContact().getContactId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.linkedUser.userContact.contactId is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserContact().getContactId() < 1) {
+                       // Not avalid id
+                       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.selectableContacts.remove(event.getLinkedUser().getUserContact());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Event observer for updated contact data by administrators
+        * <p>
+        * @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.
+        * <p>
+        * @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
+        * <p>
+        * @param event Event instance
+        */
+       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLoggedInUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.loggedInUser is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
+               }
+
+               // Copy all data to this bean
+               this.copyContact(event.getLoggedInUser().getUserContact());
+       }
+
+       /**
+        * Event observer for new user registrations
+        * <p>
+        * @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
+               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<Contact> allContacts () {
+               // Init list
+               List<Contact> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, Contact>> iterator = this.contactsCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, Contact> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
+       }
+
+       @Override
+       public void clearEmailAddresses () {
+               // Clear both
+               this.setEmailAddress(null);
+               this.setEmailAddressRepeat(null);
+       }
+
+       @Override
+       public Contact createContactInstance () {
+               // Is all required data set?
+               if (!this.isRequiredPersonalDataSet()) {
+                       // No, then abort here
+                       throw new FaceletException(new IllegalArgumentException("Not all personal data is set, but createContactInstance() is called.")); //NOI18N
+               }
+
+               // Required personal data must be set
+               assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
+
+               // Generate phone number
+               DialableLandLineNumber phone = new LandLineNumber(this.getLandLineCountry(), this.getLandLineAreaCode(), this.getLandLineNumber());
+               DialableMobileNumber mobile = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
+               DialableFaxNumber fax = new FaxNumber(this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber());
+
+               // Create new contact
+               Contact contact = new UserContact(this.getPersonalTitle(), this.getFirstName(), this.getFamilyName());
+               contact.setContactStreet(this.getStreet());
+               contact.setContactHouseNumber(this.getHouseNumber());
+               contact.setContactHouseNumberExtension(this.getHouseNumberExtension());
+               contact.setContactZipCode(this.getZipCode());
+               contact.setContactCity(this.getCity());
+               contact.setContactCountry(this.getCountry());
+               contact.setContactEmailAddress(this.getEmailAddress());
+               contact.setContactBirthday(this.getBirthday());
+               contact.setContactComment(this.getComment());
+
+               // Don't set null or wrong references
+               if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneCountry() instanceof Country) && (this.getLandLineAreaCode() != null) && (this.getLandLineNumber() != null) && (this.getLandLineAreaCode() > 0) && (this.getLandLineNumber() > 0)) {
+                       // Now the number must be given
+                       if (phone.getPhoneAreaCode() == null) {
+                               // Is null
+                               throw new NullPointerException("phone.phoneAreaCode is null"); //NOI18N
+                       } else if (phone.getPhoneAreaCode() < 1) {
+                               // Abort here
+                               throw new IllegalArgumentException("phone.phoneAreaCode is zero or below."); //NOI18N
+                       } else if (phone.getPhoneNumber() == null) {
+                               // Is null
+                               throw new NullPointerException("phone.phoneNumber is null"); //NOI18N
+                       } else if (phone.getPhoneNumber() < 1) {
+                               // Abort here
+                               throw new IllegalArgumentException("phone.phoneNumber is zero or below."); //NOI18N
+                       }
+
+                       // Set phone number
+                       contact.setContactLandLineNumber(phone);
+               }
+
+               // Don't set null or wrong references
+               if ((fax instanceof DialableFaxNumber) && (fax.getPhoneCountry() instanceof Country) && (this.getFaxAreaCode() != null) && (this.getFaxNumber() != null) && (this.getFaxAreaCode() > 0) && (this.getFaxNumber() > 0)) {
+                       // Now the number must be given
+                       if (fax.getPhoneAreaCode() == null) {
+                               // Is null
+                               throw new NullPointerException("fax.phoneAreaCode is null"); //NOI18N
+                       } else if (fax.getPhoneAreaCode() < 1) {
+                               // Abort here
+                               throw new IllegalArgumentException("fax.phoneAreaCode is zero or below."); //NOI18N
+                       } else if (fax.getPhoneNumber() == null) {
+                               // Is null
+                               throw new NullPointerException("fax.phoneNumber is null"); //NOI18N
+                       } else if (fax.getPhoneNumber() < 1) {
+                               // Abort here
+                               throw new IllegalArgumentException("fax.phoneNumber is zero or below."); //NOI18N
+                       }
+
+                       // Set fax number
+                       contact.setContactFaxNumber(fax);
+               }
+
+               // Is the provider set?
+               if ((mobile instanceof DialableMobileNumber) && (this.getMobileProvider() instanceof MobileProvider) && (this.getMobileNumber() != null) && (this.getMobileNumber() > 0)) {
+                       // Is the number set?
+                       if (mobile.getPhoneNumber() == null) {
+                               // Is null
+                               throw new NullPointerException("mobile.phoneNumber is null"); //NOI18N
+                       } else if (mobile.getPhoneNumber() < 1) {
+                               // Abort here
+                               throw new IllegalArgumentException("mobile.phoneNumber is zero or below."); //NOI18N
+                       }
+
+                       // Set mobile number
+                       contact.setContactMobileNumber(mobile);
+               }
+
+               // Return it
+               return contact;
+       }
+
+       @Override
+       public String doChangePersonalContactData () {
+               // This method shall only be called if the user is logged-in
+               if (!this.userLoginController.isUserLoggedIn()) {
+                       // Not logged-in
+                       throw new IllegalStateException("User is not logged-in"); //NOI18N
+               } else if (!this.isRequiredChangePersonalDataSet()) {
+                       // Not all required fields are set
+                       throw new FaceletException("Not all required fields are set."); //NOI18N
+               } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
+                       // Password not matching
+                       this.showFacesMessage("form_login_change_personal:currentPassword", new UserPasswordMismatchException(this.userLoginController.getLoggedInUser())); //NOI18N
+                       return ""; //NOI18N
+               }
+
+               // Get contact instance
+               Contact contact = this.userLoginController.getLoggedInUser().getUserContact();
+
+               // It should be there, so run some tests on it
+               assert (contact instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
+               assert (contact.getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
+               assert (contact.getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", contact.getContactId()); //NOI18N
+
+               // Update all fields
+               contact.setContactPersonalTitle(this.getPersonalTitle());
+               contact.setContactFirstName(this.getFirstName());
+               contact.setContactFamilyName(this.getFamilyName());
+               contact.setContactStreet(this.getStreet());
+               contact.setContactHouseNumber(this.getHouseNumber());
+               contact.setContactHouseNumberExtension(this.getHouseNumberExtension());
+               contact.setContactZipCode(this.getZipCode());
+               contact.setContactCity(this.getCity());
+               contact.setContactCountry(this.getCountry());
+
+               // Update contact's mobile number
+               this.isMobileUnlinked = ContactUtils.updateMobileNumber(contact, this.getMobileProvider(), this.getMobileNumber());
+
+               // Update contact's land-line number
+               this.isLandLineUnlinked = ContactUtils.updateLandLineNumber(contact, this.getLandLineCountry(), this.getLandLineAreaCode(), this.getLandLineNumber());
+
+               // Update contact's fax number
+               this.isFaxUnlinked = ContactUtils.updateFaxNumber(contact, this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber());
+
+               // Send it to the EJB
+               this.contactBean.updateContactData(contact, this.isMobileUnlinked, this.isLandLineUnlinked, this.isFaxUnlinked);
+
+               // All fine
+               return "contact_data_saved"; //NOI18N
+       }
+
+       /**
+        * Getter for academic title
+        * <p>
+        * @return Academic title
+        */
+       public String getAcademicTitle () {
+               return this.academicTitle;
+       }
+
+       /**
+        * Setter for academic title
+        * <p>
+        * @param academicTitle Academic title
+        */
+       public void setAcademicTitle (final String academicTitle) {
+               this.academicTitle = academicTitle;
+       }
+
+       /**
+        * Getter for birth day
+        * <p>
+        * @return Birth day
+        */
+       @SuppressWarnings ("ReturnOfDateField")
+       public Date getBirthday () {
+               return this.birthday;
+       }
+
+       /**
+        * Setter for birth day
+        * <p>
+        * @param birthday Birth day
+        */
+       @SuppressWarnings ("AssignmentToDateFieldFromParameter")
+       public void setBirthday (final Date birthday) {
+               this.birthday = birthday;
+       }
+
+       /**
+        * Getter for city name
+        * <p>
+        * @return City name
+        */
+       public String getCity () {
+               return this.city;
+       }
+
+       /**
+        * Setter for city name
+        * <p>
+        * @param city City name
+        */
+       public void setCity (final String city) {
+               this.city = city;
+       }
+
+       /**
+        * Getter for comments
+        * <p>
+        * @return Comments
+        */
+       public String getComment () {
+               return this.comment;
+       }
+
+       /**
+        * Setter for comment
+        * <p>
+        * @param comment Comments
+        */
+       public void setComment (final String comment) {
+               this.comment = comment;
+       }
+
+       @Override
+       public String getControllerType () {
+               return "general"; //NOI18N
+       }
+
+       @Override
+       @Deprecated
+       public void setControllerType (final String controllerType) {
+               throw new UnsupportedOperationException("Setting controller type is not supported."); //NOI18N
+       }
+
+       /**
+        * Getter for country instance
+        * <p>
+        * @return Country instance
+        */
+       public Country getCountry () {
+               return this.country;
+       }
+
+       /**
+        * Setter for country instance
+        * <p>
+        * @param country Country instance
+        */
+       public void setCountry (final Country country) {
+               this.country = country;
+       }
+
+       @Override
+       public String getEmailAddress () {
+               return this.emailAddress;
+       }
+
+       /**
+        * Setter for email address
+        * <p>
+        * @param emailAddress Email address
+        */
+       public void setEmailAddress (final String emailAddress) {
+               this.emailAddress = emailAddress;
+       }
+
+       /**
+        * Getter for email address, repeated
+        * <p>
+        * @return the emailAddress, repeated
+        */
+       public String getEmailAddressRepeat () {
+               return this.emailAddressRepeat;
+       }
+
+       /**
+        * Setter for email address repeated
+        * <p>
+        * @param emailAddressRepeat the emailAddress to set
+        */
+       public void setEmailAddressRepeat (final String emailAddressRepeat) {
+               this.emailAddressRepeat = emailAddressRepeat;
+       }
+
+       /**
+        * Family name
+        * <p>
+        * @return the familyName
+        */
+       public String getFamilyName () {
+               return this.familyName;
+       }
+
+       /**
+        * Family name
+        * <p>
+        * @param familyName the familyName to set
+        */
+       public void setFamilyName (final String familyName) {
+               this.familyName = familyName;
+       }
+
+       /**
+        * Getter for fax number's area code
+        * <p>
+        * @return Fax number's area code
+        */
+       public Integer getFaxAreaCode () {
+               return this.faxAreaCode;
+       }
+
+       /**
+        * Setter for fax number's area code
+        * <p>
+        * @param faxAreaCode Fax number's area code
+        */
+       public void setFaxAreaCode (final Integer faxAreaCode) {
+               this.faxAreaCode = faxAreaCode;
+       }
+
+       /**
+        * Getter for fax's country instance
+        * <p>
+        * @return Fax' country instance
+        */
+       public Country getFaxCountry () {
+               return this.faxCountry;
+       }
+
+       /**
+        * Setter for fax's country instance
+        * <p>
+        * @param faxCountry Fax' country instance
+        */
+       public void setFaxCountry (final Country faxCountry) {
+               this.faxCountry = faxCountry;
+       }
+
+       /**
+        * Getter for fax number
+        * <p>
+        * @return Fax number
+        */
+       public Long getFaxNumber () {
+               return this.faxNumber;
+       }
+
+       /**
+        * Setter for fax number
+        * <p>
+        * @param faxNumber Fax number
+        */
+       public void setFaxNumber (final Long faxNumber) {
+               this.faxNumber = faxNumber;
+       }
+
+       /**
+        * First name
+        * <p>
+        * @return the first name
+        */
+       public String getFirstName () {
+               return this.firstName;
+       }
+
+       /**
+        * First name
+        * <p>
+        * @param firstName the first name to set
+        */
+       public void setFirstName (final String firstName) {
+               this.firstName = firstName;
+       }
+
+       /**
+        * House number
+        * <p>
+        * @return the houseNumber
+        */
+       public Short getHouseNumber () {
+               return this.houseNumber;
+       }
+
+       /**
+        * House number
+        * <p>
+        * @param houseNumber the houseNumber to set
+        */
+       public void setHouseNumber (final Short houseNumber) {
+               this.houseNumber = houseNumber;
+       }
+
+       /**
+        * Getter for house number extension, example: 123a 'a' is then the
+        * extension and 123 is the house number.
+        * <p>
+        * @return House number extension
+        */
+       public String getHouseNumberExtension () {
+               return this.houseNumberExtension;
+       }
+
+       /**
+        * Setter for house number extension
+        * <p>
+        * @param houseNumberExtension House number extension
+        */
+       public void setHouseNumberExtension (final String houseNumberExtension) {
+               this.houseNumberExtension = houseNumberExtension;
+       }
+
+       /**
+        * Getter for land-line number's area code
+        * <p>
+        * @return Land-line number's area code
+        */
+       public Integer getLandLineAreaCode () {
+               return this.landLineAreaCode;
+       }
+
+       /**
+        * Setter for land-line number's area code
+        * <p>
+        * @param landLineAreaCode Land-line number's area code
+        */
+       public void setLandLineAreaCode (final Integer landLineAreaCode) {
+               this.landLineAreaCode = landLineAreaCode;
+       }
+
+       /**
+        * Getter for land-line number's country instance
+        * <p>
+        * @return Land-line number's country instance
+        */
+       public Country getLandLineCountry () {
+               return this.landLineCountry;
+       }
+
+       /**
+        * Setter for land-line number's country instance
+        * <p>
+        * @param landLineCountry Land-line number's country instance
+        */
+       public void setLandLineCountry (final Country landLineCountry) {
+               this.landLineCountry = landLineCountry;
+       }
+
+       /**
+        * Getter for land-line number
+        * <p>
+        * @return Land-line number
+        */
+       public Long getLandLineNumber () {
+               return this.landLineNumber;
+       }
+
+       /**
+        * Setter for land-line number
+        * <p>
+        * @param landLineNumber Land-line number
+        */
+       public void setLandLineNumber (final Long landLineNumber) {
+               this.landLineNumber = landLineNumber;
+       }
+
+       /**
+        * Getter for mobile number
+        * <p>
+        * @return Mobile number
+        */
+       public Long getMobileNumber () {
+               return this.mobileNumber;
+       }
+
+       /**
+        * Setter for mobile number
+        * <p>
+        * @param mobileNumber Mobile number
+        */
+       public void setMobileNumber (final Long mobileNumber) {
+               this.mobileNumber = mobileNumber;
+       }
+
+       /**
+        * Getter for mobile number's carrier
+        * <p>
+        * @return Mobile number's carrier
+        */
+       public MobileProvider getMobileProvider () {
+               return this.mobileProvider;
+       }
+
+       /**
+        * Setter for mobile number's provider
+        * <p>
+        * @param mobileProvider Mobile number's provider
+        */
+       public void setMobileProvider (final MobileProvider mobileProvider) {
+               this.mobileProvider = mobileProvider;
+       }
+
+       /**
+        * Getter for personal title
+        * <p>
+        * @return Personal title
+        */
+       public PersonalTitle getPersonalTitle () {
+               return this.personalTitle;
+       }
+
+       /**
+        * Setter for personal title
+        * <p>
+        * @param personalTitle Personal title
+        */
+       public void setPersonalTitle (final PersonalTitle personalTitle) {
+               this.personalTitle = personalTitle;
+       }
+
+       /**
+        * Getter for street
+        * <p>
+        * @return Street
+        */
+       public String getStreet () {
+               return this.street;
+       }
+
+       /**
+        * Setter for street
+        * <p>
+        * @param street Street
+        */
+       public void setStreet (final String street) {
+               this.street = street;
+       }
+
+       /**
+        * Getter for ZIP code
+        * <p>
+        * @return ZIP code
+        */
+       public Integer getZipCode () {
+               return this.zipCode;
+       }
+
+       /**
+        * Setter for ZIP code
+        * <p>
+        * @param zipCode ZIP code
+        */
+       public void setZipCode (final Integer zipCode) {
+               this.zipCode = zipCode;
+       }
+
+       /**
+        * Post-construction method
+        */
+       @PostConstruct
+       public void init () {
+               // Get all contacts
+               final List<Contact> selectable = new LinkedList<>();
+
+               // Is cache there?
+               if (!this.contactsCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<Contact> list = this.contactBean.allContacts();
+
+                       // Add all
+                       for (final Iterator<Contact> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final Contact next = iterator.next();
+
+                               // Add it to cache
+                               this.contactsCache.put(next.getContactId(), next);
+                               this.emailAddressCache.put(next.getContactId(), next.getContactEmailAddress());
+                               selectable.add(next);
+                       }
+               }
+
+               // Get all users
+               List<User> allUsers = this.userController.allUsers();
+
+               // Get iterator
+               Iterator<Contact> iterator = selectable.iterator();
+
+               // Loop through it
+               while (iterator.hasNext()) {
+                       // Get next element
+                       Contact next = iterator.next();
+
+                       // Get iterator
+                       Iterator<User> userIterator = allUsers.iterator();
+
+                       // Loop through all users
+                       while (userIterator.hasNext()) {
+                               // Get user instance
+                               User nextUser = userIterator.next();
+
+                               // Is contact same?
+                               if (Objects.equals(next, nextUser.getUserContact())) {
+                                       // Found same
+                                       iterator.remove();
+                                       break;
+                               }
+                       }
+               }
+
+               // Set contact list
+               this.selectableContacts = selectable;
+       }
+
+       @Override
+       public boolean isEmailAddressRegistered (final Contact contact) {
+               // Cherck parameter
+               if (null == contact) {
+                       // Throw NPE
+                       throw new NullPointerException("contact is null"); //NOI18N
+               } else if (contact.getContactEmailAddress() == null) {
+                       // Throw again
+                       throw new NullPointerException("contact.contactEmailAddress is null"); //NOI18N
+               } else if (contact.getContactEmailAddress().isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("contact.contactEmailAddress is empty."); //NOI18N
+               }
+
+               // Determine it
+               return ((this.emailAddressCache instanceof List) && (this.emailAddressCache.containsKey(contact.getContactId())));
+       }
+
+       @Override
+       public boolean isRequiredChangePersonalDataSet () {
+               return ((this.getPersonalTitle() != null) &&
+                               (this.getFirstName() != null) &&
+                               (this.getFamilyName() != null) &&
+                               (this.getStreet() != null) &&
+                               (this.getHouseNumber() != null) &&
+                               (this.getZipCode() != null) &&
+                               (this.getCity() != null));
+       }
+
+       @Override
+       public boolean isRequiredPersonalDataSet () {
+               return ((this.getPersonalTitle() != null) &&
+                               (this.getFirstName() != null) &&
+                               (this.getFamilyName() != null) &&
+                               (this.getStreet() != null) &&
+                               (this.getHouseNumber() != null) &&
+                               (this.getZipCode() != null) &&
+                               (this.getCity() != null) &&
+                               (this.getEmailAddress() != null) &&
+                               (this.getEmailAddressRepeat() != null));
+       }
+
+       @Override
+       public boolean isSameEmailAddressEntered () {
+               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.
+        * <p>
+        * @return A list of all selectable contacts
+        */
+       public List<Contact> selectableContacts () {
+               return Collections.unmodifiableList(this.selectableContacts);
+       }
+
+       @Override
+       public void updateContactDataFromController (final Contact contact) {
+               // Is the instance valid?
+               if (null == contact) {
+                       // Throw NPE
+                       throw new NullPointerException("contact is null"); //NOI18N
+               } else if (contact.getContactId() == null) {
+                       // Throw NPE
+                       throw new NullPointerException("contact.contactId is null"); //NOI18N
+               } else if (contact.getContactId() < 1) {
+                       // Not valid id number
+                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
+               }
+
+               // Set all
+               this.copyContact(contact);
+       }
+
+       /**
+        * Adds email address to bean's internal list.
+        * <p>
+        * @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
+        */
+       private void clear () {
+               // Clear all data
+               // - personal data
+               this.setPersonalTitle(null);
+               this.setAcademicTitle(null);
+               this.setFirstName(null);
+               this.setFamilyName(null);
+               this.setStreet(null);
+               this.setHouseNumber(null);
+               this.setHouseNumberExtension(null);
+               this.setZipCode(null);
+               this.setCity(null);
+               this.setCountry(null);
+
+               // - contact data
+               this.clearEmailAddresses();
+               this.setLandLineAreaCode(null);
+               this.setLandLineCountry(null);
+               this.setLandLineNumber(null);
+               this.setMobileProvider(null);
+               this.setMobileNumber(null);
+               this.setFaxAreaCode(null);
+               this.setFaxCountry(null);
+               this.setFaxNumber(null);
+
+               // - other data
+               this.setBirthday(null);
+               this.setComment(null);
+       }
+
+       /**
+        * Copies given contact into the controller
+        * <p>
+        * @param contact Contact instance
+        */
+       private void copyContact (final Contact contact) {
+               // Is the instance valid?
+               if (null == contact) {
+                       // Throw NPE
+                       throw new NullPointerException("contact is null"); //NOI18N
+               } else if (contact.getContactId() == null) {
+                       // Throw NPE
+                       throw new NullPointerException("contact.contactId is null"); //NOI18N
+               } else if (contact.getContactId() < 1) {
+                       // Not valid id number
+                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
+               }
+
+               // Copy all fields:
+               // - base data
+               this.setPersonalTitle(contact.getContactPersonalTitle());
+               this.setAcademicTitle(contact.getContactTitle());
+               this.setFirstName(contact.getContactFirstName());
+               this.setFamilyName(contact.getContactFamilyName());
+               this.setStreet(contact.getContactStreet());
+               this.setHouseNumber(contact.getContactHouseNumber());
+               this.setHouseNumberExtension(contact.getContactHouseNumberExtension());
+               this.setZipCode(contact.getContactZipCode());
+               this.setCity(contact.getContactCity());
+               this.setCountry(contact.getContactCountry());
+               this.setEmailAddress(contact.getContactEmailAddress());
+               this.setBirthday(contact.getContactBirthday());
+               this.setComment(contact.getContactComment());
+
+               // Get mobile, phone and fax instance
+               DialableMobileNumber mobile = contact.getContactMobileNumber();
+               DialableFaxNumber fax = contact.getContactFaxNumber();
+               DialableLandLineNumber phone = contact.getContactLandLineNumber();
+
+               // - contact data
+               if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneAreaCode() > 0)) {
+                       this.setLandLineCountry(phone.getPhoneCountry());
+                       this.setLandLineAreaCode(phone.getPhoneAreaCode());
+                       this.setLandLineNumber(phone.getPhoneNumber());
+               }
+
+               if ((mobile instanceof DialableMobileNumber) && (mobile.getMobileProvider() instanceof MobileProvider)) {
+                       this.setMobileProvider(mobile.getMobileProvider());
+                       this.setMobileNumber(mobile.getPhoneNumber());
+               }
+
+               if ((fax instanceof DialableFaxNumber) && (fax.getPhoneAreaCode() > 0)) {
+                       this.setFaxCountry(fax.getPhoneCountry());
+                       this.setFaxAreaCode(fax.getPhoneAreaCode());
+                       this.setFaxNumber(fax.getPhoneNumber());
+               }
+       }
+
+       /**
+        * Removes given contact from all lists
+        * <p>
+        * @param contact Contact instance to remove
+        */
+       private void removeContact (final Contact contact) {
+               // Is the instance valid?
+               if (null == contact) {
+                       // Throw NPE
+                       throw new NullPointerException("contact is null"); //NOI18N
+               } else if (contact.getContactId() == null) {
+                       // Throw NPE
+                       throw new NullPointerException("contact.contactId is null"); //NOI18N
+               } else if (contact.getContactId() < 1) {
+                       // Not valid id number
+                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
+               }
+
+               // Remove from general list
+               if (!this.contactsCache.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.
+        * <p>
+        * @param contact Contact instance to add uniquely
+        */
+       private void uniqueAddContact (final Contact contact) {
+               // Is the instance valid?
+               if (null == contact) {
+                       // Throw NPE
+                       throw new NullPointerException("contact is null"); //NOI18N
+               } else if (contact.getContactId() == null) {
+                       // Throw NPE
+                       throw new NullPointerException("contact.contactId is null"); //NOI18N
+               } else if (contact.getContactId() < 1) {
+                       // Not valid id number
+                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
+               }
+
+               // Get iterator from list
+               Iterator<Cache.Entry<Long, Contact>> iterator = this.contactsCache.iterator();
+
+               // "Walk" through all entries
+               while (iterator.hasNext()) {
+                       // Get next element
+                       Cache.Entry<Long, Contact> 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.contactsCache.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
new file mode 100644 (file)
index 0000000..3718a5b
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.contact;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jcontacts.contact.Contact;
+
+/**
+ * An interface for user beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsContactWebRequestController extends Serializable {
+
+       /**
+        * Minimum password length
+        */
+       public static final Integer MINIMUM_PASSWORD_LENGTH = 5;
+
+       /**
+        * Getter for email address
+        * <p>
+        * @return Email address
+        */
+       String getEmailAddress ();
+
+       /**
+        * Clears both email address field
+        */
+       void clearEmailAddresses ();
+
+       /**
+        * Returns a list of all found contacts
+        * <p>
+        * @return A list of all contacts.
+        */
+       List<Contact> allContacts ();
+
+       /**
+        * Updates all data from bean in given contact instance
+        * <p>
+        * @param userContact Contact instance to update
+        */
+       void updateContactDataFromController (final Contact userContact);
+
+       /**
+        * Creates an instance from all properties
+        * <p>
+        * @return A contact instance
+        */
+       Contact createContactInstance ();
+
+       /**
+        * Getter for controller type
+        * <p>
+        * @return controller type
+        */
+       String getControllerType ();
+
+       /**
+        * Setter for controller type
+        * <p>
+        * @param controllerType Controller type
+        * <p>
+        * @deprecated Don't use this method.
+        */
+       @Deprecated
+       void setControllerType (final String controllerType);
+
+       /**
+        * Checks whether contact instance's email address is used
+        * <p>
+        * @param contact Contact instance's email address to check
+        * <p>
+        * @return Whether it is already used
+        */
+       boolean isEmailAddressRegistered (final Contact contact);
+
+       /**
+        * Checks whether all required personal data is set
+        * <p>
+        * @return Whether the required personal data is set
+        */
+       boolean isRequiredPersonalDataSet ();
+
+       /**
+        * Checks whether all required personal data is set for changing them
+        * <p>
+        * @return Whether the required personal data is set
+        */
+       boolean isRequiredChangePersonalDataSet ();
+
+       /**
+        * Checks whether same email addresses have been entered
+        * <p>
+        * @return Whether same email addresses have been entered
+        */
+       boolean isSameEmailAddressEntered ();
+
+       /**
+        * Changes logged-in user's personal data if the current password matches
+        * and TAC + privacy statement has been accepted.
+        * <p>
+        * @return New target page
+        */
+       String doChangePersonalContactData ();
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebSessionBean.java b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebSessionBean.java
deleted file mode 100644 (file)
index f11749c..0000000
+++ /dev/null
@@ -1,1301 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.contact;
-
-import java.text.MessageFormat;
-import java.util.Collections;
-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.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Observes;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jcontacts.contact.Contact;
-import org.mxchange.jcontacts.contact.ContactSessionBeanRemote;
-import org.mxchange.jcontacts.contact.ContactUtils;
-import org.mxchange.jcontacts.contact.UserContact;
-import org.mxchange.jcontacts.contact.title.PersonalTitle;
-import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
-import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
-import org.mxchange.jcountry.data.Country;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.user.FinancialsUserWebSessionController;
-import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
-import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
-import org.mxchange.jphone.phonenumbers.fax.FaxNumber;
-import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
-import org.mxchange.jphone.phonenumbers.landline.LandLineNumber;
-import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
-import org.mxchange.jphone.phonenumbers.mobile.MobileNumber;
-import org.mxchange.jphone.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;
-
-/**
- * A general contact bean (controller)
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("contactController")
-@SessionScoped
-public class FinancialsContactWebSessionBean extends BaseFinancialsController implements FinancialsContactWebSessionController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 542_145_347_916L;
-
-       /**
-        * Academic academicTitle
-        */
-       private String academicTitle;
-
-       /**
-        * Birth day
-        */
-       private Date birthday;
-
-       /**
-        * City
-        */
-       private String city;
-
-       /**
-        * Optional comments
-        */
-       private String comment;
-
-       /**
-        * EJB for general contact purposes
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/contact!org.mxchange.jcontacts.contact.ContactSessionBeanRemote")
-       private ContactSessionBeanRemote contactBean;
-
-       /**
-        * Contact list
-        */
-       private final List<Contact> contactList;
-
-       /**
-        * Country instance
-        */
-       private Country country;
-
-       /**
-        * Email address
-        */
-       private String emailAddress;
-
-       /**
-        * Email address list
-        */
-       private final List<String> emailAddressList;
-
-       /**
-        * Email address repeated
-        */
-       private String emailAddressRepeat;
-
-       /**
-        * Family name
-        */
-       private String familyName;
-
-       /**
-        * Fax number's area code
-        */
-       private Integer faxAreaCode;
-
-       /**
-        * Country instance for fax number
-        */
-       private Country faxCountry;
-
-       /**
-        * Fax number
-        */
-       private Long faxNumber;
-
-       /**
-        * First name
-        */
-       private String firstName;
-
-       /**
-        * House number
-        */
-       private Short houseNumber;
-
-       /**
-        * House number extension
-        */
-       private String houseNumberExtension;
-
-       /**
-        * Whether a fax entry has been unlinked
-        */
-       private boolean isFaxUnlinked;
-
-       /**
-        * Whether a land-line number has been unlinked
-        */
-       private boolean isLandLineUnlinked;
-
-       /**
-        * Whether a mobile entry has been unlinked
-        */
-       private boolean isMobileUnlinked;
-
-       /**
-        * Phone number area code
-        */
-       private Integer landLineAreaCode;
-
-       /**
-        * Country instance for phone number
-        */
-       private Country landLineCountry;
-
-       /**
-        * Phone number
-        */
-       private Long landLineNumber;
-
-       /**
-        * Mobile number
-        */
-       private Long mobileNumber;
-
-       /**
-        * Mobile number's carrier
-        */
-       private MobileProvider mobileProvider;
-
-       /**
-        * Personal academicTitle
-        */
-       private PersonalTitle personalTitle;
-
-       /**
-        * A list of all selectable contacts
-        */
-       private List<Contact> selectableContacts;
-
-       /**
-        * Street
-        */
-       private String street;
-
-       /**
-        * Regular user controller
-        */
-       @Inject
-       private FinancialsUserWebSessionController userController;
-
-       /**
-        * Login bean (controller)
-        */
-       @Inject
-       private FinancialsUserLoginWebSessionController userLoginController;
-
-       /**
-        * ZIP code
-        */
-       private Integer zipCode;
-
-       /**
-        * Default constructor
-        */
-       public FinancialsContactWebSessionBean () {
-               // Call super constructor
-               super();
-
-               // Init lists/maps
-               this.contactList = new LinkedList<>();
-               this.emailAddressList = new LinkedList<>();
-       }
-
-       /**
-        * Observes events being fired when an administrator has added a new
-        * contact.
-        * <p>
-        * @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.selectableContacts.add(event.getAddedContact());
-       }
-
-       /**
-        * Event observer for newly added users by administrator
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getAddedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.addedUser is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
-               }
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when an administrator has linked a new user
-        * with existing contact data.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLinkedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.linkedUser is null"); //NOI18N
-               } else if (event.getLinkedUser().getUserContact() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.linkedUser.userContact is null"); //NOI18N
-               } else if (event.getLinkedUser().getUserContact().getContactId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.linkedUser.userContact.contactId is null"); //NOI18N
-               } else if (event.getLinkedUser().getUserContact().getContactId() < 1) {
-                       // Not avalid id
-                       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.selectableContacts.remove(event.getLinkedUser().getUserContact());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Event observer for updated contact data by administrators
-        * <p>
-        * @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.emailAddressList.add(event.getUpdatedContact().getContactEmailAddress());
-       }
-
-       /**
-        * Event observer when user confirmed account.
-        * <p>
-        * @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
-        * <p>
-        * @param event Event instance
-        */
-       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLoggedInUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.loggedInUser is null"); //NOI18N
-               } else if (event.getLoggedInUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
-               } else if (event.getLoggedInUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
-               }
-
-               // Copy all data to this bean
-               this.copyContact(event.getLoggedInUser().getUserContact());
-       }
-
-       /**
-        * Event observer for new user registrations
-        * <p>
-        * @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
-               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<Contact> allContacts () {
-               // Return un-modified list
-               return this.contactList;
-       }
-
-       @Override
-       public void clearEmailAddresses () {
-               // Clear both
-               this.setEmailAddress(null);
-               this.setEmailAddressRepeat(null);
-       }
-
-       @Override
-       public Contact createContactInstance () {
-               // Is all required data set?
-               if (!this.isRequiredPersonalDataSet()) {
-                       // No, then abort here
-                       throw new FaceletException(new IllegalArgumentException("Not all personal data is set, but createContactInstance() is called.")); //NOI18N
-               }
-
-               // Required personal data must be set
-               assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
-
-               // Generate phone number
-               DialableLandLineNumber phone = new LandLineNumber(this.getLandLineCountry(), this.getLandLineAreaCode(), this.getLandLineNumber());
-               DialableMobileNumber mobile = new MobileNumber(this.getMobileProvider(), this.getMobileNumber());
-               DialableFaxNumber fax = new FaxNumber(this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber());
-
-               // Create new contact
-               Contact contact = new UserContact(this.getPersonalTitle(), this.getFirstName(), this.getFamilyName());
-               contact.setContactStreet(this.getStreet());
-               contact.setContactHouseNumber(this.getHouseNumber());
-               contact.setContactHouseNumberExtension(this.getHouseNumberExtension());
-               contact.setContactZipCode(this.getZipCode());
-               contact.setContactCity(this.getCity());
-               contact.setContactCountry(this.getCountry());
-               contact.setContactEmailAddress(this.getEmailAddress());
-               contact.setContactBirthday(this.getBirthday());
-               contact.setContactComment(this.getComment());
-
-               // Don't set null or wrong references
-               if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneCountry() instanceof Country) && (this.getLandLineAreaCode() != null) && (this.getLandLineNumber() != null) && (this.getLandLineAreaCode() > 0) && (this.getLandLineNumber() > 0)) {
-                       // Now the number must be given
-                       if (phone.getPhoneAreaCode() == null) {
-                               // Is null
-                               throw new NullPointerException("phone.phoneAreaCode is null"); //NOI18N
-                       } else if (phone.getPhoneAreaCode() < 1) {
-                               // Abort here
-                               throw new IllegalArgumentException("phone.phoneAreaCode is zero or below."); //NOI18N
-                       } else if (phone.getPhoneNumber() == null) {
-                               // Is null
-                               throw new NullPointerException("phone.phoneNumber is null"); //NOI18N
-                       } else if (phone.getPhoneNumber() < 1) {
-                               // Abort here
-                               throw new IllegalArgumentException("phone.phoneNumber is zero or below."); //NOI18N
-                       }
-
-                       // Set phone number
-                       contact.setContactLandLineNumber(phone);
-               }
-
-               // Don't set null or wrong references
-               if ((fax instanceof DialableFaxNumber) && (fax.getPhoneCountry() instanceof Country) && (this.getFaxAreaCode() != null) && (this.getFaxNumber() != null) && (this.getFaxAreaCode() > 0) && (this.getFaxNumber() > 0)) {
-                       // Now the number must be given
-                       if (fax.getPhoneAreaCode() == null) {
-                               // Is null
-                               throw new NullPointerException("fax.phoneAreaCode is null"); //NOI18N
-                       } else if (fax.getPhoneAreaCode() < 1) {
-                               // Abort here
-                               throw new IllegalArgumentException("fax.phoneAreaCode is zero or below."); //NOI18N
-                       } else if (fax.getPhoneNumber() == null) {
-                               // Is null
-                               throw new NullPointerException("fax.phoneNumber is null"); //NOI18N
-                       } else if (fax.getPhoneNumber() < 1) {
-                               // Abort here
-                               throw new IllegalArgumentException("fax.phoneNumber is zero or below."); //NOI18N
-                       }
-
-                       // Set fax number
-                       contact.setContactFaxNumber(fax);
-               }
-
-               // Is the provider set?
-               if ((mobile instanceof DialableMobileNumber) && (this.getMobileProvider() instanceof MobileProvider) && (this.getMobileNumber() != null) && (this.getMobileNumber() > 0)) {
-                       // Is the number set?
-                       if (mobile.getPhoneNumber() == null) {
-                               // Is null
-                               throw new NullPointerException("mobile.phoneNumber is null"); //NOI18N
-                       } else if (mobile.getPhoneNumber() < 1) {
-                               // Abort here
-                               throw new IllegalArgumentException("mobile.phoneNumber is zero or below."); //NOI18N
-                       }
-
-                       // Set mobile number
-                       contact.setContactMobileNumber(mobile);
-               }
-
-               // Return it
-               return contact;
-       }
-
-       @Override
-       public String doChangePersonalContactData () {
-               // This method shall only be called if the user is logged-in
-               if (!this.userLoginController.isUserLoggedIn()) {
-                       // Not logged-in
-                       throw new IllegalStateException("User is not logged-in"); //NOI18N
-               } else if (!this.isRequiredChangePersonalDataSet()) {
-                       // Not all required fields are set
-                       throw new FaceletException("Not all required fields are set."); //NOI18N
-               } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
-                       // Password not matching
-                       this.showFacesMessage("form_login_change_personal:currentPassword", new UserPasswordMismatchException(this.userLoginController.getLoggedInUser())); //NOI18N
-                       return ""; //NOI18N
-               }
-
-               // Get contact instance
-               Contact contact = this.userLoginController.getLoggedInUser().getUserContact();
-
-               // It should be there, so run some tests on it
-               assert (contact instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
-               assert (contact.getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
-               assert (contact.getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", contact.getContactId()); //NOI18N
-
-               // Update all fields
-               contact.setContactPersonalTitle(this.getPersonalTitle());
-               contact.setContactFirstName(this.getFirstName());
-               contact.setContactFamilyName(this.getFamilyName());
-               contact.setContactStreet(this.getStreet());
-               contact.setContactHouseNumber(this.getHouseNumber());
-               contact.setContactHouseNumberExtension(this.getHouseNumberExtension());
-               contact.setContactZipCode(this.getZipCode());
-               contact.setContactCity(this.getCity());
-               contact.setContactCountry(this.getCountry());
-
-               // Update contact's mobile number
-               this.isMobileUnlinked = ContactUtils.updateMobileNumber(contact, this.getMobileProvider(), this.getMobileNumber());
-
-               // Update contact's land-line number
-               this.isLandLineUnlinked = ContactUtils.updateLandLineNumber(contact, this.getLandLineCountry(), this.getLandLineAreaCode(), this.getLandLineNumber());
-
-               // Update contact's fax number
-               this.isFaxUnlinked = ContactUtils.updateFaxNumber(contact, this.getFaxCountry(), this.getFaxAreaCode(), this.getFaxNumber());
-
-               // Send it to the EJB
-               this.contactBean.updateContactData(contact, this.isMobileUnlinked, this.isLandLineUnlinked, this.isFaxUnlinked);
-
-               // All fine
-               return "contact_data_saved"; //NOI18N
-       }
-
-       /**
-        * Getter for academic title
-        * <p>
-        * @return Academic title
-        */
-       public String getAcademicTitle () {
-               return this.academicTitle;
-       }
-
-       /**
-        * Setter for academic title
-        * <p>
-        * @param academicTitle Academic title
-        */
-       public void setAcademicTitle (final String academicTitle) {
-               this.academicTitle = academicTitle;
-       }
-
-       /**
-        * Getter for birth day
-        * <p>
-        * @return Birth day
-        */
-       @SuppressWarnings ("ReturnOfDateField")
-       public Date getBirthday () {
-               return this.birthday;
-       }
-
-       /**
-        * Setter for birth day
-        * <p>
-        * @param birthday Birth day
-        */
-       @SuppressWarnings ("AssignmentToDateFieldFromParameter")
-       public void setBirthday (final Date birthday) {
-               this.birthday = birthday;
-       }
-
-       /**
-        * Getter for city name
-        * <p>
-        * @return City name
-        */
-       public String getCity () {
-               return this.city;
-       }
-
-       /**
-        * Setter for city name
-        * <p>
-        * @param city City name
-        */
-       public void setCity (final String city) {
-               this.city = city;
-       }
-
-       /**
-        * Getter for comments
-        * <p>
-        * @return Comments
-        */
-       public String getComment () {
-               return this.comment;
-       }
-
-       /**
-        * Setter for comment
-        * <p>
-        * @param comment Comments
-        */
-       public void setComment (final String comment) {
-               this.comment = comment;
-       }
-
-       @Override
-       public String getControllerType () {
-               return "general"; //NOI18N
-       }
-
-       @Override
-       @Deprecated
-       public void setControllerType (final String controllerType) {
-               throw new UnsupportedOperationException("Setting controller type is not supported."); //NOI18N
-       }
-
-       /**
-        * Getter for country instance
-        * <p>
-        * @return Country instance
-        */
-       public Country getCountry () {
-               return this.country;
-       }
-
-       /**
-        * Setter for country instance
-        * <p>
-        * @param country Country instance
-        */
-       public void setCountry (final Country country) {
-               this.country = country;
-       }
-
-       @Override
-       public String getEmailAddress () {
-               return this.emailAddress;
-       }
-
-       /**
-        * Setter for email address
-        * <p>
-        * @param emailAddress Email address
-        */
-       public void setEmailAddress (final String emailAddress) {
-               this.emailAddress = emailAddress;
-       }
-
-       /**
-        * Getter for email address, repeated
-        * <p>
-        * @return the emailAddress, repeated
-        */
-       public String getEmailAddressRepeat () {
-               return this.emailAddressRepeat;
-       }
-
-       /**
-        * Setter for email address repeated
-        * <p>
-        * @param emailAddressRepeat the emailAddress to set
-        */
-       public void setEmailAddressRepeat (final String emailAddressRepeat) {
-               this.emailAddressRepeat = emailAddressRepeat;
-       }
-
-       /**
-        * Family name
-        * <p>
-        * @return the familyName
-        */
-       public String getFamilyName () {
-               return this.familyName;
-       }
-
-       /**
-        * Family name
-        * <p>
-        * @param familyName the familyName to set
-        */
-       public void setFamilyName (final String familyName) {
-               this.familyName = familyName;
-       }
-
-       /**
-        * Getter for fax number's area code
-        * <p>
-        * @return Fax number's area code
-        */
-       public Integer getFaxAreaCode () {
-               return this.faxAreaCode;
-       }
-
-       /**
-        * Setter for fax number's area code
-        * <p>
-        * @param faxAreaCode Fax number's area code
-        */
-       public void setFaxAreaCode (final Integer faxAreaCode) {
-               this.faxAreaCode = faxAreaCode;
-       }
-
-       /**
-        * Getter for fax's country instance
-        * <p>
-        * @return Fax' country instance
-        */
-       public Country getFaxCountry () {
-               return this.faxCountry;
-       }
-
-       /**
-        * Setter for fax's country instance
-        * <p>
-        * @param faxCountry Fax' country instance
-        */
-       public void setFaxCountry (final Country faxCountry) {
-               this.faxCountry = faxCountry;
-       }
-
-       /**
-        * Getter for fax number
-        * <p>
-        * @return Fax number
-        */
-       public Long getFaxNumber () {
-               return this.faxNumber;
-       }
-
-       /**
-        * Setter for fax number
-        * <p>
-        * @param faxNumber Fax number
-        */
-       public void setFaxNumber (final Long faxNumber) {
-               this.faxNumber = faxNumber;
-       }
-
-       /**
-        * First name
-        * <p>
-        * @return the first name
-        */
-       public String getFirstName () {
-               return this.firstName;
-       }
-
-       /**
-        * First name
-        * <p>
-        * @param firstName the first name to set
-        */
-       public void setFirstName (final String firstName) {
-               this.firstName = firstName;
-       }
-
-       /**
-        * House number
-        * <p>
-        * @return the houseNumber
-        */
-       public Short getHouseNumber () {
-               return this.houseNumber;
-       }
-
-       /**
-        * House number
-        * <p>
-        * @param houseNumber the houseNumber to set
-        */
-       public void setHouseNumber (final Short houseNumber) {
-               this.houseNumber = houseNumber;
-       }
-
-       /**
-        * Getter for house number extension, example: 123a 'a' is then the
-        * extension and 123 is the house number.
-        * <p>
-        * @return House number extension
-        */
-       public String getHouseNumberExtension () {
-               return this.houseNumberExtension;
-       }
-
-       /**
-        * Setter for house number extension
-        * <p>
-        * @param houseNumberExtension House number extension
-        */
-       public void setHouseNumberExtension (final String houseNumberExtension) {
-               this.houseNumberExtension = houseNumberExtension;
-       }
-
-       /**
-        * Getter for land-line number's area code
-        * <p>
-        * @return Land-line number's area code
-        */
-       public Integer getLandLineAreaCode () {
-               return this.landLineAreaCode;
-       }
-
-       /**
-        * Setter for land-line number's area code
-        * <p>
-        * @param landLineAreaCode Land-line number's area code
-        */
-       public void setLandLineAreaCode (final Integer landLineAreaCode) {
-               this.landLineAreaCode = landLineAreaCode;
-       }
-
-       /**
-        * Getter for land-line number's country instance
-        * <p>
-        * @return Land-line number's country instance
-        */
-       public Country getLandLineCountry () {
-               return this.landLineCountry;
-       }
-
-       /**
-        * Setter for land-line number's country instance
-        * <p>
-        * @param landLineCountry Land-line number's country instance
-        */
-       public void setLandLineCountry (final Country landLineCountry) {
-               this.landLineCountry = landLineCountry;
-       }
-
-       /**
-        * Getter for land-line number
-        * <p>
-        * @return Land-line number
-        */
-       public Long getLandLineNumber () {
-               return this.landLineNumber;
-       }
-
-       /**
-        * Setter for land-line number
-        * <p>
-        * @param landLineNumber Land-line number
-        */
-       public void setLandLineNumber (final Long landLineNumber) {
-               this.landLineNumber = landLineNumber;
-       }
-
-       /**
-        * Getter for mobile number
-        * <p>
-        * @return Mobile number
-        */
-       public Long getMobileNumber () {
-               return this.mobileNumber;
-       }
-
-       /**
-        * Setter for mobile number
-        * <p>
-        * @param mobileNumber Mobile number
-        */
-       public void setMobileNumber (final Long mobileNumber) {
-               this.mobileNumber = mobileNumber;
-       }
-
-       /**
-        * Getter for mobile number's carrier
-        * <p>
-        * @return Mobile number's carrier
-        */
-       public MobileProvider getMobileProvider () {
-               return this.mobileProvider;
-       }
-
-       /**
-        * Setter for mobile number's provider
-        * <p>
-        * @param mobileProvider Mobile number's provider
-        */
-       public void setMobileProvider (final MobileProvider mobileProvider) {
-               this.mobileProvider = mobileProvider;
-       }
-
-       /**
-        * Getter for personal title
-        * <p>
-        * @return Personal title
-        */
-       public PersonalTitle getPersonalTitle () {
-               return this.personalTitle;
-       }
-
-       /**
-        * Setter for personal title
-        * <p>
-        * @param personalTitle Personal title
-        */
-       public void setPersonalTitle (final PersonalTitle personalTitle) {
-               this.personalTitle = personalTitle;
-       }
-
-       /**
-        * Getter for street
-        * <p>
-        * @return Street
-        */
-       public String getStreet () {
-               return this.street;
-       }
-
-       /**
-        * Setter for street
-        * <p>
-        * @param street Street
-        */
-       public void setStreet (final String street) {
-               this.street = street;
-       }
-
-       /**
-        * Getter for ZIP code
-        * <p>
-        * @return ZIP code
-        */
-       public Integer getZipCode () {
-               return this.zipCode;
-       }
-
-       /**
-        * Setter for ZIP code
-        * <p>
-        * @param zipCode ZIP code
-        */
-       public void setZipCode (final Integer zipCode) {
-               this.zipCode = zipCode;
-       }
-
-       /**
-        * Post-construction method
-        */
-       @PostConstruct
-       public void init () {
-               // Get full email address list for reducing EJB calls
-               this.emailAddressList.addAll(this.contactBean.getEmailAddressList());
-
-               // Get full contact list
-               this.contactList.addAll(this.contactBean.getAllContacts());
-
-               // Get all users
-               List<User> allUsers = this.userController.allUsers();
-
-               // Get all contacts
-               List<Contact> allContacts = this.contactBean.getAllContacts();
-
-               // Get iterator
-               Iterator<Contact> iterator = allContacts.iterator();
-
-               // Loop through it
-               while (iterator.hasNext()) {
-                       // Get next element
-                       Contact next = iterator.next();
-
-                       // Get iterator
-                       Iterator<User> userIterator = allUsers.iterator();
-
-                       // Loop through all users
-                       while (userIterator.hasNext()) {
-                               // Get user instance
-                               User nextUser = userIterator.next();
-
-                               // Is contact same?
-                               if (Objects.equals(next, nextUser.getUserContact())) {
-                                       // Found same
-                                       iterator.remove();
-                                       break;
-                               }
-                       }
-               }
-
-               // Set contact list
-               this.selectableContacts = allContacts;
-       }
-
-       @Override
-       public boolean isEmailAddressRegistered (final Contact contact) {
-               // Cherck parameter
-               if (null == contact) {
-                       // Throw NPE
-                       throw new NullPointerException("contact is null"); //NOI18N
-               } else if (contact.getContactEmailAddress() == null) {
-                       // Throw again
-                       throw new NullPointerException("contact.contactEmailAddress is null"); //NOI18N
-               } else if (contact.getContactEmailAddress().isEmpty()) {
-                       // Is empty
-                       throw new IllegalArgumentException("contact.contactEmailAddress is empty."); //NOI18N
-               }
-
-               // Determine it
-               return ((this.emailAddressList instanceof List) && (this.emailAddressList.contains(contact.getContactEmailAddress())));
-       }
-
-       @Override
-       public boolean isRequiredChangePersonalDataSet () {
-               return ((this.getPersonalTitle() != null) &&
-                               (this.getFirstName() != null) &&
-                               (this.getFamilyName() != null) &&
-                               (this.getStreet() != null) &&
-                               (this.getHouseNumber() != null) &&
-                               (this.getZipCode() != null) &&
-                               (this.getCity() != null));
-       }
-
-       @Override
-       public boolean isRequiredPersonalDataSet () {
-               return ((this.getPersonalTitle() != null) &&
-                               (this.getFirstName() != null) &&
-                               (this.getFamilyName() != null) &&
-                               (this.getStreet() != null) &&
-                               (this.getHouseNumber() != null) &&
-                               (this.getZipCode() != null) &&
-                               (this.getCity() != null) &&
-                               (this.getEmailAddress() != null) &&
-                               (this.getEmailAddressRepeat() != null));
-       }
-
-       @Override
-       public boolean isSameEmailAddressEntered () {
-               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.
-        * <p>
-        * @return A list of all selectable contacts
-        */
-       public List<Contact> selectableContacts () {
-               return Collections.unmodifiableList(this.selectableContacts);
-       }
-
-       @Override
-       public void updateContactDataFromController (final Contact contact) {
-               // Is the instance valid?
-               if (null == contact) {
-                       // Throw NPE
-                       throw new NullPointerException("contact is null"); //NOI18N
-               } else if (contact.getContactId() == null) {
-                       // Throw NPE
-                       throw new NullPointerException("contact.contactId is null"); //NOI18N
-               } else if (contact.getContactId() < 1) {
-                       // Not valid id number
-                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
-               }
-
-               // Set all
-               this.copyContact(contact);
-       }
-
-       /**
-        * Adds email address to bean's internal list.
-        * <p>
-        * @param contact Contact instance
-        */
-       private void addUserNameEmailAddress (final Contact contact) {
-               // Make sure the entry is not added yet
-               if (this.emailAddressList.contains(contact.getContactEmailAddress())) {
-                       // Already added
-                       throw new IllegalArgumentException(MessageFormat.format("Email address {0} already added.", contact.getContactEmailAddress())); //NOI18N
-               }
-
-               // Add email addres
-               this.emailAddressList.add(contact.getContactEmailAddress());
-       }
-
-       /**
-        * Clears this bean
-        */
-       private void clear () {
-               // Clear all data
-               // - personal data
-               this.setPersonalTitle(null);
-               this.setAcademicTitle(null);
-               this.setFirstName(null);
-               this.setFamilyName(null);
-               this.setStreet(null);
-               this.setHouseNumber(null);
-               this.setHouseNumberExtension(null);
-               this.setZipCode(null);
-               this.setCity(null);
-               this.setCountry(null);
-
-               // - contact data
-               this.clearEmailAddresses();
-               this.setLandLineAreaCode(null);
-               this.setLandLineCountry(null);
-               this.setLandLineNumber(null);
-               this.setMobileProvider(null);
-               this.setMobileNumber(null);
-               this.setFaxAreaCode(null);
-               this.setFaxCountry(null);
-               this.setFaxNumber(null);
-
-               // - other data
-               this.setBirthday(null);
-               this.setComment(null);
-       }
-
-       /**
-        * Copies given contact into the controller
-        * <p>
-        * @param contact Contact instance
-        */
-       private void copyContact (final Contact contact) {
-               // Is the instance valid?
-               if (null == contact) {
-                       // Throw NPE
-                       throw new NullPointerException("contact is null"); //NOI18N
-               } else if (contact.getContactId() == null) {
-                       // Throw NPE
-                       throw new NullPointerException("contact.contactId is null"); //NOI18N
-               } else if (contact.getContactId() < 1) {
-                       // Not valid id number
-                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
-               }
-
-               // Copy all fields:
-               // - base data
-               this.setPersonalTitle(contact.getContactPersonalTitle());
-               this.setAcademicTitle(contact.getContactTitle());
-               this.setFirstName(contact.getContactFirstName());
-               this.setFamilyName(contact.getContactFamilyName());
-               this.setStreet(contact.getContactStreet());
-               this.setHouseNumber(contact.getContactHouseNumber());
-               this.setHouseNumberExtension(contact.getContactHouseNumberExtension());
-               this.setZipCode(contact.getContactZipCode());
-               this.setCity(contact.getContactCity());
-               this.setCountry(contact.getContactCountry());
-               this.setEmailAddress(contact.getContactEmailAddress());
-               this.setBirthday(contact.getContactBirthday());
-               this.setComment(contact.getContactComment());
-
-               // Get mobile, phone and fax instance
-               DialableMobileNumber mobile = contact.getContactMobileNumber();
-               DialableFaxNumber fax = contact.getContactFaxNumber();
-               DialableLandLineNumber phone = contact.getContactLandLineNumber();
-
-               // - contact data
-               if ((phone instanceof DialableLandLineNumber) && (phone.getPhoneAreaCode() > 0)) {
-                       this.setLandLineCountry(phone.getPhoneCountry());
-                       this.setLandLineAreaCode(phone.getPhoneAreaCode());
-                       this.setLandLineNumber(phone.getPhoneNumber());
-               }
-
-               if ((mobile instanceof DialableMobileNumber) && (mobile.getMobileProvider() instanceof MobileProvider)) {
-                       this.setMobileProvider(mobile.getMobileProvider());
-                       this.setMobileNumber(mobile.getPhoneNumber());
-               }
-
-               if ((fax instanceof DialableFaxNumber) && (fax.getPhoneAreaCode() > 0)) {
-                       this.setFaxCountry(fax.getPhoneCountry());
-                       this.setFaxAreaCode(fax.getPhoneAreaCode());
-                       this.setFaxNumber(fax.getPhoneNumber());
-               }
-       }
-
-       /**
-        * Removes given contact from all lists
-        * <p>
-        * @param contact Contact instance to remove
-        */
-       private void removeContact (final Contact contact) {
-               // Is the instance valid?
-               if (null == contact) {
-                       // Throw NPE
-                       throw new NullPointerException("contact is null"); //NOI18N
-               } else if (contact.getContactId() == null) {
-                       // Throw NPE
-                       throw new NullPointerException("contact.contactId is null"); //NOI18N
-               } else if (contact.getContactId() < 1) {
-                       // Not valid id number
-                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
-               }
-
-               // Remove from general list
-               if (!this.contactList.remove(contact)) {
-                       // Did not remove contact
-                       throw new IllegalStateException(MessageFormat.format("contact {0} was not removed.", contact.getContactId())); //NOI18N
-               }
-
-               // Remove from other lists
-               this.emailAddressList.remove(contact.getContactEmailAddress());
-       }
-
-       /**
-        * Adds unique instance to contact list. First any existing instance is
-        * being removed, then the new instance is added.
-        * <p>
-        * @param contact Contact instance to add uniquely
-        */
-       private void uniqueAddContact (final Contact contact) {
-               // Is the instance valid?
-               if (null == contact) {
-                       // Throw NPE
-                       throw new NullPointerException("contact is null"); //NOI18N
-               } else if (contact.getContactId() == null) {
-                       // Throw NPE
-                       throw new NullPointerException("contact.contactId is null"); //NOI18N
-               } else if (contact.getContactId() < 1) {
-                       // Not valid id number
-                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid.", contact.getContactId())); //NOI18N
-               }
-
-               // Get iterator from list
-               Iterator<Contact> iterator = this.contactList.iterator();
-
-               // "Walk" through all entries
-               while (iterator.hasNext()) {
-                       // Get next element
-                       Contact next = iterator.next();
-
-                       // Is id number the same?
-                       if (Objects.equals(contact.getContactId(), next.getContactId())) {
-                               // Found entry, so remove it and abort
-                               this.removeContact(next);
-                               break;
-                       }
-               }
-
-               // Add contact to list
-               this.contactList.add(contact);
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/contact/FinancialsContactWebSessionController.java
deleted file mode 100644 (file)
index b345e41..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.contact;
-
-import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jcontacts.contact.Contact;
-
-/**
- * An interface for user beans
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsContactWebSessionController extends Serializable {
-
-       /**
-        * Minimum password length
-        */
-       public static final Integer MINIMUM_PASSWORD_LENGTH = 5;
-
-       /**
-        * Getter for email address
-        * <p>
-        * @return Email address
-        */
-       String getEmailAddress ();
-
-       /**
-        * Clears both email address field
-        */
-       void clearEmailAddresses ();
-
-       /**
-        * Returns a list of all found contacts
-        * <p>
-        * @return A list of all contacts.
-        */
-       List<Contact> allContacts ();
-
-       /**
-        * Updates all data from bean in given contact instance
-        * <p>
-        * @param userContact Contact instance to update
-        */
-       void updateContactDataFromController (final Contact userContact);
-
-       /**
-        * Creates an instance from all properties
-        * <p>
-        * @return A contact instance
-        */
-       Contact createContactInstance ();
-
-       /**
-        * Getter for controller type
-        * <p>
-        * @return controller type
-        */
-       String getControllerType ();
-
-       /**
-        * Setter for controller type
-        * <p>
-        * @param controllerType Controller type
-        * <p>
-        * @deprecated Don't use this method.
-        */
-       @Deprecated
-       void setControllerType (final String controllerType);
-
-       /**
-        * Checks whether contact instance's email address is used
-        * <p>
-        * @param contact Contact instance's email address to check
-        * <p>
-        * @return Whether it is already used
-        */
-       boolean isEmailAddressRegistered (final Contact contact);
-
-       /**
-        * Checks whether all required personal data is set
-        * <p>
-        * @return Whether the required personal data is set
-        */
-       boolean isRequiredPersonalDataSet ();
-
-       /**
-        * Checks whether all required personal data is set for changing them
-        * <p>
-        * @return Whether the required personal data is set
-        */
-       boolean isRequiredChangePersonalDataSet ();
-
-       /**
-        * Checks whether same email addresses have been entered
-        * <p>
-        * @return Whether same email addresses have been entered
-        */
-       boolean isSameEmailAddressEntered ();
-
-       /**
-        * Changes logged-in user's personal data if the current password matches
-        * and TAC + privacy statement has been accepted.
-        * <p>
-        * @return New target page
-        */
-       String doChangePersonalContactData ();
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestBean.java
new file mode 100644 (file)
index 0000000..0477ae7
--- /dev/null
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.contact.phone;
+
+import java.text.MessageFormat;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import javax.cache.Cache;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
+import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
+import org.mxchange.jcontacts.events.fax.unlinked.ObservableAdminUnlinkedFaxNumberEvent;
+import org.mxchange.jcontacts.events.landline.unlinked.ObservableAdminUnlinkedLandLineNumberEvent;
+import org.mxchange.jcontacts.events.mobile.unlinked.ObservableAdminUnlinkedMobileNumberEvent;
+import org.mxchange.jcoreee.jcache.Cached;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jphone.events.fax.created.ObservableCreatedFaxNumberEvent;
+import org.mxchange.jphone.events.landline.created.ObservableCreatedLandLineNumberEvent;
+import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent;
+import org.mxchange.jphone.phonenumbers.DialableNumber;
+import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
+import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
+import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestController;
+
+/**
+ * A general contact bean (controller)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("contactPhoneController")
+@RequestScoped
+public class FinancialsContactPhoneWebRequestBean extends BaseFinancialsController implements FinancialsContactPhoneWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 542_145_347_916L;
+
+       /**
+        * General contact controller
+        */
+       @Inject
+       private FinancialsContactWebRequestController contactController;
+
+       /**
+        * "Cache" for contact's mobile, land-line and fax numbers. Currently one
+        * per each type is supported. Maybe later this will change into a OneToMany
+        * relationship (one contact, many numbers).
+        */
+       @Inject
+       @Cached(cacheName = "contactsPhoneCache")
+       private transient Cache<DialableNumber, List<Contact>> contactsPhoneCache;
+
+       /**
+        * fax number
+        */
+       private DialableFaxNumber faxNumber;
+
+       /**
+        * land-line number
+        */
+       private DialableLandLineNumber landLineNumber;
+
+       /**
+        * Chosen mobile number
+        */
+       private DialableMobileNumber mobileNumber;
+
+       /**
+        * Default constructor
+        */
+       public FinancialsContactPhoneWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Observes events being fired when an administrator has added a new
+        * contact.
+        * <p>
+        * @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
+               }
+
+               // Clear this bean
+               this.clear();
+       }
+
+       /**
+        * Event observer for newly added users by administrator
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getAddedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.addedUser is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+               }
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Event observer for unlinked fax contact by administrators
+        * <p>
+        * @param event Unlinked fax contact event
+        */
+       public void afterAdminUnlinkedFaxContactDataEvent (@Observes final ObservableAdminUnlinkedFaxNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUnlinkedFaxNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.unlinkedFaxNumber is null"); //NOI18N
+               } else if (event.getUnlinkedFaxNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.unlinkedFaxNumber.contactId is null"); //NOI18N
+               } else if (event.getUnlinkedFaxNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedFaxNumber(), event.getUnlinkedFaxNumber().getPhoneId())); //NOI18N
+               }
+
+               // Remove it from list
+               this.contactsPhoneCache.remove(event.getUnlinkedFaxNumber());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Event observer for unlinked land-line contact by administrators
+        * <p>
+        * @param event Unlinked land-line contact event
+        */
+       public void afterAdminUnlinkedLandLineContactDataEvent (@Observes final ObservableAdminUnlinkedLandLineNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUnlinkedLandLineNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.unlinkedLandLineNumber is null"); //NOI18N
+               } else if (event.getUnlinkedLandLineNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.unlinkedLandLineNumber.contactId is null"); //NOI18N
+               } else if (event.getUnlinkedLandLineNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedLandLineNumber(), event.getUnlinkedLandLineNumber().getPhoneId())); //NOI18N
+               }
+
+               // Remove it from list
+               this.contactsPhoneCache.remove(event.getUnlinkedLandLineNumber());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Event observer for unlinked mobile contact by administrators
+        * <p>
+        * @param event Unlinked mobile contact event
+        */
+       public void afterAdminUnlinkedMobileContactDataEvent (@Observes final ObservableAdminUnlinkedMobileNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUnlinkedMobileNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.unlinkedMobileNumber is null"); //NOI18N
+               } else if (event.getUnlinkedMobileNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.unlinkedMobileNumber.contactId is null"); //NOI18N
+               } else if (event.getUnlinkedMobileNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedMobileNumber(), event.getUnlinkedMobileNumber().getPhoneId())); //NOI18N
+               }
+
+               // Remove it from list
+               this.contactsPhoneCache.remove(event.getUnlinkedMobileNumber());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Event observer for updated contact data by administrators
+        * <p>
+        * @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("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
+               }
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when a bean helper has successfully created a
+        * fax number instance.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterCreatedFaxNumberEvent (@Observes final ObservableCreatedFaxNumberEvent event) {
+               // The event instance must be valid
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getFaxNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.faxNumber is null"); //NOI18N
+               } else if (event.getFaxNumber().getPhoneId() == null) {
+                       // Throw NPE yet again
+                       throw new NullPointerException("event.faxNumber.phoneId is null"); //NOI18N
+               } else if (event.getFaxNumber().getPhoneId() < 1) {
+                       // Throw NPE yet again
+                       throw new NullPointerException(MessageFormat.format("event.faxNumber.phoneId={0} is invalid", event.getFaxNumber().getPhoneId())); //NOI18N
+               }
+
+               // Set it here
+               this.setFaxNumber(event.getFaxNumber());
+       }
+
+       /**
+        * Observes events being fired when a bean helper has successfully created a
+        * land-line number instance.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterCreatedLandLineNumberEvent (@Observes final ObservableCreatedLandLineNumberEvent event) {
+               // The event instance must be valid
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLandLineNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.landLineNumber is null"); //NOI18N
+               } else if (event.getLandLineNumber().getPhoneId() == null) {
+                       // Throw NPE yet again
+                       throw new NullPointerException("event.landLineNumber.phoneId is null"); //NOI18N
+               } else if (event.getLandLineNumber().getPhoneId() < 1) {
+                       // Throw NPE yet again
+                       throw new NullPointerException(MessageFormat.format("event.landLineNumber.phoneId={0} is invalid", event.getLandLineNumber().getPhoneId())); //NOI18N
+               }
+
+               // Set it here
+               this.setLandLineNumber(event.getLandLineNumber());
+       }
+
+       /**
+        * Observes events being fired when a bean helper has successfully created a
+        * mobile number instance.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterCreatedMobileNumberEvent (@Observes final ObservableCreatedMobileNumberEvent event) {
+               // The event instance must be valid
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getMobileNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.mobileNumber is null"); //NOI18N
+               } else if (event.getMobileNumber().getPhoneId() == null) {
+                       // Throw NPE yet again
+                       throw new NullPointerException("event.mobileNumber.phoneId is null"); //NOI18N
+               } else if (event.getMobileNumber().getPhoneId() < 1) {
+                       // Throw NPE yet again
+                       throw new NullPointerException(MessageFormat.format("event.mobileNumber.phoneId={0} is invalid", event.getMobileNumber().getPhoneId())); //NOI18N
+               }
+
+               // Set it here
+               this.setMobileNumber(event.getMobileNumber());
+       }
+
+       /**
+        * Getter for all contacts having current fax number linked
+        * <p>
+        * @return List of all linked contacts
+        */
+       public List<Contact> allCurrentFaxNumberContacts () {
+               // Get id
+               DialableFaxNumber number = this.getFaxNumber();
+
+               // Is cache there?
+               if (this.contactsPhoneCache.containsKey(number)) {
+                       // Return cached version
+                       return this.contactsPhoneCache.get(number);
+               } else {
+                       // Ask bean
+                       List<Contact> list = new LinkedList<>();
+
+                       // "Walk" through all contacts
+                       for (final Contact contact : this.contactController.allContacts()) {
+                               // Is mobile instance the same?
+                               if (Objects.equals(contact.getContactFaxNumber(), number)) {
+                                       // Found one
+                                       list.add(contact);
+                               }
+                       }
+
+                       // Store result in cache
+                       this.contactsPhoneCache.put(number, list);
+
+                       // Return now-cached list
+                       return list;
+               }
+       }
+
+       /**
+        * Getter for all contacts having current land-line number linked
+        * <p>
+        * @return List of all linked contacts
+        */
+       public List<Contact> allCurrentLandLineNumberContacts () {
+               // Get id
+               DialableLandLineNumber number = this.getLandLineNumber();
+
+               // Is cache there?
+               if (this.contactsPhoneCache.containsKey(number)) {
+                       // Return cached version
+                       return this.contactsPhoneCache.get(number);
+               } else {
+                       // Ask bean
+                       List<Contact> list = new LinkedList<>();
+
+                       // "Walk" through all contacts
+                       for (final Contact contact : this.contactController.allContacts()) {
+                               // Is mobile instance the same?
+                               if (Objects.equals(contact.getContactLandLineNumber(), number)) {
+                                       // Found one
+                                       list.add(contact);
+                               }
+                       }
+
+                       // Store result in cache
+                       this.contactsPhoneCache.put(number, list);
+
+                       // Return now-cached list
+                       return list;
+               }
+       }
+
+       /**
+        * Getter for all contacts having current mobile number linked
+        * <p>
+        * @return List of all linked contacts
+        */
+       public List<Contact> allCurrentMobileNumberContacts () {
+               // Get id
+               DialableMobileNumber number = this.getMobileNumber();
+
+               // Is cache there?
+               if (this.contactsPhoneCache.containsKey(number)) {
+                       // Return cached version
+                       return this.contactsPhoneCache.get(number);
+               } else {
+                       // Ask bean
+                       List<Contact> list = new LinkedList<>();
+
+                       // "Walk" through all contacts
+                       for (final Contact contact : this.contactController.allContacts()) {
+                               // Is mobile instance the same?
+                               if (Objects.equals(contact.getContactMobileNumber(), number)) {
+                                       // Found one
+                                       list.add(contact);
+                               }
+                       }
+
+                       // Store result in cache
+                       this.contactsPhoneCache.put(number, list);
+
+                       // Return now-cached list
+                       return list;
+               }
+       }
+
+       /**
+        * Getter for chosen fax number
+        * <p>
+        * @return fax number
+        */
+       public DialableFaxNumber getFaxNumber () {
+               return this.faxNumber;
+       }
+
+       /**
+        * Setter for chosen fax number
+        * <p>
+        * @param faxNumber fax number
+        */
+       public void setFaxNumber (final DialableFaxNumber faxNumber) {
+               this.faxNumber = faxNumber;
+       }
+
+       /**
+        * Getter for chosen land-line number
+        * <p>
+        * @return land-line number
+        */
+       public DialableLandLineNumber getLandLineNumber () {
+               return this.landLineNumber;
+       }
+
+       /**
+        * Setter for chosen land-line number
+        * <p>
+        * @param landLineNumber land-line number
+        */
+       public void setLandLineNumber (final DialableLandLineNumber landLineNumber) {
+               this.landLineNumber = landLineNumber;
+       }
+
+       /**
+        * Getter for chosen mobile number
+        * <p>
+        * @return mobile number
+        */
+       public DialableMobileNumber getMobileNumber () {
+               return this.mobileNumber;
+       }
+
+       /**
+        * Setter for chosen mobile number
+        * <p>
+        * @param mobileNumber mobile number
+        */
+       public void setMobileNumber (final DialableMobileNumber mobileNumber) {
+               this.mobileNumber = mobileNumber;
+       }
+
+       /**
+        * Clears this bean
+        */
+       private void clear () {
+               // Clear all data
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebRequestController.java
new file mode 100644 (file)
index 0000000..f8233b3
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.contact.phone;
+
+import java.io.Serializable;
+
+/**
+ * An interface for user beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsContactPhoneWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebSessionBean.java b/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebSessionBean.java
deleted file mode 100644 (file)
index 17ebaa4..0000000
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.contact.phone;
-
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jcontacts.contact.Contact;
-import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
-import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
-import org.mxchange.jcontacts.events.fax.unlinked.ObservableAdminUnlinkedFaxNumberEvent;
-import org.mxchange.jcontacts.events.landline.unlinked.ObservableAdminUnlinkedLandLineNumberEvent;
-import org.mxchange.jcontacts.events.mobile.unlinked.ObservableAdminUnlinkedMobileNumberEvent;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.contact.FinancialsContactWebSessionController;
-import org.mxchange.jphone.events.fax.created.ObservableCreatedFaxNumberEvent;
-import org.mxchange.jphone.events.landline.created.ObservableCreatedLandLineNumberEvent;
-import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEvent;
-import org.mxchange.jphone.phonenumbers.DialableNumber;
-import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
-import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
-import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
-import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
-
-/**
- * A general contact bean (controller)
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("contactPhoneController")
-@SessionScoped
-public class FinancialsContactPhoneWebSessionBean extends BaseFinancialsController implements FinancialsContactPhoneWebSessionController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 542_145_347_916L;
-
-       /**
-        * General contact controller
-        */
-       @Inject
-       private FinancialsContactWebSessionController contactController;
-
-       /**
-        * "Cache" for contact's mobile, land-line and fax numbers. Currently one
-        * per each type is supported. Maybe later this will change into a OneToMany
-        * relationship (one contact, many numbers).
-        */
-       private final Map<DialableNumber, List<Contact>> contacts;
-
-       /**
-        * fax number
-        */
-       private DialableFaxNumber faxNumber;
-
-       /**
-        * land-line number
-        */
-       private DialableLandLineNumber landLineNumber;
-
-       /**
-        * Chosen mobile number
-        */
-       private DialableMobileNumber mobileNumber;
-
-       /**
-        * Default constructor
-        */
-       public FinancialsContactPhoneWebSessionBean () {
-               // Call super constructor
-               super();
-
-               // Init lists/maps
-               this.contacts = new HashMap<>(10);
-       }
-
-       /**
-        * Observes events being fired when an administrator has added a new
-        * contact.
-        * <p>
-        * @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
-               }
-
-               // Clear this bean
-               this.clear();
-       }
-
-       /**
-        * Event observer for newly added users by administrator
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getAddedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.addedUser is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
-               }
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Event observer for unlinked fax contact by administrators
-        * <p>
-        * @param event Unlinked fax contact event
-        */
-       public void afterAdminUnlinkedFaxContactDataEvent (@Observes final ObservableAdminUnlinkedFaxNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUnlinkedFaxNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.unlinkedFaxNumber is null"); //NOI18N
-               } else if (event.getUnlinkedFaxNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.unlinkedFaxNumber.contactId is null"); //NOI18N
-               } else if (event.getUnlinkedFaxNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedFaxNumber(), event.getUnlinkedFaxNumber().getPhoneId())); //NOI18N
-               }
-
-               // Remove it from list
-               this.contacts.remove(event.getUnlinkedFaxNumber());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Event observer for unlinked land-line contact by administrators
-        * <p>
-        * @param event Unlinked land-line contact event
-        */
-       public void afterAdminUnlinkedLandLineContactDataEvent (@Observes final ObservableAdminUnlinkedLandLineNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUnlinkedLandLineNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.unlinkedLandLineNumber is null"); //NOI18N
-               } else if (event.getUnlinkedLandLineNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.unlinkedLandLineNumber.contactId is null"); //NOI18N
-               } else if (event.getUnlinkedLandLineNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedLandLineNumber(), event.getUnlinkedLandLineNumber().getPhoneId())); //NOI18N
-               }
-
-               // Remove it from list
-               this.contacts.remove(event.getUnlinkedLandLineNumber());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Event observer for unlinked mobile contact by administrators
-        * <p>
-        * @param event Unlinked mobile contact event
-        */
-       public void afterAdminUnlinkedMobileContactDataEvent (@Observes final ObservableAdminUnlinkedMobileNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUnlinkedMobileNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.unlinkedMobileNumber is null"); //NOI18N
-               } else if (event.getUnlinkedMobileNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.unlinkedMobileNumber.contactId is null"); //NOI18N
-               } else if (event.getUnlinkedMobileNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("contactId of contact={0} is not valid: {1}", event.getUnlinkedMobileNumber(), event.getUnlinkedMobileNumber().getPhoneId())); //NOI18N
-               }
-
-               // Remove it from list
-               this.contacts.remove(event.getUnlinkedMobileNumber());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Event observer for updated contact data by administrators
-        * <p>
-        * @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("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
-               }
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when a bean helper has successfully created a
-        * fax number instance.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterCreatedFaxNumberEvent (@Observes final ObservableCreatedFaxNumberEvent event) {
-               // The event instance must be valid
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getFaxNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.faxNumber is null"); //NOI18N
-               } else if (event.getFaxNumber().getPhoneId() == null) {
-                       // Throw NPE yet again
-                       throw new NullPointerException("event.faxNumber.phoneId is null"); //NOI18N
-               } else if (event.getFaxNumber().getPhoneId() < 1) {
-                       // Throw NPE yet again
-                       throw new NullPointerException(MessageFormat.format("event.faxNumber.phoneId={0} is invalid", event.getFaxNumber().getPhoneId())); //NOI18N
-               }
-
-               // Set it here
-               this.setFaxNumber(event.getFaxNumber());
-       }
-
-       /**
-        * Observes events being fired when a bean helper has successfully created a
-        * land-line number instance.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterCreatedLandLineNumberEvent (@Observes final ObservableCreatedLandLineNumberEvent event) {
-               // The event instance must be valid
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLandLineNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.landLineNumber is null"); //NOI18N
-               } else if (event.getLandLineNumber().getPhoneId() == null) {
-                       // Throw NPE yet again
-                       throw new NullPointerException("event.landLineNumber.phoneId is null"); //NOI18N
-               } else if (event.getLandLineNumber().getPhoneId() < 1) {
-                       // Throw NPE yet again
-                       throw new NullPointerException(MessageFormat.format("event.landLineNumber.phoneId={0} is invalid", event.getLandLineNumber().getPhoneId())); //NOI18N
-               }
-
-               // Set it here
-               this.setLandLineNumber(event.getLandLineNumber());
-       }
-
-       /**
-        * Observes events being fired when a bean helper has successfully created a
-        * mobile number instance.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterCreatedMobileNumberEvent (@Observes final ObservableCreatedMobileNumberEvent event) {
-               // The event instance must be valid
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getMobileNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.mobileNumber is null"); //NOI18N
-               } else if (event.getMobileNumber().getPhoneId() == null) {
-                       // Throw NPE yet again
-                       throw new NullPointerException("event.mobileNumber.phoneId is null"); //NOI18N
-               } else if (event.getMobileNumber().getPhoneId() < 1) {
-                       // Throw NPE yet again
-                       throw new NullPointerException(MessageFormat.format("event.mobileNumber.phoneId={0} is invalid", event.getMobileNumber().getPhoneId())); //NOI18N
-               }
-
-               // Set it here
-               this.setMobileNumber(event.getMobileNumber());
-       }
-
-       /**
-        * Getter for all contacts having current fax number linked
-        * <p>
-        * @return List of all linked contacts
-        */
-       public List<Contact> allCurrentFaxNumberContacts () {
-               // Get id
-               DialableFaxNumber number = this.getFaxNumber();
-
-               // Is cache there?
-               if (this.contacts.containsKey(number)) {
-                       // Return cached version
-                       return this.contacts.get(number);
-               } else {
-                       // Ask bean
-                       List<Contact> list = new LinkedList<>();
-
-                       // "Walk" through all contacts
-                       for (final Contact contact : this.contactController.allContacts()) {
-                               // Is mobile instance the same?
-                               if (Objects.equals(contact.getContactFaxNumber(), number)) {
-                                       // Found one
-                                       list.add(contact);
-                               }
-                       }
-
-                       // Store result in cache
-                       this.contacts.put(number, list);
-
-                       // Return now-cached list
-                       return list;
-               }
-       }
-
-       /**
-        * Getter for all contacts having current land-line number linked
-        * <p>
-        * @return List of all linked contacts
-        */
-       public List<Contact> allCurrentLandLineNumberContacts () {
-               // Get id
-               DialableLandLineNumber number = this.getLandLineNumber();
-
-               // Is cache there?
-               if (this.contacts.containsKey(number)) {
-                       // Return cached version
-                       return this.contacts.get(number);
-               } else {
-                       // Ask bean
-                       List<Contact> list = new LinkedList<>();
-
-                       // "Walk" through all contacts
-                       for (final Contact contact : this.contactController.allContacts()) {
-                               // Is mobile instance the same?
-                               if (Objects.equals(contact.getContactLandLineNumber(), number)) {
-                                       // Found one
-                                       list.add(contact);
-                               }
-                       }
-
-                       // Store result in cache
-                       this.contacts.put(number, list);
-
-                       // Return now-cached list
-                       return list;
-               }
-       }
-
-       /**
-        * Getter for all contacts having current mobile number linked
-        * <p>
-        * @return List of all linked contacts
-        */
-       public List<Contact> allCurrentMobileNumberContacts () {
-               // Get id
-               DialableMobileNumber number = this.getMobileNumber();
-
-               // Is cache there?
-               if (this.contacts.containsKey(number)) {
-                       // Return cached version
-                       return this.contacts.get(number);
-               } else {
-                       // Ask bean
-                       List<Contact> list = new LinkedList<>();
-
-                       // "Walk" through all contacts
-                       for (final Contact contact : this.contactController.allContacts()) {
-                               // Is mobile instance the same?
-                               if (Objects.equals(contact.getContactMobileNumber(), number)) {
-                                       // Found one
-                                       list.add(contact);
-                               }
-                       }
-
-                       // Store result in cache
-                       this.contacts.put(number, list);
-
-                       // Return now-cached list
-                       return list;
-               }
-       }
-
-       /**
-        * Getter for chosen fax number
-        * <p>
-        * @return fax number
-        */
-       public DialableFaxNumber getFaxNumber () {
-               return this.faxNumber;
-       }
-
-       /**
-        * Setter for chosen fax number
-        * <p>
-        * @param faxNumber fax number
-        */
-       public void setFaxNumber (final DialableFaxNumber faxNumber) {
-               this.faxNumber = faxNumber;
-       }
-
-       /**
-        * Getter for chosen land-line number
-        * <p>
-        * @return land-line number
-        */
-       public DialableLandLineNumber getLandLineNumber () {
-               return this.landLineNumber;
-       }
-
-       /**
-        * Setter for chosen land-line number
-        * <p>
-        * @param landLineNumber land-line number
-        */
-       public void setLandLineNumber (final DialableLandLineNumber landLineNumber) {
-               this.landLineNumber = landLineNumber;
-       }
-
-       /**
-        * Getter for chosen mobile number
-        * <p>
-        * @return mobile number
-        */
-       public DialableMobileNumber getMobileNumber () {
-               return this.mobileNumber;
-       }
-
-       /**
-        * Setter for chosen mobile number
-        * <p>
-        * @param mobileNumber mobile number
-        */
-       public void setMobileNumber (final DialableMobileNumber mobileNumber) {
-               this.mobileNumber = mobileNumber;
-       }
-
-       /**
-        * Clears this bean
-        */
-       private void clear () {
-               // Clear all data
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/contact/phone/FinancialsContactPhoneWebSessionController.java
deleted file mode 100644 (file)
index 4ba4867..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.contact.phone;
-
-import java.io.Serializable;
-
-/**
- * An interface for user beans
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsContactPhoneWebSessionController extends Serializable {
-
-}
index a5cbab54c65e453e26949e06e6ac60e7ee5f87b9..1b736e359bbaefdca544e8b733b032a01d213983 100644 (file)
@@ -75,7 +75,7 @@ public class FinancialsAdminCountryWebRequestBean extends BaseFinancialsControll
         * Regular country controller
         */
        @Inject
-       private FinancialsCountryWebApplicationController countryController;
+       private FinancialsCountryWebRequestController countryController;
 
        /**
         * Local dial prefix
diff --git a/src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebApplicationBean.java b/src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebApplicationBean.java
deleted file mode 100644 (file)
index 55f9b3b..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.country;
-
-import java.text.MessageFormat;
-import java.util.List;
-import javax.annotation.PostConstruct;
-import javax.ejb.EJB;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Named;
-import org.mxchange.jcountry.data.Country;
-import org.mxchange.jcountry.data.CountrySingletonBeanRemote;
-import org.mxchange.jcountry.events.ObservableAdminAddedCountryEvent;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-
-/**
- * A country bean
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("countryController")
-@ApplicationScoped
-public class FinancialsCountryWebApplicationBean extends BaseFinancialsController implements FinancialsCountryWebApplicationController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 176_985_298_681_742_960L;
-
-       /**
-        * Remote country EJB
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/country!org.mxchange.jcountry.data.CountrySingletonBeanRemote")
-       private CountrySingletonBeanRemote countryBean;
-
-       /**
-        * List of all countries
-        */
-       private List<Country> countryList;
-
-       /**
-        * Default constructor
-        */
-       public FinancialsCountryWebApplicationBean () {
-               // Call super constructor
-               super();
-       }
-
-       /**
-        * Observing method when the event is fired that an administrator added a
-        * new country
-        * <p>
-        * @param event Event instance
-        */
-       public void afterAdminAddedCountryEvent (@Observes final ObservableAdminAddedCountryEvent event) {
-               // Is all valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getAddedCountry() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.addedCountry is null"); //NOI18N
-               } else if (event.getAddedCountry().getCountryId() == null) {
-                       // And again ...
-                       throw new NullPointerException("event.addedCountry.countryId is null"); //NOI18N
-               } else if (event.getAddedCountry().getCountryId() < 1) {
-                       // Id is invalid
-                       throw new IllegalArgumentException(MessageFormat.format("event.addedCountry.countryId={0} is not valid.", event.getAddedCountry().getCountryId())); //NOI18N
-               }
-
-               // Add the event
-               this.countryList.add(event.getAddedCountry());
-       }
-
-       @Override
-       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
-       public List<Country> allCountries () {
-               // Return "cached" version
-               return this.countryList;
-       }
-
-       /**
-        * Post-construction method
-        */
-       @PostConstruct
-       public void init () {
-               // "Cache" country list as this will not change so often.
-               this.countryList = this.countryBean.allCountries();
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebApplicationController.java b/src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebApplicationController.java
deleted file mode 100644 (file)
index 98737e0..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.country;
-
-import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jcountry.data.Country;
-
-/**
- * An interface for country beans
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsCountryWebApplicationController extends Serializable {
-
-       /**
-        * A list of all countries
-        * <p>
-        * @return All countries
-        */
-       List<Country> allCountries ();
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebRequestBean.java
new file mode 100644 (file)
index 0000000..a5a9ccf
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.country;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcoreee.jcache.Cached;
+import org.mxchange.jcountry.data.Country;
+import org.mxchange.jcountry.data.CountrySingletonBeanRemote;
+import org.mxchange.jcountry.events.ObservableAdminAddedCountryEvent;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+
+/**
+ * A country bean
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("countryController")
+@RequestScoped
+public class FinancialsCountryWebRequestBean extends BaseFinancialsController implements FinancialsCountryWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 176_985_298_681_742_960L;
+
+       /**
+        * Remote country EJB
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/country!org.mxchange.jcountry.data.CountrySingletonBeanRemote")
+       private CountrySingletonBeanRemote countryBean;
+
+       /**
+        * List of all countries
+        */
+       @Inject
+       @Cached (cacheName = "countryCache")
+       private transient Cache<Long, Country> countryCache;
+
+       /**
+        * Default constructor
+        */
+       public FinancialsCountryWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Observing method when the event is fired that an administrator added a
+        * new country
+        * <p>
+        * @param event Event instance
+        */
+       public void afterAdminAddedCountryEvent (@Observes final ObservableAdminAddedCountryEvent event) {
+               // Is all valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getAddedCountry() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.addedCountry is null"); //NOI18N
+               } else if (event.getAddedCountry().getCountryId() == null) {
+                       // And again ...
+                       throw new NullPointerException("event.addedCountry.countryId is null"); //NOI18N
+               } else if (event.getAddedCountry().getCountryId() < 1) {
+                       // Id is invalid
+                       throw new IllegalArgumentException(MessageFormat.format("event.addedCountry.countryId={0} is not valid.", event.getAddedCountry().getCountryId())); //NOI18N
+               }
+
+               // Add the event
+               this.countryCache.put(event.getAddedCountry().getCountryId(), event.getAddedCountry());
+       }
+
+       @Override
+       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+       public List<Country> allCountries () {
+               // Init list
+               List<Country> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, Country>> iterator = this.countryCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, Country> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
+       }
+
+       /**
+        * Post-construction method
+        */
+       @PostConstruct
+       public void init () {
+               // Is cache there?
+               if (!this.countryCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<Country> list = this.countryBean.allCountries();
+
+                       // Add all
+                       for (final Iterator<Country> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final Country next = iterator.next();
+
+                               // Add it to cache
+                               this.countryCache.put(next.getCountryId(), next);
+                       }
+               }
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/country/FinancialsCountryWebRequestController.java
new file mode 100644 (file)
index 0000000..b4e5960
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.country;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jcountry.data.Country;
+
+/**
+ * An interface for country beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsCountryWebRequestController extends Serializable {
+
+       /**
+        * A list of all countries
+        * <p>
+        * @return All countries
+        */
+       List<Country> allCountries ();
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebRequestBean.java
new file mode 100644 (file)
index 0000000..2eca75a
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.financial.receipt;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.List;
+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.jcontactsbusiness.basicdata.BusinessBasicData;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
+import org.mxchange.jfinancials.exceptions.ReceiptAlreadyAddedException;
+import org.mxchange.jfinancials.financial.receipt.FinancialReceiptSessionBeanRemote;
+import org.mxchange.jfinancials.model.receipt.BillableReceipt;
+import org.mxchange.jfinancials.model.receipt.FinancialReceipt;
+import org.mxchange.jproduct.model.payment.PaymentType;
+import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
+
+/**
+ * An administrative financial receipt bean (controller)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("financialReceiptController")
+@RequestScoped
+public class FinancialsReceiptWebRequestBean extends BaseFinancialsController implements FinancialsReceiptWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 56_189_028_928_371L;
+
+       /**
+        * EJB for general financial receipt purposes
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/financial!org.mxchange.jfinancials.financial.receipt.FinancialReceiptSessionBeanRemote")
+       private FinancialReceiptSessionBeanRemote financialBean;
+
+       /**
+        * Payment type being used for this receipt
+        */
+       private PaymentType paymentType;
+
+       /**
+        * Recipient issuing company (for example where the user went shopping to)
+        */
+       private BusinessBasicData receiptCompany;
+
+       /**
+        * Date/time the receipt has been issued
+        */
+       private Calendar receiptIssued;
+
+       /**
+        * Receipt number (only numbers)
+        */
+       private Long receiptNumber;
+
+       /**
+        * Cached receipts
+        */
+       private final List<BillableReceipt> receipts;
+
+       /**
+        * User instance
+        */
+       @Inject
+       private FinancialsUserLoginWebSessionController userLoginController;
+
+       /**
+        * Constructor
+        */
+       @SuppressWarnings ("CollectionWithoutInitialCapacity")
+       public FinancialsReceiptWebRequestBean () {
+               // Call super constructor
+               super();
+
+               // Init cache
+               this.receipts = new ArrayList<>();
+       }
+
+       /**
+        * Adds the completed receipt to database by calling an EJB business method.
+        * If not all required fields are set, a proper exception is being thrown.
+        * <p>
+        * @return Link outcome
+        */
+       public String addReceipt () {
+               // Pre-check if receipt number is set
+               if (this.getReceiptNumber() == null || this.getReceiptNumber() == 0) {
+                       // Generate one randomly
+                       Long randomNumber = Math.round(Math.random() * 1_000_000);
+
+                       // And set it here
+                       this.setReceiptNumber(randomNumber);
+               }
+
+               // Are all required fields set?
+               if (!this.userLoginController.isUserLoggedIn()) {
+                       // Not logged-in
+                       throw new IllegalStateException("User is not logged-in"); //NOI18N
+               } else if (this.getReceiptCompany() == null) {
+                       // Is not set
+                       throw new NullPointerException("this.receiptCompany is not set."); //NOI18N
+               } else if (this.getReceiptCompany().getCompanyDataId() == null) {
+                       // It must be an already peristed instance
+                       throw new NullPointerException("this.receiptCompany.businessContactId is not set."); //NOI18N
+               } else if (this.getReceiptCompany().getCompanyDataId() < 1) {
+                       // It must be an already peristed instance
+                       throw new IllegalArgumentException(MessageFormat.format("this.receiptCompany.businessContactId={0} is not valid.", this.getReceiptCompany().getCompanyDataId())); //NOI18N
+               } else if (this.getPaymentType() == null) {
+                       // Is not set
+                       throw new NullPointerException("this.paymentType is not set."); //NOI18N
+               } else if (this.getReceiptIssued() == null) {
+                       // Is not set
+                       throw new NullPointerException("this.receiptIssued is not set."); //NOI18N
+               }
+
+               // Prepare receipt instance
+               BillableReceipt receipt = new FinancialReceipt(this.getPaymentType(), this.getReceiptCompany(), this.userLoginController.getLoggedInUser(), this.getReceiptIssued());
+
+               if (this.isReceiptAdded(receipt)) {
+                       // Receipt has already been added
+                       throw new FaceletException(MessageFormat.format("Receipt for receiptCompany={0},receiptIssued={1},receiptNumber={2} has already been added.", this.getReceiptCompany().getCompanyDataId(), this.getReceiptIssued().toString(), this.getReceiptNumber())); //NOI18N
+               }
+
+               // Init variable
+               BillableReceipt updatedReceipt;
+
+               // All is set, then try to call EJB
+               try {
+                       // Add it
+                       updatedReceipt = this.financialBean.addReceipt(receipt);
+               } catch (final ReceiptAlreadyAddedException ex) {
+                       // Throw it again
+                       throw new FaceletException(ex);
+               }
+
+               // @TODO Maybe fire event here?
+               // Return redirect outcome
+               return "add_receipt_item?faces-redirect=true"; //NOI18N
+       }
+
+       /**
+        * Event observer for logged-in user
+        * <p>
+        * @param event Event instance
+        */
+       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLoggedInUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.loggedInUser is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
+               }
+
+               // Fill cache with all found user's receipts
+               this.receipts.addAll(this.financialBean.allUsersReceipts(this.userLoginController.getLoggedInUser()));
+       }
+
+       /**
+        * Returns a list of all payment types
+        * <p>
+        * @return A list of all payment types
+        */
+       public List<PaymentType> allPaymentTypes () {
+               return Arrays.asList(PaymentType.values());
+       }
+
+       /**
+        * Getter for payment type
+        * <p>
+        * @return Payment type
+        */
+       public PaymentType getPaymentType () {
+               return this.paymentType;
+       }
+
+       /**
+        * Setter for payment type
+        * <p>
+        * @param paymentType Payment type
+        */
+       public void setPaymentType (final PaymentType paymentType) {
+               this.paymentType = paymentType;
+       }
+
+       /**
+        * Getter for receipt issuing company
+        * <p>
+        * @return Receipt issuing company
+        */
+       public BusinessBasicData getReceiptCompany () {
+               return this.receiptCompany;
+       }
+
+       /**
+        * Setter for receipt issuing company
+        * <p>
+        * @param receiptCompany Receipt issuing company
+        */
+       public void setReceiptCompany (final BusinessBasicData receiptCompany) {
+               this.receiptCompany = receiptCompany;
+       }
+
+       /**
+        * Getter for receipt issue date and time
+        * <p>
+        * @return Receipt issue date and time
+        */
+       @SuppressWarnings ("ReturnOfDateField")
+       public Calendar getReceiptIssued () {
+               return this.receiptIssued;
+       }
+
+       /**
+        * Setter for receipt issue date and time
+        * <p>
+        * @param receiptIssued Receipt issue date and time
+        */
+       @SuppressWarnings ("AssignmentToDateFieldFromParameter")
+       public void setReceiptIssued (final Calendar receiptIssued) {
+               this.receiptIssued = receiptIssued;
+       }
+
+       /**
+        * Getter for receipt number
+        * <p>
+        * @return Receipt number
+        */
+       public Long getReceiptNumber () {
+               return this.receiptNumber;
+       }
+
+       /**
+        * Setter for receipt number
+        * <p>
+        * @param receiptNumber Receipt number
+        */
+       public void setReceiptNumber (final Long receiptNumber) {
+               this.receiptNumber = receiptNumber;
+       }
+
+       /**
+        * Checks if receipt has already been added to database
+        * <p>
+        * @param receipt Prepared receipt instance
+        * <p>
+        * @return Whether the receipt has already been added
+        */
+       private boolean isReceiptAdded (final BillableReceipt receipt) {
+               // Always trust the cache
+               return this.receipts.contains(receipt);
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebRequestController.java
new file mode 100644 (file)
index 0000000..67416d8
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.financial.receipt;
+
+import java.io.Serializable;
+
+/**
+ * An administrative interface for financial receipt beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsReceiptWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebSessionBean.java b/src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebSessionBean.java
deleted file mode 100644 (file)
index fc9cfba..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.financial.receipt;
-
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.List;
-import javax.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Observes;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jcontactsbusiness.basicdata.BusinessBasicData;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
-import org.mxchange.jfinancials.exceptions.ReceiptAlreadyAddedException;
-import org.mxchange.jfinancials.financial.receipt.FinancialReceiptSessionBeanRemote;
-import org.mxchange.jfinancials.model.receipt.BillableReceipt;
-import org.mxchange.jfinancials.model.receipt.FinancialReceipt;
-import org.mxchange.jproduct.model.payment.PaymentType;
-import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
-
-/**
- * An administrative financial receipt bean (controller)
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("financialReceiptController")
-@SessionScoped
-public class FinancialsReceiptWebSessionBean extends BaseFinancialsController implements FinancialsReceiptWebSessionController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 56_189_028_928_371L;
-
-       /**
-        * EJB for general financial receipt purposes
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/financial!org.mxchange.jfinancials.financial.receipt.FinancialReceiptSessionBeanRemote")
-       private FinancialReceiptSessionBeanRemote financialBean;
-
-       /**
-        * Payment type being used for this receipt
-        */
-       private PaymentType paymentType;
-
-       /**
-        * Recipient issuing company (for example where the user went shopping to)
-        */
-       private BusinessBasicData receiptCompany;
-
-       /**
-        * Date/time the receipt has been issued
-        */
-       private Calendar receiptIssued;
-
-       /**
-        * Receipt number (only numbers)
-        */
-       private Long receiptNumber;
-
-       /**
-        * Cached receipts
-        */
-       private final List<BillableReceipt> receipts;
-
-       /**
-        * User instance
-        */
-       @Inject
-       private FinancialsUserLoginWebSessionController userLoginController;
-
-       /**
-        * Constructor
-        */
-       @SuppressWarnings ("CollectionWithoutInitialCapacity")
-       public FinancialsReceiptWebSessionBean () {
-               // Call super constructor
-               super();
-
-               // Init cache
-               this.receipts = new ArrayList<>();
-       }
-
-       /**
-        * Adds the completed receipt to database by calling an EJB business method.
-        * If not all required fields are set, a proper exception is being thrown.
-        * <p>
-        * @return Link outcome
-        */
-       public String addReceipt () {
-               // Pre-check if receipt number is set
-               if (this.getReceiptNumber() == null || this.getReceiptNumber() == 0) {
-                       // Generate one randomly
-                       Long randomNumber = Math.round(Math.random() * 1_000_000);
-
-                       // And set it here
-                       this.setReceiptNumber(randomNumber);
-               }
-
-               // Are all required fields set?
-               if (!this.userLoginController.isUserLoggedIn()) {
-                       // Not logged-in
-                       throw new IllegalStateException("User is not logged-in"); //NOI18N
-               } else if (this.getReceiptCompany() == null) {
-                       // Is not set
-                       throw new NullPointerException("this.receiptCompany is not set."); //NOI18N
-               } else if (this.getReceiptCompany().getCompanyDataId() == null) {
-                       // It must be an already peristed instance
-                       throw new NullPointerException("this.receiptCompany.businessContactId is not set."); //NOI18N
-               } else if (this.getReceiptCompany().getCompanyDataId() < 1) {
-                       // It must be an already peristed instance
-                       throw new IllegalArgumentException(MessageFormat.format("this.receiptCompany.businessContactId={0} is not valid.", this.getReceiptCompany().getCompanyDataId())); //NOI18N
-               } else if (this.getPaymentType() == null) {
-                       // Is not set
-                       throw new NullPointerException("this.paymentType is not set."); //NOI18N
-               } else if (this.getReceiptIssued() == null) {
-                       // Is not set
-                       throw new NullPointerException("this.receiptIssued is not set."); //NOI18N
-               }
-
-               // Prepare receipt instance
-               BillableReceipt receipt = new FinancialReceipt(this.getPaymentType(), this.getReceiptCompany(), this.userLoginController.getLoggedInUser(), this.getReceiptIssued());
-
-               if (this.isReceiptAdded(receipt)) {
-                       // Receipt has already been added
-                       throw new FaceletException(MessageFormat.format("Receipt for receiptCompany={0},receiptIssued={1},receiptNumber={2} has already been added.", this.getReceiptCompany().getCompanyDataId(), this.getReceiptIssued().toString(), this.getReceiptNumber())); //NOI18N
-               }
-
-               // Init variable
-               BillableReceipt updatedReceipt;
-
-               // All is set, then try to call EJB
-               try {
-                       // Add it
-                       updatedReceipt = this.financialBean.addReceipt(receipt);
-               } catch (final ReceiptAlreadyAddedException ex) {
-                       // Throw it again
-                       throw new FaceletException(ex);
-               }
-
-               // @TODO Maybe fire event here?
-               // Return redirect outcome
-               return "add_receipt_item?faces-redirect=true"; //NOI18N
-       }
-
-       /**
-        * Event observer for logged-in user
-        * <p>
-        * @param event Event instance
-        */
-       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLoggedInUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.loggedInUser is null"); //NOI18N
-               } else if (event.getLoggedInUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
-               } else if (event.getLoggedInUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
-               }
-
-               // Fill cache with all found user's receipts
-               this.receipts.addAll(this.financialBean.allUsersReceipts(this.userLoginController.getLoggedInUser()));
-       }
-
-       /**
-        * Returns a list of all payment types
-        * <p>
-        * @return A list of all payment types
-        */
-       public List<PaymentType> allPaymentTypes () {
-               return Arrays.asList(PaymentType.values());
-       }
-
-       /**
-        * Getter for payment type
-        * <p>
-        * @return Payment type
-        */
-       public PaymentType getPaymentType () {
-               return this.paymentType;
-       }
-
-       /**
-        * Setter for payment type
-        * <p>
-        * @param paymentType Payment type
-        */
-       public void setPaymentType (final PaymentType paymentType) {
-               this.paymentType = paymentType;
-       }
-
-       /**
-        * Getter for receipt issuing company
-        * <p>
-        * @return Receipt issuing company
-        */
-       public BusinessBasicData getReceiptCompany () {
-               return this.receiptCompany;
-       }
-
-       /**
-        * Setter for receipt issuing company
-        * <p>
-        * @param receiptCompany Receipt issuing company
-        */
-       public void setReceiptCompany (final BusinessBasicData receiptCompany) {
-               this.receiptCompany = receiptCompany;
-       }
-
-       /**
-        * Getter for receipt issue date and time
-        * <p>
-        * @return Receipt issue date and time
-        */
-       @SuppressWarnings ("ReturnOfDateField")
-       public Calendar getReceiptIssued () {
-               return this.receiptIssued;
-       }
-
-       /**
-        * Setter for receipt issue date and time
-        * <p>
-        * @param receiptIssued Receipt issue date and time
-        */
-       @SuppressWarnings ("AssignmentToDateFieldFromParameter")
-       public void setReceiptIssued (final Calendar receiptIssued) {
-               this.receiptIssued = receiptIssued;
-       }
-
-       /**
-        * Getter for receipt number
-        * <p>
-        * @return Receipt number
-        */
-       public Long getReceiptNumber () {
-               return this.receiptNumber;
-       }
-
-       /**
-        * Setter for receipt number
-        * <p>
-        * @param receiptNumber Receipt number
-        */
-       public void setReceiptNumber (final Long receiptNumber) {
-               this.receiptNumber = receiptNumber;
-       }
-
-       /**
-        * Checks if receipt has already been added to database
-        * <p>
-        * @param receipt Prepared receipt instance
-        * <p>
-        * @return Whether the receipt has already been added
-        */
-       private boolean isReceiptAdded (final BillableReceipt receipt) {
-               // Always trust the cache
-               return this.receipts.contains(receipt);
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/financial/receipt/FinancialsReceiptWebSessionController.java
deleted file mode 100644 (file)
index 957f012..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.financial.receipt;
-
-import java.io.Serializable;
-
-/**
- * An administrative interface for financial receipt beans
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsReceiptWebSessionController extends Serializable {
-
-}
index 44c9144cef12f498717186b235094824d40d6f60..a1d6a3788eaed84328b012f1cca0370099fc3b41 100644 (file)
@@ -29,7 +29,6 @@ import org.mxchange.jfinancials.beans.BaseFinancialsController;
 import org.mxchange.jfinancials.beans.contact.FinancialsAdminContactWebRequestController;
 import org.mxchange.jfinancials.beans.phone.FinancialsAdminPhoneWebRequestController;
 import org.mxchange.jfinancials.beans.user.FinancialsAdminUserWebRequestController;
-import org.mxchange.jfinancials.beans.user.FinancialsUserWebSessionController;
 import org.mxchange.jphone.events.fax.created.CreatedFaxNumberEvent;
 import org.mxchange.jphone.events.fax.created.ObservableCreatedFaxNumberEvent;
 import org.mxchange.jphone.events.landline.created.CreatedLandLineNumberEvent;
@@ -42,6 +41,7 @@ import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
 import org.mxchange.jusercore.events.user.created.CreatedUserEvent;
 import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
 import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jfinancials.beans.user.FinancialsUserWebRequestController;
 
 /**
  * A general helper for beans
@@ -137,7 +137,7 @@ public class FinancialsWebRequestHelperBean extends BaseFinancialsController imp
         * Regular user controller
         */
        @Inject
-       private FinancialsUserWebSessionController userController;
+       private FinancialsUserWebRequestController userController;
 
        /**
         * Event for when a user instance was created
index ee1509be34d4dc12ea3212fc60d10af22b75c2a9..f4490ca908d986bd2e24823291c2f0ea0d6a979e 100644 (file)
 package org.mxchange.jfinancials.beans.mobileprovider;
 
 import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import javax.annotation.PostConstruct;
+import javax.cache.Cache;
 import javax.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
+import javax.enterprise.context.RequestScoped;
 import javax.enterprise.event.Observes;
+import javax.inject.Inject;
 import javax.inject.Named;
+import org.mxchange.jcoreee.jcache.Cached;
 import org.mxchange.jfinancials.beans.BaseFinancialsController;
 import org.mxchange.jphone.events.mobileprovider.added.AdminAddedMobileProviderEvent;
 import org.mxchange.jphone.phonenumbers.mobileprovider.MobileProvider;
@@ -34,7 +39,7 @@ import org.mxchange.jphone.phonenumbers.mobileprovider.MobileProviderSingletonBe
  * @author Roland Häder<roland@mxchange.org>
  */
 @Named ("mobileProviderController")
-@SessionScoped
+@RequestScoped
 public class FinancialsMobileProviderWebRequestBean extends BaseFinancialsController implements FinancialsMobileProviderWebRequestController {
 
        /**
@@ -45,13 +50,15 @@ public class FinancialsMobileProviderWebRequestBean extends BaseFinancialsContro
        /**
         * "Cached" list of mobile providers
         */
-       private List<MobileProvider> mobileProviders;
+       @Inject
+       @Cached (cacheName = "mobileProviderCache")
+       private transient Cache<Long, MobileProvider> mobileProviderCache;
 
        /**
         * Remote EJB for mobile providers (regular)
         */
        @EJB (lookup = "java:global/jfinancials-ejb/mobileprovider!org.mxchange.jphone.phonenumbers.mobileprovider.MobileProviderSingletonBeanRemote")
-       private MobileProviderSingletonBeanRemote mobileRemoteBean;
+       private MobileProviderSingletonBeanRemote mobileProviderBean;
 
        /**
         * Default constructor
@@ -84,13 +91,29 @@ public class FinancialsMobileProviderWebRequestBean extends BaseFinancialsContro
                }
 
                // Add it to the list
-               this.mobileProviders.add(event.getAddedMobileProvider());
+               this.mobileProviderCache.put(event.getAddedMobileProvider().getProviderId(), event.getAddedMobileProvider());
        }
 
        @Override
        @SuppressWarnings ("ReturnOfCollectionOrArrayField")
        public List<MobileProvider> allMobileProviders () {
-               return this.mobileProviders;
+               // Init list
+               List<MobileProvider> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, MobileProvider>> iterator = this.mobileProviderCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, MobileProvider> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
        }
 
        /**
@@ -98,8 +121,20 @@ public class FinancialsMobileProviderWebRequestBean extends BaseFinancialsContro
         */
        @PostConstruct
        public void init () {
-               // Init list of mobile providers
-               this.mobileProviders = this.mobileRemoteBean.allMobileProvider();
+               // Is cache there?
+               if (!this.mobileProviderCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<MobileProvider> list = this.mobileProviderBean.allMobileProviders();
+
+                       // Add all
+                       for (final Iterator<MobileProvider> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final MobileProvider next = iterator.next();
+
+                               // Add it to cache
+                               this.mobileProviderCache.put(next.getProviderId(), next);
+                       }
+               }
        }
 
 }
index e99b72fcf362a154d2357a85b0a869a4b2d07ec1..fc5a681db92d00f99c95c865ec024ed0dcb74205 100644 (file)
@@ -155,7 +155,7 @@ public class FinancialsAdminPhoneWebRequestBean extends BaseFinancialsController
         * Generic hone controller
         */
        @Inject
-       private FinancialsPhoneWebApplicationController phoneController;
+       private FinancialsPhoneWebRequestController phoneController;
 
        /**
         * Country (for dial prefix)
diff --git a/src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebApplicationBean.java b/src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebApplicationBean.java
deleted file mode 100644 (file)
index 367019a..0000000
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.phone;
-
-import java.text.MessageFormat;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.ejb.EJB;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Named;
-import org.mxchange.jcontacts.contact.Contact;
-import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
-import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
-import org.mxchange.jcontacts.events.fax.linked.ObservableAdminLinkedFaxNumberEvent;
-import org.mxchange.jcontacts.events.landline.linked.ObservableAdminLinkedLandLineNumberEvent;
-import org.mxchange.jcontacts.events.mobile.linked.ObservableAdminLinkedMobileNumberEvent;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jphone.events.fax.deleted.AdminDeletedFaxNumberEvent;
-import org.mxchange.jphone.events.fax.updated.AdminUpdatedFaxNumberEvent;
-import org.mxchange.jphone.events.landline.deleted.AdminDeletedLandLineNumberEvent;
-import org.mxchange.jphone.events.landline.updated.AdminUpdatedLandLineNumberEvent;
-import org.mxchange.jphone.events.mobile.deleted.AdminDeletedMobileNumberEvent;
-import org.mxchange.jphone.events.mobile.updated.AdminUpdatedMobileNumberEvent;
-import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
-import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
-import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
-import org.mxchange.jphone.phonenumbers.phone.PhoneSessionBeanRemote;
-import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
-
-/**
- * Regular controller (bean) for phone numbers
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("phoneController")
-@ApplicationScoped
-public class FinancialsPhoneWebApplicationBean extends BaseFinancialsController implements FinancialsPhoneWebApplicationController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 491_058_674_675_690_105L;
-
-       /**
-        * All fax numbers
-        */
-       private final List<DialableFaxNumber> faxNumbers;
-
-       /**
-        * All land-line numbers
-        */
-       private final List<DialableLandLineNumber> landLineNumbers;
-
-       /**
-        * All mobile numbers
-        */
-       private final List<DialableMobileNumber> mobileNumbers;
-
-       /**
-        * General EJB for phone numbers
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/phone!org.mxchange.jphone.phonenumbers.phone.PhoneSessionBeanRemote")
-       private PhoneSessionBeanRemote phoneBean;
-
-       /**
-        * Default constructor
-        */
-       public FinancialsPhoneWebApplicationBean () {
-               // Call super constructor
-               super();
-
-               // Init all lists
-               this.mobileNumbers = new LinkedList<>();
-               this.faxNumbers = new LinkedList<>();
-               this.landLineNumbers = new LinkedList<>();
-       }
-
-       /**
-        * Observes events being fired when an administrator has added a new
-        * contact.
-        * <p>
-        * @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
-               }
-
-               // Update contact's mobile, land-line and fax number
-               this.updateContactPhoneNumbers(event.getAddedContact());
-
-               // Clear this bean
-               this.clear();
-       }
-
-       /**
-        * Event observer for newly added users by administrator
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getAddedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.addedUser is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
-               }
-
-               // Update contact's mobile, land-line and fax number
-               this.updateContactPhoneNumbers(event.getAddedUser().getUserContact());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when an administrator has deleted a fax
-        * number
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminDeletedFaxNumberEvent (@Observes final AdminDeletedFaxNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getDeletedFaxNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.deletedFaxNumber is null"); //NOI18N
-               } else if (event.getDeletedFaxNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.deletedFaxNumber.phoneId is null"); //NOI18N
-               } else if (event.getDeletedFaxNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedFaxNumber(), event.getDeletedFaxNumber().getPhoneId())); //NOI18N
-               }
-
-               // Update contact's mobile, land-line and fax number
-               this.allFaxNumbers().remove(event.getDeletedFaxNumber());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when an administrator has deleted a land-line
-        * number
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminDeletedLandLineNumberEvent (@Observes final AdminDeletedLandLineNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getDeletedLandLineNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.deletedLandLineNumber is null"); //NOI18N
-               } else if (event.getDeletedLandLineNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.deletedLandLineNumber.phoneId is null"); //NOI18N
-               } else if (event.getDeletedLandLineNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedLandLineNumber(), event.getDeletedLandLineNumber().getPhoneId())); //NOI18N
-               }
-
-               // Update contact's mobile, land-line and fax number
-               this.allLandLineNumbers().remove(event.getDeletedLandLineNumber());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when an administrator has deleted a mobile
-        * number
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminDeletedMobileNumberEvent (@Observes final AdminDeletedMobileNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getDeletedMobileNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.deletedMobileNumber is null"); //NOI18N
-               } else if (event.getDeletedMobileNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.deletedMobileNumber.phoneId is null"); //NOI18N
-               } else if (event.getDeletedMobileNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedMobileNumber(), event.getDeletedMobileNumber().getPhoneId())); //NOI18N
-               }
-
-               // Update contact's mobile, land-line and fax number
-               this.allMobileNumbers().remove(event.getDeletedMobileNumber());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when an administrator has a linked a fax
-        * number
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminLinkedFaxNumberEvent (@Observes final ObservableAdminLinkedFaxNumberEvent event) {
-               // Is the event fine?
-               if (event == null) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getContact() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact is null");
-               } else if (event.getContact().getContactId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactId is null");
-               } else if (event.getContact().getContactId() < 1) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
-               } else if (event.getContact().getContactFaxNumber() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactFaxNumber is null");
-               } else if (event.getContact().getContactFaxNumber().getPhoneId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactFaxNumber.phoneId is null");
-               } else if (event.getContact().getContactFaxNumber().getPhoneId() < 1) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactFaxNumber.phoneId=" + event.getContact().getContactFaxNumber().getPhoneId() + " is invalid");
-               } else if (event.getLinkedFaxNumber() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.linkedFaxNumer is null");
-               }
-
-               // Is the id number in linked number not set?
-               if (event.getLinkedFaxNumber().getPhoneId() == null) {
-                       // Then it is a new number, so add it from contact as there the id number has been set
-                       this.uniqueAddFaxNumber(event.getContact().getContactFaxNumber());
-               }
-       }
-
-       /**
-        * Observes events being fired when an administrator has a linked a
-        * land-line number
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminLinkedLandLineNumberEvent (@Observes final ObservableAdminLinkedLandLineNumberEvent event) {
-               // Is the event fine?
-               if (event == null) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getContact() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact is null");
-               } else if (event.getContact().getContactId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactId is null");
-               } else if (event.getContact().getContactId() < 1) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
-               } else if (event.getContact().getContactLandLineNumber() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactLandLineNumber is null");
-               } else if (event.getContact().getContactLandLineNumber().getPhoneId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactLandLineNumber.phoneId is null");
-               } else if (event.getContact().getContactLandLineNumber().getPhoneId() < 1) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactLandLineNumber.phoneId=" + event.getContact().getContactLandLineNumber().getPhoneId() + " is invalid");
-               } else if (event.getLinkedLandLineNumber() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.linkedLandLineNumer is null");
-               }
-
-               // Is the id number in linked number not set?
-               if (event.getLinkedLandLineNumber().getPhoneId() == null) {
-                       // Then it is a new number, so add it from contact as there the id number has been set
-                       this.uniqueAddLandLineNumber(event.getContact().getContactLandLineNumber());
-               }
-       }
-
-       /**
-        * Observes events being fired when an administrator has a linked a mobile
-        * number
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminLinkedMobileNumberEvent (@Observes final ObservableAdminLinkedMobileNumberEvent event) {
-               // Is the event fine?
-               if (event == null) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getContact() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact is null");
-               } else if (event.getContact().getContactId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactId is null");
-               } else if (event.getContact().getContactId() < 1) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
-               } else if (event.getContact().getContactMobileNumber() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactMobileNumber is null");
-               } else if (event.getContact().getContactMobileNumber().getPhoneId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactMobileNumber.phoneId is null");
-               } else if (event.getContact().getContactMobileNumber().getPhoneId() < 1) {
-                       // Throw again ...
-                       throw new NullPointerException("event.contact.contactMobileNumber.phoneId=" + event.getContact().getContactMobileNumber().getPhoneId() + " is invalid");
-               } else if (event.getLinkedMobileNumber() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("event.linkedMobileNumer is null");
-               }
-
-               // Is the id number in linked number not set?
-               if (event.getLinkedMobileNumber().getPhoneId() == null) {
-                       // Then it is a new number, so add it from contact as there the id number has been set
-                       this.uniqueAddMobileNumber(event.getContact().getContactMobileNumber());
-               }
-       }
-
-       /**
-        * Observes events being fired when an administrator has updated contact
-        * data.
-        * <p>
-        * @param event Event being fired
-        */
-       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("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
-               }
-
-               // Update contact's mobile, land-line and fax number
-               this.updateContactPhoneNumbers(event.getUpdatedContact());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when an administrator has updated a fax
-        * number.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminUpdatedFaxNumberEvent (@Observes final AdminUpdatedFaxNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUpdatedFaxNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.updatedFaxNumber is null"); //NOI18N
-               } else if (event.getUpdatedFaxNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.updatedFaxNumber.phoneId is null"); //NOI18N
-               } else if (event.getUpdatedFaxNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedFaxNumber(), event.getUpdatedFaxNumber().getPhoneId())); //NOI18N
-               }
-
-               // Uniquely add it
-               this.uniqueAddFaxNumber(event.getUpdatedFaxNumber());
-
-               // Clear it
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when an administrator has updated a land-line
-        * number.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminUpdatedLandLineNumberEvent (@Observes final AdminUpdatedLandLineNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUpdatedLandLineNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.updatedLandLineNumber is null"); //NOI18N
-               } else if (event.getUpdatedLandLineNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.updatedLandLineNumber.phoneId is null"); //NOI18N
-               } else if (event.getUpdatedLandLineNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedLandLineNumber(), event.getUpdatedLandLineNumber().getPhoneId())); //NOI18N
-               }
-
-               // Uniquely add it
-               this.uniqueAddLandLineNumber(event.getUpdatedLandLineNumber());
-
-               // Clear it
-               this.clear();
-       }
-
-       /**
-        * Observes events being fired when an administrator has updated a mobile
-        * number.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminUpdatedMobileNumberEvent (@Observes final AdminUpdatedMobileNumberEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUpdatedMobileNumber() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.updatedMobileNumber is null"); //NOI18N
-               } else if (event.getUpdatedMobileNumber().getPhoneId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.updatedMobileNumber.phoneId is null"); //NOI18N
-               } else if (event.getUpdatedMobileNumber().getPhoneId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedMobileNumber(), event.getUpdatedMobileNumber().getPhoneId())); //NOI18N
-               }
-
-               // Uniquely add it
-               this.uniqueAddMobileNumber(event.getUpdatedMobileNumber());
-
-               // Clear it
-               this.clear();
-       }
-
-       @Override
-       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
-       public List<DialableFaxNumber> allFaxNumbers () {
-               return this.faxNumbers;
-       }
-
-       @Override
-       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
-       public List<DialableLandLineNumber> allLandLineNumbers () {
-               return this.landLineNumbers;
-       }
-
-       @Override
-       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
-       public List<DialableMobileNumber> allMobileNumbers () {
-               return this.mobileNumbers;
-       }
-
-       /**
-        * Post-construction method
-        */
-       @PostConstruct
-       public void init () {
-               // All phone numbers
-               this.allMobileNumbers().addAll(this.phoneBean.allMobileNumbers());
-               this.allFaxNumbers().addAll(this.phoneBean.allFaxNumbers());
-               this.allLandLineNumbers().addAll(this.phoneBean.allLandLineNumbers());
-       }
-
-       /**
-        * Clears this bean
-        */
-       private void clear () {
-               // Clear all data
-       }
-
-       /**
-        * Uniquely add given fax number to this bean's list. First remove the old
-        * instance (by id number), then re-add it again.
-        * <p>
-        * @param faxNumber number to add
-        */
-       private void uniqueAddFaxNumber (final DialableFaxNumber faxNumber) {
-               // Make sure the parameter is valid
-               if (null == faxNumber) {
-                       // Throw NPE
-                       throw new NullPointerException("faxNumber is null");
-               } else if (faxNumber.getPhoneId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("faxNumber.phoneId is null");
-               } else if (faxNumber.getPhoneId() < 1) {
-                       // Not valid
-                       throw new IllegalArgumentException(MessageFormat.format("faxNumber.phoneId={0} is not valid.", faxNumber.getPhoneId()));
-               }
-
-               // First remove it
-               if (!this.allFaxNumbers().remove(faxNumber)) {
-                       // Did not work, try by id number
-                       for (final DialableFaxNumber fax : this.allFaxNumbers()) {
-                               // Is id number the same?
-                               if (Objects.equals(fax.getPhoneId(), faxNumber.getPhoneId())) {
-                                       // Found it
-                                       this.allFaxNumbers().remove(fax);
-                                       break;
-                               }
-                       }
-               }
-
-               // ... then add it
-               this.allFaxNumbers().add(faxNumber);
-       }
-
-       /**
-        * Uniquely add given land-line number to this bean's list. First remove the
-        * old instance (by id number), then re-add it again.
-        * <p>
-        * @param landLineNumber Land-line number to add
-        */
-       private void uniqueAddLandLineNumber (final DialableLandLineNumber landLineNumber) {
-               // Make sure the parameter is valid
-               if (null == landLineNumber) {
-                       // Throw NPE
-                       throw new NullPointerException("landLineNumber is null");
-               } else if (landLineNumber.getPhoneId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("landLineNumber.phoneId is null");
-               } else if (landLineNumber.getPhoneId() < 1) {
-                       // Not valid
-                       throw new IllegalArgumentException(MessageFormat.format("landLineNumber.phoneId={0} is not valid.", landLineNumber.getPhoneId()));
-               }
-
-               // First remove it
-               if (!this.allLandLineNumbers().remove(landLineNumber)) {
-                       // Did not work, try by id number
-                       for (final DialableLandLineNumber landLine : this.allLandLineNumbers()) {
-                               // Is id number the same?
-                               if (Objects.equals(landLine.getPhoneId(), landLineNumber.getPhoneId())) {
-                                       // Found it
-                                       this.allLandLineNumbers().remove(landLine);
-                                       break;
-                               }
-                       }
-               }
-
-               // ... then add it
-               this.allLandLineNumbers().add(landLineNumber);
-       }
-
-       /**
-        * Uniquely add given mobile number to this bean's list. First remove the
-        * old instance (by id number), then re-add it again.
-        * <p>
-        * @param mobileNumber Mobile number to add
-        */
-       private void uniqueAddMobileNumber (final DialableMobileNumber mobileNumber) {
-               // Make sure the parameter is valid
-               if (null == mobileNumber) {
-                       // Throw NPE
-                       throw new NullPointerException("mobileNumber is null");
-               } else if (mobileNumber.getPhoneId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("mobileNumber.phoneId is null");
-               } else if (mobileNumber.getPhoneId() < 1) {
-                       // Not valid
-                       throw new IllegalArgumentException(MessageFormat.format("mobileNumber.phoneId={0} is not valid.", mobileNumber.getPhoneId()));
-               }
-
-               // First remove it by object
-               if (!this.allMobileNumbers().remove(mobileNumber)) {
-                       // Did not work, try by id number
-                       for (final DialableMobileNumber cell : this.allMobileNumbers()) {
-                               // Is id number the same?
-                               if (Objects.equals(cell.getPhoneId(), mobileNumber.getPhoneId())) {
-                                       // Found it
-                                       this.allMobileNumbers().remove(cell);
-                                       break;
-                               }
-                       }
-               }
-
-               // ... then add it
-               this.allMobileNumbers().add(mobileNumber);
-       }
-
-       /**
-        * Updates given contact's mobile, land-line and fax number
-        * <p>
-        * @param contact Contact instance
-        */
-       private void updateContactPhoneNumbers (final Contact contact) {
-               // Parameter must be valid
-               if (null == contact) {
-                       // Throw NPE
-                       throw new NullPointerException("contact is null");
-               } else if (contact.getContactId() == null) {
-                       // Throw again
-                       throw new NullPointerException("contact.contactId is null");
-               } else if (contact.getContactId() < 1) {
-                       // Id number is not valid
-               }
-
-               // Is mobile set?
-               if (contact.getContactMobileNumber() instanceof DialableMobileNumber) {
-                       // Unique-add it
-                       this.uniqueAddMobileNumber(contact.getContactMobileNumber());
-               }
-
-               // Is land-line set?
-               if (contact.getContactLandLineNumber() instanceof DialableLandLineNumber) {
-                       // Unique-add it
-                       this.uniqueAddLandLineNumber(contact.getContactLandLineNumber());
-               }
-
-               // Is fax set?
-               if (contact.getContactFaxNumber() instanceof DialableFaxNumber) {
-                       // Unique-add it
-                       this.uniqueAddFaxNumber(contact.getContactFaxNumber());
-               }
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebApplicationController.java b/src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebApplicationController.java
deleted file mode 100644 (file)
index 57d2360..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.phone;
-
-import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
-import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
-import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
-
-/**
- * An interface for a request web controller (bean) for administrative phone
- * number purposes.
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsPhoneWebApplicationController extends Serializable {
-
-       /**
-        * Returns a list of all mobile numbers. For performance reasons, the
-        * controller (bean) should be application-scoped as from user to user
-        * nothing changes. And the controller's post-construct method should load
-        * all numbers and cache it in the controller.
-        * <p>
-        * @return List of all mobile numbers
-        */
-       List<DialableMobileNumber> allMobileNumbers ();
-
-       /**
-        * Returns a list of all fax numbers. For performance reasons, the
-        * controller (bean) should be application-scoped as from user to user
-        * nothing changes. And the controller's post-construct method should load
-        * all numbers and cache it in the controller.
-        * <p>
-        * @return List of all fax numbers
-        */
-       List<DialableFaxNumber> allFaxNumbers ();
-
-       /**
-        * Returns a list of all land-line numbers. For performance reasons, the
-        * controller (bean) should be application-scoped as from user to user
-        * nothing changes. And the controller's post-construct method should load
-        * all numbers and cache it in the controller.
-        * <p>
-        * @return List of all land-line numbers
-        */
-       List<DialableLandLineNumber> allLandLineNumbers ();
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebRequestBean.java
new file mode 100644 (file)
index 0000000..93ba631
--- /dev/null
@@ -0,0 +1,751 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.phone;
+
+import java.text.MessageFormat;
+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.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcontacts.events.contact.add.ObservableAdminAddedContactEvent;
+import org.mxchange.jcontacts.events.contact.update.ObservableAdminUpdatedContactEvent;
+import org.mxchange.jcontacts.events.fax.linked.ObservableAdminLinkedFaxNumberEvent;
+import org.mxchange.jcontacts.events.landline.linked.ObservableAdminLinkedLandLineNumberEvent;
+import org.mxchange.jcontacts.events.mobile.linked.ObservableAdminLinkedMobileNumberEvent;
+import org.mxchange.jcoreee.jcache.Cached;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jphone.events.fax.deleted.AdminDeletedFaxNumberEvent;
+import org.mxchange.jphone.events.fax.updated.AdminUpdatedFaxNumberEvent;
+import org.mxchange.jphone.events.landline.deleted.AdminDeletedLandLineNumberEvent;
+import org.mxchange.jphone.events.landline.updated.AdminUpdatedLandLineNumberEvent;
+import org.mxchange.jphone.events.mobile.deleted.AdminDeletedMobileNumberEvent;
+import org.mxchange.jphone.events.mobile.updated.AdminUpdatedMobileNumberEvent;
+import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
+import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
+import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
+import org.mxchange.jphone.phonenumbers.phone.PhoneSessionBeanRemote;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+
+/**
+ * Regular controller (bean) for phone numbers
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("phoneController")
+@RequestScoped
+public class FinancialsPhoneWebRequestBean extends BaseFinancialsController implements FinancialsPhoneWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 491_058_674_675_690_105L;
+
+       /**
+        * All fax numbers
+        */
+       @Inject
+       @Cached(cacheName = "faxNumberCache")
+       private transient Cache<Long, DialableFaxNumber> faxNumberCache;
+
+       /**
+        * All land-line numbers
+        */
+       @Inject
+       @Cached(cacheName = "landLineNumberCache")
+       private transient Cache<Long, DialableLandLineNumber> landLineNumberCache;
+
+       /**
+        * All mobile numbers
+        */
+       @Inject
+       @Cached(cacheName = "mobileNumberCache")
+       private transient Cache<Long, DialableMobileNumber> mobileNumberCache;
+
+       /**
+        * General EJB for phone numbers
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/phone!org.mxchange.jphone.phonenumbers.phone.PhoneSessionBeanRemote")
+       private PhoneSessionBeanRemote phoneBean;
+
+       /**
+        * Default constructor
+        */
+       public FinancialsPhoneWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Observes events being fired when an administrator has added a new
+        * contact.
+        * <p>
+        * @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
+               }
+
+               // Update contact's mobile, land-line and fax number
+               this.updateContactPhoneNumbers(event.getAddedContact());
+
+               // Clear this bean
+               this.clear();
+       }
+
+       /**
+        * Event observer for newly added users by administrator
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getAddedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.addedUser is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+               }
+
+               // Update contact's mobile, land-line and fax number
+               this.updateContactPhoneNumbers(event.getAddedUser().getUserContact());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when an administrator has deleted a fax
+        * number
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminDeletedFaxNumberEvent (@Observes final AdminDeletedFaxNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getDeletedFaxNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.deletedFaxNumber is null"); //NOI18N
+               } else if (event.getDeletedFaxNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.deletedFaxNumber.phoneId is null"); //NOI18N
+               } else if (event.getDeletedFaxNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedFaxNumber(), event.getDeletedFaxNumber().getPhoneId())); //NOI18N
+               }
+
+               // Update contact's mobile, land-line and fax number
+               this.allFaxNumbers().remove(event.getDeletedFaxNumber());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when an administrator has deleted a land-line
+        * number
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminDeletedLandLineNumberEvent (@Observes final AdminDeletedLandLineNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getDeletedLandLineNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.deletedLandLineNumber is null"); //NOI18N
+               } else if (event.getDeletedLandLineNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.deletedLandLineNumber.phoneId is null"); //NOI18N
+               } else if (event.getDeletedLandLineNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedLandLineNumber(), event.getDeletedLandLineNumber().getPhoneId())); //NOI18N
+               }
+
+               // Update contact's mobile, land-line and fax number
+               this.allLandLineNumbers().remove(event.getDeletedLandLineNumber());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when an administrator has deleted a mobile
+        * number
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminDeletedMobileNumberEvent (@Observes final AdminDeletedMobileNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getDeletedMobileNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.deletedMobileNumber is null"); //NOI18N
+               } else if (event.getDeletedMobileNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.deletedMobileNumber.phoneId is null"); //NOI18N
+               } else if (event.getDeletedMobileNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getDeletedMobileNumber(), event.getDeletedMobileNumber().getPhoneId())); //NOI18N
+               }
+
+               // Update contact's mobile, land-line and fax number
+               this.allMobileNumbers().remove(event.getDeletedMobileNumber());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when an administrator has a linked a fax
+        * number
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLinkedFaxNumberEvent (@Observes final ObservableAdminLinkedFaxNumberEvent event) {
+               // Is the event fine?
+               if (event == null) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getContact() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact is null");
+               } else if (event.getContact().getContactId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactId is null");
+               } else if (event.getContact().getContactId() < 1) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
+               } else if (event.getContact().getContactFaxNumber() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactFaxNumber is null");
+               } else if (event.getContact().getContactFaxNumber().getPhoneId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactFaxNumber.phoneId is null");
+               } else if (event.getContact().getContactFaxNumber().getPhoneId() < 1) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactFaxNumber.phoneId=" + event.getContact().getContactFaxNumber().getPhoneId() + " is invalid");
+               } else if (event.getLinkedFaxNumber() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.linkedFaxNumer is null");
+               }
+
+               // Is the id number in linked number not set?
+               if (event.getLinkedFaxNumber().getPhoneId() == null) {
+                       // Then it is a new number, so add it from contact as there the id number has been set
+                       this.uniqueAddFaxNumber(event.getContact().getContactFaxNumber());
+               }
+       }
+
+       /**
+        * Observes events being fired when an administrator has a linked a
+        * land-line number
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLinkedLandLineNumberEvent (@Observes final ObservableAdminLinkedLandLineNumberEvent event) {
+               // Is the event fine?
+               if (event == null) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getContact() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact is null");
+               } else if (event.getContact().getContactId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactId is null");
+               } else if (event.getContact().getContactId() < 1) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
+               } else if (event.getContact().getContactLandLineNumber() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactLandLineNumber is null");
+               } else if (event.getContact().getContactLandLineNumber().getPhoneId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactLandLineNumber.phoneId is null");
+               } else if (event.getContact().getContactLandLineNumber().getPhoneId() < 1) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactLandLineNumber.phoneId=" + event.getContact().getContactLandLineNumber().getPhoneId() + " is invalid");
+               } else if (event.getLinkedLandLineNumber() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.linkedLandLineNumer is null");
+               }
+
+               // Is the id number in linked number not set?
+               if (event.getLinkedLandLineNumber().getPhoneId() == null) {
+                       // Then it is a new number, so add it from contact as there the id number has been set
+                       this.uniqueAddLandLineNumber(event.getContact().getContactLandLineNumber());
+               }
+       }
+
+       /**
+        * Observes events being fired when an administrator has a linked a mobile
+        * number
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLinkedMobileNumberEvent (@Observes final ObservableAdminLinkedMobileNumberEvent event) {
+               // Is the event fine?
+               if (event == null) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getContact() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact is null");
+               } else if (event.getContact().getContactId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactId is null");
+               } else if (event.getContact().getContactId() < 1) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactId=" + event.getContact().getContactId() + " is invalid");
+               } else if (event.getContact().getContactMobileNumber() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactMobileNumber is null");
+               } else if (event.getContact().getContactMobileNumber().getPhoneId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactMobileNumber.phoneId is null");
+               } else if (event.getContact().getContactMobileNumber().getPhoneId() < 1) {
+                       // Throw again ...
+                       throw new NullPointerException("event.contact.contactMobileNumber.phoneId=" + event.getContact().getContactMobileNumber().getPhoneId() + " is invalid");
+               } else if (event.getLinkedMobileNumber() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("event.linkedMobileNumer is null");
+               }
+
+               // Is the id number in linked number not set?
+               if (event.getLinkedMobileNumber().getPhoneId() == null) {
+                       // Then it is a new number, so add it from contact as there the id number has been set
+                       this.uniqueAddMobileNumber(event.getContact().getContactMobileNumber());
+               }
+       }
+
+       /**
+        * Observes events being fired when an administrator has updated contact
+        * data.
+        * <p>
+        * @param event Event being fired
+        */
+       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("contactId of contact={0} is not valid: {1}", event.getUpdatedContact(), event.getUpdatedContact().getContactId())); //NOI18N
+               }
+
+               // Update contact's mobile, land-line and fax number
+               this.updateContactPhoneNumbers(event.getUpdatedContact());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when an administrator has updated a fax
+        * number.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminUpdatedFaxNumberEvent (@Observes final AdminUpdatedFaxNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedFaxNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedFaxNumber is null"); //NOI18N
+               } else if (event.getUpdatedFaxNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.updatedFaxNumber.phoneId is null"); //NOI18N
+               } else if (event.getUpdatedFaxNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedFaxNumber(), event.getUpdatedFaxNumber().getPhoneId())); //NOI18N
+               }
+
+               // Uniquely add it
+               this.uniqueAddFaxNumber(event.getUpdatedFaxNumber());
+
+               // Clear it
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when an administrator has updated a land-line
+        * number.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminUpdatedLandLineNumberEvent (@Observes final AdminUpdatedLandLineNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedLandLineNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedLandLineNumber is null"); //NOI18N
+               } else if (event.getUpdatedLandLineNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.updatedLandLineNumber.phoneId is null"); //NOI18N
+               } else if (event.getUpdatedLandLineNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedLandLineNumber(), event.getUpdatedLandLineNumber().getPhoneId())); //NOI18N
+               }
+
+               // Uniquely add it
+               this.uniqueAddLandLineNumber(event.getUpdatedLandLineNumber());
+
+               // Clear it
+               this.clear();
+       }
+
+       /**
+        * Observes events being fired when an administrator has updated a mobile
+        * number.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminUpdatedMobileNumberEvent (@Observes final AdminUpdatedMobileNumberEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedMobileNumber() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedMobileNumber is null"); //NOI18N
+               } else if (event.getUpdatedMobileNumber().getPhoneId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.updatedMobileNumber.phoneId is null"); //NOI18N
+               } else if (event.getUpdatedMobileNumber().getPhoneId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("phoneId of contact={0} is not valid: {1}", event.getUpdatedMobileNumber(), event.getUpdatedMobileNumber().getPhoneId())); //NOI18N
+               }
+
+               // Uniquely add it
+               this.uniqueAddMobileNumber(event.getUpdatedMobileNumber());
+
+               // Clear it
+               this.clear();
+       }
+
+       @Override
+       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+       public List<DialableFaxNumber> allFaxNumbers () {
+               // Init list
+               List<DialableFaxNumber> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, DialableFaxNumber>> iterator = this.faxNumberCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, DialableFaxNumber> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
+       }
+
+       @Override
+       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+       public List<DialableLandLineNumber> allLandLineNumbers () {
+               // Init list
+               List<DialableLandLineNumber> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, DialableLandLineNumber>> iterator = this.landLineNumberCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, DialableLandLineNumber> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
+       }
+
+       @Override
+       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+       public List<DialableMobileNumber> allMobileNumbers () {
+               // Init list
+               List<DialableMobileNumber> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, DialableMobileNumber>> iterator = this.mobileNumberCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, DialableMobileNumber> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
+       }
+
+       /**
+        * Post-construction method
+        */
+       @PostConstruct
+       public void init () {
+               // Is cache there?
+               if (!this.faxNumberCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<DialableFaxNumber> list = this.phoneBean.allFaxNumbers();
+
+                       // Add all
+                       for (final Iterator<DialableFaxNumber> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final DialableFaxNumber next = iterator.next();
+
+                               // Add it to cache
+                               this.faxNumberCache.put(next.getPhoneId(), next);
+                       }
+               }
+
+               // Is cache there?
+               if (!this.landLineNumberCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<DialableLandLineNumber> list = this.phoneBean.allLandLineNumbers();
+
+                       // Add all
+                       for (final Iterator<DialableLandLineNumber> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final DialableLandLineNumber next = iterator.next();
+
+                               // Add it to cache
+                               this.landLineNumberCache.put(next.getPhoneId(), next);
+                       }
+               }
+
+               // Is cache there?
+               if (!this.mobileNumberCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<DialableMobileNumber> list = this.phoneBean.allMobileNumbers();
+
+                       // Add all
+                       for (final Iterator<DialableMobileNumber> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final DialableMobileNumber next = iterator.next();
+
+                               // Add it to cache
+                               this.mobileNumberCache.put(next.getPhoneId(), next);
+                       }
+               }
+       }
+
+       /**
+        * Clears this bean
+        */
+       private void clear () {
+               // Clear all data
+       }
+
+       /**
+        * Uniquely add given fax number to this bean's list. First remove the old
+        * instance (by id number), then re-add it again.
+        * <p>
+        * @param faxNumber number to add
+        */
+       private void uniqueAddFaxNumber (final DialableFaxNumber faxNumber) {
+               // Make sure the parameter is valid
+               if (null == faxNumber) {
+                       // Throw NPE
+                       throw new NullPointerException("faxNumber is null");
+               } else if (faxNumber.getPhoneId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("faxNumber.phoneId is null");
+               } else if (faxNumber.getPhoneId() < 1) {
+                       // Not valid
+                       throw new IllegalArgumentException(MessageFormat.format("faxNumber.phoneId={0} is not valid.", faxNumber.getPhoneId()));
+               }
+
+               // First remove it
+               if (!this.allFaxNumbers().remove(faxNumber)) {
+                       // Did not work, try by id number
+                       for (final DialableFaxNumber fax : this.allFaxNumbers()) {
+                               // Is id number the same?
+                               if (Objects.equals(fax.getPhoneId(), faxNumber.getPhoneId())) {
+                                       // Found it
+                                       this.allFaxNumbers().remove(fax);
+                                       break;
+                               }
+                       }
+               }
+
+               // ... then add it
+               this.allFaxNumbers().add(faxNumber);
+       }
+
+       /**
+        * Uniquely add given land-line number to this bean's list. First remove the
+        * old instance (by id number), then re-add it again.
+        * <p>
+        * @param landLineNumber Land-line number to add
+        */
+       private void uniqueAddLandLineNumber (final DialableLandLineNumber landLineNumber) {
+               // Make sure the parameter is valid
+               if (null == landLineNumber) {
+                       // Throw NPE
+                       throw new NullPointerException("landLineNumber is null");
+               } else if (landLineNumber.getPhoneId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("landLineNumber.phoneId is null");
+               } else if (landLineNumber.getPhoneId() < 1) {
+                       // Not valid
+                       throw new IllegalArgumentException(MessageFormat.format("landLineNumber.phoneId={0} is not valid.", landLineNumber.getPhoneId()));
+               }
+
+               // First remove it
+               if (!this.allLandLineNumbers().remove(landLineNumber)) {
+                       // Did not work, try by id number
+                       for (final DialableLandLineNumber landLine : this.allLandLineNumbers()) {
+                               // Is id number the same?
+                               if (Objects.equals(landLine.getPhoneId(), landLineNumber.getPhoneId())) {
+                                       // Found it
+                                       this.allLandLineNumbers().remove(landLine);
+                                       break;
+                               }
+                       }
+               }
+
+               // ... then add it
+               this.allLandLineNumbers().add(landLineNumber);
+       }
+
+       /**
+        * Uniquely add given mobile number to this bean's list. First remove the
+        * old instance (by id number), then re-add it again.
+        * <p>
+        * @param mobileNumber Mobile number to add
+        */
+       private void uniqueAddMobileNumber (final DialableMobileNumber mobileNumber) {
+               // Make sure the parameter is valid
+               if (null == mobileNumber) {
+                       // Throw NPE
+                       throw new NullPointerException("mobileNumber is null");
+               } else if (mobileNumber.getPhoneId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("mobileNumber.phoneId is null");
+               } else if (mobileNumber.getPhoneId() < 1) {
+                       // Not valid
+                       throw new IllegalArgumentException(MessageFormat.format("mobileNumber.phoneId={0} is not valid.", mobileNumber.getPhoneId()));
+               }
+
+               // First remove it by object
+               if (!this.allMobileNumbers().remove(mobileNumber)) {
+                       // Did not work, try by id number
+                       for (final DialableMobileNumber cell : this.allMobileNumbers()) {
+                               // Is id number the same?
+                               if (Objects.equals(cell.getPhoneId(), mobileNumber.getPhoneId())) {
+                                       // Found it
+                                       this.allMobileNumbers().remove(cell);
+                                       break;
+                               }
+                       }
+               }
+
+               // ... then add it
+               this.allMobileNumbers().add(mobileNumber);
+       }
+
+       /**
+        * Updates given contact's mobile, land-line and fax number
+        * <p>
+        * @param contact Contact instance
+        */
+       private void updateContactPhoneNumbers (final Contact contact) {
+               // Parameter must be valid
+               if (null == contact) {
+                       // Throw NPE
+                       throw new NullPointerException("contact is null");
+               } else if (contact.getContactId() == null) {
+                       // Throw again
+                       throw new NullPointerException("contact.contactId is null");
+               } else if (contact.getContactId() < 1) {
+                       // Id number is not valid
+               }
+
+               // Is mobile set?
+               if (contact.getContactMobileNumber() instanceof DialableMobileNumber) {
+                       // Unique-add it
+                       this.uniqueAddMobileNumber(contact.getContactMobileNumber());
+               }
+
+               // Is land-line set?
+               if (contact.getContactLandLineNumber() instanceof DialableLandLineNumber) {
+                       // Unique-add it
+                       this.uniqueAddLandLineNumber(contact.getContactLandLineNumber());
+               }
+
+               // Is fax set?
+               if (contact.getContactFaxNumber() instanceof DialableFaxNumber) {
+                       // Unique-add it
+                       this.uniqueAddFaxNumber(contact.getContactFaxNumber());
+               }
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/phone/FinancialsPhoneWebRequestController.java
new file mode 100644 (file)
index 0000000..ce8a50d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.phone;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jphone.phonenumbers.fax.DialableFaxNumber;
+import org.mxchange.jphone.phonenumbers.landline.DialableLandLineNumber;
+import org.mxchange.jphone.phonenumbers.mobile.DialableMobileNumber;
+
+/**
+ * An interface for a request web controller (bean) for administrative phone
+ * number purposes.
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsPhoneWebRequestController extends Serializable {
+
+       /**
+        * Returns a list of all mobile numbers. For performance reasons, the
+        * controller (bean) should be application-scoped as from user to user
+        * nothing changes. And the controller's post-construct method should load
+        * all numbers and cache it in the controller.
+        * <p>
+        * @return List of all mobile numbers
+        */
+       List<DialableMobileNumber> allMobileNumbers ();
+
+       /**
+        * Returns a list of all fax numbers. For performance reasons, the
+        * controller (bean) should be application-scoped as from user to user
+        * nothing changes. And the controller's post-construct method should load
+        * all numbers and cache it in the controller.
+        * <p>
+        * @return List of all fax numbers
+        */
+       List<DialableFaxNumber> allFaxNumbers ();
+
+       /**
+        * Returns a list of all land-line numbers. For performance reasons, the
+        * controller (bean) should be application-scoped as from user to user
+        * nothing changes. And the controller's post-construct method should load
+        * all numbers and cache it in the controller.
+        * <p>
+        * @return List of all land-line numbers
+        */
+       List<DialableLandLineNumber> allLandLineNumbers ();
+
+}
index 6f2820f535f8e3a96f60db5ae408c8a342b2498c..d482c92b77876815a6ccceed4bef887776c05bc3 100644 (file)
@@ -23,11 +23,11 @@ import javax.faces.view.facelets.FaceletException;
 import javax.inject.Inject;
 import javax.inject.Named;
 import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.user.FinancialsUserWebSessionController;
 import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
 import org.mxchange.jusercore.exceptions.UserNotFoundException;
 import org.mxchange.jusercore.model.user.User;
 import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
+import org.mxchange.jfinancials.beans.user.FinancialsUserWebRequestController;
 
 /**
  * A web request bean for user profiles
@@ -47,7 +47,7 @@ public class FinancialsUserProfileWebRequestBean extends BaseFinancialsControlle
         * User controller
         */
        @Inject
-       private FinancialsUserWebSessionController userController;
+       private FinancialsUserWebRequestController userController;
 
        /**
         * Login controller
index 0eeeb10c2e5880d264fb43ee374bb3fc45c256fa..feccf11ee56b688b403effa2d79a919552a99b92 100644 (file)
@@ -33,7 +33,6 @@ import org.mxchange.jcontacts.contact.Contact;
 import org.mxchange.jcoreee.utils.FacesUtils;
 import org.mxchange.jfinancials.beans.BaseFinancialsController;
 import org.mxchange.jfinancials.beans.contact.FinancialsAdminContactWebRequestController;
-import org.mxchange.jfinancials.beans.contact.FinancialsContactWebSessionController;
 import org.mxchange.jusercore.events.user.add.AdminAddedUserEvent;
 import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
 import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
@@ -63,6 +62,7 @@ import org.mxchange.juserlogincore.container.login.UserLoginContainer;
 import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
 import org.mxchange.juserlogincore.exceptions.UserPasswordRepeatMismatchException;
 import org.mxchange.juserlogincore.login.UserLoginUtils;
+import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestController;
 
 /**
  * A user bean (controller)
@@ -106,7 +106,7 @@ public class FinancialsAdminUserWebRequestBean extends BaseFinancialsController
         * Regular contact controller
         */
        @Inject
-       private FinancialsContactWebSessionController contactController;
+       private FinancialsContactWebRequestController contactController;
 
        /**
         * Event being fired when administrator has deleted user
@@ -137,7 +137,7 @@ public class FinancialsAdminUserWebRequestBean extends BaseFinancialsController
         * Regular user controller
         */
        @Inject
-       private FinancialsUserWebSessionController userController;
+       private FinancialsUserWebRequestController userController;
 
        /**
         * Delete reason
@@ -270,7 +270,7 @@ public class FinancialsAdminUserWebRequestBean extends BaseFinancialsController
                        return ""; //NOI18N
                } else if ((this.getUserPassword() == null && (this.getUserPasswordRepeat() == null)) || ((this.getUserPassword().isEmpty()) && (this.getUserPasswordRepeat().isEmpty()))) {
                        // Empty password entered, then generate one
-                       password = UserLoginUtils.createRandomPassword(FinancialsUserWebSessionController.MINIMUM_PASSWORD_LENGTH);
+                       password = UserLoginUtils.createRandomPassword(FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
                } else if (!this.isSamePasswordEntered()) {
                        // Both passwords don't match
                        throw new FaceletException(new UserPasswordRepeatMismatchException(newUser));
@@ -281,7 +281,7 @@ public class FinancialsAdminUserWebRequestBean extends BaseFinancialsController
 
                // The password should not be null and at least 5 characters long
                assert (password != null) : "password is null"; //NOI18N
-               assert (password.length() >= FinancialsUserWebSessionController.MINIMUM_PASSWORD_LENGTH) : "Password is not long enough."; //NOI18N
+               assert (password.length() >= FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH) : "Password is not long enough."; //NOI18N
 
                // Encrypt password and set it
                newUser.setUserEncryptedPassword(UserLoginUtils.encryptPassword(password));
diff --git a/src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebRequestBean.java
new file mode 100644 (file)
index 0000000..bb2c9bc
--- /dev/null
@@ -0,0 +1,1177 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+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.Event;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.faces.context.FacesContext;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
+import org.mxchange.jcoreee.jcache.Cached;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
+import org.mxchange.jfinancials.beans.localization.FinancialsLocalizationSessionController;
+import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+import org.mxchange.jusercore.events.user.clear.password.ObservableClearUserPasswordEvent;
+import org.mxchange.jusercore.events.user.clear.username.ObservableClearUserNameEvent;
+import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
+import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
+import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
+import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
+import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
+import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
+import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
+import org.mxchange.jusercore.events.user.update.UpdatedUserPersonalDataEvent;
+import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+import org.mxchange.jusercore.model.user.LoginUser;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
+import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
+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.events.user.password_change.ObservableUpdatedUserPasswordEvent;
+import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
+import org.mxchange.juserlogincore.login.UserLoginUtils;
+import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestController;
+
+/**
+ * A user bean (controller)
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("userController")
+@RequestScoped
+public class FinancialsUserWebRequestBean extends BaseFinancialsController implements FinancialsUserWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 542_145_347_916L;
+
+       /**
+        * General contact controller
+        */
+       @Inject
+       private FinancialsContactWebRequestController contactController;
+
+       /**
+        * Features controller
+        */
+       @Inject
+       private FinancialsFeaturesWebApplicationController featureController;
+
+       /**
+        * Locale instance
+        */
+       private Locale locale;
+
+       /**
+        * Localization controller
+        */
+       @Inject
+       private FinancialsLocalizationSessionController localizationController;
+
+       /**
+        * Event being fired when user updated personal data
+        */
+       @Inject
+       @Any
+       private Event<ObservableUpdatedUserPersonalDataEvent> updatedPersonalDataEvent;
+
+       /**
+        * Remote user bean
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
+       private UserSessionBeanRemote userBean;
+
+       /**
+        * User id
+        */
+       private Long userId;
+
+       /**
+        * A list of all user profiles
+        */
+       @Inject
+       @Cached (cacheName = "userCache")
+       private transient Cache<Long, User> userCache;
+
+       /**
+        * Login controller (bean)
+        */
+       @Inject
+       private FinancialsUserLoginWebSessionController userLoginController;
+
+       /**
+        * User name
+        */
+       private String userName;
+
+       /**
+        * User name list
+        */
+       @Inject
+       @Cached (cacheName = "userNameCache")
+       private transient Cache<Long, String> userNameCache;
+
+       /**
+        * User password (clear-text from web form)
+        */
+       private String userPassword;
+
+       /**
+        * User password repeated (clear-text from web form)
+        */
+       private String userPasswordRepeat;
+
+       /**
+        * Whether the user wants a public profile
+        */
+       private ProfileMode userProfileMode;
+
+       /**
+        * Default constructor
+        */
+       public FinancialsUserWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Event observer for newly added users by administrator
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getAddedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.addedUser is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.updateList(event.getAddedUser());
+
+               // Clear all data
+               this.clear();
+
+               // Set user id again
+               this.setUserId(event.getAddedUser().getUserId());
+       }
+
+       /**
+        * Event observer for deleted user accounts (by administrator)
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getDeletedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.deletedUser is null"); //NOI18N
+               } else if (event.getDeletedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
+               } else if (event.getDeletedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.removeFromList(event.getDeletedUser());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Event observer for linked users with existing contact data
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLinkedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.linkedUser is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.updateList(event.getLinkedUser());
+
+               // Clear all data
+               this.clear();
+
+               // Set user id again
+               this.setUserId(event.getLinkedUser().getUserId());
+       }
+
+       /**
+        * Event observer for locked users
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLockedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.lockedUser is null"); //NOI18N
+               } else if (event.getLockedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
+               } else if (event.getLockedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.updateList(event.getLockedUser());
+       }
+
+       /**
+        * Event observer for unlocked users
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUnlockedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.unlockedUser is null"); //NOI18N
+               } else if (event.getUnlockedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
+               } else if (event.getUnlockedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.updateList(event.getUnlockedUser());
+       }
+
+       /**
+        * Event observer for updated user data by administrator
+        * <p>
+        * @param event Event being updated
+        */
+       public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.updateList(event.getUpdatedUser());
+
+               // Clear all data
+               this.clear();
+       }
+
+       /**
+        * Event observer for when a bean helper has successfully created a user
+        * instance, means the user exists. If the user does not exist, this event
+        * should not fire but instead a proper exception must be thrown.
+        * <p>
+        * @param event User created event
+        */
+       public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
+               // Is the instance valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getCreatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.createdUser is null"); //NOI18N
+               } else if (event.getCreatedUser().getUserId() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
+               } else if (event.getCreatedUser().getUserId() < 1) {
+                       // Throw NPE again
+                       throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
+               }
+
+               // Get user instance
+               User user = event.getCreatedUser();
+
+               // Set all fields here
+               this.copyUser(user);
+       }
+
+       /**
+        * Observer method for events being fired when the application's locale has
+        * been changed.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterLocaleChangeEvent (@Observes final ObservableLocaleChangeEvent event) {
+               // Is the parameter valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null");
+               } else if (event.getLocale() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.locale is null");
+               }
+
+               // Set it here
+               this.setLocale(event.getLocale());
+       }
+
+       /**
+        * Event observer when user confirmed account.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserConfirmedAccountEvent (@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
+               }
+
+               // Update user list
+               this.updateList(event.getConfirmedUser());
+       }
+
+       /**
+        * Event observer for logged-in user
+        * <p>
+        * @param event Event instance
+        */
+       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLoggedInUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.registeredUser is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
+               }
+
+               // "Cache" user instance
+               User loggedInUser = event.getLoggedInUser();
+
+               // Copy all data to this bean
+               this.copyUser(loggedInUser);
+       }
+
+       /**
+        * Event observer for user password changes
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserPasswordChangedEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
+               // Is it valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUserPassword() == null) {
+                       // Throw NPE
+                       throw new NullPointerException("event.userPassword is null"); //NOI18N
+               } else if (event.getUserPassword().isEmpty()) {
+                       // Throw NPE
+                       throw new IllegalArgumentException("event.userPassword is empty"); //NOI18N
+               }
+
+               // Set it here
+               this.setUserPassword(event.getUserPassword());
+               this.setUserPasswordRepeat(event.getUserPassword());
+       }
+
+       /**
+        * Event observer for new user registrations
+        * <p>
+        * @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
+               User registeredUser = event.getRegisteredUser();
+
+               // Copy all data from registered->user
+               this.copyUser(registeredUser);
+
+               // Clear all data
+               this.clear();
+
+               // Update user list
+               this.updateList(registeredUser);
+
+               // Add user name
+               this.addUserName(registeredUser);
+
+               // Set user id again
+               this.setUserId(registeredUser.getUserId());
+       }
+
+       /**
+        * Method being call after user's password has been updated (and history
+        * entry has been created).
+        * <p>
+        * @param event Event being observed
+        */
+       public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
+               // Check parameter
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getPasswordHistory() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.passwordHistory is null"); //NOI18N
+               } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
+                       // ... and again
+                       throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
+               } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
+                       // Invalid value
+                       throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
+               }
+
+               // Update user list
+               this.updateList(event.getPasswordHistory().getUserPasswordHistoryUser());
+       }
+
+       /**
+        * Listens to fired event when user updated personal data
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
+               // Check parameter
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() == null) {
+                       // ... and again
+                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() < 1) {
+                       // Invalid value
+                       throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.updateList(event.getUpdatedUser());
+       }
+
+       @Override
+       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+       public List<User> allUsers () {
+               // Init list
+               List<User> list = new LinkedList<>();
+
+               // Get iterator
+               Iterator<Cache.Entry<Long, User>> iterator = this.userCache.iterator();
+
+               // Loop over all
+               while (iterator.hasNext()) {
+                       // Get next entry
+                       final Cache.Entry<Long, User> next = iterator.next();
+
+                       // Add value to list
+                       list.add(next.getValue());
+               }
+
+               // Return it
+               return list;
+       }
+
+       /**
+        * Event observer for when a user name should be cleared
+        * <p>
+        * @param event Event being fired
+        */
+       public void clearUserNameEvent (@Observes final ObservableClearUserNameEvent event) {
+               // Is it valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null");
+               }
+
+               // Clear it
+               this.clearUserName();
+       }
+
+       /**
+        * Event observer for when both user passwords should be cleared
+        * <p>
+        * @param event Event being fired
+        */
+       public void clearUserPasswordEvent (@Observes final ObservableClearUserPasswordEvent event) {
+               // Is it valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null");
+               }
+
+               // Clear it
+               this.clearUserPasswords();
+       }
+
+       @Override
+       public User createUserInstance (final boolean createContactData) {
+               // Trace message
+               //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: CALLED!", this.getClass().getSimpleName()));
+
+               // Required personal data must be set
+               assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
+
+               // Create new user instance
+               User user = new LoginUser();
+
+               // Is user name required?
+               if (!this.isUserNameRequired()) {
+                       // Generate pseudo-random user name
+                       String randomName = this.userBean.generateRandomUserName();
+
+                       // Set it and inivisible profile
+                       this.setUserName(randomName);
+                       this.setUserProfileMode(ProfileMode.INVISIBLE);
+
+                       // Generate random password
+                       String randomPassword = UserLoginUtils.createRandomPassword(FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
+
+                       // Set random password
+                       this.setUserPassword(randomPassword);
+                       this.setUserPasswordRepeat(randomPassword);
+               }
+
+               // Set user name profile mode and locale
+               user.setUserName(this.getUserName());
+               user.setUserProfileMode(this.getUserProfileMode());
+               user.setUserLocale(this.getLocale());
+
+               // Is multiple registration page
+               if ((createContactData) || (!this.featureController.isFeatureEnabled("user_register_multiple_page"))) { //NOI18N
+                       // Create contact instance
+                       Contact contact = this.contactController.createContactInstance();
+
+                       // Debug message
+                       //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: contact={1}", this.getClass().getSimpleName(), contact));
+                       // Set contact in user
+                       user.setUserContact(contact);
+               }
+
+               // Trace message
+               //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: user={1} - EXIT!", this.getClass().getSimpleName(), user));
+               // Return it
+               return user;
+       }
+
+       @Override
+       public User createUserLogin () {
+               // Trace message
+               //* NOISY-DEBUG */ System.out.println(MessageFormat.format("{0}.createUserLogin: CALLED!", this.getClass().getSimpleName()));
+
+               // Is all data set?
+               if (this.getUserName() == null) {
+                       // Throw NPE
+                       throw new NullPointerException("userName is null"); //NOI18N
+               } else if (this.getUserName().isEmpty()) {
+                       // Is empty
+                       throw new IllegalStateException("userName is empty."); //NOI18N
+               }
+
+               // Create new user instance
+               User user = new LoginUser();
+
+               // Update all data ...
+               user.setUserName(this.getUserName());
+
+               // Trace message
+               //* NOISY-DEBUG */ System.out.println(MessageFormat.format("{0}.createUserLogin: user={1} - EXIT!", this.getClass().getSimpleName(), user));
+               // Return the new instance
+               return user;
+       }
+
+       @Override
+       public String doChangePersonalData () {
+               // This method shall only be called if the user is logged-in
+               if (!this.userLoginController.isUserLoggedIn()) {
+                       // Not logged-in
+                       throw new IllegalStateException("User is not logged-in"); //NOI18N
+               } else if (!this.isRequiredChangePersonalDataSet()) {
+                       // Not all required fields are set
+                       throw new FaceletException("Not all required fields are set."); //NOI18N
+               } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
+                       // Password not matching
+                       throw new FaceletException(new UserPasswordMismatchException(this.userLoginController.getLoggedInUser()));
+               } else if (!this.featureController.isFeatureEnabled("change_user_personal_data")) { //NOI18N
+                       // Editing is not allowed
+                       throw new IllegalStateException("User tried to edit personal data."); //NOI18N
+               }
+
+               // Get user instance
+               User user = this.userLoginController.getLoggedInUser();
+
+               // Copy contact data to contact instance
+               this.contactController.updateContactDataFromController(user.getUserContact());
+
+               // It should be there, so run some tests on it
+               assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
+               assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
+               assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
+               assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
+               assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
+               assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
+
+               // Update all fields
+               user.setUserProfileMode(this.getUserProfileMode());
+
+               // Send it to the EJB
+               User updatedUser = this.userBean.updateUserPersonalData(user);
+
+               // Fire event
+               this.updatedPersonalDataEvent.fire(new UpdatedUserPersonalDataEvent(updatedUser));
+
+               // All fine
+               return "user_contact_data_saved"; //NOI18N
+       }
+
+       /**
+        * Getter for user id
+        * <p>
+        * @return User id
+        */
+       public Long getUserId () {
+               return this.userId;
+       }
+
+       /**
+        * Setter for user id
+        * <p>
+        * @param userId User id
+        */
+       public void setUserId (final Long userId) {
+               this.userId = userId;
+       }
+
+       /**
+        * Getter for user name
+        * <p>
+        * @return User name
+        */
+       public String getUserName () {
+               return this.userName;
+       }
+
+       /**
+        * Setter for user name
+        * <p>
+        * @param userName User name
+        */
+       public void setUserName (final String userName) {
+               this.userName = userName;
+       }
+
+       @Override
+       public String getUserPassword () {
+               return this.userPassword;
+       }
+
+       /**
+        * Setter for clear-text user password
+        * <p>
+        * @param userPassword Clear-text user password
+        */
+       public void setUserPassword (final String userPassword) {
+               this.userPassword = userPassword;
+       }
+
+       /**
+        * Getter for clear-text user password repeated
+        * <p>
+        * @return Clear-text user password repeated
+        */
+       public String getUserPasswordRepeat () {
+               return this.userPasswordRepeat;
+       }
+
+       /**
+        * Setter for clear-text user password repeated
+        * <p>
+        * @param userPasswordRepeat Clear-text user password repeated
+        */
+       public void setUserPasswordRepeat (final String userPasswordRepeat) {
+               this.userPasswordRepeat = userPasswordRepeat;
+       }
+
+       /**
+        * Getter for user profile mode
+        * <p>
+        * @return User profile mode
+        */
+       public ProfileMode getUserProfileMode () {
+               return this.userProfileMode;
+       }
+
+       /**
+        * Setter for user profile mode
+        * <p>
+        * @param userProfileMode User profile mode
+        */
+       public void setUserProfileMode (final ProfileMode userProfileMode) {
+               this.userProfileMode = userProfileMode;
+       }
+
+       @Override
+       public boolean ifBothPasswordsEmptyAllowed () {
+               // Check feature first
+               return ((this.featureController.isFeatureEnabled("allow_user_registration_empty_password")) && //NOI18N
+                               ((this.getUserPassword() == null) || (this.getUserPassword().isEmpty())) &&
+                               ((this.getUserPasswordRepeat() == null) || (this.getUserPasswordRepeat().isEmpty())));
+       }
+
+       /**
+        * Post-initialization of this class
+        */
+       @PostConstruct
+       public void init () {
+               // Is cache there?
+               if (!this.userCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<User> list = this.userBean.allUsers();
+
+                       // Add all
+                       for (final Iterator<User> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final User next = iterator.next();
+
+                               // Add it to cache
+                               this.userCache.put(next.getUserId(), next);
+                               this.userNameCache.put(next.getUserId(), next.getUserName());
+                       }
+               }
+       }
+
+       @Override
+       public boolean isContactFound (final Contact contact) {
+               // The contact must be valid
+               if (null == contact) {
+                       // Throw NPE
+                       throw new NullPointerException("contact is null"); //NOI18N
+               } else if (contact.getContactId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("contact.contactId is null"); //NOI18N
+               } else if (contact.getContactId() < 1) {
+                       // Not valid
+                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid", contact.getContactId())); //NOI18N
+               }
+
+               // Default is not found
+               boolean isFound = false;
+
+               // Get iterator
+               Iterator<User> iterator = this.allUsers().iterator();
+
+               // Loop through all entries
+               while (iterator.hasNext()) {
+                       // Get user
+                       User next = iterator.next();
+
+                       // Compare both objects
+                       if (Objects.equals(contact, next.getUserContact())) {
+                               // Found it
+                               isFound = true;
+                               break;
+                       }
+               }
+
+               // Return status
+               return isFound;
+       }
+
+       @Override
+       public boolean isPublicUserProfileEnabled () {
+               // Get context parameter
+               String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_public_profile_enabled"); //NOI18N
+
+               // Is it set?
+               boolean isEnabled = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
+
+               // This requires user names being enabled, too.
+               if ((isEnabled) && (!this.isUserNameRequired())) {
+                       // Not valid state, users must be able to modify their profile, especially when it is public
+                       throw new IllegalStateException("Public user profiles are enabled but user name requirement is disabled, this is not possible."); //NOI18N
+               }
+
+               // Return value
+               return isEnabled;
+       }
+
+       @Override
+       public boolean isRequiredChangePersonalDataSet () {
+               return ((this.getUserProfileMode() != null) &&
+                               (this.getUserName() != null) && (!this.getUserName().isEmpty()) &&
+                               (this.contactController.isRequiredChangePersonalDataSet()));
+       }
+
+       @Override
+       public boolean isRequiredPersonalDataSet () {
+               if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
+                       // Multiple registration page
+                       return this.contactController.isRequiredPersonalDataSet();
+               } else {
+                       // Single registration page
+                       return (((this.getUserName() != null) || (!this.isUserNameRequired())) &&
+                                       (this.getUserProfileMode() != null) &&
+                                       (this.contactController.isRequiredPersonalDataSet()) &&
+                                       (this.getUserPassword() != null) &&
+                                       (this.getUserPasswordRepeat() != null));
+               }
+       }
+
+       @Override
+       public boolean isSamePasswordEntered () {
+               return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
+       }
+
+       @Override
+       public boolean isUserIdEmpty () {
+               return ((this.getUserId() == null) || (this.getUserId() == 0));
+       }
+
+       @Override
+       public boolean isUserNameRegistered (final User user) {
+               return ((this.userNameCache instanceof List) && (this.userNameCache.containsKey(user.getUserId())));
+       }
+
+       @Override
+       public boolean isUserNameRequired () {
+               // Get context parameter
+               String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_user_login_require_user_name"); //NOI18N
+
+               // Is it set?
+               boolean isRequired = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
+
+               // Return value
+               return isRequired;
+       }
+
+       @Override
+       public User lookupUserByEmailAddress (final String emailAddress) throws UserEmailAddressNotFoundException {
+               // Parameter must be valid
+               if (null == emailAddress) {
+                       // Throw NPE
+                       throw new NullPointerException("emailAddress is null"); //NOI18N
+               } else if (emailAddress.isEmpty()) {
+                       // Not valid
+                       throw new IllegalArgumentException("emailAddress is empty"); //NOI18N
+               }
+
+               // Init variable
+               User user = null;
+
+               // Try to lookup it in visible user list
+               for (final Iterator<Cache.Entry<Long, User>> iterator = this.userCache.iterator(); iterator.hasNext();) {
+                       // Get next user
+                       Cache.Entry<Long, User> next = iterator.next();
+
+                       // Contact should be set
+                       if (next.getValue().getUserContact() == null) {
+                               // Contact is null
+                               throw new NullPointerException(MessageFormat.format("next.userContact is null for user id {0}", next.getKey())); //NOI18N
+                       } else if (next.getValue().getUserContact().getContactEmailAddress() == null) {
+                               // Email address should be set
+                               throw new NullPointerException(MessageFormat.format("next.userContact.contactEmailAddress is null for user id {0}", next.getKey())); //NOI18N
+                       }
+
+                       // Is the email address found?
+                       if (Objects.equals(next.getValue().getUserContact().getContactEmailAddress(), emailAddress)) {
+                               // Copy to other variable
+                               user = next.getValue();
+                               break;
+                       }
+               }
+
+               // Is it still null?
+               if (null == user) {
+                       // Not visible for the current user
+                       throw new UserEmailAddressNotFoundException(emailAddress);
+               }
+
+               // Return it
+               return user;
+       }
+
+       @Override
+       public User lookupUserById (final Long userId) throws UserNotFoundException {
+               // Parameter must be valid
+               if (null == userId) {
+                       // Throw NPE
+                       throw new NullPointerException("userId is null"); //NOI18N
+               } else if (userId < 1) {
+                       // Not valid
+                       throw new IllegalArgumentException(MessageFormat.format("userId={0} is not valid.", userId)); //NOI18N
+               }
+
+               // Init variable
+               User user = null;
+
+               // Try to lookup it in visible user list
+               for (final Iterator<Cache.Entry<Long, User>> iterator = this.userCache.iterator(); iterator.hasNext();) {
+                       // Get next user
+                       Cache.Entry<Long, User> next = iterator.next();
+
+                       // Is the user id found?
+                       if (Objects.equals(next.getKey(), userId)) {
+                               // Copy to other variable
+                               user = next.getValue();
+                               break;
+                       }
+               }
+
+               // Is it still null?
+               if (null == user) {
+                       // Not visible for the current user
+                       throw new UserNotFoundException(userId);
+               }
+
+               // Return it
+               return user;
+       }
+
+       /**
+        * Adds user's name to bean's internal list. It also updates the public user
+        * list if the user has decided to have a public account,
+        * <p>
+        * @param user User instance
+        */
+       private void addUserName (final User user) {
+               // Make sure the entry is not added yet
+               if (this.userNameCache.containsKey(user.getUserId())) {
+                       // Abort here
+                       throw new IllegalArgumentException(MessageFormat.format("User name {0} already added.", user.getUserName())); //NOI18N
+               }
+
+               // Add user name
+               this.userNameCache.put(user.getUserId(), user.getUserName());
+       }
+
+       /**
+        * Clears this bean
+        */
+       private void clear () {
+               // Clear all data
+               // - personal data
+               this.setUserId(null);
+               this.setUserProfileMode(null);
+
+               // - other data
+               this.clearUserName();
+               this.clearUserPasswords();
+               this.setLocale(null);
+       }
+
+       /**
+        * Clears user name
+        */
+       private void clearUserName () {
+               // Clear it
+               this.setUserName(null);
+       }
+
+       /**
+        * Clears both user passwords
+        */
+       private void clearUserPasswords () {
+               // Clear both
+               this.setUserPassword(null);
+               this.setUserPasswordRepeat(null);
+       }
+
+       /**
+        * Copies given user into the controller
+        * <p>
+        * @param user User instance
+        */
+       private void copyUser (final User user) {
+               // Make sure the instance is valid
+               if (null == user) {
+                       // Throw NPE
+                       throw new NullPointerException("user is null"); //NOI18N
+               } else if (user.getUserContact() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("user.userContact is null"); //NOI18N
+               }
+
+               // Copy all fields:
+               // - base data
+               this.setUserId(user.getUserId());
+               this.setUserProfileMode(user.getUserProfileMode());
+       }
+
+       /**
+        * Getter for locale instance
+        * <p>
+        * @return Locale instance
+        */
+       private Locale getLocale () {
+               return this.locale;
+       }
+
+       /**
+        * Setter for locale instance
+        * <p>
+        * @param locale Locale instance
+        */
+       private void setLocale (final Locale locale) {
+               this.locale = locale;
+       }
+
+       /**
+        * Removes user from all lists
+        * <p>
+        * @param user User to remove
+        */
+       private void removeFromList (final User user) {
+               // The user should be valid
+               if (null == user) {
+                       // Throw NPE
+                       throw new NullPointerException("user is null"); //NOI18N
+               } else if (user.getUserId() == null) {
+                       // ... again NPE
+                       throw new NullPointerException("user.userId is null"); //NOI18N
+               } else if (user.getUserId() < 1) {
+                       // Invalid id
+                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
+               }
+
+               // Remove it from lists
+               this.userCache.remove(user.getUserId());
+
+               // Remove name from list
+               this.userNameCache.remove(user.getUserId());
+       }
+
+       /**
+        * Updates list with given user instance
+        * <p>
+        * @param user User instance
+        */
+       private void updateList (final User user) {
+               // The user should be valid
+               if (null == user) {
+                       // Throw NPE
+                       throw new NullPointerException("user is null"); //NOI18N
+               } else if (user.getUserId() == null) {
+                       // ... again NPE
+                       throw new NullPointerException("user.userId is null"); //NOI18N
+               } else if (user.getUserId() < 1) {
+                       // Invalid id
+                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
+               } else if (user.getUserContact() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("user.userContact is null"); //NOI18N
+               } else if (user.getUserContact().getContactId() == null) {
+                       // Throw again ...
+                       throw new NullPointerException("user.userContact.contactId is null"); //NOI18N
+               } else if (user.getUserContact().getContactId() < 1) {
+                       // Throw again ...
+                       throw new NullPointerException(MessageFormat.format("user.userContact.contactId={0} is invalid.", user.getUserContact().getContactId())); //NOI18N
+               }
+
+               // Add/update user
+               this.userCache.put(user.getUserId(), user);
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebRequestController.java
new file mode 100644 (file)
index 0000000..206d155
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user;
+
+import java.io.Serializable;
+import java.util.List;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+import org.mxchange.jusercore.model.user.User;
+
+/**
+ * An interface for user beans
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsUserWebRequestController extends Serializable {
+
+       /**
+        * Minimum password length
+        * <p>
+        * @deprecated Better set as context parameter
+        */
+       public static final Integer MINIMUM_PASSWORD_LENGTH = 5;
+
+       /**
+        * Getter for clear-text user password
+        * <p>
+        * @return Clear-text user password
+        */
+       String getUserPassword ();
+
+       /**
+        * Checks if both user passwords are left empty and if this is enabled
+        * (allowed) in context parameter. If true, the calling bean should create a
+        * random password (preferable with UserUtils.createRandomPassword() and set
+        * it in both user password fields.
+        * <p>
+        * @return Whether empty passwords are allowed
+        */
+       boolean ifBothPasswordsEmptyAllowed ();
+
+       /**
+        * All users
+        * <p>
+        * @return A list of all public user profiles
+        */
+       List<User> allUsers ();
+
+       /**
+        * Checks whether the given contact is a user
+        * <p>
+        * @param contact Contact to check
+        * <p>
+        * @return Whether the contact is a user
+        */
+       boolean isContactFound (final Contact contact);
+
+       /**
+        * Checks whether given user instance's name is used
+        * <p>
+        * @param user User instance's name to check
+        * <p>
+        * @return Whether it is already used
+        */
+       boolean isUserNameRegistered (final User user);
+
+       /**
+        * Tries to lookup user by given id number. If the user is not found or the
+        * account status is not CONFIRMED proper exceptions are thrown.
+        * <p>
+        * @param userId User id
+        * <p>
+        * @return User instance
+        * <p>
+        * @throws UserNotFoundException If the user is not found
+        */
+       User lookupUserById (final Long userId) throws UserNotFoundException;
+
+       /**
+        * Tries to lookup user by given email address. If the user is not found a
+        * proper exceptions is thrown.
+        * <p>
+        * @param emailAddress Email address
+        * <p>
+        * @return User instance
+        * <p>
+        * @throws UserEmailAddressNotFoundException If the user's email address is
+        * not found
+        */
+       User lookupUserByEmailAddress (final String emailAddress) throws UserEmailAddressNotFoundException;
+
+       /**
+        * Creates an instance from all properties
+        * <p>
+        * @param createContactData Whether contact data should be created
+        * <p>
+        * @return A user instance
+        */
+       User createUserInstance (final boolean createContactData);
+
+       /**
+        * Creates a user instance for login phase
+        * <p>
+        * @return User instance
+        */
+       User createUserLogin ();
+
+       /**
+        * Checks whether all required personal data is set
+        * <p>
+        * @return Whether the required personal data is set
+        */
+       boolean isRequiredPersonalDataSet ();
+
+       /**
+        * Checks whether all required personal data is set for changing them
+        * <p>
+        * @return Whether the required personal data is set
+        */
+       boolean isRequiredChangePersonalDataSet ();
+
+       /**
+        * Checks whether same passwords has been entered
+        * <p>
+        * @return Whether same passwords has been entered
+        */
+       boolean isSamePasswordEntered ();
+
+       /**
+        * Checks if the user id is empty
+        * <p>
+        * @return Whether the user id is empty
+        */
+       boolean isUserIdEmpty ();
+
+       /**
+        * Changes logged-in user's personal data if the current password matches
+        * and TAC + privacy statement has been accepted.
+        * <p>
+        * @return New target page
+        */
+       String doChangePersonalData ();
+
+       /**
+        * Checks whether this application requires a user name to be entered.
+        * Otherwise a random name like "userXXXXX" is generated
+        * <p>
+        * @return Whether this application requires a user name
+        */
+       boolean isUserNameRequired ();
+
+       /**
+        * Checks wether public user profiles are enabled. This requires that user
+        * names are also enabled.
+        * <p>
+        * @return Whether public user profiles are enabled
+        */
+       boolean isPublicUserProfileEnabled ();
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebSessionBean.java b/src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebSessionBean.java
deleted file mode 100644 (file)
index 08d64fd..0000000
+++ /dev/null
@@ -1,1203 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user;
-
-import java.text.MessageFormat;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Event;
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.Any;
-import javax.faces.context.FacesContext;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jcontacts.contact.Contact;
-import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.contact.FinancialsContactWebSessionController;
-import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
-import org.mxchange.jfinancials.beans.localization.FinancialsLocalizationSessionController;
-import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
-import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
-import org.mxchange.jusercore.events.user.clear.password.ObservableClearUserPasswordEvent;
-import org.mxchange.jusercore.events.user.clear.username.ObservableClearUserNameEvent;
-import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
-import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
-import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
-import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
-import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
-import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
-import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
-import org.mxchange.jusercore.events.user.update.UpdatedUserPersonalDataEvent;
-import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-import org.mxchange.jusercore.model.user.LoginUser;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
-import org.mxchange.jusercore.model.user.profilemodes.ProfileMode;
-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.events.user.password_change.ObservableUpdatedUserPasswordEvent;
-import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
-import org.mxchange.juserlogincore.login.UserLoginUtils;
-
-/**
- * A user bean (controller)
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("userController")
-@SessionScoped
-public class FinancialsUserWebSessionBean extends BaseFinancialsController implements FinancialsUserWebSessionController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 542_145_347_916L;
-
-       /**
-        * General contact controller
-        */
-       @Inject
-       private FinancialsContactWebSessionController contactController;
-
-       /**
-        * Features controller
-        */
-       @Inject
-       private FinancialsFeaturesWebApplicationController featureController;
-
-       /**
-        * Locale instance
-        */
-       private Locale locale;
-
-       /**
-        * Localization controller
-        */
-       @Inject
-       private FinancialsLocalizationSessionController localizationController;
-
-       /**
-        * Event being fired when user updated personal data
-        */
-       @Inject
-       @Any
-       private Event<ObservableUpdatedUserPersonalDataEvent> updatedPersonalDataEvent;
-
-       /**
-        * Remote user bean
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/user!org.mxchange.jusercore.model.user.UserSessionBeanRemote")
-       private UserSessionBeanRemote userBean;
-
-       /**
-        * User id
-        */
-       private Long userId;
-
-       /**
-        * A list of all user profiles
-        */
-       private List<User> userList;
-
-       /**
-        * Login controller (bean)
-        */
-       @Inject
-       private FinancialsUserLoginWebSessionController userLoginController;
-
-       /**
-        * User name
-        */
-       private String userName;
-
-       /**
-        * User name list
-        */
-       private List<String> userNameList;
-
-       /**
-        * User password (clear-text from web form)
-        */
-       private String userPassword;
-
-       /**
-        * User password repeated (clear-text from web form)
-        */
-       private String userPasswordRepeat;
-
-       /**
-        * Whether the user wants a public profile
-        */
-       private ProfileMode userProfileMode;
-
-       /**
-        * A list of all public user profiles
-        * <p>
-        * @TODO Hmm, makes that sense? Having visible user list in current
-        * (session-scoped) user's visible user list?
-        */
-       private List<User> visibleUserList;
-
-       /**
-        * Default constructor
-        */
-       public FinancialsUserWebSessionBean () {
-               // Call super constructor
-               super();
-       }
-
-       /**
-        * Event observer for newly added users by administrator
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getAddedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.addedUser is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.updateList(event.getAddedUser());
-
-               // Clear all data
-               this.clear();
-
-               // Set user id again
-               this.setUserId(event.getAddedUser().getUserId());
-       }
-
-       /**
-        * Event observer for deleted user accounts (by administrator)
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getDeletedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.deletedUser is null"); //NOI18N
-               } else if (event.getDeletedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
-               } else if (event.getDeletedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.removeFromList(event.getDeletedUser());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Event observer for linked users with existing contact data
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLinkedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.linkedUser is null"); //NOI18N
-               } else if (event.getLinkedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
-               } else if (event.getLinkedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.updateList(event.getLinkedUser());
-
-               // Clear all data
-               this.clear();
-
-               // Set user id again
-               this.setUserId(event.getLinkedUser().getUserId());
-       }
-
-       /**
-        * Event observer for locked users
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLockedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.lockedUser is null"); //NOI18N
-               } else if (event.getLockedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
-               } else if (event.getLockedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.updateList(event.getLockedUser());
-       }
-
-       /**
-        * Event observer for unlocked users
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUnlockedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.unlockedUser is null"); //NOI18N
-               } else if (event.getUnlockedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
-               } else if (event.getUnlockedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.updateList(event.getUnlockedUser());
-       }
-
-       /**
-        * Event observer for updated user data by administrator
-        * <p>
-        * @param event Event being updated
-        */
-       public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUpdatedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
-               } else if (event.getUpdatedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
-               } else if (event.getUpdatedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.updateList(event.getUpdatedUser());
-
-               // Clear all data
-               this.clear();
-       }
-
-       /**
-        * Event observer for when a bean helper has successfully created a user
-        * instance, means the user exists. If the user does not exist, this event
-        * should not fire but instead a proper exception must be thrown.
-        * <p>
-        * @param event User created event
-        */
-       public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
-               // Is the instance valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getCreatedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.createdUser is null"); //NOI18N
-               } else if (event.getCreatedUser().getUserId() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
-               } else if (event.getCreatedUser().getUserId() < 1) {
-                       // Throw NPE again
-                       throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
-               }
-
-               // Get user instance
-               User user = event.getCreatedUser();
-
-               // Set all fields here
-               this.copyUser(user);
-       }
-
-       /**
-        * Observer method for events being fired when the application's locale has
-        * been changed.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterLocaleChangeEvent (@Observes final ObservableLocaleChangeEvent event) {
-               // Is the parameter valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null");
-               } else if (event.getLocale() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.locale is null");
-               }
-
-               // Set it here
-               this.setLocale(event.getLocale());
-       }
-
-       /**
-        * Event observer when user confirmed account.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterUserConfirmedAccountEvent (@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
-               }
-
-               // Update user list
-               this.updateList(event.getConfirmedUser());
-       }
-
-       /**
-        * Event observer for logged-in user
-        * <p>
-        * @param event Event instance
-        */
-       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLoggedInUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.registeredUser is null"); //NOI18N
-               } else if (event.getLoggedInUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
-               } else if (event.getLoggedInUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
-               }
-
-               // "Cache" user instance
-               User loggedInUser = event.getLoggedInUser();
-
-               // Copy all data to this bean
-               this.copyUser(loggedInUser);
-
-               // Is the user visible?
-               if (Objects.equals(loggedInUser.getUserProfileMode(), ProfileMode.PUBLIC)) {
-                       // Yes, then add user
-                       this.visibleUserList.add(loggedInUser);
-               }
-       }
-
-       /**
-        * Event observer for user password changes
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterUserPasswordChangedEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
-               // Is it valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUserPassword() == null) {
-                       // Throw NPE
-                       throw new NullPointerException("event.userPassword is null"); //NOI18N
-               } else if (event.getUserPassword().isEmpty()) {
-                       // Throw NPE
-                       throw new IllegalArgumentException("event.userPassword is empty"); //NOI18N
-               }
-
-               // Set it here
-               this.setUserPassword(event.getUserPassword());
-               this.setUserPasswordRepeat(event.getUserPassword());
-       }
-
-       /**
-        * Event observer for new user registrations
-        * <p>
-        * @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
-               User registeredUser = event.getRegisteredUser();
-
-               // Copy all data from registered->user
-               this.copyUser(registeredUser);
-
-               // Clear all data
-               this.clear();
-
-               // Update user list
-               this.updateList(registeredUser);
-
-               // Add user name
-               this.addUserName(registeredUser);
-
-               // Is the account public?
-               if (Objects.equals(registeredUser.getUserProfileMode(), ProfileMode.PUBLIC)) {
-                       // Also add it to this list
-                       this.visibleUserList.add(registeredUser);
-               }
-
-               // Set user id again
-               this.setUserId(registeredUser.getUserId());
-       }
-
-       /**
-        * Method being call after user's password has been updated (and history
-        * entry has been created).
-        * <p>
-        * @param event Event being observed
-        */
-       public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
-               // Check parameter
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getPasswordHistory() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.passwordHistory is null"); //NOI18N
-               } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
-                       // ... and again
-                       throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
-               } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
-                       // Invalid value
-                       throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
-               }
-
-               // Update user list
-               this.updateList(event.getPasswordHistory().getUserPasswordHistoryUser());
-       }
-
-       /**
-        * Listens to fired event when user updated personal data
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
-               // Check parameter
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUpdatedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
-               } else if (event.getUpdatedUser().getUserId() == null) {
-                       // ... and again
-                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
-               } else if (event.getUpdatedUser().getUserId() < 1) {
-                       // Invalid value
-                       throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.updateList(event.getUpdatedUser());
-       }
-
-       @Override
-       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
-       public List<User> allUsers () {
-               // Return it
-               return this.userList;
-       }
-
-       @Override
-       @SuppressWarnings ("ReturnOfCollectionOrArrayField")
-       public List<User> allVisibleUsers () {
-               // Return it
-               return this.visibleUserList;
-       }
-
-       /**
-        * Event observer for when a user name should be cleared
-        * <p>
-        * @param event Event being fired
-        */
-       public void clearUserNameEvent (@Observes final ObservableClearUserNameEvent event) {
-               // Is it valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null");
-               }
-
-               // Clear it
-               this.clearUserName();
-       }
-
-       /**
-        * Event observer for when both user passwords should be cleared
-        * <p>
-        * @param event Event being fired
-        */
-       public void clearUserPasswordEvent (@Observes final ObservableClearUserPasswordEvent event) {
-               // Is it valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null");
-               }
-
-               // Clear it
-               this.clearUserPasswords();
-       }
-
-       @Override
-       public User createUserInstance (final boolean createContactData) {
-               // Trace message
-               //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: CALLED!", this.getClass().getSimpleName()));
-
-               // Required personal data must be set
-               assert (this.isRequiredPersonalDataSet()) : "not all personal data is set"; //NOI18N
-
-               // Create new user instance
-               User user = new LoginUser();
-
-               // Is user name required?
-               if (!this.isUserNameRequired()) {
-                       // Generate pseudo-random user name
-                       String randomName = this.userBean.generateRandomUserName();
-
-                       // Set it and inivisible profile
-                       this.setUserName(randomName);
-                       this.setUserProfileMode(ProfileMode.INVISIBLE);
-
-                       // Generate random password
-                       String randomPassword = UserLoginUtils.createRandomPassword(FinancialsUserWebSessionController.MINIMUM_PASSWORD_LENGTH);
-
-                       // Set random password
-                       this.setUserPassword(randomPassword);
-                       this.setUserPasswordRepeat(randomPassword);
-               }
-
-               // Set user name profile mode and locale
-               user.setUserName(this.getUserName());
-               user.setUserProfileMode(this.getUserProfileMode());
-               user.setUserLocale(this.getLocale());
-
-               // Is multiple registration page
-               if ((createContactData) || (!this.featureController.isFeatureEnabled("user_register_multiple_page"))) { //NOI18N
-                       // Create contact instance
-                       Contact contact = this.contactController.createContactInstance();
-
-                       // Debug message
-                       //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: contact={1}", this.getClass().getSimpleName(), contact));
-                       // Set contact in user
-                       user.setUserContact(contact);
-               }
-
-               // Trace message
-               //* NOISY-DEBUG: */ System.out.println(MessageFormat.format("{0}.createUserInstance: user={1} - EXIT!", this.getClass().getSimpleName(), user));
-               // Return it
-               return user;
-       }
-
-       @Override
-       public User createUserLogin () {
-               // Trace message
-               //* NOISY-DEBUG */ System.out.println(MessageFormat.format("{0}.createUserLogin: CALLED!", this.getClass().getSimpleName()));
-
-               // Is all data set?
-               if (this.getUserName() == null) {
-                       // Throw NPE
-                       throw new NullPointerException("userName is null"); //NOI18N
-               } else if (this.getUserName().isEmpty()) {
-                       // Is empty
-                       throw new IllegalStateException("userName is empty."); //NOI18N
-               }
-
-               // Create new user instance
-               User user = new LoginUser();
-
-               // Update all data ...
-               user.setUserName(this.getUserName());
-
-               // Trace message
-               //* NOISY-DEBUG */ System.out.println(MessageFormat.format("{0}.createUserLogin: user={1} - EXIT!", this.getClass().getSimpleName(), user));
-               // Return the new instance
-               return user;
-       }
-
-       @Override
-       public String doChangePersonalData () {
-               // This method shall only be called if the user is logged-in
-               if (!this.userLoginController.isUserLoggedIn()) {
-                       // Not logged-in
-                       throw new IllegalStateException("User is not logged-in"); //NOI18N
-               } else if (!this.isRequiredChangePersonalDataSet()) {
-                       // Not all required fields are set
-                       throw new FaceletException("Not all required fields are set."); //NOI18N
-               } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
-                       // Password not matching
-                       throw new FaceletException(new UserPasswordMismatchException(this.userLoginController.getLoggedInUser()));
-               } else if (!this.featureController.isFeatureEnabled("change_user_personal_data")) { //NOI18N
-                       // Editing is not allowed
-                       throw new IllegalStateException("User tried to edit personal data."); //NOI18N
-               }
-
-               // Get user instance
-               User user = this.userLoginController.getLoggedInUser();
-
-               // Copy contact data to contact instance
-               this.contactController.updateContactDataFromController(user.getUserContact());
-
-               // It should be there, so run some tests on it
-               assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
-               assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
-               assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
-               assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
-               assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
-               assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
-
-               // Update all fields
-               user.setUserProfileMode(this.getUserProfileMode());
-
-               // Send it to the EJB
-               User updatedUser = this.userBean.updateUserPersonalData(user);
-
-               // Fire event
-               this.updatedPersonalDataEvent.fire(new UpdatedUserPersonalDataEvent(updatedUser));
-
-               // All fine
-               return "user_contact_data_saved"; //NOI18N
-       }
-
-       /**
-        * Getter for user id
-        * <p>
-        * @return User id
-        */
-       public Long getUserId () {
-               return this.userId;
-       }
-
-       /**
-        * Setter for user id
-        * <p>
-        * @param userId User id
-        */
-       public void setUserId (final Long userId) {
-               this.userId = userId;
-       }
-
-       /**
-        * Getter for user name
-        * <p>
-        * @return User name
-        */
-       public String getUserName () {
-               return this.userName;
-       }
-
-       /**
-        * Setter for user name
-        * <p>
-        * @param userName User name
-        */
-       public void setUserName (final String userName) {
-               this.userName = userName;
-       }
-
-       @Override
-       public String getUserPassword () {
-               return this.userPassword;
-       }
-
-       /**
-        * Setter for clear-text user password
-        * <p>
-        * @param userPassword Clear-text user password
-        */
-       public void setUserPassword (final String userPassword) {
-               this.userPassword = userPassword;
-       }
-
-       /**
-        * Getter for clear-text user password repeated
-        * <p>
-        * @return Clear-text user password repeated
-        */
-       public String getUserPasswordRepeat () {
-               return this.userPasswordRepeat;
-       }
-
-       /**
-        * Setter for clear-text user password repeated
-        * <p>
-        * @param userPasswordRepeat Clear-text user password repeated
-        */
-       public void setUserPasswordRepeat (final String userPasswordRepeat) {
-               this.userPasswordRepeat = userPasswordRepeat;
-       }
-
-       /**
-        * Getter for user profile mode
-        * <p>
-        * @return User profile mode
-        */
-       public ProfileMode getUserProfileMode () {
-               return this.userProfileMode;
-       }
-
-       /**
-        * Setter for user profile mode
-        * <p>
-        * @param userProfileMode User profile mode
-        */
-       public void setUserProfileMode (final ProfileMode userProfileMode) {
-               this.userProfileMode = userProfileMode;
-       }
-
-       @Override
-       public boolean ifBothPasswordsEmptyAllowed () {
-               // Check feature first
-               return ((this.featureController.isFeatureEnabled("allow_user_registration_empty_password")) && //NOI18N
-                               ((this.getUserPassword() == null) || (this.getUserPassword().isEmpty())) &&
-                               ((this.getUserPasswordRepeat() == null) || (this.getUserPasswordRepeat().isEmpty())));
-       }
-
-       /**
-        * Post-initialization of this class
-        */
-       @PostConstruct
-       public void init () {
-               // Initialize user list
-               this.userList = this.userBean.allUsers();
-
-               // Get full user name list for reducing EJB calls
-               this.userNameList = this.userBean.getUserNameList();
-
-               // Is the user logged-in?
-               if (this.userLoginController.isUserLoggedIn()) {
-                       // Is logged-in, so load also users visible to memebers
-                       this.visibleUserList = this.userBean.allMemberPublicVisibleUsers();
-               } else {
-                       // Initialize user list
-                       this.visibleUserList = this.userBean.allPublicUsers();
-               }
-       }
-
-       @Override
-       public boolean isContactFound (final Contact contact) {
-               // The contact must be valid
-               if (null == contact) {
-                       // Throw NPE
-                       throw new NullPointerException("contact is null"); //NOI18N
-               } else if (contact.getContactId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("contact.contactId is null"); //NOI18N
-               } else if (contact.getContactId() < 1) {
-                       // Not valid
-                       throw new IllegalArgumentException(MessageFormat.format("contact.contactId={0} is not valid", contact.getContactId())); //NOI18N
-               }
-
-               // Default is not found
-               boolean isFound = false;
-
-               // Get iterator
-               Iterator<User> iterator = this.allUsers().iterator();
-
-               // Loop through all entries
-               while (iterator.hasNext()) {
-                       // Get user
-                       User next = iterator.next();
-
-                       // Compare both objects
-                       if (Objects.equals(contact, next.getUserContact())) {
-                               // Found it
-                               isFound = true;
-                               break;
-                       }
-               }
-
-               // Return status
-               return isFound;
-       }
-
-       @Override
-       public boolean isPublicUserProfileEnabled () {
-               // Get context parameter
-               String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_public_profile_enabled"); //NOI18N
-
-               // Is it set?
-               boolean isEnabled = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
-
-               // This requires user names being enabled, too.
-               if ((isEnabled) && (!this.isUserNameRequired())) {
-                       // Not valid state, users must be able to modify their profile, especially when it is public
-                       throw new IllegalStateException("Public user profiles are enabled but user name requirement is disabled, this is not possible."); //NOI18N
-               }
-
-               // Return value
-               return isEnabled;
-       }
-
-       @Override
-       public boolean isRequiredChangePersonalDataSet () {
-               return ((this.getUserProfileMode() != null) &&
-                               (this.getUserName() != null) && (!this.getUserName().isEmpty()) &&
-                               (this.contactController.isRequiredChangePersonalDataSet()));
-       }
-
-       @Override
-       public boolean isRequiredPersonalDataSet () {
-               if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
-                       // Multiple registration page
-                       return this.contactController.isRequiredPersonalDataSet();
-               } else {
-                       // Single registration page
-                       return (((this.getUserName() != null) || (!this.isUserNameRequired())) &&
-                                       (this.getUserProfileMode() != null) &&
-                                       (this.contactController.isRequiredPersonalDataSet()) &&
-                                       (this.getUserPassword() != null) &&
-                                       (this.getUserPasswordRepeat() != null));
-               }
-       }
-
-       @Override
-       public boolean isSamePasswordEntered () {
-               return ((!this.getUserPassword().isEmpty()) && (Objects.equals(this.getUserPassword(), this.getUserPasswordRepeat())));
-       }
-
-       @Override
-       public boolean isUserIdEmpty () {
-               return ((this.getUserId() == null) || (this.getUserId() == 0));
-       }
-
-       @Override
-       public boolean isUserNameRegistered (final User user) {
-               return ((this.userNameList instanceof List) && (this.userNameList.contains(user.getUserName())));
-       }
-
-       @Override
-       public boolean isUserNameRequired () {
-               // Get context parameter
-               String contextParameter = FacesContext.getCurrentInstance().getExternalContext().getInitParameter("is_user_login_require_user_name"); //NOI18N
-
-               // Is it set?
-               boolean isRequired = ((contextParameter instanceof String) && (contextParameter.toLowerCase().equals("true"))); //NOI18N
-
-               // Return value
-               return isRequired;
-       }
-
-       @Override
-       public boolean isVisibleUserFound () {
-               return ((this.visibleUserList instanceof List) && (this.visibleUserList.size() > 0));
-       }
-
-       @Override
-       public User lookupUserByEmailAddress (final String emailAddress) throws UserEmailAddressNotFoundException {
-               // Parameter must be valid
-               if (null == emailAddress) {
-                       // Throw NPE
-                       throw new NullPointerException("emailAddress is null"); //NOI18N
-               } else if (emailAddress.isEmpty()) {
-                       // Not valid
-                       throw new IllegalArgumentException("emailAddress is empty"); //NOI18N
-               }
-
-               // Init variable
-               User user = null;
-
-               // Try to lookup it in visible user list
-               for (final Iterator<User> iterator = this.userList.iterator(); iterator.hasNext();) {
-                       // Get next user
-                       User next = iterator.next();
-
-                       // Contact should be set
-                       if (next.getUserContact() == null) {
-                               // Contact is null
-                               throw new NullPointerException(MessageFormat.format("next.userContact is null for user id {0}", next.getUserId())); //NOI18N
-                       } else if (next.getUserContact().getContactEmailAddress() == null) {
-                               // Email address should be set
-                               throw new NullPointerException(MessageFormat.format("next.userContact.contactEmailAddress is null for user id {0}", next.getUserId())); //NOI18N
-                       }
-
-                       // Is the email address found?
-                       if (Objects.equals(next.getUserContact().getContactEmailAddress(), emailAddress)) {
-                               // Copy to other variable
-                               user = next;
-                               break;
-                       }
-               }
-
-               // Is it still null?
-               if (null == user) {
-                       // Not visible for the current user
-                       throw new UserEmailAddressNotFoundException(emailAddress);
-               }
-
-               // Return it
-               return user;
-       }
-
-       @Override
-       public User lookupUserById (final Long userId) throws UserNotFoundException {
-               // Parameter must be valid
-               if (null == userId) {
-                       // Throw NPE
-                       throw new NullPointerException("userId is null"); //NOI18N
-               } else if (userId < 1) {
-                       // Not valid
-                       throw new IllegalArgumentException(MessageFormat.format("userId={0} is not valid.", userId)); //NOI18N
-               }
-
-               // Init variable
-               User user = null;
-
-               // Try to lookup it in visible user list
-               for (final Iterator<User> iterator = this.userList.iterator(); iterator.hasNext();) {
-                       // Get next user
-                       User next = iterator.next();
-
-                       // Is the user id found?
-                       if (Objects.equals(next.getUserId(), userId)) {
-                               // Copy to other variable
-                               user = next;
-                               break;
-                       }
-               }
-
-               // Is it still null?
-               if (null == user) {
-                       // Not visible for the current user
-                       throw new UserNotFoundException(userId);
-               }
-
-               // Return it
-               return user;
-       }
-
-       /**
-        * Adds user's name to bean's internal list. It also updates the public user
-        * list if the user has decided to have a public account,
-        * <p>
-        * @param user User instance
-        */
-       private void addUserName (final User user) {
-               // Make sure the entry is not added yet
-               if (this.userNameList.contains(user.getUserName())) {
-                       // Abort here
-                       throw new IllegalArgumentException(MessageFormat.format("User name {0} already added.", user.getUserName())); //NOI18N
-               }
-
-               // Add user name
-               this.userNameList.add(user.getUserName());
-       }
-
-       /**
-        * Clears this bean
-        */
-       private void clear () {
-               // Clear all data
-               // - personal data
-               this.setUserId(null);
-               this.setUserProfileMode(null);
-
-               // - other data
-               this.clearUserName();
-               this.clearUserPasswords();
-               this.setLocale(null);
-       }
-
-       /**
-        * Clears user name
-        */
-       private void clearUserName () {
-               // Clear it
-               this.setUserName(null);
-       }
-
-       /**
-        * Clears both user passwords
-        */
-       private void clearUserPasswords () {
-               // Clear both
-               this.setUserPassword(null);
-               this.setUserPasswordRepeat(null);
-       }
-
-       /**
-        * Copies given user into the controller
-        * <p>
-        * @param user User instance
-        */
-       private void copyUser (final User user) {
-               // Make sure the instance is valid
-               if (null == user) {
-                       // Throw NPE
-                       throw new NullPointerException("user is null"); //NOI18N
-               } else if (user.getUserContact() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("user.userContact is null"); //NOI18N
-               }
-
-               // Copy all fields:
-               // - base data
-               this.setUserId(user.getUserId());
-               this.setUserProfileMode(user.getUserProfileMode());
-       }
-
-       /**
-        * Getter for locale instance
-        * <p>
-        * @return Locale instance
-        */
-       private Locale getLocale () {
-               return this.locale;
-       }
-
-       /**
-        * Setter for locale instance
-        * <p>
-        * @param locale Locale instance
-        */
-       private void setLocale (final Locale locale) {
-               this.locale = locale;
-       }
-
-       /**
-        * Removes user from all lists
-        * <p>
-        * @param user User to remove
-        */
-       private void removeFromList (final User user) {
-               // The user should be valid
-               if (null == user) {
-                       // Throw NPE
-                       throw new NullPointerException("user is null"); //NOI18N
-               } else if (user.getUserId() == null) {
-                       // ... again NPE
-                       throw new NullPointerException("user.userId is null"); //NOI18N
-               } else if (user.getUserId() < 1) {
-                       // Invalid id
-                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
-               }
-
-               // Remove it from lists
-               this.userList.remove(user);
-               this.visibleUserList.remove(user);
-
-               // Remove name from list
-               this.userNameList.remove(user.getUserName());
-       }
-
-       /**
-        * Updates list with given user instance
-        * <p>
-        * @param user User instance
-        */
-       private void updateList (final User user) {
-               // The user should be valid
-               if (null == user) {
-                       // Throw NPE
-                       throw new NullPointerException("user is null"); //NOI18N
-               } else if (user.getUserId() == null) {
-                       // ... again NPE
-                       throw new NullPointerException("user.userId is null"); //NOI18N
-               } else if (user.getUserId() < 1) {
-                       // Invalid id
-                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is invalid", user.getUserId())); //NOI18N
-               } else if (user.getUserContact() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("user.userContact is null"); //NOI18N
-               } else if (user.getUserContact().getContactId() == null) {
-                       // Throw again ...
-                       throw new NullPointerException("user.userContact.contactId is null"); //NOI18N
-               } else if (user.getUserContact().getContactId() < 1) {
-                       // Throw again ...
-                       throw new NullPointerException(MessageFormat.format("user.userContact.contactId={0} is invalid.", user.getUserContact().getContactId())); //NOI18N
-               }
-
-               // Get iterator from list
-               Iterator<User> iterator = this.userList.iterator();
-
-               // "Walk" through all entries
-               while (iterator.hasNext()) {
-                       // Get next element
-                       User next = iterator.next();
-
-                       // Is user id number the same?
-                       if (Objects.equals(user.getUserId(), next.getUserId())) {
-                               // Found entry, so remove it and abort
-                               this.userList.remove(next);
-                               break;
-                       }
-               }
-
-               // Re-add user
-               this.userList.add(user);
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/user/FinancialsUserWebSessionController.java
deleted file mode 100644 (file)
index b0b9ac8..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user;
-
-import java.io.Serializable;
-import java.util.List;
-import org.mxchange.jcontacts.contact.Contact;
-import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-import org.mxchange.jusercore.model.user.User;
-
-/**
- * An interface for user beans
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsUserWebSessionController extends Serializable {
-
-       /**
-        * Minimum password length
-        * <p>
-        * @deprecated Better set as context parameter
-        */
-       public static final Integer MINIMUM_PASSWORD_LENGTH = 5;
-
-       /**
-        * Getter for clear-text user password
-        * <p>
-        * @return Clear-text user password
-        */
-       String getUserPassword ();
-
-       /**
-        * Checks if both user passwords are left empty and if this is enabled
-        * (allowed) in context parameter. If true, the calling bean should create a
-        * random password (preferable with UserUtils.createRandomPassword() and set
-        * it in both user password fields.
-        * <p>
-        * @return Whether empty passwords are allowed
-        */
-       boolean ifBothPasswordsEmptyAllowed ();
-
-       /**
-        * All users
-        * <p>
-        * @return A list of all public user profiles
-        */
-       List<User> allUsers ();
-
-       /**
-        * All public user profiles
-        * <p>
-        * @return A list of all public user profiles
-        */
-       List<User> allVisibleUsers ();
-
-       /**
-        * Checks whether the given contact is a user
-        * <p>
-        * @param contact Contact to check
-        * <p>
-        * @return Whether the contact is a user
-        */
-       boolean isContactFound (final Contact contact);
-
-       /**
-        * Checks whether a public user account is registered. This means that at
-        * least one user profile has its flag "public user profile" enabled.
-        * <p>
-        * @return Whether at least one user has a public profile
-        */
-       boolean isVisibleUserFound ();
-
-       /**
-        * Checks whether given user instance's name is used
-        * <p>
-        * @param user User instance's name to check
-        * <p>
-        * @return Whether it is already used
-        */
-       boolean isUserNameRegistered (final User user);
-
-       /**
-        * Tries to lookup user by given id number. If the user is not found or the
-        * account status is not CONFIRMED proper exceptions are thrown.
-        * <p>
-        * @param userId User id
-        * <p>
-        * @return User instance
-        * <p>
-        * @throws UserNotFoundException If the user is not found
-        */
-       User lookupUserById (final Long userId) throws UserNotFoundException;
-
-       /**
-        * Tries to lookup user by given email address. If the user is not found a
-        * proper exceptions is thrown.
-        * <p>
-        * @param emailAddress Email address
-        * <p>
-        * @return User instance
-        * <p>
-        * @throws UserEmailAddressNotFoundException If the user's email address is
-        * not found
-        */
-       User lookupUserByEmailAddress (final String emailAddress) throws UserEmailAddressNotFoundException;
-
-       /**
-        * Creates an instance from all properties
-        * <p>
-        * @param createContactData Whether contact data should be created
-        * <p>
-        * @return A user instance
-        */
-       User createUserInstance (final boolean createContactData);
-
-       /**
-        * Creates a user instance for login phase
-        * <p>
-        * @return User instance
-        */
-       User createUserLogin ();
-
-       /**
-        * Checks whether all required personal data is set
-        * <p>
-        * @return Whether the required personal data is set
-        */
-       boolean isRequiredPersonalDataSet ();
-
-       /**
-        * Checks whether all required personal data is set for changing them
-        * <p>
-        * @return Whether the required personal data is set
-        */
-       boolean isRequiredChangePersonalDataSet ();
-
-       /**
-        * Checks whether same passwords has been entered
-        * <p>
-        * @return Whether same passwords has been entered
-        */
-       boolean isSamePasswordEntered ();
-
-       /**
-        * Checks if the user id is empty
-        * <p>
-        * @return Whether the user id is empty
-        */
-       boolean isUserIdEmpty ();
-
-       /**
-        * Changes logged-in user's personal data if the current password matches
-        * and TAC + privacy statement has been accepted.
-        * <p>
-        * @return New target page
-        */
-       String doChangePersonalData ();
-
-       /**
-        * Checks whether this application requires a user name to be entered.
-        * Otherwise a random name like "userXXXXX" is generated
-        * <p>
-        * @return Whether this application requires a user name
-        */
-       boolean isUserNameRequired ();
-
-       /**
-        * Checks wether public user profiles are enabled. This requires that user
-        * names are also enabled.
-        * <p>
-        * @return Whether public user profiles are enabled
-        */
-       boolean isPublicUserProfileEnabled ();
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebApplicationBean.java b/src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebApplicationBean.java
deleted file mode 100644 (file)
index 9a2a119..0000000
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.activity;
-
-import java.text.MessageFormat;
-import java.util.Collections;
-import java.util.GregorianCalendar;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import javax.annotation.PostConstruct;
-import javax.ejb.EJB;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Named;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
-import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
-import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
-import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
-import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
-import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
-import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
-import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.activity.LogableUserActivity;
-import org.mxchange.jusercore.model.user.activity.UserActivityLog;
-import org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote;
-import org.mxchange.jusercore.model.user.activity.comparator.UserActivityLogTimestampComparator;
-import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
-import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
-import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
-import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
-import org.mxchange.juserlogincore.events.resendlink.ObservableUserResendLinkAccountEvent;
-import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
-
-/**
- * A controller (bean) for user activity log
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("userActivityController")
-@ApplicationScoped
-public class FinancialsUserActivityWebApplicationBean extends BaseFinancialsController implements FinancialsUserActivityWebApplicationController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 192_586_376_717_856_904L;
-
-       /**
-        * User instance
-        */
-       private User user;
-
-       /**
-        * EJB for user activity log
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/userActivity!org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote")
-       private UserActivityLogSessionBeanRemote userActivityBean;
-
-       /**
-        * "Cache" for activity log per user
-        */
-       private final Map<User, List<LogableUserActivity>> usersActivity;
-
-       /**
-        * Default constructor
-        */
-       @SuppressWarnings ("CollectionWithoutInitialCapacity")
-       public FinancialsUserActivityWebApplicationBean () {
-               // Init cache
-               this.usersActivity = new LinkedHashMap<>();
-       }
-
-       /**
-        * Event observer for newly added users by administrator
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getAddedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.addedUser is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
-               } else if (event.getAddedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.addUserActivity(event.getAddedUser(), "ADMIN_ADDED_USER_ACCOUNT"); //NOI18N
-       }
-
-       /**
-        * Event observer for deleted user accounts (by administrator)
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getDeletedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.deletedUser is null"); //NOI18N
-               } else if (event.getDeletedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
-               } else if (event.getDeletedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
-               }
-
-               // Add acitivity
-               this.addUserActivity(event.getDeletedUser(), "ADMIN_DELETED_USER_ACCOUNT", event.getUserDeleteReason()); //NOI18N
-       }
-
-       /**
-        * Event observer for linked users with existing contact data
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLinkedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.linkedUser is null"); //NOI18N
-               } else if (event.getLinkedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
-               } else if (event.getLinkedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.addUserActivity(event.getLinkedUser(), "ADMIN_LINKED_USER_ACCOUNT"); //NOI18N
-       }
-
-       /**
-        * Event observer for locked users
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLockedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.lockedUser is null"); //NOI18N
-               } else if (event.getLockedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
-               } else if (event.getLockedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.addUserActivity(event.getLockedUser(), "ADMIN_LOCKED_USER_ACCOUNT", event.getLockedUser().getUserLastLockedReason()); //NOI18N
-       }
-
-       /**
-        * Event observer for unlocked users
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUnlockedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.unlockedUser is null"); //NOI18N
-               } else if (event.getUnlockedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
-               } else if (event.getUnlockedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.addUserActivity(event.getUnlockedUser(), "ADMIN_UNLOCKED_USER_ACCOUNT"); //NOI18N
-       }
-
-       /**
-        * Event observer for updated user data by administrator
-        * <p>
-        * @param event Event being updated
-        */
-       public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUpdatedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
-               } else if (event.getUpdatedUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
-               } else if (event.getUpdatedUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.addUserActivity(event.getUpdatedUser(), "ADMIN_UPDATED_USER_PERSONAL_DATA"); //NOI18N
-       }
-
-       /**
-        * Event observer for when a bean helper has successfully created a user
-        * instance, means the user exists. If the user does not exist, this event
-        * should not fire but instead a proper exception must be thrown.
-        * <p>
-        * @param event User created event
-        */
-       public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
-               // Is the instance valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getCreatedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.createdUser is null"); //NOI18N
-               } else if (event.getCreatedUser().getUserId() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
-               } else if (event.getCreatedUser().getUserId() < 1) {
-                       // Throw NPE again
-                       throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
-               }
-
-               // Set whole user
-               this.setUser(event.getCreatedUser());
-       }
-
-       /**
-        * Event observer when user confirmed account.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterUserConfirmedAccountEvent (@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
-               }
-
-               // Update user list
-               this.addUserActivity(event.getConfirmedUser(), "USER_CONFIRMED_ACCOUNT"); //NOI18N
-       }
-
-       /**
-        * Event observer for logged-in user
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLoggedInUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.registeredUser is null"); //NOI18N
-               } else if (event.getLoggedInUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
-               } else if (event.getLoggedInUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
-               }
-
-               // Copy all data to this bean
-               this.addUserActivity(event.getLoggedInUser(), "USER_LOGGED_IN"); //NOI18N
-       }
-
-       /**
-        * Event observer for logged-out user
-        * <p>
-        * @param event Event instance
-        */
-       public void afterUserLogoutEvent (@Observes final ObservableUserLogoutEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getLoggedOutUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.loggedOutUser is null"); //NOI18N
-               } else if (event.getLoggedOutUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.loggedOutUser.userId is null"); //NOI18N
-               } else if (event.getLoggedOutUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedOutUser(), event.getLoggedOutUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.addUserActivity(event.getLoggedOutUser(), "USER_LOGGED_OUT"); //NOI18N
-       }
-
-       /**
-        * Event observer for new user registrations
-        * <p>
-        * @param event Event being fired
-        */
-       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
-               }
-
-               // Update user list
-               this.addUserActivity(event.getRegisteredUser(), "USER_REGISTERED_NEW_ACCOUNT"); //NOI18N
-       }
-
-       /**
-        * Event observer for users resending their confirmation link
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterUserResendConfirmationLinkEvent (@Observes final ObservableUserResendLinkAccountEvent event) {
-               // event should not be null
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getResendLinkUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.resendLinkUser is null"); //NOI18N
-               } else if (event.getResendLinkUser().getUserId() == null) {
-                       // userId is null
-                       throw new NullPointerException("event.resendLinkUser.userId is null"); //NOI18N
-               } else if (event.getResendLinkUser().getUserId() < 1) {
-                       // Not avalid id
-                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getResendLinkUser(), event.getResendLinkUser().getUserId())); //NOI18N
-               }
-
-               // Copy all data to this bean
-               this.addUserActivity(event.getResendLinkUser(), "USER_RESEND_CONFIRMATION_LINK"); //NOI18N
-       }
-
-       /**
-        * Method being call after user's password has been updated (and history
-        * entry has been created).
-        * <p>
-        * @param event Event being observed
-        */
-       public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
-               // Check parameter
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getPasswordHistory() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.passwordHistory is null"); //NOI18N
-               } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
-                       // ... and again
-                       throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
-               } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
-                       // Invalid value
-                       throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
-               }
-
-               // Update user list
-               this.addUserActivity(event.getPasswordHistory().getUserPasswordHistoryUser(), "USER_UPDATED_PASSWORD"); //NOI18N
-       }
-
-       /**
-        * Listens to fired event when user updated personal data
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
-               // Check parameter
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null"); //NOI18N
-               } else if (event.getUpdatedUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
-               } else if (event.getUpdatedUser().getUserId() == null) {
-                       // ... and again
-                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
-               } else if (event.getUpdatedUser().getUserId() < 1) {
-                       // Invalid value
-                       throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
-               }
-
-               // Update user list
-               this.addUserActivity(event.getUpdatedUser(), "USER_UPDATED_PERSONAL_DATA"); //NOI18N
-       }
-
-       /**
-        * Expands given activity type into a i18n string for administrators
-        * <p>
-        * @param activityType Activity type
-        * <p>
-        * @return Expanded i18n string
-        */
-       public String expandAdminActivityType (final String activityType) {
-               // Is it valid?
-               if (null == activityType) {
-                       // Throw NPE
-                       throw new NullPointerException("activityType is null"); //NOI18N
-               } else if (activityType.isEmpty()) {
-                       // Is empty
-                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
-               }
-
-               // Expand it
-               return "ADMIN_ACTIVITY_" + activityType; //NOI18N
-       }
-
-       /**
-        * Expands given activity type into a i18n string for users
-        * <p>
-        * @param activityType Activity type
-        * <p>
-        * @return Expanded i18n string
-        */
-       public String expandUserActivityType (final String activityType) {
-               // Is it valid?
-               if (null == activityType) {
-                       // Throw NPE
-                       throw new NullPointerException("activityType is null"); //NOI18N
-               } else if (activityType.isEmpty()) {
-                       // Is empty
-                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
-               }
-
-               // Expand it
-               return "USER_ACTIVITY_" + activityType; //NOI18N
-       }
-
-       /**
-        * Returns a list of in beanHelper set user instance's activity log
-        * <p>
-        * @return List of user's activity log
-        */
-       public List<LogableUserActivity> fetchCurrentUsersActivityLog () {
-               // beanHelper.user should be set and valid
-               if (this.getUser() == null) {
-                       // Is not set
-                       throw new NullPointerException("this.beanHelper.user is null"); //NOI18N
-               } else if (this.getUser().getUserId() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("this.beanHelper.user.userId is null"); //NOI18N
-               } else if (this.getUser().getUserId() < 1) {
-                       // Invalid id number
-                       throw new IllegalArgumentException(MessageFormat.format("this.beanHelper.user.userId={0} is not valid", this.getUser().getUserId())); //NOI18N
-               }
-
-               // Init list
-               List<LogableUserActivity> list = new LinkedList<>();
-
-               // Is the user set?
-               if (this.usersActivity.containsKey(this.getUser())) {
-                       // Return it
-                       list.addAll(this.usersActivity.get(this.getUser()));
-
-                       // Sort list and reverse it
-                       Collections.sort(list, new UserActivityLogTimestampComparator());
-                       Collections.reverse(list);
-               }
-
-               // Return it
-               return list;
-       }
-
-       /**
-        * Getter for user instance
-        * <p>
-        * @return User instance
-        */
-       public User getUser () {
-               return this.user;
-       }
-
-       /**
-        * Setter for user instance
-        * <p>
-        * @param user User instance
-        */
-       public void setUser (final User user) {
-               this.user = user;
-       }
-
-       /**
-        * Post-constructor method
-        */
-       @PostConstruct
-       public void init () {
-               // Get whole list
-               List<LogableUserActivity> list = this.userActivityBean.fetchAllUserActivityLog();
-
-               // Put all in map, per-user
-               for (final LogableUserActivity userActivity : list) {
-                       // Is the list there?
-                       if (!this.usersActivity.containsKey(userActivity.getActivityUser())) {
-                               // Init list
-                               this.usersActivity.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
-                       }
-
-                       // Add by user instance
-                       boolean added = this.usersActivity.get(userActivity.getActivityUser()).add(userActivity);
-
-                       // Should be added
-                       assert (added) : "Activity log not added"; //NOI18N
-               }
-       }
-
-       /**
-        * Adds user activity entry with given type
-        * <p>
-        * @param user         User instance
-        * @param activityType Activity type
-        */
-       private void addUserActivity (final User user, final String activityType) {
-               // Better re-validate
-               if (null == user) {
-                       // Throw NPE
-                       throw new NullPointerException("user is null"); //NOI18N
-               } else if (user.getUserId() == null) {
-                       // Throw again
-                       throw new NullPointerException("user.userId is null"); //NOI18N
-               } else if (user.getUserId() < 1) {
-                       // Invalid id number
-                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
-               } else if (null == activityType) {
-                       // Throw NPE again
-                       throw new NullPointerException("activityType is null"); //NOI18N
-               } else if (activityType.isEmpty()) {
-                       // Is empty
-                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
-               }
-
-               // Create new activity object
-               LogableUserActivity userActivity = new UserActivityLog(activityType, user, new GregorianCalendar(), this.determinePrincipalName());
-
-               // Call bean to add it
-               this.userActivityBean.addUserActivityLog(userActivity);
-
-               // Add to cache, too
-               this.addUserActivityToCache(userActivity);
-       }
-
-       /**
-        * Adds user activity log with type and message
-        * <p>
-        * @param user         User instance
-        * @param activityType Activity type
-        * @param message      Activity message
-        */
-       private void addUserActivity (final User user, final String activityType, final String message) {
-               // Better re-validate
-               if (null == user) {
-                       // Throw NPE
-                       throw new NullPointerException("user is null"); //NOI18N
-               } else if (user.getUserId() == null) {
-                       // Throw again
-                       throw new NullPointerException("user.userId is null"); //NOI18N
-               } else if (user.getUserId() < 1) {
-                       // Invalid id number
-                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
-               } else if (null == activityType) {
-                       // Throw NPE again
-                       throw new NullPointerException("activityType is null"); //NOI18N
-               } else if (activityType.isEmpty()) {
-                       // Is empty
-                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
-               } else if (null == message) {
-                       // Throw NPE again
-                       throw new NullPointerException("message is null"); //NOI18N
-               } else if (message.isEmpty()) {
-                       // Is empty
-                       throw new IllegalArgumentException("message is empty"); //NOI18N
-               }
-
-               // Create new activity object
-               LogableUserActivity userActivity = new UserActivityLog(message, activityType, user, new GregorianCalendar(), this.determinePrincipalName());
-
-               // Call bean to add it
-               this.userActivityBean.addUserActivityLog(userActivity);
-
-               // Add to cache, too
-               this.addUserActivityToCache(userActivity);
-       }
-
-       /**
-        * Adds given user activity instance to "cache" (local map)
-        * <p>
-        * @param userActivity User activity instance
-        */
-       private void addUserActivityToCache (final LogableUserActivity userActivity) {
-               // Is the instance valid
-               if (null == userActivity) {
-                       // Throw NPE again
-                       throw new NullPointerException("userActivity is null");
-               } else if (userActivity.getActivityId() instanceof Long) {
-                       // Is not null
-                       throw new IllegalArgumentException("userActivity.activityId=" + userActivity.getActivityId() + " is not null");
-               } else if (userActivity.getActivityUser() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("userActivity.activityUser is null");
-               } else if (userActivity.getActivityUser().getUserId() == null) {
-                       // Throw it again
-                       throw new NullPointerException("userActivity.activityUser.userId is null");
-               } else if (userActivity.getActivityUser().getUserId() < 1) {
-                       // Invalid id number
-                       throw new IllegalArgumentException("userActivity.activityUser.userId=" + userActivity.getActivityUser().getUserId() + " is not valid");
-               }
-
-               // Is it there?
-               if (!this.usersActivity.containsKey(userActivity.getActivityUser())) {
-                       // Init it
-                       this.usersActivity.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
-               }
-
-               // Add activity to log
-               this.usersActivity.get(userActivity.getActivityUser()).add(userActivity);
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebApplicationController.java b/src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebApplicationController.java
deleted file mode 100644 (file)
index 802c11a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.activity;
-
-import java.io.Serializable;
-
-/**
- * A controller (bean) interface for user activity log
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsUserActivityWebApplicationController extends Serializable {
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebRequestBean.java
new file mode 100644 (file)
index 0000000..e699cf6
--- /dev/null
@@ -0,0 +1,677 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.activity;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.GregorianCalendar;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.cache.Cache;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcoreee.jcache.Cached;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jusercore.events.user.add.ObservableAdminAddedUserEvent;
+import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
+import org.mxchange.jusercore.events.user.delete.ObservableAdminDeletedUserEvent;
+import org.mxchange.jusercore.events.user.linked.ObservableAdminLinkedUserEvent;
+import org.mxchange.jusercore.events.user.locked.ObservableAdminLockedUserEvent;
+import org.mxchange.jusercore.events.user.unlocked.ObservableAdminUnlockedUserEvent;
+import org.mxchange.jusercore.events.user.update.ObservableAdminUpdatedUserDataEvent;
+import org.mxchange.jusercore.events.user.update.ObservableUpdatedUserPersonalDataEvent;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.activity.LogableUserActivity;
+import org.mxchange.jusercore.model.user.activity.UserActivityLog;
+import org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote;
+import org.mxchange.jusercore.model.user.activity.comparator.UserActivityLogTimestampComparator;
+import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
+import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
+import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
+import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
+import org.mxchange.juserlogincore.events.resendlink.ObservableUserResendLinkAccountEvent;
+import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
+
+/**
+ * A controller (bean) for user activity log
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("userActivityController")
+@RequestScoped
+public class FinancialsUserActivityWebRequestBean extends BaseFinancialsController implements FinancialsUserActivityWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 192_586_376_717_856_904L;
+
+       /**
+        * User instance
+        */
+       private User user;
+
+       /**
+        * EJB for user activity log
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/userActivity!org.mxchange.jusercore.model.user.activity.UserActivityLogSessionBeanRemote")
+       private UserActivityLogSessionBeanRemote userActivityBean;
+
+       /**
+        * "Cache" for activity log per user
+        */
+       @Inject
+       @Cached(cacheName = "usersActivityCache")
+       private transient Cache<User, List<LogableUserActivity>> usersActivityCache;
+
+       /**
+        * Default constructor
+        */
+       @SuppressWarnings ("CollectionWithoutInitialCapacity")
+       public FinancialsUserActivityWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Event observer for newly added users by administrator
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminAddedUserEvent (@Observes final ObservableAdminAddedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getAddedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.addedUser is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.addedUser.userId is null"); //NOI18N
+               } else if (event.getAddedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getAddedUser(), event.getAddedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getAddedUser(), "ADMIN_ADDED_USER_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for deleted user accounts (by administrator)
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminDeletedUserEvent (@Observes final ObservableAdminDeletedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getDeletedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.deletedUser is null"); //NOI18N
+               } else if (event.getDeletedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.deletedUser.userId is null"); //NOI18N
+               } else if (event.getDeletedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getDeletedUser(), event.getDeletedUser().getUserId())); //NOI18N
+               }
+
+               // Add acitivity
+               this.addUserActivity(event.getDeletedUser(), "ADMIN_DELETED_USER_ACCOUNT", event.getUserDeleteReason()); //NOI18N
+       }
+
+       /**
+        * Event observer for linked users with existing contact data
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLinkedUserEvent (@Observes final ObservableAdminLinkedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLinkedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.linkedUser is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.linkedUser.userId is null"); //NOI18N
+               } else if (event.getLinkedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLinkedUser(), event.getLinkedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getLinkedUser(), "ADMIN_LINKED_USER_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for locked users
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminLockedUserEvent (@Observes final ObservableAdminLockedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLockedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.lockedUser is null"); //NOI18N
+               } else if (event.getLockedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.lockedUser.userId is null"); //NOI18N
+               } else if (event.getLockedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLockedUser(), event.getLockedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getLockedUser(), "ADMIN_LOCKED_USER_ACCOUNT", event.getLockedUser().getUserLastLockedReason()); //NOI18N
+       }
+
+       /**
+        * Event observer for unlocked users
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterAdminUnlockedUserEvent (@Observes final ObservableAdminUnlockedUserEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUnlockedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.unlockedUser is null"); //NOI18N
+               } else if (event.getUnlockedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.unlockedUser.userId is null"); //NOI18N
+               } else if (event.getUnlockedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUnlockedUser(), event.getUnlockedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getUnlockedUser(), "ADMIN_UNLOCKED_USER_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for updated user data by administrator
+        * <p>
+        * @param event Event being updated
+        */
+       public void afterAdminUpdatedUserDataEvent (@Observes final ObservableAdminUpdatedUserDataEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getUpdatedUser(), event.getUpdatedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getUpdatedUser(), "ADMIN_UPDATED_USER_PERSONAL_DATA"); //NOI18N
+       }
+
+       /**
+        * Event observer for when a bean helper has successfully created a user
+        * instance, means the user exists. If the user does not exist, this event
+        * should not fire but instead a proper exception must be thrown.
+        * <p>
+        * @param event User created event
+        */
+       public void afterCreatedUserEvent (@Observes final ObservableCreatedUserEvent event) {
+               // Is the instance valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getCreatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.createdUser is null"); //NOI18N
+               } else if (event.getCreatedUser().getUserId() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.createdUser.userId is null"); //NOI18N
+               } else if (event.getCreatedUser().getUserId() < 1) {
+                       // Throw NPE again
+                       throw new NullPointerException(MessageFormat.format("event.createdUser.userId={0} is not valid", event.getCreatedUser().getUserId())); //NOI18N
+               }
+
+               // Set whole user
+               this.setUser(event.getCreatedUser());
+       }
+
+       /**
+        * Event observer when user confirmed account.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserConfirmedAccountEvent (@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
+               }
+
+               // Update user list
+               this.addUserActivity(event.getConfirmedUser(), "USER_CONFIRMED_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for logged-in user
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLoggedInUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.registeredUser is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.registeredUser.userId is null"); //NOI18N
+               } else if (event.getLoggedInUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
+               }
+
+               // Copy all data to this bean
+               this.addUserActivity(event.getLoggedInUser(), "USER_LOGGED_IN"); //NOI18N
+       }
+
+       /**
+        * Event observer for logged-out user
+        * <p>
+        * @param event Event instance
+        */
+       public void afterUserLogoutEvent (@Observes final ObservableUserLogoutEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getLoggedOutUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.loggedOutUser is null"); //NOI18N
+               } else if (event.getLoggedOutUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.loggedOutUser.userId is null"); //NOI18N
+               } else if (event.getLoggedOutUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedOutUser(), event.getLoggedOutUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getLoggedOutUser(), "USER_LOGGED_OUT"); //NOI18N
+       }
+
+       /**
+        * Event observer for new user registrations
+        * <p>
+        * @param event Event being fired
+        */
+       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
+               }
+
+               // Update user list
+               this.addUserActivity(event.getRegisteredUser(), "USER_REGISTERED_NEW_ACCOUNT"); //NOI18N
+       }
+
+       /**
+        * Event observer for users resending their confirmation link
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserResendConfirmationLinkEvent (@Observes final ObservableUserResendLinkAccountEvent event) {
+               // event should not be null
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getResendLinkUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.resendLinkUser is null"); //NOI18N
+               } else if (event.getResendLinkUser().getUserId() == null) {
+                       // userId is null
+                       throw new NullPointerException("event.resendLinkUser.userId is null"); //NOI18N
+               } else if (event.getResendLinkUser().getUserId() < 1) {
+                       // Not avalid id
+                       throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getResendLinkUser(), event.getResendLinkUser().getUserId())); //NOI18N
+               }
+
+               // Copy all data to this bean
+               this.addUserActivity(event.getResendLinkUser(), "USER_RESEND_CONFIRMATION_LINK"); //NOI18N
+       }
+
+       /**
+        * Method being call after user's password has been updated (and history
+        * entry has been created).
+        * <p>
+        * @param event Event being observed
+        */
+       public void afterUserUpdatedPasswordEvent (@Observes final ObservableUpdatedUserPasswordEvent event) {
+               // Check parameter
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getPasswordHistory() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.passwordHistory is null"); //NOI18N
+               } else if (event.getPasswordHistory().getUserPasswordHistoryId() == null) {
+                       // ... and again
+                       throw new NullPointerException("event.passwordHistory.userPasswordHistoryId is null"); //NOI18N
+               } else if (event.getPasswordHistory().getUserPasswordHistoryId() < 1) {
+                       // Invalid value
+                       throw new IllegalArgumentException(MessageFormat.format("event.passwordHistory.userPasswordHistoryId={0} is in valid", event.getPasswordHistory().getUserPasswordHistoryId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getPasswordHistory().getUserPasswordHistoryUser(), "USER_UPDATED_PASSWORD"); //NOI18N
+       }
+
+       /**
+        * Listens to fired event when user updated personal data
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterUserUpdatedPersonalDataEvent (@Observes final ObservableUpdatedUserPersonalDataEvent event) {
+               // Check parameter
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null"); //NOI18N
+               } else if (event.getUpdatedUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.updatedUser is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() == null) {
+                       // ... and again
+                       throw new NullPointerException("event.updatedUser.userId is null"); //NOI18N
+               } else if (event.getUpdatedUser().getUserId() < 1) {
+                       // Invalid value
+                       throw new IllegalArgumentException(MessageFormat.format("event.updatedUser.userId={0} is in valid", event.getUpdatedUser().getUserId())); //NOI18N
+               }
+
+               // Update user list
+               this.addUserActivity(event.getUpdatedUser(), "USER_UPDATED_PERSONAL_DATA"); //NOI18N
+       }
+
+       /**
+        * Expands given activity type into a i18n string for administrators
+        * <p>
+        * @param activityType Activity type
+        * <p>
+        * @return Expanded i18n string
+        */
+       public String expandAdminActivityType (final String activityType) {
+               // Is it valid?
+               if (null == activityType) {
+                       // Throw NPE
+                       throw new NullPointerException("activityType is null"); //NOI18N
+               } else if (activityType.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
+               }
+
+               // Expand it
+               return "ADMIN_ACTIVITY_" + activityType; //NOI18N
+       }
+
+       /**
+        * Expands given activity type into a i18n string for users
+        * <p>
+        * @param activityType Activity type
+        * <p>
+        * @return Expanded i18n string
+        */
+       public String expandUserActivityType (final String activityType) {
+               // Is it valid?
+               if (null == activityType) {
+                       // Throw NPE
+                       throw new NullPointerException("activityType is null"); //NOI18N
+               } else if (activityType.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
+               }
+
+               // Expand it
+               return "USER_ACTIVITY_" + activityType; //NOI18N
+       }
+
+       /**
+        * Returns a list of in beanHelper set user instance's activity log
+        * <p>
+        * @return List of user's activity log
+        */
+       public List<LogableUserActivity> fetchCurrentUsersActivityLog () {
+               // beanHelper.user should be set and valid
+               if (this.getUser() == null) {
+                       // Is not set
+                       throw new NullPointerException("this.beanHelper.user is null"); //NOI18N
+               } else if (this.getUser().getUserId() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("this.beanHelper.user.userId is null"); //NOI18N
+               } else if (this.getUser().getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalArgumentException(MessageFormat.format("this.beanHelper.user.userId={0} is not valid", this.getUser().getUserId())); //NOI18N
+               }
+
+               // Init list
+               List<LogableUserActivity> list = new LinkedList<>();
+
+               // Is the user set?
+               if (this.usersActivityCache.containsKey(this.getUser())) {
+                       // Return it
+                       list.addAll(this.usersActivityCache.get(this.getUser()));
+
+                       // Sort list and reverse it
+                       Collections.sort(list, new UserActivityLogTimestampComparator());
+                       Collections.reverse(list);
+               }
+
+               // Return it
+               return list;
+       }
+
+       /**
+        * Getter for user instance
+        * <p>
+        * @return User instance
+        */
+       public User getUser () {
+               return this.user;
+       }
+
+       /**
+        * Setter for user instance
+        * <p>
+        * @param user User instance
+        */
+       public void setUser (final User user) {
+               this.user = user;
+       }
+
+       /**
+        * Post-constructor method
+        */
+       @PostConstruct
+       public void init () {
+               // Get whole list
+               List<LogableUserActivity> list = this.userActivityBean.fetchAllUserActivityLog();
+
+               // Put all in map, per-user
+               for (final LogableUserActivity userActivity : list) {
+                       // Is the list there?
+                       if (!this.usersActivityCache.containsKey(userActivity.getActivityUser())) {
+                               // Init list
+                               this.usersActivityCache.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
+                       }
+
+                       // Add by user instance
+                       boolean added = this.usersActivityCache.get(userActivity.getActivityUser()).add(userActivity);
+
+                       // Should be added
+                       assert (added) : "Activity log not added"; //NOI18N
+               }
+       }
+
+       /**
+        * Adds user activity entry with given type
+        * <p>
+        * @param user         User instance
+        * @param activityType Activity type
+        */
+       private void addUserActivity (final User user, final String activityType) {
+               // Better re-validate
+               if (null == user) {
+                       // Throw NPE
+                       throw new NullPointerException("user is null"); //NOI18N
+               } else if (user.getUserId() == null) {
+                       // Throw again
+                       throw new NullPointerException("user.userId is null"); //NOI18N
+               } else if (user.getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
+               } else if (null == activityType) {
+                       // Throw NPE again
+                       throw new NullPointerException("activityType is null"); //NOI18N
+               } else if (activityType.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
+               }
+
+               // Create new activity object
+               LogableUserActivity userActivity = new UserActivityLog(activityType, user, new GregorianCalendar(), this.determinePrincipalName());
+
+               // Call bean to add it
+               this.userActivityBean.addUserActivityLog(userActivity);
+
+               // Add to cache, too
+               this.addUserActivityToCache(userActivity);
+       }
+
+       /**
+        * Adds user activity log with type and message
+        * <p>
+        * @param user         User instance
+        * @param activityType Activity type
+        * @param message      Activity message
+        */
+       private void addUserActivity (final User user, final String activityType, final String message) {
+               // Better re-validate
+               if (null == user) {
+                       // Throw NPE
+                       throw new NullPointerException("user is null"); //NOI18N
+               } else if (user.getUserId() == null) {
+                       // Throw again
+                       throw new NullPointerException("user.userId is null"); //NOI18N
+               } else if (user.getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalArgumentException(MessageFormat.format("user.userId={0} is not valid", user.getUserId())); //NOI18N
+               } else if (null == activityType) {
+                       // Throw NPE again
+                       throw new NullPointerException("activityType is null"); //NOI18N
+               } else if (activityType.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("activityType is empty"); //NOI18N
+               } else if (null == message) {
+                       // Throw NPE again
+                       throw new NullPointerException("message is null"); //NOI18N
+               } else if (message.isEmpty()) {
+                       // Is empty
+                       throw new IllegalArgumentException("message is empty"); //NOI18N
+               }
+
+               // Create new activity object
+               LogableUserActivity userActivity = new UserActivityLog(message, activityType, user, new GregorianCalendar(), this.determinePrincipalName());
+
+               // Call bean to add it
+               this.userActivityBean.addUserActivityLog(userActivity);
+
+               // Add to cache, too
+               this.addUserActivityToCache(userActivity);
+       }
+
+       /**
+        * Adds given user activity instance to "cache" (local map)
+        * <p>
+        * @param userActivity User activity instance
+        */
+       private void addUserActivityToCache (final LogableUserActivity userActivity) {
+               // Is the instance valid
+               if (null == userActivity) {
+                       // Throw NPE again
+                       throw new NullPointerException("userActivity is null");
+               } else if (userActivity.getActivityId() instanceof Long) {
+                       // Is not null
+                       throw new IllegalArgumentException("userActivity.activityId=" + userActivity.getActivityId() + " is not null");
+               } else if (userActivity.getActivityUser() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("userActivity.activityUser is null");
+               } else if (userActivity.getActivityUser().getUserId() == null) {
+                       // Throw it again
+                       throw new NullPointerException("userActivity.activityUser.userId is null");
+               } else if (userActivity.getActivityUser().getUserId() < 1) {
+                       // Invalid id number
+                       throw new IllegalArgumentException("userActivity.activityUser.userId=" + userActivity.getActivityUser().getUserId() + " is not valid");
+               }
+
+               // Is it there?
+               if (!this.usersActivityCache.containsKey(userActivity.getActivityUser())) {
+                       // Init it
+                       this.usersActivityCache.put(userActivity.getActivityUser(), new LinkedList<LogableUserActivity>());
+               }
+
+               // Add activity to log
+               this.usersActivityCache.get(userActivity.getActivityUser()).add(userActivity);
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/user/activity/FinancialsUserActivityWebRequestController.java
new file mode 100644 (file)
index 0000000..a6ea444
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.activity;
+
+import java.io.Serializable;
+
+/**
+ * A controller (bean) interface for user activity log
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsUserActivityWebRequestController extends Serializable {
+
+}
index bcbe74861600afbf7e8e4a99a74369f77412e218..1c73afdc20cf0af25fa9da30968edec541c6b187 100644 (file)
@@ -31,7 +31,6 @@ import org.mxchange.jcoreee.events.helper.clear.HelperCleanupEvent;
 import org.mxchange.jcoreee.events.helper.clear.ObservableHelperCleanupEvent;
 import org.mxchange.jcoreee.utils.FacesUtils;
 import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.user.FinancialsUserWebSessionController;
 import org.mxchange.jusercore.events.user.created.CreatedUserEvent;
 import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
 import org.mxchange.jusercore.exceptions.UserStatusConfirmedException;
@@ -41,6 +40,7 @@ import org.mxchange.jusercore.model.user.UserSessionBeanRemote;
 import org.mxchange.jusercore.model.user.status.UserAccountStatus;
 import org.mxchange.juserlogincore.events.confirmation.ObservableUserConfirmedAccountEvent;
 import org.mxchange.juserlogincore.events.confirmation.UserConfirmedAccountEvent;
+import org.mxchange.jfinancials.beans.user.FinancialsUserWebRequestController;
 
 /**
  * A web request bean for confirmation link handling
@@ -85,7 +85,7 @@ public class FinancialsConfirmationLinkWebRequestBean extends BaseFinancialsCont
         * User controller
         */
        @Inject
-       private FinancialsUserWebSessionController userController;
+       private FinancialsUserWebRequestController userController;
 
        /**
         * Event for when a user instance was created
diff --git a/src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebRequestBean.java
new file mode 100644 (file)
index 0000000..d386269
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.email_address;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+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.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcoreee.jcache.Cached;
+import org.mxchange.jcoreee.utils.FacesUtils;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
+import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
+import org.mxchange.jusercore.model.email_address.ChangeableEmailAddress;
+import org.mxchange.jusercore.model.email_address.EmailAddressChange;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote;
+import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
+
+/**
+ * A web session-scoped bean for changing email addresses
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("userEmailChangeController")
+@RequestScoped
+public class FinancialsEmailChangeWebRequestBean extends BaseFinancialsController implements FinancialsEmailChangeWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 186_078_724_659_153L;
+
+       /**
+        * Email address 1 (changing)
+        */
+       private String emailAddress;
+
+       /**
+        * Email address 2 (repeat in changing)
+        */
+       private String emailAddressRepeat;
+
+       /**
+        * Remote email change bean
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/userEmailChange!org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote")
+       private UserEmailChangeSessionBeanRemote emailChangeBean;
+
+       /**
+        * Features controller
+        */
+       @Inject
+       private FinancialsFeaturesWebApplicationController featureController;
+
+       /**
+        * Local list of already queued email addresses
+        */
+       @Inject
+       @Cached (cacheName = "queuedEmailCache")
+       private transient Cache<String, Boolean> queuedEmailCache;
+
+       /**
+        * Login controller (bean)
+        */
+       @Inject
+       private FinancialsUserLoginWebSessionController userLoginController;
+
+       /**
+        * Default constructor
+        */
+       public FinancialsEmailChangeWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Changes logged-in user's email address if the current password matches.
+        * <p>
+        * @return Redirect outcome
+        */
+       public String doUserChangeEmailAddress () {
+               // This method shall only be called if the user is logged-in
+               if (!this.userLoginController.isUserLoggedIn()) {
+                       // Not logged-in
+                       throw new IllegalStateException("User is not logged-in"); //NOI18N
+               } else if (!this.featureController.isFeatureEnabled("user_change_email_address")) { //NOI18N
+                       // Editing is not allowed
+                       throw new IllegalStateException("User tried to change email address"); //NOI18N
+               } else if (!this.isRequiredChangeEmailAddressSet()) {
+                       // Not all required fields are set
+                       throw new FaceletException("Not all required fields are set."); //NOI18N
+               } else if (!Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat())) {
+                       // Email address 1+2 mismatch
+                       this.showFacesMessage("form_user_change_email_address:emailAddressRepeat", "ERROR_USER_EMAIL_ADDRESSES_MISMATCH"); //NOI18N
+                       return ""; //NOI18N
+               } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
+                       // Password not matching
+                       this.showFacesMessage("form_login_user_change_email_address:currentPassword", new UserPasswordMismatchException(this.userLoginController.getLoggedInUser())); //NOI18N
+                       return ""; //NOI18N
+               }
+
+               // Get user instance
+               User user = this.userLoginController.getLoggedInUser();
+
+               // It should be there, so run some tests on it
+               assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
+               assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
+               assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
+               assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
+               assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
+               assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
+
+               // Check if the email address is already enqueued
+               if (this.isEmailAddressQueued(this.getEmailAddress())) {
+                       // Clear both email addresses
+                       this.setEmailAddress(null);
+                       this.setEmailAddressRepeat(null);
+
+                       // Yes, then abort here
+                       this.showFacesMessage("form_user_change_email_address:emailAddress", "ERROR_USER_CHANGE_EMAIL_ADDRESS_ALREADY_QUEUED"); //NOI18N
+                       return ""; //NOI18N
+               }
+
+               // Create change object, to save EJB calls, the hash is not generated here
+               ChangeableEmailAddress emailChange = new EmailAddressChange(user, this.getEmailAddress());
+
+               // Get base URL
+               String baseUrl = FacesUtils.generateBaseUrl();
+
+               // Call EJB
+               this.emailChangeBean.enqueueEmailAddressForChange(emailChange, baseUrl);
+
+               // Unset all so the user is forced to re-enter it
+               this.clear();
+
+               // All fine
+               return "user_login_email_change_queued"; //NOI18N
+       }
+
+       /**
+        * Getter for email address 1 (changing)
+        * <p>
+        * @return Email address
+        */
+       public String getEmailAddress () {
+               return this.emailAddress;
+       }
+
+       /**
+        * Setter for email address 1 (changing)
+        * <p>
+        * @param emailAddress Email address 1
+        */
+       public void setEmailAddress (final String emailAddress) {
+               this.emailAddress = emailAddress;
+       }
+
+       /**
+        * Getter for email address 2 (repeat changing)
+        * <p>
+        * @return Email address 2
+        */
+       public String getEmailAddressRepeat () {
+               return this.emailAddressRepeat;
+       }
+
+       /**
+        * Setter for email address 2 (repeat changing)
+        * <p>
+        * @param emailAddressRepeat Email address 2
+        */
+       public void setEmailAddressRepeat (final String emailAddressRepeat) {
+               this.emailAddressRepeat = emailAddressRepeat;
+       }
+
+       /**
+        * Post-construction
+        */
+       @PostConstruct
+       public void init () {
+               // Is cache there?
+               if (!this.queuedEmailCache.iterator().hasNext()) {
+                       // Get whole list
+                       List<String> list = this.emailChangeBean.allQueuedAddresses();
+
+                       // Add all
+                       for (final Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
+                               // Get next element
+                               final String next = iterator.next();
+
+                               // Add it to cache
+                               this.queuedEmailCache.put(next, Boolean.TRUE);
+                       }
+               }
+       }
+
+       @Override
+       public boolean isRequiredChangeEmailAddressSet () {
+               return ((this.getEmailAddress() != null) &&
+                               (this.getEmailAddressRepeat() != null));
+       }
+
+       /**
+        * Clears email address fields so the user has to re-enter them
+        */
+       private void clear () {
+               // Clear fields
+               this.setEmailAddress(null);
+               this.setEmailAddressRepeat(null);
+       }
+
+       /**
+        * Checks if given email address has already been queued. First a local list
+        * is being checked, if not found, the EJB is called. Only if found, the
+        * result is "cached" in the list.
+        * <p>
+        * @param emailAddress Email address to verify
+        * <p>
+        * @return Whether the email address in field emailAddress is already queued
+        */
+       private boolean isEmailAddressQueued (final String emailAddress) {
+               // It should be there
+               assert (emailAddress != null) : "emailAddress should not be null"; //NOI18N
+               assert (!emailAddress.trim().isEmpty()) : "emailAddress should not be empty"; //NOI18N
+
+               // Check list
+               if (this.queuedEmailCache.containsKey(emailAddress)) {
+                       // Okay, found it
+                       return true;
+               }
+
+               // Check EJB
+               boolean isQueued = this.emailChangeBean.isEmailAddressEnqueued(emailAddress);
+
+               // Is it there?
+               if (isQueued) {
+                       // Add to list
+                       this.queuedEmailCache.put(emailAddress, Boolean.TRUE);
+               }
+
+               // Return status
+               return isQueued;
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebRequestController.java
new file mode 100644 (file)
index 0000000..c452240
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.email_address;
+
+import java.io.Serializable;
+
+/**
+ * An interface for an email change controller
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsEmailChangeWebRequestController extends Serializable {
+
+       /**
+        * Checks whether all required are set for changing email address
+        * <p>
+        * @return Whether the required personal data is set
+        */
+       boolean isRequiredChangeEmailAddressSet ();
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebSessionBean.java b/src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebSessionBean.java
deleted file mode 100644 (file)
index 044ccb3..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.email_address;
-
-import java.text.MessageFormat;
-import java.util.List;
-import java.util.Objects;
-import javax.annotation.PostConstruct;
-import javax.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jcontacts.contact.Contact;
-import org.mxchange.jcoreee.utils.FacesUtils;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
-import org.mxchange.jfinancials.beans.user.login.FinancialsUserLoginWebSessionController;
-import org.mxchange.jusercore.model.email_address.ChangeableEmailAddress;
-import org.mxchange.jusercore.model.email_address.EmailAddressChange;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote;
-import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
-
-/**
- * A web session-scoped bean for changing email addresses
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("userEmailChangeController")
-@SessionScoped
-public class FinancialsEmailChangeWebSessionBean extends BaseFinancialsController implements FinancialsEmailChangeWebSessionController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 186_078_724_659_153L;
-
-       /**
-        * Email address 1 (changing)
-        */
-       private String emailAddress;
-
-       /**
-        * Email address 2 (repeat in changing)
-        */
-       private String emailAddressRepeat;
-
-       /**
-        * Local list of already queued email addresses
-        */
-       private List<String> emailAddresses;
-
-       /**
-        * Remote email change bean
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/userEmailChange!org.mxchange.jusercore.model.user.email_address.UserEmailChangeSessionBeanRemote")
-       private UserEmailChangeSessionBeanRemote emailChangeBean;
-
-       /**
-        * Features controller
-        */
-       @Inject
-       private FinancialsFeaturesWebApplicationController featureController;
-
-       /**
-        * Login controller (bean)
-        */
-       @Inject
-       private FinancialsUserLoginWebSessionController userLoginController;
-
-       /**
-        * Default constructor
-        */
-       public FinancialsEmailChangeWebSessionBean () {
-               // Call super constructor
-               super();
-       }
-
-       /**
-        * Changes logged-in user's email address if the current password matches.
-        * <p>
-        * @return Redirect outcome
-        */
-       public String doUserChangeEmailAddress () {
-               // This method shall only be called if the user is logged-in
-               if (!this.userLoginController.isUserLoggedIn()) {
-                       // Not logged-in
-                       throw new IllegalStateException("User is not logged-in"); //NOI18N
-               } else if (!this.featureController.isFeatureEnabled("user_change_email_address")) { //NOI18N
-                       // Editing is not allowed
-                       throw new IllegalStateException("User tried to change email address"); //NOI18N
-               } else if (!this.isRequiredChangeEmailAddressSet()) {
-                       // Not all required fields are set
-                       throw new FaceletException("Not all required fields are set."); //NOI18N
-               } else if (!Objects.equals(this.getEmailAddress(), this.getEmailAddressRepeat())) {
-                       // Email address 1+2 mismatch
-                       this.showFacesMessage("form_user_change_email_address:emailAddressRepeat", "ERROR_USER_EMAIL_ADDRESSES_MISMATCH"); //NOI18N
-                       return ""; //NOI18N
-               } else if (!this.userLoginController.ifCurrentPasswordMatches()) {
-                       // Password not matching
-                       this.showFacesMessage("form_login_user_change_email_address:currentPassword", new UserPasswordMismatchException(this.userLoginController.getLoggedInUser())); //NOI18N
-                       return ""; //NOI18N
-               }
-
-               // Get user instance
-               User user = this.userLoginController.getLoggedInUser();
-
-               // It should be there, so run some tests on it
-               assert (user instanceof User) : "Instance userLoginController.loggedInUser is null"; //NOI18N
-               assert (user.getUserId() instanceof Long) : "Instance userLoginController.loggedInUser.userId is null"; //NOI18N
-               assert (user.getUserId() > 0) : MessageFormat.format("userLoginController.loggedInUser.userId={0} is invalid", user.getUserId()); //NOI18N
-               assert (user.getUserContact() instanceof Contact) : "Instance userLoginController.loggedInUser.userContact is null"; //NOI18N
-               assert (user.getUserContact().getContactId() instanceof Long) : "Instance userLoginController.userContact.contactId is null"; //NOI18N
-               assert (user.getUserContact().getContactId() > 0) : MessageFormat.format("Instance userLoginController.userContact.contactId={0} is invalid", user.getUserContact().getContactId()); //NOI18N
-
-               // Check if the email address is already enqueued
-               if (this.isEmailAddressQueued(this.getEmailAddress())) {
-                       // Clear both email addresses
-                       this.setEmailAddress(null);
-                       this.setEmailAddressRepeat(null);
-
-                       // Yes, then abort here
-                       this.showFacesMessage("form_user_change_email_address:emailAddress", "ERROR_USER_CHANGE_EMAIL_ADDRESS_ALREADY_QUEUED"); //NOI18N
-                       return ""; //NOI18N
-               }
-
-               // Create change object, to save EJB calls, the hash is not generated here
-               ChangeableEmailAddress emailChange = new EmailAddressChange(user, this.getEmailAddress());
-
-               // Get base URL
-               String baseUrl = FacesUtils.generateBaseUrl();
-
-               // Call EJB
-               this.emailChangeBean.enqueueEmailAddressForChange(emailChange, baseUrl);
-
-               // Unset all so the user is forced to re-enter it
-               this.clear();
-
-               // All fine
-               return "user_login_email_change_queued"; //NOI18N
-       }
-
-       /**
-        * Getter for email address 1 (changing)
-        * <p>
-        * @return Email address
-        */
-       public String getEmailAddress () {
-               return this.emailAddress;
-       }
-
-       /**
-        * Setter for email address 1 (changing)
-        * <p>
-        * @param emailAddress Email address 1
-        */
-       public void setEmailAddress (final String emailAddress) {
-               this.emailAddress = emailAddress;
-       }
-
-       /**
-        * Getter for email address 2 (repeat changing)
-        * <p>
-        * @return Email address 2
-        */
-       public String getEmailAddressRepeat () {
-               return this.emailAddressRepeat;
-       }
-
-       /**
-        * Setter for email address 2 (repeat changing)
-        * <p>
-        * @param emailAddressRepeat Email address 2
-        */
-       public void setEmailAddressRepeat (final String emailAddressRepeat) {
-               this.emailAddressRepeat = emailAddressRepeat;
-       }
-
-       /**
-        * Post-construction
-        */
-       @PostConstruct
-       public void init () {
-               // Init list
-               this.emailAddresses = this.emailChangeBean.allQueuedAddresses();
-       }
-
-       @Override
-       public boolean isRequiredChangeEmailAddressSet () {
-               return ((this.getEmailAddress() != null) &&
-                               (this.getEmailAddressRepeat() != null));
-       }
-
-       /**
-        * Clears email address fields so the user has to re-enter them
-        */
-       private void clear () {
-               // Clear fields
-               this.setEmailAddress(null);
-               this.setEmailAddressRepeat(null);
-       }
-
-       /**
-        * Checks if given email address has already been queued. First a local list
-        * is being checked, if not found, the EJB is called. Only if found, the
-        * result is "cached" in the list.
-        * <p>
-        * @param emailAddress Email address to verify
-        * <p>
-        * @return Whether the email address in field emailAddress is already queued
-        */
-       private boolean isEmailAddressQueued (final String emailAddress) {
-               // It should be there
-               assert (emailAddress != null) : "emailAddress should not be null"; //NOI18N
-               assert (!emailAddress.trim().isEmpty()) : "emailAddress should not be empty"; //NOI18N
-
-               // Check list
-               if (this.emailAddresses.contains(emailAddress)) {
-                       // Okay, found it
-                       return true;
-               }
-
-               // Check EJB
-               boolean isQueued = this.emailChangeBean.isEmailAddressEnqueued(emailAddress);
-
-               // Is it there?
-               if (isQueued) {
-                       // Add to list
-                       this.emailAddresses.add(emailAddress);
-               }
-
-               // Return status
-               return isQueued;
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/user/email_address/FinancialsEmailChangeWebSessionController.java
deleted file mode 100644 (file)
index 17c3d1e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.email_address;
-
-import java.io.Serializable;
-
-/**
- * An interface for an email change controller
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsEmailChangeWebSessionController extends Serializable {
-
-       /**
-        * Checks whether all required are set for changing email address
-        * <p>
-        * @return Whether the required personal data is set
-        */
-       boolean isRequiredChangeEmailAddressSet ();
-
-}
index 622c071f15aa302f2f0b23c6310e23a259579632..491d35940a9568e9d8ad36b6f9844a6ca98d5a9a 100644 (file)
@@ -29,7 +29,7 @@ import javax.faces.context.FacesContext;
 import javax.inject.Inject;
 import javax.inject.Named;
 import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.user.FinancialsUserWebSessionController;
+import org.mxchange.jfinancials.beans.user.FinancialsUserWebRequestController;
 import org.mxchange.jusercore.exceptions.UserNotFoundException;
 import org.mxchange.jusercore.exceptions.UserStatusLockedException;
 import org.mxchange.jusercore.exceptions.UserStatusUnconfirmedException;
@@ -88,7 +88,7 @@ public class FinancialsUserLoginWebSessionBean extends BaseFinancialsController
         * User controller
         */
        @Inject
-       private FinancialsUserWebSessionController userController;
+       private FinancialsUserWebRequestController userController;
 
        /**
         * Current password
diff --git a/src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebRequestBean.java
new file mode 100644 (file)
index 0000000..bc494e7
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.register;
+
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Event;
+import javax.enterprise.inject.Any;
+import javax.faces.view.facelets.FaceletException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcontacts.contact.UserContact;
+import org.mxchange.jcoreee.utils.FacesUtils;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
+import org.mxchange.jfinancials.beans.user.FinancialsAdminUserWebRequestController;
+import org.mxchange.jusercore.events.user.clear.password.ClearUserPasswordEvent;
+import org.mxchange.jusercore.events.user.clear.password.ObservableClearUserPasswordEvent;
+import org.mxchange.jusercore.events.user.clear.username.ClearUserNameEvent;
+import org.mxchange.jusercore.events.user.clear.username.ObservableClearUserNameEvent;
+import org.mxchange.jusercore.exceptions.DataRepeatMismatchException;
+import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException;
+import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.password_history.PasswordHistory;
+import org.mxchange.jusercore.model.user.password_history.UserPasswordHistory;
+import org.mxchange.jusercore.model.user.status.UserAccountStatus;
+import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
+import org.mxchange.juserlogincore.events.registration.UserRegisteredEvent;
+import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
+import org.mxchange.juserlogincore.events.user.password_change.UpdatedUserPasswordEvent;
+import org.mxchange.juserlogincore.login.UserLoginUtils;
+import org.mxchange.juserlogincore.model.user.register.UserRegistrationSessionBeanRemote;
+import org.mxchange.jfinancials.beans.user.FinancialsUserWebRequestController;
+import org.mxchange.jfinancials.beans.contact.FinancialsContactWebRequestController;
+
+/**
+ * A web bean for user registration
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("userRegistrationController")
+@RequestScoped
+public class FinancialsUserRegisterWebRequestBean extends BaseFinancialsController implements FinancialsUserRegisterWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 47_828_986_719_691_592L;
+
+       /**
+        * Administrative user controller
+        */
+       @Inject
+       private FinancialsAdminUserWebRequestController adminUserController;
+
+       /**
+        * An event being fired when a user name should be cleared
+        */
+       @Inject
+       @Any
+       private Event<ObservableClearUserNameEvent> clearUserNameEvent;
+
+       /**
+        * An event being fired when a user password should be cleared
+        */
+       @Inject
+       @Any
+       private Event<ObservableClearUserPasswordEvent> clearUserPasswordEvent;
+
+       /**
+        * Contact controller
+        */
+       @Inject
+       private FinancialsContactWebRequestController contactController;
+
+       /**
+        * Features controller
+        */
+       @Inject
+       private FinancialsFeaturesWebApplicationController featureController;
+
+       /**
+        * Remote register session-scoped bean
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/userRegistration!org.mxchange.juserlogincore.model.user.register.UserRegistrationSessionBeanRemote")
+       private UserRegistrationSessionBeanRemote registerBean;
+
+       /**
+        * User controller
+        */
+       @Inject
+       private FinancialsUserWebRequestController userController;
+
+       /**
+        * An event being fired when a user password was changed
+        */
+       @Inject
+       @Any
+       private Event<ObservableUpdatedUserPasswordEvent> userPasswordChangedEvent;
+
+       /**
+        * An event being fired when a new user has registered
+        */
+       @Inject
+       @Any
+       private Event<ObservableUserRegisteredEvent> userRegisteredEvent;
+
+       /**
+        * Default constructor
+        */
+       public FinancialsUserRegisterWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Registers the user, if not found. Otherwise this method should throw an
+        * exception.
+        * <p>
+        * @return Redirection target
+        */
+       public String doFinishRegistration () {
+               // Is registration enabled?
+               if (!this.featureController.isFeatureEnabled("user_registration")) { //NOI18N
+                       // Is not enabled
+                       throw new FaceletException("Registration is disabled."); //NOI18N
+               }
+
+               // Get user instance
+               User user = this.userController.createUserInstance(true);
+
+               // Null random password means registration requires user-entered password
+               String randomPassword = null;
+
+               // Is the user already used?
+               if (null == user) {
+                       // user must be set
+                       throw new NullPointerException("user is null after createUserInstance() was called"); //NOI18N
+               } else if (!this.userController.isRequiredPersonalDataSet()) {
+                       // Not all required fields are set
+                       throw new FaceletException("Not all required fields are set."); //NOI18N
+               } else if ((this.featureController.isFeatureEnabled("user_login_require_user_name")) && (this.userController.isUserNameRegistered(user))) { //NOI18N
+                       // Is multi-page enabled?
+                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
+                               // User name is already used, should not happen here
+                               throw new FaceletException(new UserNameAlreadyRegisteredException(user));
+                       } else {
+                               // May happen here, fire event
+                               this.clearUserNameEvent.fire(new ClearUserNameEvent());
+
+                               // Output message
+                               this.showFacesMessage("form_register_single:userName", "ERROR_USER_NAME_ALREADY_USED"); //NOI18N
+                               return ""; //NOI18N
+                       }
+               } else if (this.contactController.isEmailAddressRegistered(user.getUserContact())) {
+                       // Is multi-page enabled?
+                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
+                               // Email address has already been taken, should not happen here
+                               throw new FaceletException(new EmailAddressAlreadyRegisteredException(user));
+                       } else {
+                               // May happen here, reset fields
+                               this.contactController.clearEmailAddresses();
+                               this.showFacesMessage("form_register_single:emailAddressRepeat", "ERROR_EMAIL_ADDRESS_ALREADY_USED"); //NOI18N
+                               return ""; //NOI18N
+                       }
+               } else if (!this.contactController.isSameEmailAddressEntered()) {
+                       // Is multi-page enabled?
+                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
+                               // Not same email address entered, should not happen here
+                               throw new FaceletException(new DataRepeatMismatchException("Email addresses not matching.")); //NOI18N
+                       } else {
+                               // May happen here, reset fields
+                               this.contactController.clearEmailAddresses();
+                               this.showFacesMessage("form_register_single:emailAddressRepeat", "ERROR_EMAIL_ADDRESSES_MISMATCHING"); //NOI18N
+                               return ""; //NOI18N
+                       }
+               } else if (!this.userController.isSamePasswordEntered()) {
+                       // Is multi-page enabled?
+                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
+                               // Not same password entered, should no longer happen here
+                               throw new FaceletException(new DataRepeatMismatchException("Passwords not matching.")); //NOI18N
+                       } else if (this.userController.ifBothPasswordsEmptyAllowed()) {
+                               // Both passwords are left empty and is allowed, then generate a random password
+                               randomPassword = UserLoginUtils.createRandomPassword(FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
+
+                               // Generate (ignored) password-history
+                               PasswordHistory passwordHistory = new UserPasswordHistory(randomPassword, user);
+
+                               // Fire event
+                               this.userPasswordChangedEvent.fire(new UpdatedUserPasswordEvent(passwordHistory, randomPassword));
+                       }
+               }
+
+               // Encrypt password
+               String encryptedPassword = UserLoginUtils.encryptPassword(this.userController.getUserPassword());
+
+               // Set it here
+               user.setUserEncryptedPassword(encryptedPassword);
+
+               // Is developer mode?
+               if (this.isDebugModeEnabled("register")) { //NOI18N
+                       // For debugging/programming only:
+                       user.setUserAccountStatus(UserAccountStatus.CONFIRMED);
+               } else {
+                       // No debugging of this part
+                       user.setUserAccountStatus(UserAccountStatus.UNCONFIRMED);
+
+                       // Ask EJB for generating a not-existing confirmation key
+                       String confirmKey = this.registerBean.generateConfirmationKey(user);
+
+                       // Set it in user
+                       user.setUserConfirmKey(confirmKey);
+               }
+
+               try {
+                       // Get base URL
+                       String baseUrl = FacesUtils.generateBaseUrl();
+
+                       // Call bean
+                       User registeredUser = this.registerBean.registerUser(user, baseUrl, randomPassword);
+
+                       // The id number should be set
+                       assert (registeredUser.getUserId() instanceof Long) : "registeredUser.userId is null after registerUser() was called."; //NOI18N
+
+                       // Fire event
+                       this.userRegisteredEvent.fire(new UserRegisteredEvent(registeredUser));
+
+                       // All fine, redirect to proper page
+                       return "user_register_done"; //NOI18N
+               } catch (final UserNameAlreadyRegisteredException | EmailAddressAlreadyRegisteredException ex) {
+                       // Continue to throw
+                       throw new FaceletException(ex);
+               }
+       }
+
+       /**
+        * Handles registration request send from first page. The (maybe) entered
+        * user name and email address is not used and that privacy and T&C are
+        * accepted.
+        * <p>
+        * @return Redirect
+        */
+       public String doRegisterMultiPage1 () {
+               // Is registration enabled?
+               if (!this.featureController.isFeatureEnabled("user_registration")) { //NOI18N
+                       // Is not enabled
+                       throw new FaceletException("Registration is disabled."); //NOI18N
+               }
+
+               // Get user instance
+               User user = this.userController.createUserInstance(false);
+
+               // First check if user is not null and user name is not used + if same email address is entered
+               if (null == user) {
+                       // user must be set
+                       throw new NullPointerException("user is null after createUserInstance() was called"); //NOI18N
+               } else if ((this.featureController.isFeatureEnabled("user_login_require_user_name")) && (this.userController.isUserNameRegistered(user))) { //NOI18N
+                       // User name is already used, so clear it
+                       this.clearUserNameEvent.fire(new ClearUserNameEvent());
+
+                       // Output message
+                       this.showFacesMessage("form_register_page1:userName", "ERROR_USER_NAME_ALREADY_USED"); //NOI18N
+                       return ""; //NOI18N
+               } else if (!this.contactController.isSameEmailAddressEntered()) {
+                       // Not same email address entered, clear both
+                       this.contactController.clearEmailAddresses();
+                       this.showFacesMessage("form_register_page1:emailAddressRepeat", "ERROR_EMAIL_ADDRESSES_MISMATCHING"); //NOI18N
+                       return ""; //NOI18N
+               } else if (!this.userController.isSamePasswordEntered()) {
+                       // Is multi-page enabled?
+                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
+                               // Unset both
+                               this.clearUserPasswordEvent.fire(new ClearUserPasswordEvent());
+
+                               // Output faces message
+                               this.showFacesMessage("form_register_page1:userPassword", "ERROR_USER_PASSWORD_EMPTY"); //NOI18N
+                               this.showFacesMessage("form_register_page1:userPasswordRepeat", "ERROR_USER_PASSWORD_REPEAT_EMPTY"); //NOI18N
+                               return ""; //NOI18N
+                       } else if (this.userController.ifBothPasswordsEmptyAllowed()) {
+                               // Both passwords are left empty and is allowed, then generate a random password
+                               String randomPassword = UserLoginUtils.createRandomPassword(FinancialsUserWebRequestController.MINIMUM_PASSWORD_LENGTH);
+
+                               // Generate (ignored) password-history
+                               PasswordHistory passwordHistory = new UserPasswordHistory(randomPassword, user);
+
+                               // Fire event
+                               this.userPasswordChangedEvent.fire(new UpdatedUserPasswordEvent(passwordHistory, randomPassword));
+                       }
+               }
+
+               // Create half contact instance with email address
+               Contact contact = new UserContact();
+               contact.setContactEmailAddress(this.contactController.getEmailAddress());
+
+               // Set contact in user
+               user.setUserContact(contact);
+
+               // Check if email address is registered
+               if (this.contactController.isEmailAddressRegistered(user.getUserContact())) {
+                       // Email address has already been taken, clear both
+                       this.contactController.clearEmailAddresses();
+                       this.showFacesMessage("form_register_page1:emailAddress", "ERROR_EMAIL_ADDRESS_ALREADY_USED"); //NOI18N
+                       return ""; //NOI18N
+               }
+
+               // Now only redirect to next page as the JSF does it
+               return "user_register_page2"; //NOI18N
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebRequestController.java
new file mode 100644 (file)
index 0000000..dcf5fda
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.register;
+
+import java.io.Serializable;
+
+/**
+ * An interface for registration web controllers
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsUserRegisterWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebSessionBean.java b/src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebSessionBean.java
deleted file mode 100644 (file)
index 030fc10..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.register;
-
-import javax.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Event;
-import javax.enterprise.inject.Any;
-import javax.faces.view.facelets.FaceletException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jcontacts.contact.Contact;
-import org.mxchange.jcontacts.contact.UserContact;
-import org.mxchange.jcoreee.utils.FacesUtils;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.contact.FinancialsContactWebSessionController;
-import org.mxchange.jfinancials.beans.features.FinancialsFeaturesWebApplicationController;
-import org.mxchange.jfinancials.beans.user.FinancialsAdminUserWebRequestController;
-import org.mxchange.jfinancials.beans.user.FinancialsUserWebSessionController;
-import org.mxchange.jusercore.events.user.clear.password.ClearUserPasswordEvent;
-import org.mxchange.jusercore.events.user.clear.password.ObservableClearUserPasswordEvent;
-import org.mxchange.jusercore.events.user.clear.username.ClearUserNameEvent;
-import org.mxchange.jusercore.events.user.clear.username.ObservableClearUserNameEvent;
-import org.mxchange.jusercore.exceptions.DataRepeatMismatchException;
-import org.mxchange.jusercore.exceptions.EmailAddressAlreadyRegisteredException;
-import org.mxchange.jusercore.exceptions.UserNameAlreadyRegisteredException;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.password_history.PasswordHistory;
-import org.mxchange.jusercore.model.user.password_history.UserPasswordHistory;
-import org.mxchange.jusercore.model.user.status.UserAccountStatus;
-import org.mxchange.juserlogincore.events.registration.ObservableUserRegisteredEvent;
-import org.mxchange.juserlogincore.events.registration.UserRegisteredEvent;
-import org.mxchange.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
-import org.mxchange.juserlogincore.events.user.password_change.UpdatedUserPasswordEvent;
-import org.mxchange.juserlogincore.login.UserLoginUtils;
-import org.mxchange.juserlogincore.model.user.register.UserRegistrationSessionBeanRemote;
-
-/**
- * A web bean for user registration
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("userRegistrationController")
-@SessionScoped
-public class FinancialsUserRegisterWebSessionBean extends BaseFinancialsController implements FinancialsUserRegisterWebSessionController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 47_828_986_719_691_592L;
-
-       /**
-        * Administrative user controller
-        */
-       @Inject
-       private FinancialsAdminUserWebRequestController adminUserController;
-
-       /**
-        * An event being fired when a user name should be cleared
-        */
-       @Inject
-       @Any
-       private Event<ObservableClearUserNameEvent> clearUserNameEvent;
-
-       /**
-        * An event being fired when a user password should be cleared
-        */
-       @Inject
-       @Any
-       private Event<ObservableClearUserPasswordEvent> clearUserPasswordEvent;
-
-       /**
-        * Contact controller
-        */
-       @Inject
-       private FinancialsContactWebSessionController contactController;
-
-       /**
-        * Features controller
-        */
-       @Inject
-       private FinancialsFeaturesWebApplicationController featureController;
-
-       /**
-        * Remote register session-scoped bean
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/userRegistration!org.mxchange.juserlogincore.model.user.register.UserRegistrationSessionBeanRemote")
-       private UserRegistrationSessionBeanRemote registerBean;
-
-       /**
-        * User controller
-        */
-       @Inject
-       private FinancialsUserWebSessionController userController;
-
-       /**
-        * An event being fired when a user password was changed
-        */
-       @Inject
-       @Any
-       private Event<ObservableUpdatedUserPasswordEvent> userPasswordChangedEvent;
-
-       /**
-        * An event being fired when a new user has registered
-        */
-       @Inject
-       @Any
-       private Event<ObservableUserRegisteredEvent> userRegisteredEvent;
-
-       /**
-        * Default constructor
-        */
-       public FinancialsUserRegisterWebSessionBean () {
-               // Call super constructor
-               super();
-       }
-
-       /**
-        * Registers the user, if not found. Otherwise this method should throw an
-        * exception.
-        * <p>
-        * @return Redirection target
-        */
-       public String doFinishRegistration () {
-               // Is registration enabled?
-               if (!this.featureController.isFeatureEnabled("user_registration")) { //NOI18N
-                       // Is not enabled
-                       throw new FaceletException("Registration is disabled."); //NOI18N
-               }
-
-               // Get user instance
-               User user = this.userController.createUserInstance(true);
-
-               // Null random password means registration requires user-entered password
-               String randomPassword = null;
-
-               // Is the user already used?
-               if (null == user) {
-                       // user must be set
-                       throw new NullPointerException("user is null after createUserInstance() was called"); //NOI18N
-               } else if (!this.userController.isRequiredPersonalDataSet()) {
-                       // Not all required fields are set
-                       throw new FaceletException("Not all required fields are set."); //NOI18N
-               } else if ((this.featureController.isFeatureEnabled("user_login_require_user_name")) && (this.userController.isUserNameRegistered(user))) { //NOI18N
-                       // Is multi-page enabled?
-                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
-                               // User name is already used, should not happen here
-                               throw new FaceletException(new UserNameAlreadyRegisteredException(user));
-                       } else {
-                               // May happen here, fire event
-                               this.clearUserNameEvent.fire(new ClearUserNameEvent());
-
-                               // Output message
-                               this.showFacesMessage("form_register_single:userName", "ERROR_USER_NAME_ALREADY_USED"); //NOI18N
-                               return ""; //NOI18N
-                       }
-               } else if (this.contactController.isEmailAddressRegistered(user.getUserContact())) {
-                       // Is multi-page enabled?
-                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
-                               // Email address has already been taken, should not happen here
-                               throw new FaceletException(new EmailAddressAlreadyRegisteredException(user));
-                       } else {
-                               // May happen here, reset fields
-                               this.contactController.clearEmailAddresses();
-                               this.showFacesMessage("form_register_single:emailAddressRepeat", "ERROR_EMAIL_ADDRESS_ALREADY_USED"); //NOI18N
-                               return ""; //NOI18N
-                       }
-               } else if (!this.contactController.isSameEmailAddressEntered()) {
-                       // Is multi-page enabled?
-                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
-                               // Not same email address entered, should not happen here
-                               throw new FaceletException(new DataRepeatMismatchException("Email addresses not matching.")); //NOI18N
-                       } else {
-                               // May happen here, reset fields
-                               this.contactController.clearEmailAddresses();
-                               this.showFacesMessage("form_register_single:emailAddressRepeat", "ERROR_EMAIL_ADDRESSES_MISMATCHING"); //NOI18N
-                               return ""; //NOI18N
-                       }
-               } else if (!this.userController.isSamePasswordEntered()) {
-                       // Is multi-page enabled?
-                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
-                               // Not same password entered, should no longer happen here
-                               throw new FaceletException(new DataRepeatMismatchException("Passwords not matching.")); //NOI18N
-                       } else if (this.userController.ifBothPasswordsEmptyAllowed()) {
-                               // Both passwords are left empty and is allowed, then generate a random password
-                               randomPassword = UserLoginUtils.createRandomPassword(FinancialsUserWebSessionController.MINIMUM_PASSWORD_LENGTH);
-
-                               // Generate (ignored) password-history
-                               PasswordHistory passwordHistory = new UserPasswordHistory(randomPassword, user);
-
-                               // Fire event
-                               this.userPasswordChangedEvent.fire(new UpdatedUserPasswordEvent(passwordHistory, randomPassword));
-                       }
-               }
-
-               // Encrypt password
-               String encryptedPassword = UserLoginUtils.encryptPassword(this.userController.getUserPassword());
-
-               // Set it here
-               user.setUserEncryptedPassword(encryptedPassword);
-
-               // Is developer mode?
-               if (this.isDebugModeEnabled("register")) { //NOI18N
-                       // For debugging/programming only:
-                       user.setUserAccountStatus(UserAccountStatus.CONFIRMED);
-               } else {
-                       // No debugging of this part
-                       user.setUserAccountStatus(UserAccountStatus.UNCONFIRMED);
-
-                       // Ask EJB for generating a not-existing confirmation key
-                       String confirmKey = this.registerBean.generateConfirmationKey(user);
-
-                       // Set it in user
-                       user.setUserConfirmKey(confirmKey);
-               }
-
-               try {
-                       // Get base URL
-                       String baseUrl = FacesUtils.generateBaseUrl();
-
-                       // Call bean
-                       User registeredUser = this.registerBean.registerUser(user, baseUrl, randomPassword);
-
-                       // The id number should be set
-                       assert (registeredUser.getUserId() instanceof Long) : "registeredUser.userId is null after registerUser() was called."; //NOI18N
-
-                       // Fire event
-                       this.userRegisteredEvent.fire(new UserRegisteredEvent(registeredUser));
-
-                       // All fine, redirect to proper page
-                       return "user_register_done"; //NOI18N
-               } catch (final UserNameAlreadyRegisteredException | EmailAddressAlreadyRegisteredException ex) {
-                       // Continue to throw
-                       throw new FaceletException(ex);
-               }
-       }
-
-       /**
-        * Handles registration request send from first page. The (maybe) entered
-        * user name and email address is not used and that privacy and T&C are
-        * accepted.
-        * <p>
-        * @return Redirect
-        */
-       public String doRegisterMultiPage1 () {
-               // Is registration enabled?
-               if (!this.featureController.isFeatureEnabled("user_registration")) { //NOI18N
-                       // Is not enabled
-                       throw new FaceletException("Registration is disabled."); //NOI18N
-               }
-
-               // Get user instance
-               User user = this.userController.createUserInstance(false);
-
-               // First check if user is not null and user name is not used + if same email address is entered
-               if (null == user) {
-                       // user must be set
-                       throw new NullPointerException("user is null after createUserInstance() was called"); //NOI18N
-               } else if ((this.featureController.isFeatureEnabled("user_login_require_user_name")) && (this.userController.isUserNameRegistered(user))) { //NOI18N
-                       // User name is already used, so clear it
-                       this.clearUserNameEvent.fire(new ClearUserNameEvent());
-
-                       // Output message
-                       this.showFacesMessage("form_register_page1:userName", "ERROR_USER_NAME_ALREADY_USED"); //NOI18N
-                       return ""; //NOI18N
-               } else if (!this.contactController.isSameEmailAddressEntered()) {
-                       // Not same email address entered, clear both
-                       this.contactController.clearEmailAddresses();
-                       this.showFacesMessage("form_register_page1:emailAddressRepeat", "ERROR_EMAIL_ADDRESSES_MISMATCHING"); //NOI18N
-                       return ""; //NOI18N
-               } else if (!this.userController.isSamePasswordEntered()) {
-                       // Is multi-page enabled?
-                       if (this.featureController.isFeatureEnabled("user_register_multiple_page")) { //NOI18N
-                               // Unset both
-                               this.clearUserPasswordEvent.fire(new ClearUserPasswordEvent());
-
-                               // Output faces message
-                               this.showFacesMessage("form_register_page1:userPassword", "ERROR_USER_PASSWORD_EMPTY"); //NOI18N
-                               this.showFacesMessage("form_register_page1:userPasswordRepeat", "ERROR_USER_PASSWORD_REPEAT_EMPTY"); //NOI18N
-                               return ""; //NOI18N
-                       } else if (this.userController.ifBothPasswordsEmptyAllowed()) {
-                               // Both passwords are left empty and is allowed, then generate a random password
-                               String randomPassword = UserLoginUtils.createRandomPassword(FinancialsUserWebSessionController.MINIMUM_PASSWORD_LENGTH);
-
-                               // Generate (ignored) password-history
-                               PasswordHistory passwordHistory = new UserPasswordHistory(randomPassword, user);
-
-                               // Fire event
-                               this.userPasswordChangedEvent.fire(new UpdatedUserPasswordEvent(passwordHistory, randomPassword));
-                       }
-               }
-
-               // Create half contact instance with email address
-               Contact contact = new UserContact();
-               contact.setContactEmailAddress(this.contactController.getEmailAddress());
-
-               // Set contact in user
-               user.setUserContact(contact);
-
-               // Check if email address is registered
-               if (this.contactController.isEmailAddressRegistered(user.getUserContact())) {
-                       // Email address has already been taken, clear both
-                       this.contactController.clearEmailAddresses();
-                       this.showFacesMessage("form_register_page1:emailAddress", "ERROR_EMAIL_ADDRESS_ALREADY_USED"); //NOI18N
-                       return ""; //NOI18N
-               }
-
-               // Now only redirect to next page as the JSF does it
-               return "user_register_page2"; //NOI18N
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/user/register/FinancialsUserRegisterWebSessionController.java
deleted file mode 100644 (file)
index 6d20c7a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.register;
-
-import java.io.Serializable;
-
-/**
- * An interface for registration web controllers
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsUserRegisterWebSessionController extends Serializable {
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebRequestBean.java
new file mode 100644 (file)
index 0000000..8a4c4d5
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.resendlink;
+
+import java.util.Locale;
+import javax.ejb.EJB;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Event;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
+import org.mxchange.jcoreee.utils.FacesUtils;
+import org.mxchange.jfinancials.beans.BaseFinancialsController;
+import org.mxchange.jfinancials.beans.localization.FinancialsLocalizationSessionController;
+import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
+import org.mxchange.jusercore.exceptions.UserNotFoundException;
+import org.mxchange.jusercore.exceptions.UserStatusConfirmedException;
+import org.mxchange.jusercore.exceptions.UserStatusLockedException;
+import org.mxchange.jusercore.model.user.User;
+import org.mxchange.jusercore.model.user.status.UserAccountStatus;
+import org.mxchange.juserlogincore.events.resendlink.ObservableUserResendLinkAccountEvent;
+import org.mxchange.juserlogincore.events.resendlink.UserResendLinkAccountEvent;
+import org.mxchange.juserlogincore.model.user.resendlink.ResendLinkSessionBeanRemote;
+import org.mxchange.jfinancials.beans.user.FinancialsUserWebRequestController;
+
+/**
+ * A web session-scoped bean for resending confirmation link
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+@Named ("userResendConfirmationController")
+@RequestScoped
+public class FinancialsResendLinkWebRequestBean extends BaseFinancialsController implements FinancialsResendLinkWebRequestController {
+
+       /**
+        * Serial number
+        */
+       private static final long serialVersionUID = 186_078_724_659_153L;
+
+       /**
+        * Email address
+        */
+       private String emailAddress;
+
+       /**
+        * Locale instance
+        */
+       private Locale locale;
+
+       /**
+        * Localization controller
+        */
+       @Inject
+       private FinancialsLocalizationSessionController localizationController;
+
+       /**
+        * EJB for resending confirmation link
+        */
+       @EJB (lookup = "java:global/jfinancials-ejb/userResendConfirmationLink!org.mxchange.juserlogincore.model.user.resendlink.ResendLinkSessionBeanRemote")
+       private ResendLinkSessionBeanRemote resendLinkBean;
+
+       /**
+        * Regular user controller
+        */
+       @Inject
+       private FinancialsUserWebRequestController userController;
+
+       /**
+        * Event being fired after confirmation link is being sent
+        */
+       @Inject
+       @Any
+       private Event<ObservableUserResendLinkAccountEvent> userResendLinkEvent;
+
+       /**
+        * Default constructor
+        */
+       public FinancialsResendLinkWebRequestBean () {
+               // Call super constructor
+               super();
+       }
+
+       /**
+        * Observer method for events being fired when the application's locale has
+        * been changed.
+        * <p>
+        * @param event Event being fired
+        */
+       public void afterLocaleChangeEvent (@Observes final ObservableLocaleChangeEvent event) {
+               // Is the parameter valid?
+               if (null == event) {
+                       // Throw NPE
+                       throw new NullPointerException("event is null");
+               } else if (event.getLocale() == null) {
+                       // Throw NPE again
+                       throw new NullPointerException("event.locale is null");
+               }
+
+               // Set it here
+               this.setLocale(event.getLocale());
+       }
+
+       /**
+        * Resends (new) confirmation link to given email address, if found.
+        * Otherwise an exception is thrown. On success a redirect takes place.
+        * <p>
+        * @return Redirect outcome
+        */
+       public String doResendLink () {
+               // The email address should not be empty as the JSF validates this
+               if (this.getEmailAddress() == null) {
+                       // Throw NPE
+                       throw new NullPointerException("this.emailAddress is null"); //NOI18N
+               }
+
+               // Init user instance
+               User user;
+
+               try {
+                       // Is the email address really not used?
+                       user = this.userController.lookupUserByEmailAddress(this.getEmailAddress());
+               } catch (final UserEmailAddressNotFoundException ex) {
+                       // Always clear bean
+                       this.clear();
+
+                       // Not found, should not happen as the registered validator should find it
+                       this.showFacesMessage("form_resend_link:", "ERROR_USER_EMAIL_ADDRESS_NOT_FOUND"); //NOI18N
+                       return ""; //NOI18N
+               }
+
+               // Is the user account already confirmed?
+               if (user.getUserAccountStatus() == UserAccountStatus.CONFIRMED) {
+                       // Always clear bean
+                       this.clear();
+
+                       // Then abort here
+                       this.showFacesMessage("form_resend_link:resendEmailAddress", "ERROR_USER_STATUS_ALREADY_CONFIRMED"); //NOI18N
+                       return ""; //NOI18N
+               } else if (user.getUserAccountStatus() == UserAccountStatus.LOCKED) {
+                       // Always clear bean
+                       this.clear();
+
+                       // User account is locked
+                       this.showFacesMessage("form_resend_link:resendEmailAddress", "ERROR_USER_STATUS_LOCKED"); //NOI18N
+                       return ""; //NOI18N
+               } else if (user.getUserConfirmKey() == null) {
+                       // Status is UNCONFIRMED but confirmation key is NULL
+                       throw new NullPointerException("user.userConfirmKey is null"); //NOI18N
+               }
+
+               // Init managed user instance
+               User managedUser;
+
+               try {
+                       // Get base URL
+                       String baseUrl = FacesUtils.generateBaseUrl();
+
+                       // Call EJB and return redirect target
+                       managedUser = this.resendLinkBean.resendConfirmationLink(user, this.getLocale(), baseUrl);
+               } catch (final UserNotFoundException ex) {
+                       // User not found
+                       this.showFacesMessage("form_resend_link:resendEmailAddress", "ERROR_USER_NOT_FOUND"); //NOI18N
+                       return ""; //NOI18N
+               } catch (final UserStatusLockedException | UserStatusConfirmedException ex) {
+                       // Output message, this should not happen as the confirmation key is being removed
+                       this.showFacesMessage("form_resend_link:resendEmailAddress", ex); //NOI18N
+                       return ""; //NOI18N
+               }
+
+               // Clear this bean
+               this.clear();
+
+               // Fire event
+               this.userResendLinkEvent.fire(new UserResendLinkAccountEvent(managedUser));
+
+               // Return redirect target
+               return "user_resend_done"; //NOI18N
+       }
+
+       /**
+        * Getter for email address 1 (changing)
+        * <p>
+        * @return Email address
+        */
+       public String getEmailAddress () {
+               return this.emailAddress;
+       }
+
+       /**
+        * Setter for email address 1 (changing)
+        * <p>
+        * @param emailAddress Email address 1
+        */
+       public void setEmailAddress (final String emailAddress) {
+               this.emailAddress = emailAddress;
+       }
+
+       /**
+        * Clears email address fields so the user has to re-enter them
+        */
+       private void clear () {
+               // Clear fields
+               this.setEmailAddress(null);
+       }
+
+       /**
+        * Getter for locale instance
+        * <p>
+        * @return Locale instance
+        */
+       private Locale getLocale () {
+               return this.locale;
+       }
+
+       /**
+        * Setter for locale instance
+        * <p>
+        * @param locale Locale instance
+        */
+       private void setLocale (final Locale locale) {
+               this.locale = locale;
+       }
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebRequestController.java b/src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebRequestController.java
new file mode 100644 (file)
index 0000000..4ad42c6
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016, 2017 Roland Häder
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.jfinancials.beans.user.resendlink;
+
+import java.io.Serializable;
+
+/**
+ * An interface for an email change controller
+ * <p>
+ * @author Roland Häder<roland@mxchange.org>
+ */
+public interface FinancialsResendLinkWebRequestController extends Serializable {
+
+}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebSessionBean.java b/src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebSessionBean.java
deleted file mode 100644 (file)
index 56ecd73..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.resendlink;
-
-import java.util.Locale;
-import javax.ejb.EJB;
-import javax.enterprise.context.SessionScoped;
-import javax.enterprise.event.Event;
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.Any;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
-import org.mxchange.jcoreee.utils.FacesUtils;
-import org.mxchange.jfinancials.beans.BaseFinancialsController;
-import org.mxchange.jfinancials.beans.localization.FinancialsLocalizationSessionController;
-import org.mxchange.jfinancials.beans.user.FinancialsUserWebSessionController;
-import org.mxchange.jusercore.exceptions.UserEmailAddressNotFoundException;
-import org.mxchange.jusercore.exceptions.UserNotFoundException;
-import org.mxchange.jusercore.exceptions.UserStatusConfirmedException;
-import org.mxchange.jusercore.exceptions.UserStatusLockedException;
-import org.mxchange.jusercore.model.user.User;
-import org.mxchange.jusercore.model.user.status.UserAccountStatus;
-import org.mxchange.juserlogincore.events.resendlink.ObservableUserResendLinkAccountEvent;
-import org.mxchange.juserlogincore.events.resendlink.UserResendLinkAccountEvent;
-import org.mxchange.juserlogincore.model.user.resendlink.ResendLinkSessionBeanRemote;
-
-/**
- * A web session-scoped bean for resending confirmation link
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-@Named ("userResendConfirmationController")
-@SessionScoped
-public class FinancialsResendLinkWebSessionBean extends BaseFinancialsController implements FinancialsResendLinkWebSessionController {
-
-       /**
-        * Serial number
-        */
-       private static final long serialVersionUID = 186_078_724_659_153L;
-
-       /**
-        * Email address
-        */
-       private String emailAddress;
-
-       /**
-        * Locale instance
-        */
-       private Locale locale;
-
-       /**
-        * Localization controller
-        */
-       @Inject
-       private FinancialsLocalizationSessionController localizationController;
-
-       /**
-        * EJB for resending confirmation link
-        */
-       @EJB (lookup = "java:global/jfinancials-ejb/userResendConfirmationLink!org.mxchange.juserlogincore.model.user.resendlink.ResendLinkSessionBeanRemote")
-       private ResendLinkSessionBeanRemote resendLinkBean;
-
-       /**
-        * Regular user controller
-        */
-       @Inject
-       private FinancialsUserWebSessionController userController;
-
-       /**
-        * Event being fired after confirmation link is being sent
-        */
-       @Inject
-       @Any
-       private Event<ObservableUserResendLinkAccountEvent> userResendLinkEvent;
-
-       /**
-        * Default constructor
-        */
-       public FinancialsResendLinkWebSessionBean () {
-               // Call super constructor
-               super();
-       }
-
-       /**
-        * Observer method for events being fired when the application's locale has
-        * been changed.
-        * <p>
-        * @param event Event being fired
-        */
-       public void afterLocaleChangeEvent (@Observes final ObservableLocaleChangeEvent event) {
-               // Is the parameter valid?
-               if (null == event) {
-                       // Throw NPE
-                       throw new NullPointerException("event is null");
-               } else if (event.getLocale() == null) {
-                       // Throw NPE again
-                       throw new NullPointerException("event.locale is null");
-               }
-
-               // Set it here
-               this.setLocale(event.getLocale());
-       }
-
-       /**
-        * Resends (new) confirmation link to given email address, if found.
-        * Otherwise an exception is thrown. On success a redirect takes place.
-        * <p>
-        * @return Redirect outcome
-        */
-       public String doResendLink () {
-               // The email address should not be empty as the JSF validates this
-               if (this.getEmailAddress() == null) {
-                       // Throw NPE
-                       throw new NullPointerException("this.emailAddress is null"); //NOI18N
-               }
-
-               // Init user instance
-               User user;
-
-               try {
-                       // Is the email address really not used?
-                       user = this.userController.lookupUserByEmailAddress(this.getEmailAddress());
-               } catch (final UserEmailAddressNotFoundException ex) {
-                       // Always clear bean
-                       this.clear();
-
-                       // Not found, should not happen as the registered validator should find it
-                       this.showFacesMessage("form_resend_link:", "ERROR_USER_EMAIL_ADDRESS_NOT_FOUND"); //NOI18N
-                       return ""; //NOI18N
-               }
-
-               // Is the user account already confirmed?
-               if (user.getUserAccountStatus() == UserAccountStatus.CONFIRMED) {
-                       // Always clear bean
-                       this.clear();
-
-                       // Then abort here
-                       this.showFacesMessage("form_resend_link:resendEmailAddress", "ERROR_USER_STATUS_ALREADY_CONFIRMED"); //NOI18N
-                       return ""; //NOI18N
-               } else if (user.getUserAccountStatus() == UserAccountStatus.LOCKED) {
-                       // Always clear bean
-                       this.clear();
-
-                       // User account is locked
-                       this.showFacesMessage("form_resend_link:resendEmailAddress", "ERROR_USER_STATUS_LOCKED"); //NOI18N
-                       return ""; //NOI18N
-               } else if (user.getUserConfirmKey() == null) {
-                       // Status is UNCONFIRMED but confirmation key is NULL
-                       throw new NullPointerException("user.userConfirmKey is null"); //NOI18N
-               }
-
-               // Init managed user instance
-               User managedUser;
-
-               try {
-                       // Get base URL
-                       String baseUrl = FacesUtils.generateBaseUrl();
-
-                       // Call EJB and return redirect target
-                       managedUser = this.resendLinkBean.resendConfirmationLink(user, this.getLocale(), baseUrl);
-               } catch (final UserNotFoundException ex) {
-                       // User not found
-                       this.showFacesMessage("form_resend_link:resendEmailAddress", "ERROR_USER_NOT_FOUND"); //NOI18N
-                       return ""; //NOI18N
-               } catch (final UserStatusLockedException | UserStatusConfirmedException ex) {
-                       // Output message, this should not happen as the confirmation key is being removed
-                       this.showFacesMessage("form_resend_link:resendEmailAddress", ex); //NOI18N
-                       return ""; //NOI18N
-               }
-
-               // Clear this bean
-               this.clear();
-
-               // Fire event
-               this.userResendLinkEvent.fire(new UserResendLinkAccountEvent(managedUser));
-
-               // Return redirect target
-               return "user_resend_done"; //NOI18N
-       }
-
-       /**
-        * Getter for email address 1 (changing)
-        * <p>
-        * @return Email address
-        */
-       public String getEmailAddress () {
-               return this.emailAddress;
-       }
-
-       /**
-        * Setter for email address 1 (changing)
-        * <p>
-        * @param emailAddress Email address 1
-        */
-       public void setEmailAddress (final String emailAddress) {
-               this.emailAddress = emailAddress;
-       }
-
-       /**
-        * Clears email address fields so the user has to re-enter them
-        */
-       private void clear () {
-               // Clear fields
-               this.setEmailAddress(null);
-       }
-
-       /**
-        * Getter for locale instance
-        * <p>
-        * @return Locale instance
-        */
-       private Locale getLocale () {
-               return this.locale;
-       }
-
-       /**
-        * Setter for locale instance
-        * <p>
-        * @param locale Locale instance
-        */
-       private void setLocale (final Locale locale) {
-               this.locale = locale;
-       }
-
-}
diff --git a/src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebSessionController.java b/src/java/org/mxchange/jfinancials/beans/user/resendlink/FinancialsResendLinkWebSessionController.java
deleted file mode 100644 (file)
index 8b21db8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016, 2017 Roland Häder
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-package org.mxchange.jfinancials.beans.user.resendlink;
-
-import java.io.Serializable;
-
-/**
- * An interface for an email change controller
- * <p>
- * @author Roland Häder<roland@mxchange.org>
- */
-public interface FinancialsResendLinkWebSessionController extends Serializable {
-
-}
index c31b7ad6978f285ed0357a01923bea336e994da5..a86619c37c2b6b90f4c080cda4b069a9d01ecdd1 100644 (file)
@@ -58,7 +58,7 @@ public class FinancialsMobileProviderConverter implements Converter<MobileProvid
                }
 
                // Get full list
-               List<MobileProvider> providerList = this.mobileProviderBean.allMobileProvider();
+               List<MobileProvider> providerList = this.mobileProviderBean.allMobileProviders();
 
                // Init value
                MobileProvider provider = null;
index ba2287d61941bb8dd3b9f8c506302df963d29cc1..b1726a33079b09b520b919307e0b816b2154a19d 100644 (file)
                                <h:outputText value="#{msg.TABLE_HEADER_USER_LIST}" />
                        </div>
 
-                       <h:dataTable id="userList" var="user" value="#{userController.allVisibleUsers()}" headerClass="table-header-column25" summary="#{msg.TABLE_SUMMARY_USER_LIST}" rendered="#{userController.isVisibleUserFound()}">
-                               <h:column>
-                                       <f:facet name="header">
-                                               <h:outputText value="#{msg.USER_NAME}" />
-                                       </f:facet>
-
-                                       <widgets:outputUserProfileLink user="#{user}" />
-                               </h:column>
-
-                               <h:column>
-                                       <f:facet name="header">
-                                               <h:outputText value="#{msg.USER_CREATED}" />
-                                       </f:facet>
-
-                                       <h:outputFormat id="userCreated" value="#{user.userCreated.time}" title="#{msg.USER_CREATED_TITLE}" />
-                               </h:column>
+                       <h:dataTable id="userList" var="user" value="#{userController.allUsers()}" headerClass="table-header-column25" summary="#{msg.TABLE_SUMMARY_USER_LIST}" rendered="#{userController.allUsers().size() lt 0}">
+                               <ui:fragment rendered="#{profileController.isProfileLinkVisibleByUser(user)}">
+                                       <h:column>
+                                               <f:facet name="header">
+                                                       <h:outputText value="#{msg.USER_NAME}" />
+                                               </f:facet>
+
+                                               <widgets:outputUserProfileLink user="#{user}" />
+                                       </h:column>
+
+                                       <h:column>
+                                               <f:facet name="header">
+                                                       <h:outputText value="#{msg.USER_CREATED}" />
+                                               </f:facet>
+
+                                               <h:outputFormat id="userCreated" value="#{user.userCreated.time}" title="#{msg.USER_CREATED_TITLE}" />
+                                       </h:column>
+                               </ui:fragment>
                        </h:dataTable>
                </h:panelGroup>>
        </ui:define>