From 63327ac7633725d249cd4e04398f808b445954f1 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Roland=20H=C3=A4der?= <roland@mxchange.org>
Date: Fri, 13 May 2016 12:03:34 +0200
Subject: [PATCH] Continued with email address validator (cherry-pick/rename
 this) - added email address validator with regex validation and checking if
 the contact EJB reports an exisiting account - this validator can be used in
 JSF pages/templates like: validator="EmailAddressValidator" - in addition you
 may want to use a simple regex validator in addition to this to prevent ugly
 messages being shown - added message output for missing privacy/terms
 checkboxes - added required-message for email address
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

Signed-off-by: Roland Häder <roland@mxchange.org>
---
 ...AddressbookUserRegisterWebSessionBean.java |   2 +-
 .../localization/bundle_de_DE.properties      |   2 +
 .../localization/bundle_en_US.properties      |   2 +
 .../PizzaEmailAddressValidator.java           | 108 ++++++++++++++++++
 .../guest_email_address_repeat_fields.tpl     |  14 ++-
 .../templates/guest/guest_privacy_terms.tpl   |   4 +
 ...ser_change_email_address_repeat_fields.tpl |  14 ++-
 7 files changed, 141 insertions(+), 5 deletions(-)
 create mode 100644 src/java/org/mxchange/pizzaapplication/validator/emailaddress/PizzaEmailAddressValidator.java

diff --git a/src/java/org/mxchange/addressbook/beans/register/AddressbookUserRegisterWebSessionBean.java b/src/java/org/mxchange/addressbook/beans/register/AddressbookUserRegisterWebSessionBean.java
index f68c0532..f8417551 100644
--- a/src/java/org/mxchange/addressbook/beans/register/AddressbookUserRegisterWebSessionBean.java
+++ b/src/java/org/mxchange/addressbook/beans/register/AddressbookUserRegisterWebSessionBean.java
@@ -149,7 +149,7 @@ public class AddressbookUserRegisterWebSessionBean extends BaseAddressbookContro
 			User registeredUser = this.registerBean.registerUser(user);
 
 			// The id number should be set
-			assert (registeredUser.getUserId() instanceof Long) : "registerUser.userId is null after registerUser() was called."; //NOI18N
+			assert (registeredUser.getUserId() instanceof Long) : "registeredUser.userId is null after registerUser() was called."; //NOI18N
 
 			// Fire event
 			this.registeredEvent.fire(new RegisteredUserEvent(registeredUser));
diff --git a/src/java/org/mxchange/localization/bundle_de_DE.properties b/src/java/org/mxchange/localization/bundle_de_DE.properties
index be47a1f2..12b2f50e 100644
--- a/src/java/org/mxchange/localization/bundle_de_DE.properties
+++ b/src/java/org/mxchange/localization/bundle_de_DE.properties
@@ -537,3 +537,5 @@ ERROR_GUEST_USER_LOGIN_DEACTIVATED=Fehler: Der Benutzerbereich wurde administrat
 ERROR_GUEST_USER_RECOVER_PASSWORD_DEACTIVATED=Fehler: Wiederherstellen des Passwortes wurde administrativ deaktiviert.
 ERROR_GUEST_USER_RESEND_CONFIRMATION_DEACTIVATED=Fehler: Erneutes Aussenden des Best\u00e4tigungslinked ist administrativ deaktiviert.
 ERROR_GUEST_USER_PROFILE_DEACTIVATED=Fehler: \u00d6ffentliche Benutzerprofile sind administrativ deaktiviert.
+EMAIL_ADDRESS_NOT_ENTERED=Bitte geben Sie Ihre Email-Adresse ein.
+EMAIL_ADDRESS_REPEAT_NOT_ENTERED=Bitte wiederholen Sie Ihre Email-Adresse.
diff --git a/src/java/org/mxchange/localization/bundle_en_US.properties b/src/java/org/mxchange/localization/bundle_en_US.properties
index 23ff4181..4fa312b6 100644
--- a/src/java/org/mxchange/localization/bundle_en_US.properties
+++ b/src/java/org/mxchange/localization/bundle_en_US.properties
@@ -501,3 +501,5 @@ ERROR_GUEST_USER_LOGIN_DEACTIVATED=Error: User area is deactivated by administra
 ERROR_GUEST_USER_RECOVER_PASSWORD_DEACTIVATED=Error: password recovery is deactivated by administrators.
 ERROR_GUEST_USER_RESEND_CONFIRMATION_DEACTIVATED=Error: Resending confirmation link is deactivated by administrators.
 ERROR_GUEST_USER_PROFILE_DEACTIVATED=Error: Public user profiles are deactivated by administrators.
+EMAIL_ADDRESS_NOT_ENTERED=Please enter your email address.
+EMAIL_ADDRESS_REPEAT_NOT_ENTERED=Please repeat your email address.
diff --git a/src/java/org/mxchange/pizzaapplication/validator/emailaddress/PizzaEmailAddressValidator.java b/src/java/org/mxchange/pizzaapplication/validator/emailaddress/PizzaEmailAddressValidator.java
new file mode 100644
index 00000000..3d0c9c34
--- /dev/null
+++ b/src/java/org/mxchange/pizzaapplication/validator/emailaddress/PizzaEmailAddressValidator.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 Roland Haeder
+ *
+ * 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.pizzaapplication.validator.emailaddress;
+
+import java.text.MessageFormat;
+import java.util.regex.Pattern;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.FacesValidator;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+import javax.faces.view.facelets.FaceletException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import org.mxchange.jcontacts.contact.ContactSessionBeanRemote;
+import org.mxchange.jcoreee.validator.string.BaseStringValidator;
+
+/**
+ * A validator for email address validation
+ * <p>
+ * @author Roland Haeder<roland@mxchange.org>
+ */
+@FacesValidator ("EmailAddressValidator")
+public class PizzaEmailAddressValidator extends BaseStringValidator implements Validator {
+
+	/**
+	 * Serial number
+	 */
+	private static final long serialVersionUID = 187_536_745_607_192L;
+
+	/**
+	 * Contact session bean
+	 */
+	private final ContactSessionBeanRemote contactBean;
+
+	/**
+	 * Default constructor
+	 */
+	public PizzaEmailAddressValidator () {
+		// Try it
+		try {
+			// Get initial context
+			Context context = new InitialContext();
+
+			// Try to lookup
+			this.contactBean = (ContactSessionBeanRemote) context.lookup("java:global/PizzaService-ejb/contact!org.mxchange.jcontacts.contact.ContactSessionBeanRemote"); //NOI18N
+		} catch (final NamingException e) {
+			// Throw again
+			throw new FaceletException(e);
+		}
+	}
+
+	@Override
+	public void validate (final FacesContext context, final UIComponent component, final Object value) throws ValidatorException {
+		// Trace message
+		//* NOISY-DEBUG: */ System.out.println(MessageFormat.format("validate: context={0},component={1},value={2} - CALLED!", context, component, value)); //NOI18N
+
+		// The required field
+		String[] requiredFields = {"emailAddress", "emailAddressRepeat"}; //NOI18N
+
+		// Pre-validation (example: not null, not a string, empty string ...)
+		super.preValidate(context, component, value, requiredFields, false);
+
+		// Get string from object ... ;-)
+		String emailAddress = String.valueOf(value);
+
+		// Checks if the email address matches a regex ("low-level" check, should also be done by <f:validatorRegex />)
+		boolean matches = Pattern.matches("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", emailAddress); //NOI18N
+
+		// Is the email address valid?
+		if (!matches) {
+			// Generate message
+			String message = MessageFormat.format("Email address {0} does not match regular expression.", emailAddress); //NOI18N
+
+			// Not matching
+			throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message));
+		}
+
+		// Is the email address already registered?
+		if (this.contactBean.isEmailAddressRegistered(emailAddress)) {
+			// Generate message
+			String message = MessageFormat.format("Email address {0} is already registered.", emailAddress); //NOI18N
+
+			// No, then abort here
+			throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));
+		}
+
+		// Trace message
+		//* NOISY-DEBUG: */ System.out.println("validate: EXIT!"); //NOI18N
+	}
+
+}
diff --git a/web/WEB-INF/templates/guest/guest_email_address_repeat_fields.tpl b/web/WEB-INF/templates/guest/guest_email_address_repeat_fields.tpl
index a3a69c0c..357f9157 100644
--- a/web/WEB-INF/templates/guest/guest_email_address_repeat_fields.tpl
+++ b/web/WEB-INF/templates/guest/guest_email_address_repeat_fields.tpl
@@ -12,7 +12,9 @@
 		</div>
 
 		<div class="table_right">
-			<h:inputText styleClass="input" id="emailAddress" size="20" maxlength="255" value="#{contactController.emailAddress}" required="true" validator="EmailAddressValidator" />
+			<h:inputText styleClass="input" id="emailAddress" size="20" maxlength="255" value="#{contactController.emailAddress}" required="true" requiredMessage="#{msg.EMAIL_ADDRESS_NOT_ENTERED}">
+				<f:validator validatorId="EmailAddressValidator" />
+			</h:inputText>
 		</div>
 
 		<div class="clear"></div>
@@ -24,9 +26,17 @@
 		</div>
 
 		<div class="table_right">
-			<h:inputText styleClass="input" id="emailAddressRepeat" size="20" maxlength="255" value="#{contactController.emailAddressRepeat}" required="true" validator="EmailAddressValidator" />
+			<h:inputText styleClass="input" id="emailAddressRepeat" size="20" maxlength="255" value="#{contactController.emailAddressRepeat}" required="true" requiredMessage="#{msg.EMAIL_ADDRESS_REPEAT_NOT_ENTERED}" />
 		</div>
 
 		<div class="clear"></div>
 	</div>
+
+	<div>
+		<h:message for="emailAddress" errorClass="errors" warnClass="warnings" fatalClass="errors" />
+	</div>
+
+	<div>
+		<h:message for="emailAddressRepeat" errorClass="errors" warnClass="warnings" fatalClass="errors" />
+	</div>
 </ui:composition>
diff --git a/web/WEB-INF/templates/guest/guest_privacy_terms.tpl b/web/WEB-INF/templates/guest/guest_privacy_terms.tpl
index 385dfc85..b060e38f 100644
--- a/web/WEB-INF/templates/guest/guest_privacy_terms.tpl
+++ b/web/WEB-INF/templates/guest/guest_privacy_terms.tpl
@@ -25,6 +25,8 @@
 				<div class="clear"></div>
 			</div>
 
+			<h:message for="privacy" errorClass="errors" warnClass="warnings" fatalClass="errors" />
+
 			<div class="table_row">
 				<div class="table_left25">
 					<h:selectBooleanCheckbox styleClass="input" id="terms" required="true" requiredMessage="#{msg.TERMS_NOT_ACCEPTED_MESSAGE}">
@@ -40,6 +42,8 @@
 
 				<div class="clear"></div>
 			</div>
+
+			<h:message for="terms" errorClass="errors" warnClass="warnings" fatalClass="errors" />
 		</fieldset>
 	</div>
 </ui:composition>
diff --git a/web/WEB-INF/templates/login/user/user_change_email_address_repeat_fields.tpl b/web/WEB-INF/templates/login/user/user_change_email_address_repeat_fields.tpl
index 3ca9f128..b1123544 100644
--- a/web/WEB-INF/templates/login/user/user_change_email_address_repeat_fields.tpl
+++ b/web/WEB-INF/templates/login/user/user_change_email_address_repeat_fields.tpl
@@ -12,7 +12,9 @@
 		</div>
 
 		<div class="table_right">
-			<h:inputText class="input" id="emailAddress" size="20" maxlength="255" value="#{emailChangeController.emailAddress}" required="true" validator="EmailAddressValidator" />
+			<h:inputText class="input" id="emailAddress" size="20" maxlength="255" value="#{emailChangeController.emailAddress}" required="true" requiredMessage="#{msg.EMAIL_ADDRESS_NOT_ENTERED}">
+				<f:validator validatorId="EmailAddressValidator" />
+			</h:inputText>
 		</div>
 
 		<div class="clear"></div>
@@ -24,9 +26,17 @@
 		</div>
 
 		<div class="table_right">
-			<h:inputText class="input" id="emailAddressRepeat" size="20" maxlength="255" value="#{emailChangeController.emailAddressRepeat}" required="true" validator="EmailAddressValidator" />
+			<h:inputText class="input" id="emailAddressRepeat" size="20" maxlength="255" value="#{emailChangeController.emailAddressRepeat}" required="true" requiredMessage="#{msg.EMAIL_ADDRESS_REPEAT_NOT_ENTERED}" />
 		</div>
 
 		<div class="clear"></div>
 	</div>
+
+	<div>
+		<h:message for="emailAddress" errorClass="errors" warnClass="warnings" fatalClass="errors" />
+	</div>
+
+	<div>
+		<h:message for="emailAddressRepeat" errorClass="errors" warnClass="warnings" fatalClass="errors" />
+	</div>
 </ui:composition>
-- 
2.39.5