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 |