Mercurial > pub > Impl
view lib/IMPL/Resources/StringLocaleMap.pm @ 417:3ed0c58e9da3 ref20150831
working on di container, tests
author | cin |
---|---|
date | Mon, 02 Nov 2015 01:56:53 +0300 |
parents | c6e90e02dd17 |
children |
line wrap: on
line source
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;