comparison lib/IMPL/Resources/StringMap.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::StringMap;
2 use strict;
3
4 use IMPL::Const qw(:prop);
5 use IMPL::declare {
6 require => {
7 Exception => 'IMPL::Exception',
8 IOException => '-IMPL::IOException',
9 ArgException => '-IMPL::InvalidArgumentException'
10 },
11 base => [
12 'IMPL::Object' => '@_'
13 ],
14 props => [
15 _data => PROP_RW,
16 _parent => PROP_RW
17 ]
18 };
19
20 sub CTOR {
21 my ($this,$data,$parent) = @_;
22
23 die ArgException->new( data => 'A hash reference is required' )
24 unless ref($data) eq 'HASH';
25
26 die ArgException->new( data => 'A hash must contain either scalars or subs')
27 if grep ref($_) && ref($_) ne 'CODE', values %$data;
28
29 $this->_data($data);
30 $this->_parent($parent);
31 }
32
33 sub GetString {
34 my ($this,$id,$args) = @_;
35
36 if(my $format = $this->_data->{$id}) {
37 return ref($format) eq 'CODE' ? &$format($this,$args || {}) : $this->FormatString($format,$args);
38 } else {
39 return $this->_parent? $this->_parent->GetString($id,$args) : "[ $id ]";
40 }
41
42 }
43
44 sub AddFormat {
45 my ($this,$id,$format) = @_;
46
47 die ArgException->new( id => 'A format id is required' )
48 unless $id;
49
50 die ArgException->new( format => 'A format must be a scalar or a sub' )
51 if ref($format) and ref($format) ne 'CODE';
52
53 $this->_data->{$id} = $format;
54 }
55
56 sub FormatString {
57 my ($self,$text,$args) = @_;
58
59 $args ||= {};
60 $text ||= '';
61
62 $text =~ s/%(\w+(?:\.\w+)*)%/$self->GetValue($args,$1,"\[$1\]")/ge;
63
64 return $text;
65
66 }
67
68 sub GetValue {
69 my ($self,$obj,$path,$default) = @_;
70
71 foreach my $chunk (split /\./,$path) {
72 return $default unless $obj;
73 if (ref $obj eq 'HASH') {
74 $obj = $obj->{$chunk};
75 } else {
76 $obj = $self->Resolve($obj,$chunk);
77 }
78 }
79 return $obj||'<undef>';
80 }
81
82 sub Resolve {
83 my ($self,$obj,$prop) = @_;
84
85 return eval { $obj->$prop() };
86 }
87
88 1;
89
90 __END__
91
92 =pod
93
94 =head1 NAME
95
96 C<IMPL::Web::Resources::StringMap>
97
98 =head1 SYNOPSIS
99
100 =begin code
101
102 use IMPL::require {
103 StringMap => 'IMPL::Resources::StringMap'
104 };
105
106 my $data = {
107 TitleLabel => 'Search results',
108 ViewLabel => 'View %name%', # same as sub { $_[0]->Format('View %name%',$_[1]) }
109 ResultsCountLabel => sub {
110 my ($self,$args) = @_;
111
112 $args ||= {};
113
114 if (not $args->{count}) {
115 return "No items found";
116 } elsif($args->{count} == 1) {
117 return "Found one item";
118 } else {
119 return $self->Format('Found %count% items', $args);
120 }
121 }
122 }
123
124 my $def = StringMap->new({
125 ResultsCountLabel => 'Found %count% items'
126 });
127
128 my $map = StringMap->new($data, $def);
129
130 print $map->GetString('TitleLabel');
131 print $map->GetString(ResultsCountLabel => { count => 0 }); # will print "No items found"
132
133
134 =end code
135
136 =head1 DESCRIPTION
137
138 =head1 MEMBERS
139
140 =cut