]> git.mxchange.org Git - jjobs-war.git/blob - src/java/org/mxchange/jjobs/beans/localization/JobsLocalizationSessionBean.java
Please cherry-pick:
[jjobs-war.git] / src / java / org / mxchange / jjobs / beans / localization / JobsLocalizationSessionBean.java
1 /*
2  * Copyright (C) 2016, 2017 Roland Häder
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Affero General Public License as
6  * published by the Free Software Foundation, either version 3 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Affero General Public License for more details.
13  *
14  * You should have received a copy of the GNU Affero General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 package org.mxchange.jjobs.beans.localization;
18
19 import java.text.MessageFormat;
20 import java.util.Iterator;
21 import java.util.LinkedHashMap;
22 import java.util.Locale;
23 import java.util.Map;
24 import java.util.Objects;
25 import javax.annotation.PostConstruct;
26 import javax.enterprise.context.SessionScoped;
27 import javax.enterprise.event.Event;
28 import javax.enterprise.event.Observes;
29 import javax.enterprise.inject.Any;
30 import javax.faces.context.FacesContext;
31 import javax.inject.Inject;
32 import javax.inject.Named;
33 import org.mxchange.jcoreee.events.locale.LocaleChangeEvent;
34 import org.mxchange.jcoreee.events.locale.ObservableLocaleChangeEvent;
35 import org.mxchange.jjobs.beans.BaseJobsController;
36 import org.mxchange.juserlogincore.events.login.ObservableUserLoggedInEvent;
37 import org.mxchange.juserlogincore.events.logout.ObservableUserLogoutEvent;
38
39 /**
40  * A session-scoped bean for handling localization/internationalization changes.
41  * This class is based on an example at [1] from mkyong.
42  * <p>
43  * 1: http://www.mkyong.com/jsf2/jsf-2-internationalization-example/
44  * <p>
45  * @author Roland Häder<roland@mxchange.org>
46  */
47 @Named ("localizationController")
48 @SessionScoped
49 public class JobsLocalizationSessionBean extends BaseJobsController implements JobsLocalizationSessionController {
50
51         /**
52          * Serial number
53          */
54         private static final long serialVersionUID = 158_768_216_759_107L;
55
56         /**
57          * Current Locale
58          */
59         private Locale locale;
60
61         /**
62          * Event being fired when a locale has changed successfully
63          */
64         @Inject
65         @Any
66         private Event<ObservableLocaleChangeEvent> localeChangeEvent;
67
68         /**
69          * Locale code (example: de for Germany)
70          */
71         private String localeCode;
72
73         /**
74          * A map of all supported locales, using language code as key
75          */
76         private final Map<String, Locale> supportedLocales;
77
78         /**
79          * Default constructor
80          */
81         public JobsLocalizationSessionBean () {
82                 // Call super constructor
83                 super();
84
85                 // Init list
86                 this.supportedLocales = new LinkedHashMap<>(2);
87         }
88
89         /**
90          * Event observer for logged-in user
91          * <p>
92          * @param event Event instance
93          */
94         public void afterUserLoginEvent (@Observes final ObservableUserLoggedInEvent event) {
95                 // event should not be null
96                 if (null == event) {
97                         // Throw NPE
98                         throw new NullPointerException("event is null"); //NOI18N
99                 } else if (event.getLoggedInUser() == null) {
100                         // Throw NPE again
101                         throw new NullPointerException("event.loggedInUser is null"); //NOI18N
102                 } else if (event.getLoggedInUser().getUserId() == null) {
103                         // userId is null
104                         throw new NullPointerException("event.loggedInUser.userId is null"); //NOI18N
105                 } else if (event.getLoggedInUser().getUserId() < 1) {
106                         // Not avalid id
107                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedInUser(), event.getLoggedInUser().getUserId())); //NOI18N
108                 }
109
110                 // Is the locale set?
111                 if (event.getLoggedInUser().getUserLocale() instanceof Locale) {
112                         // Get user local
113                         Locale userLocale = event.getLoggedInUser().getUserLocale();
114
115                         // Change locale
116                         this.changeLocale(userLocale);
117                 }
118         }
119
120         /**
121          * Event observer for logged-out user
122          * <p>
123          * @param event Event instance
124          */
125         public void afterUserLogoutEvent (@Observes final ObservableUserLogoutEvent event) {
126                 // event should not be null
127                 if (null == event) {
128                         // Throw NPE
129                         throw new NullPointerException("event is null"); //NOI18N
130                 } else if (event.getLoggedOutUser() == null) {
131                         // Throw NPE again
132                         throw new NullPointerException("event.loggedOutUser is null"); //NOI18N
133                 } else if (event.getLoggedOutUser().getUserId() == null) {
134                         // userId is null
135                         throw new NullPointerException("event.loggedOutUser.userId is null"); //NOI18N
136                 } else if (event.getLoggedOutUser().getUserId() < 1) {
137                         // Not avalid id
138                         throw new IllegalArgumentException(MessageFormat.format("userId of user={0} is not valid: {1}", event.getLoggedOutUser(), event.getLoggedOutUser().getUserId())); //NOI18N
139                 }
140
141                 // Clear this bean as well
142                 this.clear();
143         }
144
145         /**
146          * Changes locale in application
147          */
148         public void doChangeLocale () {
149                 // Is locale code set?
150                 if (this.getLocaleCode() == null) {
151                         // Throw NPE
152                         throw new NullPointerException("this.localeCode is null");
153                 } else if (this.getLocaleCode().isEmpty()) {
154                         // Throw IAE
155                         throw new IllegalArgumentException("this.localeCode is empty");
156                 }
157
158                 // Default new locale is null, will be handled later
159                 Locale newLocale = null;
160
161                 // Iterate over whole map
162                 for (Map.Entry<String, Locale> entry : this.getSupportedLocales().entrySet()) {
163                         Locale foundLocale = entry.getValue();
164                         System.out.println(MessageFormat.format("foundLocale={0},this.localeCode={1}", foundLocale, this.getLocaleCode()));
165
166                         // Does the language match?
167                         if (Objects.equals(foundLocale.toString(), this.getLocaleCode())) {
168                                 // Is found, take it as request locale
169                                 newLocale = foundLocale;
170                                 break;
171                         }
172                 }
173
174                 // Clear locale code field
175                 this.clear();
176
177                 // Has a matching locale
178                 System.out.println("newLocale=" + newLocale);
179                 if (null == newLocale) {
180                         // Throw NPE
181                         throw new NullPointerException("this.localeCode=" + this.getLocaleCode() + " cannot be found.");
182                 }
183
184                 // Then change it
185                 this.changeLocale(newLocale);
186         }
187
188         /**
189          * Getter for locale
190          * <p>
191          * @return Locale
192          */
193         public Locale getLocale () {
194                 System.out.println("Getting this.locale=" + this.locale);
195                 return this.locale;
196         }
197
198         /**
199          * Setter for locale
200          * <p>
201          * @param locale Locale
202          */
203         public void setLocale (final Locale locale) {
204                 System.out.println("Setting locale=" + locale);
205                 this.locale = locale;
206         }
207
208         /**
209          * Getter for localeCode code
210          * <p>
211          * @return Language code
212          */
213         public String getLocaleCode () {
214                 System.out.println("Getting this.localeCode=" + this.localeCode);
215                 return this.localeCode;
216         }
217
218         /**
219          * Setter for localeCode code
220          * <p>
221          * @param localeCode Language code
222          */
223         public void setLocaleCode (final String localeCode) {
224                 System.out.println("Setting localeCode=" + localeCode);
225                 this.localeCode = localeCode;
226         }
227
228         /**
229          * Getter for selectable localizations
230          * <p>
231          * @return Selectable localizations
232          */
233         @SuppressWarnings ("ReturnOfCollectionOrArrayField")
234         public Map<String, Locale> getSupportedLocales () {
235                 // Return full list
236                 return this.supportedLocales;
237         }
238
239         /**
240          * Initializer for this bean
241          */
242         @PostConstruct
243         public void init () {
244                 // Get default locale
245                 Locale defaultLocale = FacesContext.getCurrentInstance().getApplication().getDefaultLocale();
246                 System.out.println("defaultLocale=" + defaultLocale);
247
248                 // Add it to list
249                 this.getSupportedLocales().put(defaultLocale.toString(), defaultLocale);
250
251                 // Get iterator from faces context
252                 Iterator<Locale> iterator = FacesContext.getCurrentInstance().getApplication().getSupportedLocales();
253
254                 // Add all locales
255                 while (iterator.hasNext()) {
256                         // Get next locale
257                         Locale supportedLocale = iterator.next();
258                         System.out.println("supportedLocale=" + supportedLocale);
259
260                         // Add it
261                         this.getSupportedLocales().put(supportedLocale.toString(), supportedLocale);
262                 }
263
264                 // Get locale instance from request (e.g. browser)
265                 Locale requestLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
266
267                 // Is no country code found?
268                 if (requestLocale.getCountry().isEmpty()) {
269                         // Then try to find one
270                         System.out.println("Request locale is without country information, looking up in map ...");
271
272                         // Get language from it
273                         String language = requestLocale.getLanguage();
274                         Boolean found = Boolean.FALSE;
275
276                         // Iterate over whole map
277                         for (Map.Entry<String, Locale> entry : this.getSupportedLocales().entrySet()) {
278                                 String languageCode = entry.getKey();
279                                 Locale foundLocale = entry.getValue();
280                                 System.out.println(MessageFormat.format("languageCode={0},language={1}", languageCode, language));
281
282                                 // Does the language match?
283                                 if (languageCode.startsWith(language)) {
284                                         // Is found, take it as request locale
285                                         requestLocale = foundLocale;
286                                         found = Boolean.TRUE;
287                                         break;
288                                 }
289                         }
290
291                         // Nothing found?
292                         if (!found) {
293                                 // Then set default locale
294                                 requestLocale = defaultLocale;
295                         }
296                 }
297
298                 // Change locale, may set same back in faces context, but triggers event
299                 this.changeLocale(requestLocale);
300         }
301
302         /**
303          * Changes current locale in this controller and faces context to given.
304          * This method makes sure that locales with at least language and country
305          * information are being changed to.
306          * <p>
307          * @param locale New locale to set
308          */
309         private void changeLocale (final Locale locale) {
310                 // Is the locale language_country at least?
311                 if (null == locale) {
312                         // Throw NPE
313                         throw new NullPointerException("locale is null");
314                 } else if (!locale.toString().contains("_")) {
315                         // Throw IAE
316                         throw new IllegalArgumentException(MessageFormat.format("locale={0} does not have country information set.", locale));
317                 }
318
319                 System.out.println("Changing locale to " + locale + " ...");
320
321                 // Set locale + code here
322                 this.setLocale(locale);
323                 this.setLocaleCode(locale.toString());
324
325                 // Inform faces context
326                 FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
327
328                 // Fire event
329                 this.localeChangeEvent.fire(new LocaleChangeEvent(locale));
330         }
331
332         /**
333          * Clears this bean
334          */
335         private void clear () {
336                 // Clear all fields
337                 this.setLocaleCode(null);
338                 this.setLocale(null);
339         }
340
341 }