Mercurial > pub > Impl
comparison lib/IMPL/Web/Application.pm @ 407:c6e90e02dd17 ref20150831
renamed Lib->lib
| author | cin |
|---|---|
| date | Fri, 04 Sep 2015 19:40:23 +0300 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 406:f23fcb19d3c1 | 407:c6e90e02dd17 |
|---|---|
| 1 package IMPL::Web::Application; | |
| 2 use strict; | |
| 3 use warnings; | |
| 4 | |
| 5 use CGI; | |
| 6 use Carp qw(carp); | |
| 7 use IMPL::Const qw(:prop); | |
| 8 | |
| 9 use IMPL::declare { | |
| 10 require => { | |
| 11 Locator => 'IMPL::Web::AutoLocator', | |
| 12 TAction => 'IMPL::Web::Application::Action', | |
| 13 HttpResponse => 'IMPL::Web::HttpResponse', | |
| 14 TFactory => '-IMPL::Object::Factory', | |
| 15 Exception => 'IMPL::Exception', | |
| 16 ArgException => '-IMPL::InvalidArgumentException', | |
| 17 InvalidOperationException => '-IMPL::InvalidOperationException', | |
| 18 Loader => 'IMPL::Code::Loader' | |
| 19 }, | |
| 20 base => [ | |
| 21 'IMPL::Config' => '@_', | |
| 22 'IMPL::Object::Singleton' => undef | |
| 23 ], | |
| 24 props => [ | |
| 25 baseUrl => PROP_RW, | |
| 26 actionFactory => PROP_RW, | |
| 27 handlers => PROP_RW | PROP_LIST, | |
| 28 securityFactory => PROP_RW, | |
| 29 output => PROP_RW, | |
| 30 location => PROP_RO, | |
| 31 _handler => PROP_RW | |
| 32 ] | |
| 33 }; | |
| 34 | |
| 35 sub CTOR { | |
| 36 my ($this) = @_; | |
| 37 | |
| 38 die IMPL::InvalidArgumentException->new( "handlers", | |
| 39 "At least one handler should be supplied" ) | |
| 40 unless $this->handlers->Count; | |
| 41 | |
| 42 $this->baseUrl('/') unless $this->baseUrl; | |
| 43 | |
| 44 $this->actionFactory(TAction) unless $this->actionFactory; | |
| 45 $this->location(Locator->new(base => $this->baseUrl)); | |
| 46 } | |
| 47 | |
| 48 sub CreateSecurity { | |
| 49 my $factory = shift->securityFactory; | |
| 50 return $factory ? $factory->new() : undef; | |
| 51 } | |
| 52 | |
| 53 sub ProcessRequest { | |
| 54 my ($this,$q) = @_; | |
| 55 | |
| 56 die ArgException->new(q => 'A query is required') | |
| 57 unless $q; | |
| 58 | |
| 59 my $handler = $this->_handler; | |
| 60 unless ($handler) { | |
| 61 $handler = _ChainHandler( $_, $handler ) foreach $this->handlers; | |
| 62 $this->_handler($handler); | |
| 63 } | |
| 64 | |
| 65 my $action = $this->actionFactory->new( | |
| 66 query => $q, | |
| 67 application => $this, | |
| 68 ); | |
| 69 | |
| 70 eval { | |
| 71 my $result = $handler->($action); | |
| 72 | |
| 73 die InvalidOperationException->new("Invalid handlers result. A reference to IMPL::Web::HttpResponse is expexted.") | |
| 74 unless eval { $result->isa(HttpResponse) }; | |
| 75 | |
| 76 $result->PrintResponse( $this->output ); | |
| 77 }; | |
| 78 | |
| 79 $action->Dispose(); | |
| 80 | |
| 81 if ($@) { | |
| 82 my $e = $@; | |
| 83 | |
| 84 HttpResponse->InternalError( | |
| 85 type => 'text/plain', | |
| 86 charset => 'utf-8', | |
| 87 body => $e | |
| 88 )->PrintResponse( $this->output ); | |
| 89 | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 sub _ChainHandler { | |
| 94 my ( $handler, $next ) = @_; | |
| 95 | |
| 96 if ( ref $handler eq 'CODE' ) { | |
| 97 return sub { | |
| 98 my ($action) = @_; | |
| 99 return $handler->( $action, $next ); | |
| 100 }; | |
| 101 } | |
| 102 elsif ( eval { $handler->can('Invoke') } ) { | |
| 103 return sub { | |
| 104 my ($action) = @_; | |
| 105 return $handler->Invoke( $action, $next ); | |
| 106 }; | |
| 107 } | |
| 108 elsif ( eval { $handler->isa(TFactory) } ) { | |
| 109 return sub { | |
| 110 my ($action) = @_; | |
| 111 my $inst = $handler->new(); | |
| 112 return $inst->Invoke( $action, $next ); | |
| 113 } | |
| 114 } | |
| 115 elsif ( $handler | |
| 116 and not ref $handler | |
| 117 and $handler =~ m/^(-)?(\w+(?:::\w+)*)$/ ) | |
| 118 { | |
| 119 my $class = $2; | |
| 120 if ( not $1 ) { | |
| 121 Loader->safe->Require($class); | |
| 122 die IMPL::InvalidArgumentException->( | |
| 123 "An invalid handler supplied", $handler | |
| 124 ) unless $class->can('Invoke'); | |
| 125 } | |
| 126 | |
| 127 return sub { | |
| 128 my ($action) = @_; | |
| 129 my $inst = $class->new(); | |
| 130 return $inst->Invoke( $action, $next ); | |
| 131 }; | |
| 132 } | |
| 133 else { | |
| 134 die new IMPL::InvalidArgumentException( "An invalid handler supplied", | |
| 135 $handler ); | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 1; | |
| 140 | |
| 141 __END__ | |
| 142 | |
| 143 =pod | |
| 144 | |
| 145 =head1 NAME | |
| 146 | |
| 147 C<IMPL::Web::Application> Базовай класс для веб-приложения | |
| 148 | |
| 149 =cut |
