Mercurial > pub > Impl
diff lib/IMPL/Web/Application.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
author | cin |
---|---|
date | Fri, 04 Sep 2015 19:40:23 +0300 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/IMPL/Web/Application.pm Fri Sep 04 19:40:23 2015 +0300 @@ -0,0 +1,149 @@ +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', + ArgException => '-IMPL::InvalidArgumentException', + InvalidOperationException => '-IMPL::InvalidOperationException', + Loader => 'IMPL::Code::Loader' + }, + base => [ + 'IMPL::Config' => '@_', + 'IMPL::Object::Singleton' => undef + ], + props => [ + baseUrl => PROP_RW, + actionFactory => PROP_RW, + handlers => PROP_RW | PROP_LIST, + securityFactory => PROP_RW, + output => PROP_RW, + location => PROP_RO, + _handler => PROP_RW + ] +}; + +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 CreateSecurity { + my $factory = shift->securityFactory; + return $factory ? $factory->new() : undef; +} + +sub ProcessRequest { + my ($this,$q) = @_; + + die ArgException->new(q => 'A query is required') + unless $q; + + my $handler = $this->_handler; + unless ($handler) { + $handler = _ChainHandler( $_, $handler ) foreach $this->handlers; + $this->_handler($handler); + } + + my $action = $this->actionFactory->new( + query => $q, + 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 ); + }; + + $action->Dispose(); + + 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 ); + } +} + +1; + +__END__ + +=pod + +=head1 NAME + +C<IMPL::Web::Application> Базовай класс для веб-приложения + +=cut