Mercurial > pub > Impl
annotate Lib/IMPL/Web/Application/Action.pm @ 63:76b878ad6596
Added serialization support for the IMPL::Object::List
More intelligent Exception message
Fixed encoding support in the actions
Improoved tests
Minor fixes
author | wizard |
---|---|
date | Mon, 15 Mar 2010 02:38:09 +0300 |
parents | c64bd1bf727d |
children | 2840c4c85db8 |
rev | line source |
---|---|
52 | 1 package IMPL::Web::Application::Action; |
55 | 2 use strict; |
52 | 3 |
62 | 4 use base qw(IMPL::Object IMPL::Object::Autofill); |
52 | 5 |
63
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
6 __PACKAGE__->PassThroughArgs; |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
7 |
52 | 8 use IMPL::Class::Property; |
9 | |
10 BEGIN { | |
11 public property application => prop_get | owner_set; | |
62 | 12 public property query => prop_get | owner_set; |
52 | 13 public property response => prop_get | owner_set; |
55 | 14 |
15 private property _entryPoint => prop_all; | |
16 } | |
17 | |
63
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
18 #todo: make ability to discard old and create new response |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
19 |
55 | 20 sub Invoke { |
21 my ($this) = @_; | |
22 | |
23 if ($this->_entryPoint) { | |
24 $this->_entryPoint->(); | |
25 } else { | |
26 die new IMPL::InvalidOperationException("At least one handler is required"); | |
27 } | |
28 } | |
29 | |
30 sub ChainHandler { | |
31 my ($this,$handler) = @_; | |
32 | |
33 my $delegateNext = $this->_entryPoint(); | |
34 | |
35 if (ref $handler eq 'CODE') { | |
56 | 36 $this->_entryPoint( sub { |
55 | 37 $handler->($this,$delegateNext); |
56 | 38 } ); |
63
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
39 } elsif (ref $handler and UNIVERSAL::isa($handler,'IMPL::Web::QueryHandler')) { |
56 | 40 $this->_entryPoint( sub { |
55 | 41 $handler->Invoke($this,$delegateNext); |
56 | 42 } ); |
43 } elsif ($handler and not ref $handler) { | |
44 | |
63
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
45 if (my $method = $this->can($handler) ) { |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
46 $this->_entryPoint( sub { |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
47 $method->($this,$delegateNext); |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
48 } ); |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
49 } else { |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
50 { |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
51 no strict 'refs'; |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
52 eval "require $handler; 1;" or die new IMPL::InvalidArgumentException("An invalid handler supplied",$handler,"Failed to load module") unless keys %{"${handler}::"}; |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
53 } |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
54 |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
55 if (UNIVERSAL::isa($handler,'IMPL::Web::QueryHandler')) { |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
56 $this->_entryPoint( sub { |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
57 $handler->Invoke($this,$delegateNext); |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
58 } ); |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
59 } else { |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
60 die new IMPL::InvalidArgumentException("An invalid handler supplied",$handler); |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
61 } |
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
62 } |
55 | 63 } else { |
63
76b878ad6596
Added serialization support for the IMPL::Object::List
wizard
parents:
62
diff
changeset
|
64 die new IMPL::InvalidArgumentException("An invalid handler supplied",$handler); |
55 | 65 } |
66 | |
52 | 67 } |
68 | |
69 1; | |
70 | |
71 __END__ | |
72 | |
73 =pod | |
74 | |
75 =head1 DESCRIPTION | |
76 | |
57 | 77 Определяет порядок выполнения запроса. |
52 | 78 |
57 | 79 Запрос выполняется последовательным вызовом цепочки обработчиков, при этом обработчики |
80 сами вызывают следующие. | |
52 | 81 |
82 Типичная цепочка может быть такой, в порядке добавления | |
83 | |
57 | 84 SecCallToMethod($target,$method) |
85 AuthenticateMethod | |
86 TDocumentOut($file) | |
52 | 87 |
88 что приведет к следующей последовательности | |
89 | |
90 Action->Invoke() { | |
91 TDocumentOut->Invoke($Action,$nextHandler) { | |
92 my $result = $nextHandler() { | |
93 $AuthenticateMethod($Action,$nextHandler) { | |
62 | 94 my $context = $Action->application->security->Authenticate($Action->query,$Action->response); |
52 | 95 return $context->Impersonate($nextHandler) { |
96 $objSecCallToMethod->Invoke($Action,undef) { | |
97 IMPL::Security->AccessCheck($target,$method); | |
98 return $target->$method(); | |
99 } | |
100 } | |
101 } | |
102 } | |
103 $this->format($result,$Action->response->streamBody); | |
104 } | |
105 } | |
106 | |
107 или как альтернатива может быть еще | |
108 | |
109 $objSecCallToMethod($target,$method) | |
110 $AuthenticateMethod | |
111 $TransfromToSimpleData | |
112 $JSONOut | |
113 | |
114 В данной цепочке также происходит вызов метода, но его результат потом преобразуется | |
115 в простые структуры и передается JSON преобразователю. Таким образом модулю логики | |
116 не требуется знать о выходном формате, всю работу проделают дополнительные фильтры. | |
117 | |
56 | 118 =head1 HANDLERS |
119 | |
120 =head2 subroutines | |
121 | |
122 =over | |
123 | |
124 =item CODE ref | |
125 | |
126 Ссылка на процедуру может являться обработчиком, при этом функция будет вызвана с | |
127 двумя параметрами: ссылкой на action объект, и точкой входа следующего обработчика. | |
128 | |
129 =item Method Name | |
130 | |
131 Имя метода, передается в виде строки. У текущего объекта action ищется метод с | |
132 указанным именем, после чего используется ссылка на этот метод для вызова с двумя | |
133 параметрами: ссылкой на action объект, и точкой входа следующего обработчика. | |
134 | |
135 Получается вызов идентичный следующему C<< $action->MethodName($nextHandler) >>; | |
136 | |
137 =back | |
138 | |
57 | 139 =head2 C< IMPL::Web::Application::QueryHandler > |
140 | |
141 Любой объект наследованный от C< IMPL::Web::Application::QueryHandler > может быть | |
142 использован в качестве обработчика запроса | |
143 | |
52 | 144 =cut |