Mercurial > pub > Impl
view Lib/IMPL/Web/Application/ResourceContract.pm @ 228:431db7034a88
Для синхронизации
author | andrei <andrei@nap21.upri> |
---|---|
date | Thu, 13 Sep 2012 17:55:01 +0400 |
parents | 70ad6bc20908 |
children | 47f77e6409f7 |
line wrap: on
line source
package IMPL::Web::Application::ResourceContract; use strict; use IMPL::lang qw(:declare); use IMPL::declare { require => { 'Exception' => 'IMPL::Exception', 'ArgumentException' => '-IMPL::ArgumentException', 'KeyNotFoundException' => '-IMPL::KeyNotFoundException', 'ResourceClass' => 'IMPL::Web::Application::Resource' }, base => [ 'IMPL::Object' => undef ] }; BEGIN { public property resourceFactory => PROP_ALL; public property operations => PROP_ALL; private property _namedResources => PROP_ALL; private property _regexpResources => PROP_ALL | PROP_LIST; } sub CTOR { my $this = shift; my %args = @_; $this->resourceFactory( $args{resourceFactory} || ResourceClass ); my $resources = $args{resources} || []; my $operations = $args{operations} || {}; die ArgumentException->new(resources => 'resources parameter must be a reference to an array') unless ref $resources eq 'ARRAY'; die ArgumentException->new(opearations => 'operations parameter must be a reference to a hash') unless ref $operations eq 'HASH'; my %nameMap; foreach my $res (@$resources) { next unless $res->{contract}; if(my $name = $res->{name}) { $nameMap{$name} = $res; } if($res->{match}) { $this->_regexpResources->Append($res); } } $this->_namedResources(\%nameMap); } sub CreateResource { my $this = shift; my %args = @_; return $this->resourceFactory->new ( %args, contract => $this ); } sub FindChildResourceContractInfo { my ($this,$name) = @_; if(my $contract = $this->_namedResources->{$name}) { return $contract; } else { foreach my $info ( $this->_regexpResources ) { my $rx = $info->{match}; return $info if $name =~ m/$rx/; } } return undef; } sub CreateChildResource { my $this = @_; my %args = @_; my $id = $args{id} or die ArgumentException( id => 'id parameter must be specified'); my $parent = $args{parent}; my $model = $parent->model if $parent; my $binding, $childContract, @bindingVars; if(my $info = $this->_namedResources->{$id}) { @bindingVars = ($id); $childContract = $info->{contract}; $binding = $info->{bind}; } else { foreach my $info ( $this->_regexpResources ) { my $rx = $info->{match}; next unless $rx; if( @bindingVars = ($id =~ m/$rx/) ) { $childContract = $info->{contract}; $binding = $info->{bind}; } } } if ($childContract) { my $childModel = $binding ? $binding->($parent,$model,@bindingVars) : undef; return $childContract->CreateResource( %args, model => $childModel ); } else { die KeyNotFoundException->new($id); } } 1; __END__ =pod =head1 NAME C<IMPL::Web::Application::ResourceContract> - описание ресурса =head1 SYNIOSIS =begin code use IMPL::require { ResourceContract => 'IMPL::Web::Application::ResourceContract', OperationContract => 'IMPL::Web::Application::OperationContract' }; my $contract = ResourceContract->new( operations => { get => OperationContract->new( bind => sub { return "Hello!"; } ) }, resources => [ { name => 'info', bind => sub { return $_[0]->model->info; }, contract => ResourceContract->new( get => OperationContract->new( bind => sub { my ($resource,$model) = @_; return $model; # or the same: $resource->model; } ) ) } ] ) my $obj = My::App::Data->fetch('something'); my $resource = $contract->CreateResource( model => $obj, parent => $prentResource, id => 'item-something' ); my $child = $contract->CreateChildResource( parent => $resource, id => 'info' ); =end code =head1 DESCRIPTION =cut