407
|
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; |