Mercurial > pub > Impl
view Lib/IMPL/Resources/StringMap.pm @ 379:a471e8b77544
sync
author | cin |
---|---|
date | Thu, 16 Jan 2014 18:10:50 +0400 |
parents | 2eed076cb944 |
children | ced5937ff21a |
line wrap: on
line source
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->can($prop) } ? $obj->$prop() : undef ); } 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