Mercurial > pub > Impl
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 |
