comparison lib/IMPL/Resources/StringLocaleMap.pm @ 407:c6e90e02dd17 ref20150831

renamed Lib->lib
author cin
date Fri, 04 Sep 2015 19:40:23 +0300
parents
children
comparison
equal deleted inserted replaced
406:f23fcb19d3c1 407:c6e90e02dd17
1 package IMPL::Resources::StringLocaleMap;
2 use strict;
3
4 use List::Util qw(first);
5 use IMPL::lang qw(:base);
6 use IMPL::Const qw(:prop);
7 use IMPL::declare {
8 require => {
9 Resources => 'IMPL::Resources',
10 StringMap => 'IMPL::Resources::StringMap',
11 Exception => 'IMPL::Exception',
12 FS => 'File::Spec'
13 },
14 base => {
15 'IMPL::Object' => '@_'
16 },
17 props => [
18 _maps => PROP_RW,
19 name => PROP_RW,
20 paths => PROP_RW | PROP_LIST
21 ]
22 };
23
24 sub CTOR {
25 my ($this,$data,$parent) = @_;
26
27 if (is($data, StringMap)) {
28 $this->_maps({ default => $data });
29 } elsif ( ref($data) eq 'HASH' ) {
30 $this->_maps({ default => StringMap->new($data,$parent)});
31 } else {
32 # в данном случае таблица строк по-умолчанию будет загружена
33 # из файла при необходимости
34 $this->_maps({});
35 }
36 }
37
38 sub GetString {
39 my ($this,$id,$args) = @_;
40
41 my $locale = Resources->currentLocale || 'default';
42 my $map;
43
44 #warn "id: $id,\t\tlocale: $locale";
45
46 if(not $map = $this->_maps->{$locale}) {
47 my $default = $this->GetDefaultMap();
48 $map = $this->LoadMap($locale,$default);
49 if (is($map,StringMap)) {
50 #nop
51 } elsif (ref($map) eq 'HASH') {
52 $map = StringMap->new($map,$default);
53 } elsif( not $map ) {
54 $map = $default;
55 } else {
56 die Exception->new("ResolveLocale returned unexpected data", $map);
57 }
58
59 $this->_maps->{$locale} = $map;
60 }
61
62 return $map->GetString($id,$args);
63 }
64
65 sub GetDefaultMap {
66 my ($this) = @_;
67
68 my $map = $this->_maps->{default};
69 return $map
70 if $map;
71
72 $map = $this->LoadMap('default') || StringMap->new({});
73 $this->_maps->{default} = $map;
74
75 return $map;
76 }
77
78 sub LoadMap {
79 my ($this,$locale,$default) = @_;
80
81 my @spec = split /_/, $locale;
82
83 my @locales;
84
85 do {
86 push @locales, join('_', @spec);
87 } while(pop @spec);
88
89 my $file = first { -f } map {
90 my $path = $_;
91
92 map {
93 my $name = FS->catfile($path,$_,$this->name);
94 ("$name.s", "$name.p");
95 } @locales;
96 } $this->paths;
97
98 if($file) {
99 if ($file =~ /\.s$/) {
100 return $this->LoadStringMap($file);
101 } else {
102 return $this->LoadPerlMap($file,$default);
103 }
104 }
105
106 return;
107 }
108
109 sub LoadPerlMap {
110 my ($self,$file,$parent) = @_;
111
112 my $data = do $file;
113 my $e = $@;
114 die Exception->new("Failed to load file '$file'", $e) if $e;
115 die IOException->new("Failed to load file '$file'", $!) if not defined $data and $!;
116 die Exception->new("Failed to load file '$file'", "A hash data is expected") unless ref($data) eq 'HASH';
117
118 return StringMap->new($data,$parent);
119 }
120
121 sub LoadStringMap {
122 my ($this,$fname) = @_;
123
124 open my $hRes, "<:encoding(utf-8)", $fname or die "Failed to open file $fname: $!";
125 local $_;
126 my %map;
127 my $line = 1;
128 while (<$hRes>) {
129 chomp;
130 $line ++ and next if /^\s*$/;
131
132 if (/^([\w\.]+)\s*=\s*(.*)$/) {
133 $map{$1} = $2;
134 } else {
135 die "Invalid resource format in $fname at $line";
136 }
137 $line ++;
138 }
139
140 return \%map;
141 }
142
143 1;