package org.mxchange.addressbook.beans.localization;
import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
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.inject.Inject;
import javax.inject.Named;
import org.mxchange.addressbook.beans.BaseAddressbookController;
+import org.mxchange.jcoreee.events.locale.LocaleChangeEvent;
+import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
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 map of all supported locales, using language code as key
+ */
+ private final Map<String, Locale> supportedLocales;
+
/**
* Default constructor
*/
public AddressbookLocalizationSessionBean () {
// Call super constructor
super();
+
+ // Init list
+ this.supportedLocales = new LinkedHashMap<>(2);
}
/**
// 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;
+ /**
+ * Changes locale in application
+ */
+ public void doChangeLocale () {
+ // Is locale code set?
+ if (this.getLocaleCode() == null) {
+ // Throw NPE
+ throw new NullPointerException("this.localeCode is null");
+ } else if (this.getLocaleCode().isEmpty()) {
+ // Throw IAE
+ throw new IllegalArgumentException("this.localeCode is empty");
}
- // Language splits
- String[] splits = language.split("_"); //NOI18N
- if (null == splits[1]) {
- splits[1] = ""; //NOI18N
+ // Default new locale is null, will be handled later
+ Locale newLocale = null;
+
+ // Iterate over whole map
+ for (Map.Entry<String, Locale> entry : this.getSupportedLocales().entrySet()) {
+ Locale foundLocale = entry.getValue();
+ System.out.println(MessageFormat.format("foundLocale={0},this.localeCode={1}", foundLocale, this.getLocaleCode()));
+
+ // Does the language match?
+ if (Objects.equals(foundLocale.toString(), this.getLocaleCode())) {
+ // Is found, take it as request locale
+ newLocale = foundLocale;
+ break;
+ }
}
- // Get new locale with upper-case country code
- Locale loc = new Locale(splits[0], splits[1]);
+ // Clear locale code field
+ this.clear();
+
+ // Has a matching locale
+ System.out.println("newLocale=" + newLocale);
+ if (null == newLocale) {
+ // Throw NPE
+ throw new NullPointerException("this.localeCode=" + this.getLocaleCode() + " cannot be found.");
+ }
- // Set it here and in the JSF context
- this.setLocale(loc);
- FacesContext.getCurrentInstance().getViewRoot().setLocale(loc);
+ // Then change it
+ this.changeLocale(newLocale);
}
- @Override
+ /**
+ * Getter for locale
+ * <p>
+ * @return Locale
+ */
public Locale getLocale () {
+ System.out.println("Getting this.locale=" + this.locale);
return this.locale;
}
- @Override
+ /**
+ * Setter for locale
+ * <p>
+ * @param locale Locale
+ */
public void setLocale (final Locale locale) {
+ System.out.println("Setting 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 () {
+ System.out.println("Getting this.localeCode=" + this.localeCode);
+ return this.localeCode;
+ }
+
+ /**
+ * Setter for localeCode code
+ * <p>
+ * @param localeCode Language code
+ */
+ public void setLocaleCode (final String localeCode) {
+ System.out.println("Setting localeCode=" + localeCode);
+ this.localeCode = localeCode;
+ }
+
+ /**
+ * Getter for selectable localizations
+ * <p>
+ * @return Selectable localizations
+ */
+ @SuppressWarnings ("ReturnOfCollectionOrArrayField")
+ public Map<String, Locale> getSupportedLocales () {
+ // Return full list
+ return this.supportedLocales;
}
/**
*/
@PostConstruct
public void init () {
- // Create locale instance from context
- Locale loc = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
+ // Get default locale
+ Locale defaultLocale = FacesContext.getCurrentInstance().getApplication().getDefaultLocale();
+ System.out.println("defaultLocale=" + defaultLocale);
+
+ // Add it to list
+ this.getSupportedLocales().put(defaultLocale.toString(), 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();
+ System.out.println("supportedLocale=" + supportedLocale);
+
+ // Add it
+ this.getSupportedLocales().put(supportedLocale.toString(), supportedLocale);
+ }
+
+ // Get locale instance from request (e.g. browser)
+ Locale requestLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
+
+ // Is no country code found?
+ if (requestLocale.getCountry().isEmpty()) {
+ // Then try to find one
+ System.out.println("Request locale is without country information, looking up in map ...");
+
+ // Get language from it
+ String language = requestLocale.getLanguage();
+ Boolean found = Boolean.FALSE;
+
+ // Iterate over whole map
+ for (Map.Entry<String, Locale> entry : this.getSupportedLocales().entrySet()) {
+ String languageCode = entry.getKey();
+ Locale foundLocale = entry.getValue();
+ System.out.println(MessageFormat.format("languageCode={0},language={1}", languageCode, language));
+
+ // Does the language match?
+ if (languageCode.startsWith(language)) {
+ // Is found, take it as request locale
+ requestLocale = foundLocale;
+ found = Boolean.TRUE;
+ break;
+ }
+ }
+
+ // Nothing found?
+ if (!found) {
+ // Then set default locale
+ requestLocale = defaultLocale;
+ }
+ }
+
+ // Change locale, may set same back in faces context, but triggers event
+ this.changeLocale(requestLocale);
+ }
+
+ /**
+ * Changes current locale in this controller and faces context to given.
+ * This method makes sure that locales with at least language and country
+ * information are being changed to.
+ * <p>
+ * @param locale New locale to set
+ */
+ private void changeLocale (final Locale locale) {
+ // Is the locale language_country at least?
+ if (null == locale) {
+ // Throw NPE
+ throw new NullPointerException("locale is null");
+ } else if (!locale.toString().contains("_")) {
+ // Throw IAE
+ throw new IllegalArgumentException(MessageFormat.format("locale={0} does not have country information set.", locale));
+ }
+
+ System.out.println("Changing locale to " + locale + " ...");
+
+ // Set locale + code here
+ this.setLocale(locale);
+ this.setLocaleCode(locale.toString());
+
+ // 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);
}
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">
- <ui:insert name="metadata" />
+ <html lang="#{localizationController.locale.language}" xml:lang="#{localizationController.locale.language}" xmlns="http://www.w3.org/1999/xhtml">
+ <f:view locale="#{localizationController.locale}" contentType="text/html">
+ <h:head>
+ <ui:insert name="metadata" />
- <h:head>
- <meta http-equiv="Content-Type" content="text/htmlcharset=UTF-8" />
+ <meta http-equiv="Content-Type" content="text/htmlcharset=UTF-8" />
- <f:loadBundle var="msg" basename="org.mxchange.localization.bundle" />
+ <f:loadBundle var="msg" basename="org.mxchange.localization.bundle" />
- <h:outputStylesheet name="/css/default.css" />
- <h:outputStylesheet name="/css/cssLayout.css" />
+ <h:outputStylesheet name="/css/default.css" />
+ <h:outputStylesheet name="/css/cssLayout.css" />
- <title>
- <h:outputText value="Addressbook" />
- <h:outputText value=" - " />
- <ui:insert name="title">
- <h:outputText value="Default title" />
- </ui:insert>
- </title>
- </h:head>
+ <title>
+ <h:outputText value="Addressbook" />
+ <h:outputText value=" - " />
+ <ui:insert name="title">
+ <h:outputText value="Default title" />
+ </ui:insert>
+ </title>
+ </h:head>
- <h:body>
- <f:view locale="#{localizationController.locale}" contentType="text/html">
+ <h:body>
<div id="top">
<div id="page_header">
<div id="page_title">
<h:panelGroup id="menu_content" layout="block">
<div id="left">
- <ui:insert name="menu">Default menu</ui:insert>
+ <ui:insert name="menu">
+ <h:outputText value="Default menu" />
+ </ui:insert>
<ui:include src="/WEB-INF/templates/generic/locale_selection_box.tpl" />
</div>
<h:panelGroup id="content_outer" class="left_content" layout="block">
<div id="content_header">
- <ui:insert name="content_header">Default content header</ui:insert>
+ <ui:insert name="content_header">
+ <h:outputText value="Default content header" />
+ </ui:insert>
</div>
<div id="content">
- <ui:insert name="content">Default content</ui:insert>
+ <ui:insert name="content">
+ <h:outputText value="Default content" />
+ </ui:insert>
</div>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup id="page_footer" layout="block">
- <ui:insert name="footer">Default footer</ui:insert>
+ <ui:insert name="footer">
+ <h:outputText value="Default footer" />
+ </ui:insert>
</h:panelGroup>
<h:panelGroup styleClass="error_container" layout="block">
<h:messages showDetail="true" errorClass="errors" fatalClass="errors" warnClass="errors" />
</h:panelGroup>
- </f:view>
- </h:body>
+ </h:body>
+ </f:view>
</html>
</ui:composition>