Author: dan.j.allen
Date: 2008-09-20 16:35:39 -0400 (Sat, 20 Sep 2008)
New Revision: 9044
Added:
branches/community/Seam_2_0/src/main/org/jboss/seam/international/LocaleConfig.java
branches/community/Seam_2_0/src/main/org/jboss/seam/mock/MockApplicationFactory.java
Modified:
branches/community/Seam_2_0/src/main/org/jboss/seam/international-2.0.xsd
branches/community/Seam_2_0/src/main/org/jboss/seam/mock/BaseSeamTest.java
branches/community/Seam_2_0/src/main/org/jboss/seam/mock/MockApplication.java
branches/community/Seam_2_0/src/test/integration/resources/WEB-INF/components.xml
branches/community/Seam_2_0/src/test/integration/src/org/jboss/seam/test/integration/i8ln/LocaleTest.java
Log:
JBSEAM-3088
Also, enhanced the BaseSeamTest to use FactoryFinder to locate the MockApplication
so that external code can locate the same Application instance
Added:
branches/community/Seam_2_0/src/main/org/jboss/seam/international/LocaleConfig.java
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/international/LocaleConfig.java
(rev 0)
+++
branches/community/Seam_2_0/src/main/org/jboss/seam/international/LocaleConfig.java 2008-09-20
20:35:39 UTC (rev 9044)
@@ -0,0 +1,137 @@
+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.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
+(a)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;
+
+ @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;
+ }
+
+ public List<String> getSupportedLocales()
+ {
+ return supportedLocales;
+ }
+
+ public void setSupportedLocales(List<String> supportedLocales)
+ {
+ this.supportedLocales = 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()
+ {
+ ApplicationFactory factory = (ApplicationFactory) FactoryFinder
+ .getFactory(FactoryFinder.APPLICATION_FACTORY);
+ return factory.getApplication();
+ }
+}
\ No newline at end of file
Modified: branches/community/Seam_2_0/src/main/org/jboss/seam/international-2.0.xsd
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/international-2.0.xsd 2008-09-20
17:08:27 UTC (rev 9043)
+++ branches/community/Seam_2_0/src/main/org/jboss/seam/international-2.0.xsd 2008-09-20
20:35:39 UTC (rev 9044)
@@ -4,6 +4,21 @@
xmlns:components="http://jboss.com/products/seam/components"
attributeFormDefault="unqualified">
<xs:import
namespace="http://jboss.com/products/seam/components"
schemaLocation="components-2.0.xsd"/>
+ <xs:element name="locale-config">
+ <xs:complexType mixed="true">
+ <xs:choice minOccurs="0" maxOccurs="1">
+ <xs:element ref="international:supported-locales"/>
+ </xs:choice>
+ <xs:attributeGroup ref="components:attlist.component"/>
+ <xs:attributeGroup
ref="international:attlist.localeConfig"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="supported-locales"
type="components:multiValuedProperty"/>
+ <xs:attributeGroup name="attlist.localeConfig">
+ <xs:attribute name="default-locale" type="xs:string"/>
+ <xs:attribute name="supported-locales"
type="xs:string"/>
+ </xs:attributeGroup>
+
<xs:element name="locale-selector">
<xs:complexType mixed="true">
<xs:attributeGroup ref="components:attlist.component"/>
Modified: branches/community/Seam_2_0/src/main/org/jboss/seam/mock/BaseSeamTest.java
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/mock/BaseSeamTest.java 2008-09-20
17:08:27 UTC (rev 9043)
+++ branches/community/Seam_2_0/src/main/org/jboss/seam/mock/BaseSeamTest.java 2008-09-20
20:35:39 UTC (rev 9044)
@@ -12,7 +12,9 @@
import javax.el.ELResolver;
import javax.el.ValueExpression;
+import javax.faces.FactoryFinder;
import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
@@ -47,7 +49,6 @@
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.faces.Renderer;
import org.jboss.seam.init.Initialization;
-import org.jboss.seam.jsf.SeamApplication;
import org.jboss.seam.jsf.SeamPhaseListener;
import org.jboss.seam.mail.MailSession;
import org.jboss.seam.pageflow.Pageflow;
@@ -959,7 +960,8 @@
protected void setupClass() throws Exception
{
servletContext = (MockServletContext) ServletLifecycle.getServletContext();
- application = new SeamApplication(new MockApplication());
+ FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
"org.jboss.seam.mock.MockApplicationFactory");
+ application = ((ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication();
phases = new SeamPhaseListener();
conversationViewRootAttributes = new HashMap<String, Map>();
seamFilter = createSeamFilter();
Modified: branches/community/Seam_2_0/src/main/org/jboss/seam/mock/MockApplication.java
===================================================================
---
branches/community/Seam_2_0/src/main/org/jboss/seam/mock/MockApplication.java 2008-09-20
17:08:27 UTC (rev 9043)
+++
branches/community/Seam_2_0/src/main/org/jboss/seam/mock/MockApplication.java 2008-09-20
20:35:39 UTC (rev 9044)
@@ -54,6 +54,7 @@
private javax.el.CompositeELResolver elResolver;
private javax.el.CompositeELResolver additionalResolvers;
+ private Collection locales;
public MockApplication()
{
@@ -374,13 +375,20 @@
@Override
public Iterator getSupportedLocales()
{
- return Collections.singleton(defaultLocale).iterator();
+ if (locales == null)
+ {
+ return Collections.singleton(defaultLocale).iterator();
+ }
+ else
+ {
+ return locales.iterator();
+ }
}
@Override
public void setSupportedLocales(Collection locales)
{
- throw new UnsupportedOperationException();
+ this.locales = locales;
}
private final Map<String, Validator> validatorsById = new HashMap<String,
Validator>();
Added:
branches/community/Seam_2_0/src/main/org/jboss/seam/mock/MockApplicationFactory.java
===================================================================
--- branches/community/Seam_2_0/src/main/org/jboss/seam/mock/MockApplicationFactory.java
(rev 0)
+++
branches/community/Seam_2_0/src/main/org/jboss/seam/mock/MockApplicationFactory.java 2008-09-20
20:35:39 UTC (rev 9044)
@@ -0,0 +1,41 @@
+package org.jboss.seam.mock;
+
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
+
+import org.jboss.seam.jsf.SeamApplication;
+
+/**
+ * An mock implementation of the JSF ApplicationFactory which returns a mock
+ * Application wrapped in a SeamApplication. This class can be registered with
+ * JSF to allow JSF to be used formally in a test environment as follows:
+ *
+ * <code>
+ * FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
+ * "org.jboss.seam.mock.MockApplicationFactory");
+ * Application application = ((ApplicationFactory) FactoryFinder
+ * .getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication();
+ * </code>
+ *
+ * @author Dan Allen
+ */
+public class MockApplicationFactory extends ApplicationFactory
+{
+ private Application application;
+
+ @Override
+ public Application getApplication()
+ {
+ if (application == null) {
+ application = new SeamApplication(new MockApplication());
+ }
+ return application;
+ }
+
+ @Override
+ public void setApplication(Application application)
+ {
+ this.application = application;
+ }
+
+}
Modified:
branches/community/Seam_2_0/src/test/integration/resources/WEB-INF/components.xml
===================================================================
---
branches/community/Seam_2_0/src/test/integration/resources/WEB-INF/components.xml 2008-09-20
17:08:27 UTC (rev 9043)
+++
branches/community/Seam_2_0/src/test/integration/resources/WEB-INF/components.xml 2008-09-20
20:35:39 UTC (rev 9044)
@@ -2,6 +2,7 @@
<components
xmlns="http://jboss.com/products/seam/components"
xmlns:bpm="http://jboss.com/products/seam/bpm"
xmlns:core="http://jboss.com/products/seam/core"
+
xmlns:i18n="http://jboss.com/products/seam/international"
xmlns:security="http://jboss.com/products/seam/security"
xmlns:persistence="http://jboss.com/products/seam/persistence"
xmlns:web="http://jboss.com/products/seam/web"
@@ -11,6 +12,7 @@
xsi:schemaLocation=
"http://jboss.com/products/seam/core
http://jboss.com/products/seam/core-2.0.xsd
http://jboss.com/products/seam/bpm
http://jboss.com/products/seam/bpm-2.0.xsd
+
http://jboss.com/products/seam/international
http://jboss.com/products/seam/international-2.0.xsd
http://jboss.com/products/seam/security
http://jboss.com/products/seam/security-2.0.xsd
http://jboss.com/products/seam/persistence
http://jboss.com/products/seam/persistence-2.0.xsd
http://jboss.com/products/seam/components
http://jboss.com/products/seam/components-2.0.xsd
@@ -23,6 +25,8 @@
<core:manager concurrent-request-timeout="500"
conversation-timeout="120000"
conversation-id-parameter="cid"/>
+
+ <i18n:locale-config default-locale="fr_CA" supported-locales="fr_CA
fr_FR en"/>
<persistence:managed-persistence-context name="entityManager"
auto-create="true"
Modified:
branches/community/Seam_2_0/src/test/integration/src/org/jboss/seam/test/integration/i8ln/LocaleTest.java
===================================================================
---
branches/community/Seam_2_0/src/test/integration/src/org/jboss/seam/test/integration/i8ln/LocaleTest.java 2008-09-20
17:08:27 UTC (rev 9043)
+++
branches/community/Seam_2_0/src/test/integration/src/org/jboss/seam/test/integration/i8ln/LocaleTest.java 2008-09-20
20:35:39 UTC (rev 9044)
@@ -1,5 +1,8 @@
package org.jboss.seam.test.integration.i8ln;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
import javax.faces.component.UIOutput;
@@ -20,6 +23,25 @@
@Override
protected void invokeApplication() throws Exception
{
+ // <i18:locale-config default-locale="fr_CA"
supported-locales="fr_CA fr_FR en"/>
+ List<Locale> supportedLocales = new ArrayList<Locale>();
+ for (Iterator<Locale> iter =
getFacesContext().getApplication().getSupportedLocales(); iter.hasNext();)
+ {
+ supportedLocales.add(iter.next());
+ }
+ assert supportedLocales.size() == 3;
+ assert supportedLocales.contains(Locale.CANADA_FRENCH);
+ assert supportedLocales.contains(Locale.ENGLISH);
+ assert supportedLocales.contains(Locale.FRANCE);
+ assert
getFacesContext().getApplication().getDefaultLocale().equals(Locale.CANADA_FRENCH);
+
+ // why not? I guess be default locale means different things in different
contexts (server vs user)
+ //assert
org.jboss.seam.international.Locale.instance().equals(Locale.CANADA_FRENCH);
+
+ // reset the locale configuration (as it would be w/o
<i18n:locale-config>)
+ getFacesContext().getApplication().setDefaultLocale(Locale.ENGLISH);
+ getFacesContext().getApplication().setSupportedLocales(null);
+
assert
org.jboss.seam.international.Locale.instance().equals(Locale.getDefault());
LocaleSelector.instance().setLocale(Locale.UK);