Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added useful method to get LocaleCode by country #2

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

cardil
Copy link

@cardil cardil commented Jan 31, 2013

Hi,
I've just added method to find first occurrence of LocaleCode by country ISO 3166-1 alpha-2 code.

@TakahikoKawasaki
Copy link
Owner

Thank you for your having interest in nv-i18n. It seems to me that getByCode(String language, String country, boolean caseSensitive) should keep the current implementation to ensure that it returns a non-null value only when it finds the one that exactly matches the pair of the given country code and language code. On the other hand, your idea to find LocaleCode instances by country sounds good and should be implemented in a generic way. So, I'll implement getByCountry methods that return a list of LocaleCode instances whose country matches the specified one. Thank you, anyway.

@cardil
Copy link
Author

cardil commented Jan 31, 2013

Good point. What about series of methods to the interface of enums:

  • enum LocaleCode
    • static Collection<LocaleCode> getByCountry(CountryCode code)
    • static Collection<LocaleCode> getByCountry(String code)
    • static Collection<LocaleCode> getByLanguage(LanguageCode language)
    • static Collection<LocaleCode> getByLanguage(String language)
    • static LocaleCode findByCountry(CountryCode code) - main locale ex.: GB -> en_GB
    • static LocaleCode findByCountry(String code) - main locale ex.: GB -> en_GB
    • static LocaleCode findByLanguage(LanguageCode language) - main locale ex.: en -> en_GB
    • static LocaleCode findByLanguage(String language) - main locale ex.: GB -> en_GB
  • enum CountryCode
    • Collection<LocaleCode> getLocales()
    • Collection<LanguageCode> getLanguages()
    • LanguageCode getMainLanguage()
    • static Collection<CountryCode> getCountries(LanguageCode language) ex.: en -> [GB, US, ...]
    • static CountryCode findRepresentingCountry(LanguageCode language) ex.: en -> GB
  • enum LanguageCode
    • Collection<LocaleCode> getLocales()
    • Collection<CountryCode> getCountries()
    • CountryCode getRepresentingCountry()
    • static Collection<LanguageCode> getLanguages(CountryCode country) ex.: ES -> [es, ca, gl, ...]
    • static LanguageCode getMainLanguage(CountryCode country) ex.: ES -> es

Of course, all of above as public. Thats many methods to implement. What do you think? I can help with it.

@TakahikoKawasaki
Copy link
Owner

Sometimes it is technically and/or politically difficult to select one main language from among multiple official languages. For example, Singapore has four official languages: English, Chinese, Malay and Tamil, and which language should be regarded as main depends on what criterion is selected. Likewise, it is difficult to select one representing country for a given language. Polish and Japanese are simple cases and it is easy to select representing countries (Poland and Japan) for these, but it is difficult to select a representing country for Arabic. Therefore, I'd like to avoid adding getMainLanguage and getRepresentingCountry methods.

Collection<?> getXxx() method candidates for CountryCode and LanguageCode (e.g. CountryCode.getLanguages()) would eventually have to refer to LocaleCode in their implementations. This implies that programmers can achieve the same functionalities by using LocaleCode.getByCountry and LocaleCode.getByLanguage. Therefore, it may be redundant to add getXxx() methods to CountryCode and LanguageCode. However, it may be worth adding such (redundant) alias methods for convenience, but at this moment, it is difficult for me to judge whether they are worth being added or not. Need some time to judge...

I think that your suggestion to add getByCountry and getByLanguage to LocaleCode is good.

* @return
* A LocaleCode instance, or null if not found.
*/
public static LocaleCode getByCountry(String country, boolean caseSensitive) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also create a

getByCountry(String country) 

which delegates to

getByCountry(country, false) . 

Same as what is done with the getByCode methods.

@TakahikoKawasaki
Copy link
Owner

New methods listed below:

List<LocaleCode> getByCountry(CountryCode)
List<LocaleCode> getByCountry(String)
List<LocaleCode> getByCountry(String, boolean)
List<LocaleCode> getByLanguage(LanguageCode)
List<LocaleCode> getByLanguage(String)
List<LocaleCode> getByLanguage(String, boolean)

were added to LocaleCode by:

6c69dae

Thank you for your suggestions.

Version 1.3 containing these methods is now able to be downloaded from Maven Central Repository. (but I forgot to change '1.2' to '1.3' in package-info.java... I'll fix the javadoc in the next release.)

@cardil
Copy link
Author

cardil commented Feb 1, 2013

Nice changes :-).

But about methods:

  • static CountryCode findRepresentingCountry(LanguageCode language)
  • static LanguageCode getMainLanguage(CountryCode country)

My story: I came up to a problem in my project to guess language based on internet address. I should print this language with SOME flag in select box(each language should has it flag). For ex.: addres http://example.eg --> country EG(Egypt) --> most popular/official language ar(Arabic) --> representative language country SA(Saudi Arabia). I know that this is not unambiguous to select SA(Saudi Arabia) as a representing country of language ar(Arabic) but this will be extremely useful in many cases. Every english teaching book has a GB flag on it, this connection is used in real life and in internet. Look at this Google query for example: http://bit.ly/WXDHbb or this Drupal plugin: http://drupal.org/project/languageicons (website installs: 25519)

If you don't like those methods, what do you think of sorting output of methods added in 6c69dae to represent most representative cases first? For ex.:

  • getByLanguage("en") --> [en, en_GB, en_US, en_AU, ...]
  • getByCountry("CH") --> [de_CH, fr_CH, it_CH]

BTW.: You can use junit assertArrayEquals( expectedResult, result ) to compare lists: http://stackoverflow.com/questions/4228161/comparing-arrays-in-junit-assertions-concise-built-in-way

BTW2.: I notice that there are several missing LocaleCode's. I was comparing languages that google translator supports with this list. Couple of them are not listed for ex.: af, az, eu, ... https://developers.google.com/translate/v2/using_rest?hl=pl#language-params

@TakahikoKawasaki
Copy link
Owner

Thank you for your informative comment, cardil.

Regarding main languages and representing countries, it still sounds to me that the logic to select them should be implemented in upper layers or in other middleware (e.g. libraries over nv-i18n, application layer, your geolocation-related services, etc.) than nv-i18n library. But, thank you for explaining me real-world requirements. It game me some insights.

JUnit API provides assertion methods for arrays, but I could not find assertion methods for List here: http://junit.sourceforge.net/javadoc/org/junit/Assert.html

The list of LocaleCode was generated based on the output from Locale.getAvailableLocales() of Java SE 7 as I wrote in the javadoc. The reason LocaleCode for 'af' is not contained is just because Locale.getAvailableLocales() does not contain it. However, there is no convincing reason to avoid adding LocaleCode for 'af'. I should consider how to treat these missing entries. I need some time to find consistent and convincing reasons to add or not to add the missing entries. Anyway, thank you for your pointing out the issue.

@cardil
Copy link
Author

cardil commented Feb 1, 2013

Ad. jUnit: New assertThat() methods:

import static org.junit.Assert.*;
import static org.hamcrest.core.Is.is;

class ListTest {

  @Test
  public void testListPass()
  {
    List<String> actual = Arrays.asList("fee", "fi", "foe");
    List<String> expected = Arrays.asList("fee", "fi", "foe");

    System.out.println(actual == expected);       // false
    assertThat(actual, is(expected));             // passes
  }
}

Peace!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants