view Lib/IMPL/Web/Application/Action.pm @ 59:0f3e369553bd

Rewritten property implementation (probably become slower but more flexible) Configuration infrastructure in progress (in the aspect of the lazy activation) Initial concept for the code generator
author wizard
date Tue, 09 Mar 2010 02:50:45 +0300
parents bf59ee1cd506
children c64bd1bf727d
line wrap: on
line source

package IMPL::Web::Application::Action;
use strict;

use base qw(IMPL::Object);

use IMPL::Class::Property;

BEGIN {
	public property application => prop_get | owner_set;
	public property request => prop_get | owner_set;
	public property response => prop_get | owner_set;
	
	private property _entryPoint => prop_all;
}

sub Invoke {
	my ($this) = @_;
	
	if ($this->_entryPoint) {
		$this->_entryPoint->();
	} else {
		die new IMPL::InvalidOperationException("At least one handler is required");
	}
}

sub ChainHandler {
	my ($this,$handler) = @_;
	
	my $delegateNext = $this->_entryPoint();
	
	if (ref $handler eq 'CODE') {
		$this->_entryPoint( sub {
			$handler->($this,$delegateNext);			
		} );
	} elsif (UNIVERSAL::isa($handler,'IMPL::Web::Application::QueryHandler')) {
		$this->_entryPoint( sub {
			$handler->Invoke($this,$delegateNext);
		} );
	} elsif ($handler and not ref $handler) {
		my $method = $this->can($handler) or die new IMPL::InvalidArgumentException("An invalid handler supplied");
		
		$this->_entryPoint( sub {
			$method->($this,$delegateNext);			
		} );
	} else {
		die new IMPL::InvalidArgumentException("An invalid handler supplied");
	}
	
}

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->request,$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