annotate lib/IMPL/Resources/StringLocaleMap.pm @ 410:9335cf010b23 ref20150831

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