Mercurial > pub > Impl
diff lib/IMPL/Resources/StringLocaleMap.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/IMPL/Resources/StringLocaleMap.pm Fri Sep 04 19:40:23 2015 +0300 @@ -0,0 +1,143 @@ +package IMPL::Resources::StringLocaleMap; +use strict; + +use List::Util qw(first); +use IMPL::lang qw(:base); +use IMPL::Const qw(:prop); +use IMPL::declare { + require => { + Resources => 'IMPL::Resources', + StringMap => 'IMPL::Resources::StringMap', + Exception => 'IMPL::Exception', + FS => 'File::Spec' + }, + base => { + 'IMPL::Object' => '@_' + }, + props => [ + _maps => PROP_RW, + name => PROP_RW, + paths => PROP_RW | PROP_LIST + ] +}; + +sub CTOR { + my ($this,$data,$parent) = @_; + + if (is($data, StringMap)) { + $this->_maps({ default => $data }); + } elsif ( ref($data) eq 'HASH' ) { + $this->_maps({ default => StringMap->new($data,$parent)}); + } else { + # в данном случае таблица строк по-умолчанию будет загружена + # из файла при необходимости + $this->_maps({}); + } +} + +sub GetString { + my ($this,$id,$args) = @_; + + my $locale = Resources->currentLocale || 'default'; + my $map; + + #warn "id: $id,\t\tlocale: $locale"; + + if(not $map = $this->_maps->{$locale}) { + my $default = $this->GetDefaultMap(); + $map = $this->LoadMap($locale,$default); + if (is($map,StringMap)) { + #nop + } elsif (ref($map) eq 'HASH') { + $map = StringMap->new($map,$default); + } elsif( not $map ) { + $map = $default; + } else { + die Exception->new("ResolveLocale returned unexpected data", $map); + } + + $this->_maps->{$locale} = $map; + } + + return $map->GetString($id,$args); +} + +sub GetDefaultMap { + my ($this) = @_; + + my $map = $this->_maps->{default}; + return $map + if $map; + + $map = $this->LoadMap('default') || StringMap->new({}); + $this->_maps->{default} = $map; + + return $map; +} + +sub LoadMap { + my ($this,$locale,$default) = @_; + + my @spec = split /_/, $locale; + + my @locales; + + do { + push @locales, join('_', @spec); + } while(pop @spec); + + my $file = first { -f } map { + my $path = $_; + + map { + my $name = FS->catfile($path,$_,$this->name); + ("$name.s", "$name.p"); + } @locales; + } $this->paths; + + if($file) { + if ($file =~ /\.s$/) { + return $this->LoadStringMap($file); + } else { + return $this->LoadPerlMap($file,$default); + } + } + + return; +} + +sub LoadPerlMap { + my ($self,$file,$parent) = @_; + + my $data = do $file; + my $e = $@; + die Exception->new("Failed to load file '$file'", $e) if $e; + die IOException->new("Failed to load file '$file'", $!) if not defined $data and $!; + die Exception->new("Failed to load file '$file'", "A hash data is expected") unless ref($data) eq 'HASH'; + + return StringMap->new($data,$parent); +} + +sub LoadStringMap { + my ($this,$fname) = @_; + + open my $hRes, "<:encoding(utf-8)", $fname or die "Failed to open file $fname: $!"; + local $_; + my %map; + my $line = 1; + while (<$hRes>) { + chomp; + $line ++ and next if /^\s*$/; + + if (/^([\w\.]+)\s*=\s*(.*)$/) { + $map{$1} = $2; + } else { + die "Invalid resource format in $fname at $line"; + } + $line ++; + } + + return \%map; +} + +1; \ No newline at end of file