MappedCountry with ISO 2-letter Country Codes?

967 views
Skip to first unread message

Franz Bettag

unread,
Feb 8, 2012, 6:00:09 AM2/8/12
to lif...@googlegroups.com
Morning,

i've really been working a lot with countries in mapper-objects lately, now i've got another challenge which is to import a country based on the 2-letter ISO Code.

I thought that maybe the Country-Codes in https://github.com/lift/framework/blob/master/persistence/mapper/src/main/scala/net/liftweb/mapper/MappedPostalCode.scala are ISO Codes, but it turns out they are not :/

Is there any way to get a Mapping from ISO to net.liftweb.mapper.Countries? Otherwise i'll have to come up with something  ;)

thanks in advance!

Richard Dallaway

unread,
Feb 8, 2012, 6:35:32 AM2/8/12
to lif...@googlegroups.com
Looks like you'll need to do that yourself, although I'd like to know what the codes are too: I think they are arbitrary to match up the the country names in framework/web/webkit/src/main/resources/i18n/lift-core.properties

This might seem odd as you can get those resources from the VM:

scala> import java.util._

scala> Locale.UK.getDisplayCountry
res0: java.lang.String = United Kingdom

scala> Locale.UK.getDisplayCountry(Locale.FRANCE)
res1: java.lang.String = Royaume-Uni

scala> Locale.UK.getLanguage
res2: java.lang.String = en

scala> Locale.UK.getCountry
res3: java.lang.String = GB


…but country codes change, and possibly the VM doesn't have everything, or might not be relied on for non-international installs, so doesn't hurt to keep a separate numbering system and lookup.

Perhaps you can use the translations to get the instances of Countries? This looks iffy to me but might get somewhere:

List("de", "fr", "gb").map( cc => new Locale("en", cc).getDisplayCountry ).flatMap( c => Countries.values.find(_.toString == c) )
res16: List[net.liftweb.mapper.Countries.Value] = List(Germany, France, United Kingdom)

Yuk… but perhaps useful for generating lookup code:

List("de", "fr", "gb").map( cc => new Locale("en", cc).getDisplayCountry ).flatMap( c => Countries.values.find(_.toString == c) ).map(_.id)
res21: List[Int] = List(65, 61, 184)

i.e C65 is Germany.

Richard


On Wednesday, 8 February 2012 at 11:00, Franz Bettag wrote:

> Morning,
>
> i've really been working a lot with countries in mapper-objects lately, now i've got another challenge which is to import a country based on the 2-letter ISO Code.
>
> I thought that maybe the Country-Codes in https://github.com/lift/framework/blob/master/persistence/mapper/src/main/scala/net/liftweb/mapper/MappedPostalCode.scala are ISO Codes, but it turns out they are not :/
>

> Is there any way to get a Mapping from ISO to net.liftweb.mapper.Countries (http://web.mapper.Countries)? Otherwise i'll have to come up with something ;)
>
> thanks in advance!
>
> --
> Lift, the simply functional web framework: http://liftweb.net
> Code: http://github.com/lift
> Discussion: http://groups.google.com/group/liftweb
> Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

Franz Bettag

unread,
Feb 8, 2012, 7:16:15 AM2/8/12
to lif...@googlegroups.com
Thank you! Exactly what i was looking for! Should have dug deeper into the docs. sorry!

Peter Robinett

unread,
Feb 8, 2012, 9:51:45 AM2/8/12
to lif...@googlegroups.com
Interesting. For Miogiro I just made a Scala Enumeration with all the ISO 3166-1 alpha-2 two letter country codes from http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2.

It works fine, though I I guess I probably should be using the standard Java stuff, though I think the reason I didn't is that there don't seem to country objects independent of locales.

Peter

Franz Bettag

unread,
Feb 9, 2012, 9:31:07 AM2/9/12
to lif...@googlegroups.com
Seems like am a bit slow with this matter, i have my issues with java.util.Locale *grmpf*

you don't happen to have an idea for the exact way back? :s so from getting to Countries.Value to "de" or "gb"?

thanks in advance

Richard Dallaway

unread,
Feb 9, 2012, 10:30:35 AM2/9/12
to lif...@googlegroups.com
Just a comment: are the Countries I18N values really a good fit for your app? I liked Peter's idea of having a enumeration just for ISO codes - heck, even a VARCHAR(2) seems reasonable :-)

Franz Bettag

unread,
Feb 9, 2012, 10:46:00 AM2/9/12
to lif...@googlegroups.com
the goal is to get as far as possible with lift base components, also prolly only 4-5 countries will be effectively used. Reinventing the wheel doesn't seem necessary :)

Richard Dallaway

unread,
Feb 9, 2012, 11:58:49 AM2/9/12
to lif...@googlegroups.com
If it's a handful, I'd be tempted to hand code a lookup somewhere.

This goes from Country to a Locale…but...

scala> Locale.getAvailableLocales.find( _.getDisplayCountry == Countries.UK.toString)
res19: Option[java.util.Locale] = Some(en_GB)

…has pain written all over it. It's matching against a I18N resource name ("United Kingdom" in this case) so you want to be careful what locale you're running in. Good luck! :-)

--
http://richard.dallaway.com


On Thursday, 9 February 2012 at 15:46, Franz Bettag wrote:

> the goal is to get as far as possible with lift base components, also prolly only 4-5 countries will be effectively used. Reinventing the wheel doesn't seem necessary :)
>

Franz Bettag

unread,
Feb 9, 2012, 4:04:42 PM2/9/12
to lif...@googlegroups.com
thank you! 

Peter Robinett

unread,
Feb 9, 2012, 7:02:29 PM2/9/12
to lif...@googlegroups.com
If you're using Enums you can do something like:

def getCountry(code: String) = {
  if (Country.values.exists((country) => country.toString == code)) Some(Country.withName(code))
  else None
}

Here's how I do it with parser combinators:

lazy val countryCode: Parser[Country.Value] = """\w+""".r ^? ({
    // if lower-cased
    case str if Country.values.exists((ctry) => ctry.toString == str) => Country.withName(str)
    // if upper-cased
    case str if Country.values.exists((ctry) => ctry.toString.toUpperCase == str) => Country.withName(str.toLowerCase)
  }, "Unknown country code: " + _)

Hope that helps.

Peter
Reply all
Reply to author
Forward
0 new messages