Mercurial > pub > Impl
diff lib/IMPL/Resources/StringMap.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/IMPL/Resources/StringMap.pm Fri Sep 04 19:40:23 2015 +0300 @@ -0,0 +1,140 @@ +package IMPL::Resources::StringMap; +use strict; + +use IMPL::Const qw(:prop); +use IMPL::declare { + require => { + Exception => 'IMPL::Exception', + IOException => '-IMPL::IOException', + ArgException => '-IMPL::InvalidArgumentException' + }, + base => [ + 'IMPL::Object' => '@_' + ], + props => [ + _data => PROP_RW, + _parent => PROP_RW + ] +}; + +sub CTOR { + my ($this,$data,$parent) = @_; + + die ArgException->new( data => 'A hash reference is required' ) + unless ref($data) eq 'HASH'; + + die ArgException->new( data => 'A hash must contain either scalars or subs') + if grep ref($_) && ref($_) ne 'CODE', values %$data; + + $this->_data($data); + $this->_parent($parent); +} + +sub GetString { + my ($this,$id,$args) = @_; + + if(my $format = $this->_data->{$id}) { + return ref($format) eq 'CODE' ? &$format($this,$args || {}) : $this->FormatString($format,$args); + } else { + return $this->_parent? $this->_parent->GetString($id,$args) : "[ $id ]"; + } + +} + +sub AddFormat { + my ($this,$id,$format) = @_; + + die ArgException->new( id => 'A format id is required' ) + unless $id; + + die ArgException->new( format => 'A format must be a scalar or a sub' ) + if ref($format) and ref($format) ne 'CODE'; + + $this->_data->{$id} = $format; +} + +sub FormatString { + my ($self,$text,$args) = @_; + + $args ||= {}; + $text ||= ''; + + $text =~ s/%(\w+(?:\.\w+)*)%/$self->GetValue($args,$1,"\[$1\]")/ge; + + return $text; + +} + +sub GetValue { + my ($self,$obj,$path,$default) = @_; + + foreach my $chunk (split /\./,$path) { + return $default unless $obj; + if (ref $obj eq 'HASH') { + $obj = $obj->{$chunk}; + } else { + $obj = $self->Resolve($obj,$chunk); + } + } + return $obj||'<undef>'; +} + +sub Resolve { + my ($self,$obj,$prop) = @_; + + return eval { $obj->$prop() }; +} + +1; + +__END__ + +=pod + +=head1 NAME + +C<IMPL::Web::Resources::StringMap> + +=head1 SYNOPSIS + +=begin code + +use IMPL::require { + StringMap => 'IMPL::Resources::StringMap' +}; + +my $data = { + TitleLabel => 'Search results', + ViewLabel => 'View %name%', # same as sub { $_[0]->Format('View %name%',$_[1]) } + ResultsCountLabel => sub { + my ($self,$args) = @_; + + $args ||= {}; + + if (not $args->{count}) { + return "No items found"; + } elsif($args->{count} == 1) { + return "Found one item"; + } else { + return $self->Format('Found %count% items', $args); + } + } +} + +my $def = StringMap->new({ + ResultsCountLabel => 'Found %count% items' +}); + +my $map = StringMap->new($data, $def); + +print $map->GetString('TitleLabel'); +print $map->GetString(ResultsCountLabel => { count => 0 }); # will print "No items found" + + +=end code + +=head1 DESCRIPTION + +=head1 MEMBERS + +=cut \ No newline at end of file