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