Mercurial > pub > Impl
view Lib/IMPL/Web/Application/Action.pm @ 65:2840c4c85db8
Application configuration improvements
Documentation
author | wizard |
---|---|
date | Tue, 16 Mar 2010 17:36:13 +0300 |
parents | 76b878ad6596 |
children | 9f5795a10939 |
line wrap: on
line source
package IMPL::Web::Application::Action; use strict; use base qw(IMPL::Object IMPL::Object::Autofill); __PACKAGE__->PassThroughArgs; use IMPL::Class::Property; BEGIN { public property application => prop_get | owner_set; public property query => prop_get | owner_set; public property response => prop_get | owner_set; public property responseFactory => prop_get | owner_set; private property _entryPoint => prop_all; } sub CTOR { my ($this) = @_; $this->responseFactory('IMPL::Web::Application::Response') unless $this->responseFactory; $this->response( $this->responseFactory->new(query => $this->query) ); } sub Invoke { my ($this) = @_; if ($this->_entryPoint) { $this->_entryPoint->(); } else { die new IMPL::InvalidOperationException("At least one handler is required"); } } sub ReinitResponse { my ($this) = @_; die new IMPL::InvalidOperationException("Response already sent") if $this->response->isHeaderPrinted; $this->response->Discard; $this->response($this->responseFactory->new(query => $this->query)); } sub ChainHandler { my ($this,$handler) = @_; my $delegateNext = $this->_entryPoint(); if (ref $handler eq 'CODE') { $this->_entryPoint( sub { $handler->($this,$delegateNext); } ); } elsif (ref $handler and UNIVERSAL::isa($handler,'IMPL::Web::QueryHandler')) { $this->_entryPoint( sub { $handler->Invoke($this,$delegateNext); } ); } elsif ($handler and not ref $handler) { if (my $method = $this->can($handler) ) { $this->_entryPoint( sub { $method->($this,$delegateNext); } ); } else { { no strict 'refs'; eval "require $handler; 1;" or die new IMPL::InvalidArgumentException("An invalid handler supplied",$handler,"Failed to load module") unless keys %{"${handler}::"}; } if (UNIVERSAL::isa($handler,'IMPL::Web::QueryHandler')) { $this->_entryPoint( sub { $handler->Invoke($this,$delegateNext); } ); } else { die new IMPL::InvalidArgumentException("An invalid handler supplied",$handler); } } } else { die new IMPL::InvalidArgumentException("An invalid handler supplied",$handler); } } 1; __END__ =pod =head1 DESCRIPTION Определяет порядок выполнения запроса. Запрос выполняется последовательным вызовом цепочки обработчиков, при этом обработчики сами вызывают следующие. Типичная цепочка может быть такой, в порядке добавления SecCallToMethod($target,$method) AuthenticateMethod TDocumentOut($file) что приведет к следующей последовательности Action->Invoke() { TDocumentOut->Invoke($Action,$nextHandler) { my $result = $nextHandler() { $AuthenticateMethod($Action,$nextHandler) { my $context = $Action->application->security->Authenticate($Action->query,$Action->response); return $context->Impersonate($nextHandler) { $objSecCallToMethod->Invoke($Action,undef) { IMPL::Security->AccessCheck($target,$method); return $target->$method(); } } } } $this->format($result,$Action->response->streamBody); } } или как альтернатива может быть еще $objSecCallToMethod($target,$method) $AuthenticateMethod $TransfromToSimpleData $JSONOut В данной цепочке также происходит вызов метода, но его результат потом преобразуется в простые структуры и передается JSON преобразователю. Таким образом модулю логики не требуется знать о выходном формате, всю работу проделают дополнительные фильтры. =head1 HANDLERS =head2 subroutines =over =item CODE ref Ссылка на процедуру может являться обработчиком, при этом функция будет вызвана с двумя параметрами: ссылкой на action объект, и точкой входа следующего обработчика. =item Method Name Имя метода, передается в виде строки. У текущего объекта action ищется метод с указанным именем, после чего используется ссылка на этот метод для вызова с двумя параметрами: ссылкой на action объект, и точкой входа следующего обработчика. Получается вызов идентичный следующему C<< $action->MethodName($nextHandler) >>; =back =head2 C< IMPL::Web::Application::QueryHandler > Любой объект наследованный от C< IMPL::Web::Application::QueryHandler > может быть использован в качестве обработчика запроса =cut