]> git.mxchange.org Git - addressbook-war.git/commitdiff
Please cherry-pick:
authorRoland Häder <roland@mxchange.org>
Sat, 19 Aug 2017 11:18:04 +0000 (13:18 +0200)
committerRoland Häder <roland@mxchange.org>
Sat, 19 Aug 2017 13:25:15 +0000 (15:25 +0200)
- changed List to Map to have locale name (e.g. de_DE) as key and the locale
  itself as value stored in a map for a quick lookup
- this map is also being used to handle browser's language-only locales, like
  "de" and not "de_AT" or other equivalents
- there is now a submit button for JS-less users to change locale

Signed-off-by: Roland Häder <roland@mxchange.org>
nbproject/project.properties
src/java/org/mxchange/addressbook/beans/localization/AddressbookLocalizationSessionBean.java
src/java/org/mxchange/addressbook/beans/localization/AddressbookLocalizationSessionController.java
src/java/org/mxchange/localization/bundle_de_DE.properties
src/java/org/mxchange/localization/bundle_en_US.properties
web/WEB-INF/templates/base.tpl
web/WEB-INF/templates/generic/locale_selection_box.tpl

index b13c987a217914b76e5188be2f7141f112a2ee7e..3fd08273ff2413ea63698682dc9c0ee4b04ad2c4 100644 (file)
@@ -62,7 +62,7 @@ j2ee.compile.on.save=true
 j2ee.copy.static.files.on.save=true
 j2ee.deploy.on.save=true
 j2ee.platform=1.7-web
-j2ee.platform.classpath=${j2ee.server.home}/modules/endorsed/javax.annotation-api.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar:${j2ee.server.home}/modules/javax.batch-api.jar:${j2ee.server.home}/modules/javax.security.auth.message-api.jar:${j2ee.server.home}/modules/javax.faces.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jstl-api.jar:${j2ee.server.home}/modules/javax.transaction-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jar:${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/javax.mail.jar:${j2ee.server.home}/modules/javax.interceptor-api.jar:${j2ee.server.home}/modules/javax.inject.jar:${j2ee.server.home}/modules/javax.resource-api.jar:${j2ee.server.home}/modules/javax.enterprise.concurrent-api.jar:${j2ee.server.home}/modules/javax.el.jar:${j2ee.server.home}/modules/javax.ejb-api.jar:${j2ee.server.home}/modules/javax.xml.rpc-api.jar:${j2ee.server.home}/modules/javax.security.jacc-api.jar:${j2ee.server.home}/modules/javax.json.jar:${j2ee.server.home}/modules/javax.xml.registry-api.jar:${j2ee.server.home}/modules/javax.websocket-api.jar:${j2ee.server.home}/modules/javax.management.j2ee-api.jar:${j2ee.server.home}/modules/javax.servlet-api.jar:${j2ee.server.home}/modules/javax.jms-api.jar:${j2ee.server.home}/modules/javax.enterprise.concurrent.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jstl.jar:${j2ee.server.home}/modules/javax.enterprise.deploy-api.jar:${j2ee.server.home}/modules/bean-validator.jar:${j2ee.server.home}/modules/javax.ws.rs-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp-api.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/cdi-api.jar:${j2ee.server.home}/modules/javax.persistence.jar:${j2ee.server.middleware}/mq/lib/jaxm-api.jar
+j2ee.platform.classpath=${j2ee.server.home}/modules/endorsed/javax.annotation-api.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar:${j2ee.server.home}/modules/javax.batch-api.jar:${j2ee.server.home}/modules/javax.security.auth.message-api.jar:${j2ee.server.home}/modules/javax.faces.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jstl-api.jar:${j2ee.server.home}/modules/javax.transaction-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jar:${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/javax.mail.jar:${j2ee.server.home}/modules/javax.interceptor-api.jar:${j2ee.server.home}/modules/javax.inject.jar:${j2ee.server.home}/modules/javax.resource-api.jar:${j2ee.server.home}/modules/javax.enterprise.concurrent-api.jar:${j2ee.server.home}/modules/javax.el.jar:${j2ee.server.home}/modules/javax.ejb-api.jar:${j2ee.server.home}/modules/javax.xml.rpc-api.jar:${j2ee.server.home}/modules/javax.security.jacc-api.jar:${j2ee.server.home}/modules/javax.json.jar:${j2ee.server.home}/modules/javax.xml.registry-api.jar:${j2ee.server.home}/modules/javax.websocket-api.jar:${j2ee.server.home}/modules/javax.management.j2ee-api.jar:${j2ee.server.home}/modules/javax.servlet-api.jar:${j2ee.server.home}/modules/javax.jms-api.jar:${j2ee.server.home}/modules/javax.enterprise.concurrent.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jstl.jar:${j2ee.server.home}/modules/javax.enterprise.deploy-api.jar:${j2ee.server.home}/modules/javax.ws.rs-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp-api.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/cdi-api.jar:${j2ee.server.home}/modules/javax.persistence.jar:${j2ee.server.middleware}/mq/lib/jaxm-api.jar
 j2ee.platform.embeddableejb.classpath=${j2ee.server.home}/lib/embedded/glassfish-embedded-static-shell.jar
 j2ee.platform.wscompile.classpath=${j2ee.server.home}/modules/webservices-osgi.jar
 j2ee.platform.wsgen.classpath=${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar
index 9c281d5103e65cd5924267dd4122b68d528df376..192558f89259ef58ed4a8e7bf77e2795261a59d6 100644 (file)
 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;
 
@@ -49,12 +58,32 @@ public class AddressbookLocalizationSessionBean extends BaseAddressbookControlle
         */
        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);
        }
 
        /**
@@ -80,8 +109,11 @@ public class AddressbookLocalizationSessionBean extends BaseAddressbookControlle
 
                // 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);
                }
        }
 
@@ -110,50 +142,98 @@ public class AddressbookLocalizationSessionBean extends BaseAddressbookControlle
                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;
        }
 
        /**
@@ -161,11 +241,92 @@ public class AddressbookLocalizationSessionBean extends BaseAddressbookControlle
         */
        @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));
        }
 
        /**
@@ -173,7 +334,7 @@ public class AddressbookLocalizationSessionBean extends BaseAddressbookControlle
         */
        private void clear () {
                // Clear all fields
-               this.setLanguage(null);
+               this.setLocaleCode(null);
                this.setLocale(null);
        }
 
index cbb15a09c2e89e7e1a32413f173ca6b57320e165..575a9510c7b47f79e9b8bc1dd81ab65e95ac8846 100644 (file)
@@ -17,7 +17,6 @@
 package org.mxchange.addressbook.beans.localization;
 
 import java.io.Serializable;
-import java.util.Locale;
 
 /**
  * An interface for localization change beans
@@ -26,39 +25,4 @@ import java.util.Locale;
  */
 public interface AddressbookLocalizationSessionController 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 ();
-
 }
index f9437d4495cf2841174f3f05a8f19220af13ac6e..a1bb1140789df28a275b32ddc1a0ca6aaf0c6298 100644 (file)
@@ -894,3 +894,7 @@ ADMIN_BUSINESS_DATA_COMPANY_EMAIL_ADDRESS=Haupt-Email-Adresse:
 #@TODO Please fix German umlauts!
 BUTTON_ADMIN_CONTINUE_BUSINESS_CONTACT_PERSON=Basisdaten hinzufuegen
 ERROR_GUEST_REGISTRATION_IN_INDEX_ENABLED=Fehler: Falscher Aufruf der Anmeldeseite, da die Eingangsseite als Anmeldeseite fungiert.
+#@TODO Please fix German umlauts!
+BUTTON_CHANGE_LOCALE=Aendern
+#@TODO Please fix German umlauts!
+BUTTON_CHANGE_LOCALE_TITLE=Aendern Sie hier in der aktuellen Sitzung die angezeigte Sprache.
index 7b3d1b8a8e4836991510ec44c02cacbd6f73fb6f..c2709808118c8e2dad32e770739c516d9e7c5a8c 100644 (file)
@@ -871,3 +871,5 @@ ADMIN_BUSINESS_DATA_COMPANY_EMAIL_ADDRESS=Main email address:
 BUTTON_ADMIN_CONTINUE_BUSINESS_CONTACT_PERSON=Add basic data
 #Fehler: Falscher Aufruf der Anmeldeseite, da die Eingangsseite als Anmeldeseite fungiert.
 ERROR_GUEST_REGISTRATION_IN_INDEX_ENABLED=Error: Wrong request on registration page as the index page serves as registration page.
+BUTTON_CHANGE_LOCALE=Change
+BUTTON_CHANGE_LOCALE_TITLE=Change here in your current session the used language for text output.
index 02f4eb11b4c1b00d982936a4134e5453c6df90d2..1436d3796850adb16928b7ffe174a01b59553380 100644 (file)
@@ -5,28 +5,28 @@
                                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>
index 303a52602d6bc21c77cdf2ad04f9e748ac54f7c0..c4b41bc668387043f64e8beed4a3707de2551906 100644 (file)
@@ -5,10 +5,16 @@
        xmlns:h="http://java.sun.com/jsf/html"
        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()">
-                       <f:selectItem itemLabel="#{msg.SELECT_LANGUAGE}" noSelectionOption="true" />
-                       <f:selectItems value="#{localizationController.selectableLocalizations}" var="locale" itemValue="#{locale}" itemLabel="#{msg[locale.toString().toUpperCase()]}" />
-               </h:selectOneMenu>
+       <h:form>
+               <h:panelGroup layout="block" styleClass="locale_selection_container">
+                       <h:panelGroup layout="block">
+                               <h:selectOneMenu styleClass="select" value="#{localizationController.localeCode}" onchange="submit()">
+                                       <f:selectItem itemLabel="#{msg.SELECT_LANGUAGE}" noSelectionOption="true" itemDisabled="true" />
+                                       <f:selectItems value="#{localizationController.supportedLocales}" var="locale" itemValue="#{locale}" itemLabel="#{msg[locale.toString().toUpperCase()]}" />
+                               </h:selectOneMenu>
+                       </h:panelGroup>
+
+                       <h:commandButton styleClass="submit" type="submit" action="#{localizationController.doChangeLocale()}" value="#{msg.BUTTON_CHANGE_LOCALE}" title="#{msg.BUTTON_CHANGE_LOCALE_TITLE}" />
+               </h:panelGroup>
        </h:form>
 </ui:composition>