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