Mercurial > pub > Impl
changeset 331:2ff1726c066c
removed operation contract (due it's useless)
author | cin |
---|---|
date | Wed, 05 Jun 2013 18:21:11 +0400 |
parents | fe725fad2d90 |
children | 04a093f0a5a6 |
files | Lib/IMPL/Web/Application/CustomResourceContract.pm Lib/IMPL/Web/Application/OperationContract.pm Lib/IMPL/Web/Application/ResourceContract.pm |
diffstat | 3 files changed, 12 insertions(+), 194 deletions(-) [+] |
line wrap: on
line diff
--- a/Lib/IMPL/Web/Application/CustomResourceContract.pm Tue Jun 04 19:25:54 2013 +0400 +++ b/Lib/IMPL/Web/Application/CustomResourceContract.pm Wed Jun 05 18:21:11 2013 +0400 @@ -4,8 +4,7 @@ use IMPL::Const qw(:prop); use IMPL::declare { require => { - NotAllowedException => 'IMPL::Web::NotAllowedException', - OperationContract => 'IMPL::Web::Application::OperationContract' + NotAllowedException => 'IMPL::Web::NotAllowedException' }, base => [ 'IMPL::Web::Application::ResourceContract' => '@_' @@ -23,21 +22,18 @@ sub CTOR { my ($this) = @_; - $this->verbs->{options} ||= OperationContract->new( binding => \&_HttpOptionsBinding ); + $this->verbs->{options} ||= \&_HttpOptionsBinding; while(my ($verb,$methodName) = each %RESOURCE_BINDINGS) { - $this->verbs->{lc($verb)} ||= OperationContract->new ( - binding => sub { - my ($resource,$action) = @_; - - if (eval { $resource->can($methodName) }) { - return $resource->$methodName($action); - } else { - die NotAllowedException->new(allow => join(',', _GetAllowedHttpMethods($resource))); - } - + $this->verbs->{lc($verb)} ||= sub { + my ($resource,$action) = @_; + + if (eval { $resource->can($methodName) }) { + return $resource->$methodName($action); + } else { + die NotAllowedException->new(allow => join(',', _GetAllowedHttpMethods($resource))); } - ); + } } }
--- a/Lib/IMPL/Web/Application/OperationContract.pm Tue Jun 04 19:25:54 2013 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -package IMPL::Web::Application::OperationContract; -use strict; - -use IMPL::lang qw(:declare); -use IMPL::declare { - require => { - Exception => 'IMPL::Exception', - ArgumentException => '-IMPL::InvalidArgumentException', - ResourceInterface => 'IMPL::Web::Application::ResourceInterface' - }, - base => [ - 'IMPL::Object' => undef, - 'IMPL::Object::Autofill' => '@_' - ], - props => [ - binding => PROP_ALL, - success => PROP_ALL, - error => PROP_ALL - ] -}; - -sub Invoke { - my ( $this, $resource, $request ) = @_; - - die ArgumentException->new( resource => 'A valid resource is required' ) - unless eval { $resource->isa(ResourceInterface) }; - - my $result = eval { - _InvokeDelegate($this->binding, $resource, $request) - }; - - if (my $e = $@) { - if ($this->error) { - $result = _InvokeDelegate($this->error, $resource, $request, $e) ; - } else { - die $e; - } - - } else { - $result = _InvokeDelegate($this->success, $resource, $request, $result) - if ($this->success); - } - - return $result; -} - -sub _InvokeDelegate { - my $delegate = shift; - - return $delegate->(@_) if ref $delegate eq 'CODE'; - return $delegate->Invoke(@_) if eval { $delegate->can('Invoke')}; -} - -1; - -__END__ - -=pod - -=head1 NAME - -C<IMPL::Web::Application::OperationContract> - Описание операции над -веб-ресурсом. - -=head1 SYNOPSIS - -=begin code - -use IMPL::require { - 'OperationContract' => 'IMPL::Web::Application::OperationContract', - 'HttpReponse' => 'IMPL::Web::Application::HttpReponse' -}; - -my $operation = OperationContract->new( - binding => sub { - my ($resource,$request) = @_; - - my $itemName = $request->param('itemName', qr/^(\w+)$/); - - return $model->FindItem($itemName); - }, - success => sub { - my ($resource,$request,$result) = @_; - return HttpReponse->Redirect(location => $resource->location->Child($result->id)); - } -); - -my $response = $operation->InvokeOperation($resource); - -=end code - -=head1 DESCRIPTION - -Для описания контракта операции используется понятие делегата, тоесть объекта, -представляющего собой функцию, либо объект, имеющий метод C<Invoke>. - -Поскольку предметная область должна быть отделена от -контроллеров веб-сервиса, она ничего не знает про существование ресурсов и их -организацию и тем более о протоколе C<HTTP>, поэтому все вещи, связанные с -формированием ответов сервера, представлениями данных и т.п. должны выполняться -самими контроллерами. Поведение контроллеров описывается контрактами, в которых -указываются делегаты для реализации необходимого функционала, для корректного -отображения ресурсов в объекты предметной области и обратно. - -Контракт операции состоит из нескольких свойств, осуществляющих привязку к -предметной области: - -=over - -=item * C<binding> - -делегат для привязки операции над ресурсом к предметной области. - -=item * C<success> - -делегат для обработки результат операции, например для формирования ответа с -перенаправлением. - -=item * C<error> - -делегат для обработки исключительной ситуации, может быть использован для -формирования представления для повторного ввода данных на форме. - -=back - -=head1 MEMBERS - -=head2 C<[get,set] binding> - -Привязка операции к ресурсу, например - -=begin code - -$operationContract->binding(sub { - my ($resource,$action) = @_; - $resource->model -}) - -=end code - -Может быть как ссылка на процедуру, так и ссылкой на объект, имеющий метод -C<Invoke>. - -=head2 C<[get,set] success> - -Обрабатывает результат привязки к предметной области. - -=begin code - -# redirect (for example after POST) -$operationContract->success(sub { - my ($resource,$action,$result) = @_; - - return IMPL::Web::HttpResponse - ->Redirect($resource->location->Child($result->id)); -}) - -=end code - -Может быть как ссылка на процедуру, так и ссылкой на объект, имеющий метод -C<Invoke>. - -=head2 C<[get,set] error> - -Обрабатывает ошибку возникшую при выполнении привязки к предметной области. - -=begin - -$operationContract->error(sub { - my ($resource,$action,$error) = @_; - - $action->form->errors->{''} = $error; - - return $resource->model; -}); - -=end - -=cut
--- a/Lib/IMPL/Web/Application/ResourceContract.pm Tue Jun 04 19:25:54 2013 +0400 +++ b/Lib/IMPL/Web/Application/ResourceContract.pm Wed Jun 05 18:21:11 2013 +0400 @@ -44,7 +44,8 @@ foreach my $res (@$resources) { if (ref $res->{contract} eq 'HASH') { - $res->{contract} = __PACKAGE__->new(%{$res->{contract}}); + # custom contract will add OPTIONS verb if needed + $res->{contract} = CustomContract->new(%{$res->{contract}}); } next unless $res->{contract};