view Lib/IMPL/Resources/StringMap.pm @ 376:a54a2faf2f7e

added localizable string maps
author cin
date Mon, 13 Jan 2014 17:52:04 +0400
parents
children a0d342ac9a36
line wrap: on
line source

package IMPL::Web::Resources::StringMap;
use strict;

use IMPL::Const qw(:prop);
use IMPL::declare {
	require => {
		Exception => 'IMPL::Exception',
		IOException => '-IMPL::IOException',
		ArgException => '-IMPL::InvalidArgumentException'
	},
	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 not($_) || (ref($_) and ref($_) ne 'CODE'), values %$data;
	
	$this->_data($data);
	$this->_parent($parent);
}

sub GetString {
	my ($this,$id,$args) = @_;
	
	if(my $format = $this->_data->{$id}) {
		return $this->FormatString($format,$args);
	} else {
		return $this->_parent? $this->_parent->GetString($id,$args) : "[$id]";
	}
	
}

sub FormatString {
	my ($self,$text,$args) = @_;
    
    $args ||= {};
    $resolver ||= \&_defaultResolver;
    $text ||= '';
    
    $string =~ s/%(\w+(?:\.\w+)*)%/$self->GetValue($args,$1,"\[$1\]")/ge;
    
    return $string;
	
}

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 );
}

sub _LoadMap {
	my ($self,$file,$parent) = @_;
	
	my $data = do $file;
	my $e = $@;
	die Exception->new("Failed to load file '$file'", $e) if $e;
	die IOException->new("Failed to load file '$file'", $!) if not defined $data and $!;
	die Exception->new("Failed to load file '$file'", "A hash data is expected") unless ref($data) eq 'HASH';
	
	return $self->new($data,$parent);
}

1;

__END__

=pod 

=head1 NAME

C<IMPL::Web::Resources::StringMap>

=head1 SYNOPSIS

My/App/locale/default/Search.labels

My/App/locale/en/Search.map

=begin code

{
	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);
		}
	}
}

=end code

=head1 DESCRIPTION

=head

=cut