Mercurial > pub > Impl
view Lib/IMPL/Web/Application.pm @ 250:129e48bb5afb
DOM refactoring
ObjectToDOM methods are virtual
QueryToDOM uses inflators
Fixed transform for the complex values in the ObjectToDOM
QueryToDOM doesn't allow to use complex values (HASHes) as values for nodes (overpost problem)
author | sergey |
---|---|
date | Wed, 07 Nov 2012 04:17:53 +0400 |
parents | a02b110da931 |
children | 546957c50a36 |
line wrap: on
line source
package IMPL::Web::Application; use strict; use warnings; use CGI; use Carp qw(carp); use IMPL::Const qw(:prop); use IMPL::declare { require => { Locator => 'IMPL::Web::AutoLocator', TAction => 'IMPL::Web::Application::Action', HttpResponse => 'IMPL::Web::HttpResponse', TFactory => '-IMPL::Object::Factory', Exception => 'IMPL::Exception', InvalidOperationException => '-IMPL::InvalidOperationException', Loader => 'IMPL::Code::Loader' }, base => [ 'IMPL::Config' => '@_', 'IMPL::Object::Singleton' => '@_' ], props => [ baseUrl => PROP_RW, actionFactory => PROP_RW, handlers => PROP_RW | PROP_LIST, security => PROP_RW, options => PROP_RW, requestCharset => PROP_RW, output => PROP_RW, location => PROP_RO ] }; sub CTOR { my ($this) = @_; die IMPL::InvalidArgumentException->new( "handlers", "At least one handler should be supplied" ) unless $this->handlers->Count; $this->baseUrl('/') unless $this->baseUrl; $this->actionFactory(TAction) unless $this->actionFactory; $this->location(Locator->new(base => $this->baseUrl)); } sub Run { my ($this) = @_; my $handler; $handler = _ChainHandler( $_, $handler ) foreach $this->handlers; while ( my $query = $this->FetchRequest() ) { my $action = $this->actionFactory->new( query => $query, application => $this, ); eval { my $result = $handler->($action); die InvalidOperationException->new( "Invalid handlers result. A reference to IMPL::Web::HttpResponse is expexted." ) unless eval { $result->isa(HttpResponse) }; $result->PrintResponse( $this->output ); }; if ($@) { my $e = $@; HttpResponse->InternalError( type => 'text/plain', charset => 'utf-8', body => $e )->PrintResponse( $this->output ); } } } sub _ChainHandler { my ( $handler, $next ) = @_; if ( ref $handler eq 'CODE' ) { return sub { my ($action) = @_; return $handler->( $action, $next ); }; } elsif ( eval { $handler->can('Invoke') } ) { return sub { my ($action) = @_; return $handler->Invoke( $action, $next ); }; } elsif ( eval { $handler->isa(TFactory) } ) { return sub { my ($action) = @_; my $inst = $handler->new(); return $inst->Invoke( $action, $next ); } } elsif ( $handler and not ref $handler and $handler =~ m/^(-)?(\w+(?:::\w+)*)$/ ) { my $class = $2; if ( not $1 ) { Loader->safe->Require($class); die IMPL::InvalidArgumentException->( "An invalid handler supplied", $handler ) unless $class->can('Invoke'); } return sub { my ($action) = @_; my $inst = $class->new(); return $inst->Invoke( $action, $next ); }; } else { die new IMPL::InvalidArgumentException( "An invalid handler supplied", $handler ); } } sub FetchRequest { return; } 1; __END__ =pod =head1 NAME C<IMPL::Web::Application> Базовай класс для создания экземпляров приложения =head1 SYNOPSIS =begin code use IMPL::require { App => 'IMPL::Web::Application' }; my $instance = App->spawn(); # will use ./IMPL/Web/Application.xml as configuration $instance->Run; =end code =head1 DESCRIPTION Создает экземпляр объекта, который получает и обрабатывает C<HTTP> запрос. Приложение можно загрузить из C<xml> файла в котором описано состояние свойств, для этого используется механизм C<IMPL::Serialization>. Приложение представлет собой модульную конструкцию, которая состоит из цепочки обработчиков. Цепочка обработчиков вызывается снизу вверх, при этом каждый обработчик самостоятельно рекурсивно вызывает следующий (более высокого уровня). См. также C<IMPL::Web::CGIApplication> =cut