package org.mxchange.jfinancials.beans.localization;
import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct;
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.event.ValueChangeEvent;
+import javax.inject.Inject;
import javax.inject.Named;
+import org.mxchange.jcoreee.events.locale.LocaleChangeEvent;
+import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
import org.mxchange.jfinancials.beans.BaseFinancialsController;
import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
*/
private Locale locale;
+ /**
+ * Event being fired when a locale has changed successfully
+ */
+ @Inject
+ @Any
+ private Event<ObservableLocaleChangeEvent> localeChangeEvent;
+
+ /**
+ * Locale code (example: de for Germany)
+ */
+ private String localeCode;
+
+ /**
+ * A list of all supported locales
+ */
+ private final List<Locale> supportedLocales;
+
/**
* Default constructor
*/
public FinancialsLocalizationSessionBean () {
// Call super constructor
super();
+
+ // Init list
+ this.supportedLocales = new LinkedList<>();
}
/**
// Is the locale set?
if (event.getLoggedInUser().getUserLocale() instanceof Locale) {
- // Set locale here
- this.setLocale(event.getLoggedInUser().getUserLocale());
+ // Get user local
+ Locale userLocale = event.getLoggedInUser().getUserLocale();
+
+ // Change locale
+ this.changeLocale(userLocale);
}
}
this.clear();
}
- @Override
- public String getLanguage () {
- return this.getLocale().getLanguage().toLowerCase();
- }
-
- @Override
- public void setLanguage (final String language) {
- // Is the language null?
- if (null == language) {
- // This may sometimes happen, so abort here
- return;
- }
-
- // Language splits
- String[] splits = language.split("_"); //NOI18N
- if (null == splits[1]) {
- splits[1] = ""; //NOI18N
- }
-
- // Get new locale with upper-case country code
- Locale loc = new Locale(splits[0], splits[1]);
-
- // Set it here and in the JSF context
- this.setLocale(loc);
- FacesContext.getCurrentInstance().getViewRoot().setLocale(loc);
- }
-
- @Override
+ /**
+ * Getter for locale
+ * <p>
+ * @return Locale
+ */
public Locale getLocale () {
return this.locale;
}
- @Override
+ /**
+ * Setter for locale
+ * <p>
+ * @param locale Locale
+ */
public void setLocale (final Locale locale) {
this.locale = locale;
}
- @Override
- public Locale[] getSelectableLocalizations () {
- Locale[] locales = {
- Locale.GERMANY,
- Locale.US
- };
- return locales;
+ /**
+ * Getter for localeCode code
+ * <p>
+ * @return Language code
+ */
+ public String getLocaleCode () {
+ return this.localeCode;
+ }
+
+ /**
+ * Setter for localeCode code
+ * <p>
+ * @param localeCode Language code
+ */
+ public void setLocaleCode (final String localeCode) {
+ this.localeCode = localeCode;
+ }
+
+ /**
+ * Getter for selectable localizations
+ * <p>
+ * @return Selectable localizations
+ */
+ @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+ public List<Locale> getSupportedLocales () {
+ // Return full list
+ return this.supportedLocales;
}
/**
*/
@PostConstruct
public void init () {
- // Create locale instance from context
- Locale loc = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
+ // Get locale instance from context
+ Locale currentLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
+
+ // Change locale, may set same back in faces context, but triggers event
+ this.changeLocale(currentLocale);
+
+ // Get default locale
+ Locale defaultLocale = FacesContext.getCurrentInstance().getApplication().getDefaultLocale();
+
+ // Add it to list
+ this.getSupportedLocales().add(defaultLocale);
+
+ // Get iterator from faces context
+ Iterator<Locale> iterator = FacesContext.getCurrentInstance().getApplication().getSupportedLocales();
+
+ // Add all locales
+ while (iterator.hasNext()) {
+ // Get next locale
+ Locale supportedLocale = iterator.next();
+
+ // Add it
+ this.getSupportedLocales().add(supportedLocale);
+ }
+ }
+
+ /**
+ * Listens on value-change event and changes locale accordingly, if found in
+ * list.
+ * <p>
+ * This method has been taken from
+ * https://www.mkyong.com/jsf2/jsf-2-internationalization-example/ and has
+ * been customized, e.g. checked parameter deeply. If the selected locale
+ * does not exist (someone changed the value in HTML form) then a proper
+ * exception is thrown.
+ * <p>
+ * @param event Event being triggered by JSF view/template
+ *
+ * @throws NullPointerException If event or newValue field is empty
+ * @throws IllegalArgumentException If newValue is empty or the locale does
+ * not exist
+ */
+ public void localeCodeChanged (final ValueChangeEvent event) {
+ // Validate event
+ if (null == event) {
+ // Abort here
+ throw new NullPointerException("event is null"); //NOI18N
+ } else if (event.getNewValue() == null) {
+ // Abort again
+ throw new NullPointerException("event.newValue is null"); //NOI18N
+ }
+
+ // First, get new value from event
+ String newCountryCode = event.getNewValue().toString();
+
+ // Is it valid?
+ if (null == newCountryCode) {
+ // Abort here
+ throw new NullPointerException("newCountryCode is null"); //NOI18N
+ } else if (newCountryCode.isEmpty()) {
+ // Is empty
+ throw new IllegalArgumentException("newCountryCode is empty"); //NOI18N
+ }
+
+ // Generate locale from new value (which is the 2-letter country code)
+ Locale newLocale = new Locale(newCountryCode);
+
+ // Lookup locale in list, very easy
+ if (!this.getSupportedLocales().contains(newLocale)) {
+ // Locale is not in supportedLocales list
+ throw new IllegalArgumentException(MessageFormat.format("Country code {0} is not supported.", newCountryCode)); //NOI18N
+ }
+
+ // All fine, then change locale
+ this.changeLocale(newLocale);
+ }
+
+ /**
+ * Changes current locale in this controller and faces context to given
+ * <p>
+ * @param locale New locale to set
+ */
+ private void changeLocale (final Locale locale) {
+ // Set locale here
+ this.setLocale(locale);
+
+ // Inform faces context
+ FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
- // Set it here
- this.setLocale(loc);
+ // Fire event
+ this.localeChangeEvent.fire(new LocaleChangeEvent(locale));
}
/**
*/
private void clear () {
// Clear all fields
- this.setLanguage(null);
+ this.setLocaleCode(null);
this.setLocale(null);
}
package org.mxchange.jfinancials.beans.localization;
import java.io.Serializable;
-import java.util.Locale;
/**
* An interface for localization change beans
*/
public interface FinancialsLocalizationSessionController extends Serializable {
- /**
- * Getter for locale
- * <p>
- * @return Locale
- */
- Locale getLocale ();
-
- /**
- * Setter for locale
- * <p>
- * @param locale Locale
- */
- void setLocale (final Locale locale);
-
- /**
- * Getter for language code
- * <p>
- * @return Language code
- */
- String getLanguage ();
-
- /**
- * Setter for language code
- * <p>
- * @param language Language code
- */
- void setLanguage (final String language);
-
- /**
- * Getter for selectable localizations
- * <p>
- * @return Selectable localizations
- */
- Locale[] getSelectableLocalizations ();
-
}
package org.mxchange.jfinancials.beans.user;
import java.text.MessageFormat;
+import java.util.Locale;
import java.util.Objects;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.mxchange.jcontacts.contact.Contact;
+import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
import org.mxchange.jcoreee.utils.FacesUtils;
import org.mxchange.jfinancials.beans.BaseFinancialsController;
import org.mxchange.jfinancials.beans.contact.FinancialsAdminContactWebRequestController;
@Any
private Event<ObservableAdminDeletedUserEvent> deleteUserEvent;
+ /**
+ * Locale instance
+ */
+ private Locale locale;
+
/**
* Localization controller
*/
newUser.setUserProfileMode(ProfileMode.INVISIBLE);
// Copy user locale
- newUser.setUserLocale(this.localizationController.getLocale());
+ newUser.setUserLocale(this.getLocale());
// Init instance
Contact userContact;
this.setUser(event.getCreatedUser());
}
+ /**
+ * 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 for new user registrations
* <p>
this.setUserName(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;
+ }
+
/**
* Checks if same password is entered and that they are not empty.
* <p>
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.enterprise.context.SessionScoped;
import javax.naming.InitialContext;
import javax.naming.NamingException;
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.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.juserlogincore.events.user.password_change.ObservableUpdatedUserPasswordEvent;
import org.mxchange.juserlogincore.exceptions.UserPasswordMismatchException;
import org.mxchange.juserlogincore.login.UserLoginUtils;
-import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent;
/**
* A user bean (controller)
@Inject
private FinancialsFeaturesWebApplicationController featureController;
+ /**
+ * Locale instance
+ */
+ private Locale locale;
+
/**
* Localization controller
*/
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>
// Set user name profile mode and locale
user.setUserName(this.getUserName());
user.setUserProfileMode(this.getUserProfileMode());
- user.setUserLocale(this.localizationController.getLocale());
+ user.setUserLocale(this.getLocale());
// Is multiple registration page
if ((createContactData) || (!this.featureController.isFeatureEnabled("user_register_multiple_page"))) { //NOI18N
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>
*/
package org.mxchange.jfinancials.beans.user.resendlink;
+import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Event;
+import javax.enterprise.event.Observes;
import javax.enterprise.inject.Any;
import javax.faces.view.facelets.FaceletException;
import javax.inject.Inject;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
+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;
*/
private String emailAddress;
+ /**
+ * Locale instance
+ */
+ private Locale locale;
+
/**
* Localization controller
*/
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.
String baseUrl = FacesUtils.generateBaseUrl();
// Call EJB and return redirect target
- managedUser = this.resendLinkBean.resendConfirmationLink(user, this.localizationController.getLocale(), baseUrl);
+ 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
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;
+ }
+
}
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:doctype rootElement="html" public="-//W3C//DTD XHTML 1.0 Transitional//EN" system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
- <html lang="#{localizationController.language}" xml:lang="#{localizationController.language}" xmlns="http://www.w3.org/1999/xhtml">
+ <html lang="#{localizationController.locale.language}" xml:lang="#{localizationController.locale.language}" xmlns="http://www.w3.org/1999/xhtml">
<ui:insert name="metadata" />
<h:head>
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:form id="form_locale_selection">
- <h:selectOneMenu id="language_selection" styleClass="select" value="#{localizationController.language}" onchange="submit()">
+ <h:selectOneMenu id="language_selection" styleClass="select" value="#{localizationController.localeCode}" onchange="submit()" valueChangeListener="#{localizationController.localeCodeChanged}">
<f:selectItem itemLabel="#{msg.SELECT_LANGUAGE}" noSelectionOption="true" />
- <f:selectItems value="#{localizationController.selectableLocalizations}" var="locale" itemValue="#{locale}" itemLabel="#{msg[locale.toString().toUpperCase()]}" />
+ <f:selectItems value="#{localizationController.supportedLocales}" var="locale" itemValue="#{locale}" itemLabel="#{msg[locale.toString().toUpperCase()]}" />
</h:selectOneMenu>
</h:form>
</ui:composition>