/**
* Copyright (C) 2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.exoplatform.portal.webui.portal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.exoplatform.container.ExoContainer;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.portal.Constants;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.portal.webui.workspace.UIMaskWorkspace;
import org.exoplatform.portal.webui.workspace.UIPortalApplication;
import org.exoplatform.services.organization.OrganizationService;
import org.exoplatform.services.organization.UserProfile;
import org.exoplatform.services.resources.LocaleConfig;
import org.exoplatform.services.resources.LocaleConfigService;
import org.exoplatform.services.resources.LocaleContextInfo;
import org.exoplatform.services.resources.ResourceBundleService;
import org.exoplatform.web.url.navigation.NodeURL;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIContainer;
import org.exoplatform.webui.core.UIItemSelector;
import org.exoplatform.webui.core.model.SelectItemCategory;
import org.exoplatform.webui.core.model.SelectItemOption;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.Event.Phase;
import org.exoplatform.webui.event.EventListener;
@ComponentConfig(template = "system:/groovy/portal/webui/portal/UILanguageSelector.gtmpl", events = {
@EventConfig(listeners = UILanguageSelector.SaveActionListener.class),
@EventConfig(listeners = UIMaskWorkspace.CloseActionListener.class) })
public class UILanguageSelector extends UIContainer {
private String name_;
@SuppressWarnings("unchecked")
public UILanguageSelector() throws Exception {
name_ = "UIChangeLanguage";
LocaleConfigService configService = getApplicationComponent(LocaleConfigService.class);
Locale currentLocale = Util.getPortalRequestContext().getLocale();
SelectItemOption localeItem = null;
List<SelectItemOption> optionsList = new ArrayList<SelectItemOption>();
for (Object object : configService.getLocalConfigs()) {
LocaleConfig localeConfig = (LocaleConfig) object;
Locale locale = localeConfig.getLocale();
String lang = locale.getLanguage();
String country = locale.getCountry();
ResourceBundle currentLocaleResourceBundle = getResourceBundle(currentLocale);
ResourceBundle localeResourceBundle = getResourceBundle(locale);
String key = "Locale." + lang;
String displayName = null;
try {
String translation = currentLocaleResourceBundle.getString(key);
displayName = translation;
} catch (MissingResourceException e) {
displayName = capitalizeFirstLetter(locale.getDisplayLanguage(currentLocale));
}
String localedName = null;
try {
String translation = localeResourceBundle.getString(key);
localedName = translation;
} catch (MissingResourceException e) {
localedName = capitalizeFirstLetter(locale.getDisplayLanguage(locale));
}
if (country != null && country.length() > 0) {
lang = lang + "_" + country;
key = "Locale." + lang;
try {
String translation = currentLocaleResourceBundle.getString(key);
displayName = translation;
} catch (MissingResourceException e) {
displayName = capitalizeFirstLetter(locale.getDisplayLanguage(currentLocale)) + " - "
+ capitalizeFirstLetter(locale.getDisplayCountry(currentLocale));
}
try {
String translation = localeResourceBundle.getString(key);
localedName = translation;
} catch (MissingResourceException e) {
localedName = capitalizeFirstLetter(locale.getDisplayLanguage(locale)) + " - "
+ capitalizeFirstLetter(locale.getDisplayCountry(locale));
}
}
if (localedName == null || localedName.length() == 0)
localedName = "???";
if (locale.getDisplayName().equalsIgnoreCase(currentLocale.getDisplayName())) {
localeItem = new SelectItemOption(displayName, lang, localedName, "", true);
} else {
localeItem = new SelectItemOption(displayName, lang, localedName, "");
}
optionsList.add(localeItem);
}
// TODO need use other UIComponent here
Collections.sort(optionsList, new LanguagesComparator());
List<SelectItemCategory> contientsCategories = new ArrayList<SelectItemCategory>();
SelectItemCategory category = new SelectItemCategory("Languages");
category.setSelectItemOptions(optionsList);
contientsCategories.add(category);
UIItemSelector selector = new UIItemSelector("Language");
selector.setItemCategories(contientsCategories);
selector.setRendered(true);
addChild(selector);
}
public String getName() {
return name_;
}
private class LanguagesComparator implements Comparator<SelectItemOption> {
public int compare(SelectItemOption item0, SelectItemOption item1) {
return item0.getLabel().compareToIgnoreCase(item1.getLabel());
}
}
public static class SaveActionListener extends EventListener<UILanguageSelector> {
public void execute(Event<UILanguageSelector> event) throws Exception {
WebuiRequestContext rContext = event.getRequestContext();
String language = event.getRequestContext().getRequestParameter("language");
PortalRequestContext prqCtx = PortalRequestContext.getCurrentInstance();
UIPortalApplication uiApp = Util.getUIPortalApplication();
UIMaskWorkspace uiMaskWS = uiApp.getChildById(UIPortalApplication.UI_MASK_WS_ID);
uiMaskWS.createEvent("Close", Phase.DECODE, rContext).broadcast();
if (language == null || language.isEmpty() || language.trim().equals(prqCtx.getLocale().getLanguage())) {
// LocalizationLifecycle will save userProfile if locale is changed
// We need to handle case : locale is not changed, but user's locale setting has not been initialized
if (prqCtx.getRemoteUser() != null) {
saveLocaleToUserProfile(prqCtx);
}
return;
}
LocaleConfigService localeConfigService = event.getSource().getApplicationComponent(LocaleConfigService.class);
LocaleConfig localeConfig = localeConfigService.getLocaleConfig(language);
if (localeConfig == null)
localeConfig = localeConfigService.getDefaultLocaleConfig();
prqCtx.setLocale(localeConfig.getLocale());
if (prqCtx.getRequestLocale() != null) {
NodeURL url = prqCtx.createURL(NodeURL.TYPE).setNode(Util.getUIPortal().getNavPath());
url.setLocale(prqCtx.getLocale());
prqCtx.sendRedirect(url.toString());
}
}
private void saveLocaleToUserProfile(PortalRequestContext context) throws Exception {
ExoContainer container = context.getApplication().getApplicationServiceContainer();
OrganizationService svc = (OrganizationService) container.getComponentInstanceOfType(OrganizationService.class);
// Don't rely on UserProfileLifecycle loaded UserProfile when doing
// an update to avoid a potential overwrite of other changes
UserProfile userProfile = svc.getUserProfileHandler().findUserProfileByName(context.getRemoteUser());
if (userProfile != null && userProfile.getUserInfoMap() != null) {
// Only save if user's locale has not been set
String currLocale = userProfile.getUserInfoMap().get(Constants.USER_LANGUAGE);
if (currLocale == null || currLocale.trim().equals("")) {
userProfile.getUserInfoMap().put(Constants.USER_LANGUAGE,
LocaleContextInfo.getLocaleAsString(context.getLocale()));
svc.getUserProfileHandler().saveUserProfile(userProfile, false);
}
}
}
}
private String capitalizeFirstLetter(String word) {
if (word == null) {
return null;
}
if (word.length() == 0) {
return word;
}
StringBuilder result = new StringBuilder(word);
result.replace(0, 1, result.substring(0, 1).toUpperCase());
return result.toString();
}
private ResourceBundle getResourceBundle(Locale locale) {
ExoContainer appContainer = ExoContainerContext.getCurrentContainer();
ResourceBundleService service = (ResourceBundleService) appContainer
.getComponentInstanceOfType(ResourceBundleService.class);
ResourceBundle res = service.getResourceBundle("locale.portal.webui", locale);
return res;
}
}