Skip to content

Commit

Permalink
Merge pull request playframework#509 from nemecec/i18n
Browse files Browse the repository at this point in the history
use realistic values for accept-language header
  • Loading branch information
pepite committed May 10, 2012
2 parents 3b76e3f + c949cfc commit 21052ae
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 31 deletions.
40 changes: 29 additions & 11 deletions framework/src/play/i18n/Lang.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package play.i18n;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;

import play.Logger;
import play.Play;
import play.mvc.Http;
Expand Down Expand Up @@ -89,26 +92,33 @@ public static void change(String locale) {
* @param desiredLocales a collection of desired locales. If the collection is ordered, earlier locales are preferred over later ones.
* Locales should be of the form "[language]_[country" or "[language]", e.g. "en_CA" or "en".
* The locale strings are case insensitive (e.g. "EN_CA" is considered the same as "en_ca").
* Locales can also be of the form "[language]-[country", e.g. "en-CA" or "en".
* They are still case insensitive, though (e.g. "EN-CA" is considered the same as "en-ca").
* @return the closest matching locale. If no closest match for a language/country is found, null is returned
*/
private static String findClosestMatch(Iterable<String> desiredLocales) {
private static String findClosestMatch(Collection<String> desiredLocales) {
ArrayList<String> cleanLocales = new ArrayList<String>(desiredLocales.size());
//look for an exact match
for (String a: desiredLocales) {
a = a.replace("-", "_");
cleanLocales.add(a);
for (String locale: Play.langs) {
if (locale.equalsIgnoreCase(a)) {
return locale;
}
}
}
// Exact match not found, try language-only match.
for (String a: desiredLocales) {
if (a.indexOf("_") > 0) {
a = a.substring(0, a.indexOf("_"));
for (String a: cleanLocales) {
int splitPos = a.indexOf("_");
if (splitPos > 0) {
a = a.substring(0, splitPos);
}
for (String locale: Play.langs) {
String langOnlyLocale;
if (locale.indexOf("_") > 0) {
langOnlyLocale = locale.substring(0, locale.indexOf("_"));
int localeSplitPos = locale.indexOf("_");
if (localeSplitPos > 0) {
langOnlyLocale = locale.substring(0, localeSplitPos);
} else {
langOnlyLocale = locale;
}
Expand Down Expand Up @@ -171,21 +181,29 @@ public static void setDefaultLocale() {
* associated to the current Lang.
*/
public static Locale getLocale() {
String lang = get();
Locale locale = getLocale(lang);
String localeStr = get();
Locale locale = getLocale(localeStr);
if (locale != null) {
return locale;
}
return Locale.getDefault();
}

public static Locale getLocale(String lang) {
public static Locale getLocale(String localeStr) {
Locale langMatch = null;
for (Locale locale : Locale.getAvailableLocales()) {
if (locale.getLanguage().equals(lang)) {
String lang = localeStr;
int splitPos = lang.indexOf("_");
if (splitPos > 0) {
lang = lang.substring(0, splitPos);
}
if (locale.toString().equalsIgnoreCase(localeStr)) {
return locale;
} else if (locale.getLanguage().equalsIgnoreCase(lang)) {
langMatch = locale;
}
}
return null;
return langMatch;
}

}
52 changes: 32 additions & 20 deletions framework/test-src/play/i18n/LangTest.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package play.i18n;

import static org.fest.assertions.Assertions.assertThat;

import java.util.Arrays;
import java.util.Locale;

import org.junit.Test;

import play.Play;
import play.PlayBuilder;
import play.mvc.Http;
import play.test.FunctionalTest;

import java.util.ArrayList;
import java.util.Arrays;

import static org.fest.assertions.Assertions.*;

public class LangTest {

@Test
Expand Down Expand Up @@ -48,7 +49,7 @@ public void testChange() {
@Test
public void testGet() {
new PlayBuilder().build();
Play.langs = Arrays.asList("no", "en", "en_uk", "fr");
Play.langs = Arrays.asList("no", "en", "en_GB", "fr");
Lang.current.set(null);

Http.Response.current.set( new Http.Response());
Expand All @@ -61,44 +62,50 @@ public void testGet() {
Http.Request req = FunctionalTest.newRequest();
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("no");
assertLocale(new Locale("no"));

// check only with accept-language, without cookie value
req = FunctionalTest.newRequest();
req.headers.put("accept-language", new Http.Header("accept-language", "x"));
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("no");
assertLocale(new Locale("no"));

req = FunctionalTest.newRequest();
req.headers.put("accept-language", new Http.Header("accept-language", "no"));
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("no");
assertLocale(new Locale("no"));

req = FunctionalTest.newRequest();
req.headers.put("accept-language", new Http.Header("accept-language", "en"));
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("en");
assertLocale(new Locale("en"));

req = FunctionalTest.newRequest();
req.headers.put("accept-language", new Http.Header("accept-language", "x,en"));
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("en");
assertLocale(new Locale("en"));

req = FunctionalTest.newRequest();
req.headers.put("accept-language", new Http.Header("accept-language", "en-GB"));
Http.Request.current.set(req);
Lang.current.set(null);
assertLocale(new Locale("en", "GB"));

req = FunctionalTest.newRequest();
req.headers.put("accept-language", new Http.Header("accept-language", "en_uk"));
req.headers.put("accept-language", new Http.Header("accept-language", "x,en-GB"));
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("en_uk");
assertLocale(new Locale("en", "GB"));

req = FunctionalTest.newRequest();
req.headers.put("accept-language", new Http.Header("accept-language", "x,en_uk"));
req.headers.put("accept-language", new Http.Header("accept-language", "x,en-US"));
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("en_uk");
assertLocale(new Locale("en"));

// check with cookie value

Expand All @@ -111,32 +118,37 @@ public void testGet() {
req.headers.put("accept-language", new Http.Header("accept-language", "en"));
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("en");
assertLocale(new Locale("en"));

cookie = new Http.Cookie();
cookie.name = "PLAY_LANG";
cookie.value = "en";
req.cookies.put(cookie.name, cookie);
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("en");
assertLocale(new Locale("en"));

cookie = new Http.Cookie();
cookie.name = "PLAY_LANG";
cookie.value = "en_q";
req.cookies.put(cookie.name, cookie);
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("en");
assertLocale(new Locale("en"));

cookie = new Http.Cookie();
cookie.name = "PLAY_LANG";
cookie.value = "en_uk";
cookie.value = "en_GB";
req.cookies.put(cookie.name, cookie);
Http.Request.current.set(req);
Lang.current.set(null);
assertThat(Lang.get()).isEqualTo("en_uk");
assertLocale(new Locale("en", "GB"));


}

private void assertLocale(Locale locale) {
assertThat(Lang.get()).isEqualTo(locale.toString());
assertThat(Lang.getLocale()).isEqualTo(locale);
}
}

0 comments on commit 21052ae

Please sign in to comment.