package org.jboss.seam.international;
import static org.jboss.seam.ScopeType.APPLICATION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.jboss.seam.util.Strings;
/**
* Configures the JSF locale support from the Seam container.
*
* <p>
* This component merely passes on configuration settings to the JSF runtime, so
* you still have to option of configure the locale support in the JSF
* configuration file. However, if you enable this component, it will overwrite
* any settings from that file.
* </p>
*
* <code>
* <i18n:locale-config default-locale="en" supported-locales="en fr de"/>
* </code>
*
* @author Dan Allen
*/
@Scope(APPLICATION)
@BypassInterceptors
@Startup
@Name("org.jboss.seam.international.localeConfig")
@Install(value = false, precedence = BUILT_IN, classDependencies = "javax.faces.context.FacesContext")
public class LocaleConfig
{
private String defaultLocale;
private List<String> supportedLocales;
private static final LogProvider log = Logging.getLogProvider(LocaleConfig.class);
@Create
public void initLocaleConfig()
{
Application application = getApplication();
if (application == null)
{
return;
}
String defaultAsString = getDefaultLocale();
if (defaultAsString != null)
{
application.setDefaultLocale(getLocaleFromString(defaultAsString));
}
List<String> supportedAsStrings = getSupportedLocales();
int numSupported = supportedAsStrings != null ? supportedAsStrings.size() : 0;
if (numSupported > 0)
{
// use set to prevent duplicates, yet retain order just to be nice
Set<java.util.Locale> locales = new LinkedHashSet<java.util.Locale>(numSupported);
for (String supportedAsString : supportedAsStrings)
{
locales.add(getLocaleFromString(supportedAsString));
}
application.setSupportedLocales(locales);
}
}
public String getDefaultLocale()
{
return defaultLocale;
}
public void setDefaultLocale(String defaultLocale)
{
this.defaultLocale = defaultLocale;
log.debug("Default locale was set to " + this.defaultLocale);
}
public List<String> getSupportedLocales()
{
return supportedLocales;
}
public void setSupportedLocales(List<String> supportedLocales)
{
this.supportedLocales = supportedLocales;
log.debug("Supported locales are " + this.supportedLocales);
}
public static LocaleConfig instance()
{
return (LocaleConfig) Component.getInstance(LocaleConfig.class, ScopeType.APPLICATION);
}
private java.util.Locale getLocaleFromString(String localeString)
{
if (localeString == null || localeString.length() < 2)
{
throw new IllegalArgumentException("Invalid locale string: " + localeString);
}
StringTokenizer tokens = new StringTokenizer(localeString, "-_");
String language = tokens.hasMoreTokens() ? tokens.nextToken() : null;
String country = tokens.hasMoreTokens() ? tokens.nextToken() : null;
String variant = tokens.hasMoreTokens() ? tokens.nextToken() : null;
if (!Strings.isEmpty(variant))
{
return new java.util.Locale(language, country, variant);
}
else if (!Strings.isEmpty(country))
{
return new java.util.Locale(language, country);
}
else
{
return new java.util.Locale(language);
}
}
private Application getApplication()
{
try
{
ApplicationFactory factory = (ApplicationFactory) FactoryFinder
.getFactory(FactoryFinder.APPLICATION_FACTORY);
return factory.getApplication();
}
catch (IllegalStateException e)
{
log.warn("JSF is not properly initialized, see http://jira.jboss.org/jira/browse/JBSEAM-4401");
// just in case, for units and the like
// if we can't do it, it just wan't meant to be
return null;
}
}
}