Mercurial > pub > Impl
annotate Lib/IMPL/Web/Application/Resource.pm @ 251:9f394b27dccf
require can handle recursive module references
author | sergey |
---|---|
date | Fri, 16 Nov 2012 16:44:16 +0400 |
parents | 814d755e5d12 |
children | 827cf96faa1c |
rev | line source |
---|---|
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
1 package IMPL::Web::Application::Resource; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
2 use strict; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
3 |
230 | 4 use IMPL::Const qw(:prop); |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
5 use IMPL::declare { |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
6 require => { |
244 | 7 ViewResult => 'IMPL::Web::ViewResult', |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
8 Exception => 'IMPL::Exception', |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
9 ArgumentException => '-IMPL::InvalidArgumentException', |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
10 OperationException => '-IMPL::InvalidOperationException', |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
11 NotAllowedException => 'IMPL::Web::NotAllowedException', |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
12 NotFoundException => 'IMPL::Web::NotFoundException' |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
13 }, |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
14 base => [ |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
15 'IMPL::Object' => undef, |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
16 'IMPL::Web::Application::ResourceInterface' => undef |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
17 ], |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
18 props => [ |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
19 parent => PROP_GET | PROP_OWNERSET, |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
20 model => PROP_GET | PROP_OWNERSET, |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
21 id => PROP_GET | PROP_OWNERSET, |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
22 contract => PROP_GET | PROP_OWNERSET, |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
23 location => PROP_GET | PROP_OWNERSET |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
24 ] |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
25 }; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
26 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
27 sub CTOR { |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
28 my ( $this, %args ) = @_; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
29 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
30 die ArgumentException->new( id => 'A resource identifier is required' ) |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
31 unless $args{id}; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
32 die ArgumentException->new( contract => 'A contract is required' ) |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
33 unless $args{id}; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
34 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
35 $this->parent( $args{parent} ); |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
36 $this->model( $args{model} ); |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
37 $this->id( $args{id} ); |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
38 $this->contract( $args{contract} ); |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
39 |
230 | 40 # если расположение явно не указано, то оно вычисляется автоматически, |
41 # либо остается не заданным | |
42 $this->location( $args{location} || eval { $this->parent->location->Child( $this->id ) } ); | |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
43 } |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
44 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
45 sub InvokeHttpVerb { |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
46 my ( $this, $verb, $action ) = @_; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
47 |
230 | 48 my $operation = $this->contract->verbs->{ lc($verb) }; |
49 | |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
50 die NotAllowedException->new( |
230 | 51 allow => join( ',', map( uc, keys %{ $this->contract->verbs } ) ) |
52 ) | |
53 unless $operation; | |
245 | 54 |
55 # в случае, когда один ресурс вызывает HTTP метод другого ресурса, нужно | |
56 # сохранить оригинальный resourceLocation | |
57 $action->context->{resourceLocation} ||= $this->location; | |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
58 |
230 | 59 return $operation->Invoke( $this, $action ); |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
60 } |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
61 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
62 # это реализация по умолчанию, базируется информации о ресурсах, содержащийся |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
63 # в контракте. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
64 sub FetchChildResource { |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
65 my ( $this, $childId ) = @_; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
66 |
230 | 67 my ($info,$childIdParts) = $this->contract->FindChildResourceInfo($childId); |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
68 |
230 | 69 die NotFoundException->new($this->location->url,$childId) unless $info; |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
70 |
230 | 71 my $binding = $info->{binding}; |
248 | 72 my $contract = $info->{contract}; |
73 | |
74 if (ref $contract eq 'CODE') { | |
75 $contract = $contract->(); | |
76 $info->{contract} = $contract; | |
77 } | |
78 | |
79 die OperationException->new("Can't fetch a contract for the resource", $childId) | |
80 unless $contract; | |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
81 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
82 my %args = ( |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
83 parent => $this, |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
84 id => $childId |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
85 ); |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
86 |
230 | 87 $args{model} = _InvokeDelegate($binding,$this,@$childIdParts); |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
88 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
89 return $contract->CreateResource(%args); |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
90 } |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
91 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
92 sub _InvokeDelegate { |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
93 my $delegate = shift; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
94 |
230 | 95 return $delegate->(@_) if ref $delegate eq 'CODE'; |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
96 return $delegate->Invoke(@_) if eval { $delegate->can('Invoke')}; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
97 } |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
98 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
99 1; |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
100 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
101 __END__ |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
102 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
103 =pod |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
104 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
105 =head1 NAME |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
106 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
107 C<IMPL::Web::Application::Resource> - Web-ресурс. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
108 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
109 =head1 SYNOPSIS |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
110 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
111 Класс для внутреннего использования. Объединяет в себе контракт и модель данных. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
112 Основная задача - обработать поступающий от контроллера запрос на вызов C<HTTP> |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
113 метода. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
114 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
115 Экземпляры данного класса передаются в качестве параметров делегатам |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
116 осуществляющим привязку к модели в C<IMPL::Web::Application::ResourceContract> |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
117 и C<IMPL::Web::Application::OperationContract>. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
118 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
119 =head1 DESCRIPTION |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
120 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
121 Весь функционал ресурса, поддерживаемые им C<HTTP> методы определяются |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
122 контрактом. Однако можно реализовывать ресурсы, которые не имеют контракта |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
123 или он отличается от того, что предоставляется стандартно |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
124 C<IMPL::Web::Application::ResourceContract>. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
125 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
126 Каждый ресурс является контейнером, тоесть позволяет получить дочерний ресурс |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
127 по идентифифкатору, если таковой имеется, тоесть ресурс, у которого нет дочерних |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
128 ресурсов на самом деле рассматривается как пустой контейнер. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
129 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
130 С ресурсом непосредственно взаимодействует котроллер запросов |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
131 C<IMPL::Web::Handler::RestController>, вызывая два метода. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
132 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
133 =over |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
134 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
135 =item * C<FetchChildResource($childId)> |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
136 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
137 Данный метод возвращает дочерний ресурс, соответствующий C<$childId>. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
138 Текущая реализация использует метод C<FindChildResourceInfo> контракта текущего |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
139 ресурса, после чего создает дочерний ресурс. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
140 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
141 Если дочерний ресурс не найден, вызывается исключение |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
142 C<IMPL::Web::NotFoundException>. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
143 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
144 =item * C<InvokeHttpVerb($verb,$action)> |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
145 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
146 Обрабатывает запрос к ресурсу. Для этого используется контракт ресурса, в |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
147 нем выбирается соответсвующий C<IMPL::Web::Application::OperationContract>. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
148 Затем найденный контракт для указанной операции используется для обработки |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
149 запроса. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
150 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
151 =back |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
152 |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
153 Если объект реализует два вышеуказанных метода, он является веб-ресурсом, а |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
154 детали его реализации, котнракт и прочее уже не важно, поэтому можно реализовать |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
155 собственный класс ресурса, например унаследованный от |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
156 C<IMPL::Web::Application::CustomResource>. |
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
157 |
230 | 158 =head1 MEMBERS |
159 | |
160 =head2 C<[get]contract> | |
161 | |
248 | 162 Обязательное свойство для ресурса, ссылается, на контракт, соответствующий |
230 | 163 данному ресурсу, используется для выполнения C<HTTP> методов и получения |
164 дочерних ресурсов. | |
165 | |
166 =head2 C<[get]id> | |
167 | |
168 Обязательное свойство ресурса, идентифицирует его в родительском контейнере, | |
169 для корневого ресурса может иметь произвольное значение. | |
170 | |
171 =head2 C<[get]parent> | |
172 | |
173 Ссылка на родительский ресурс, для корневого ресурса не определена. | |
174 | |
175 =head2 C<[get]model> | |
176 | |
177 Ссылка на объект предметной области, представляемый данным ресурсом. Данное | |
178 свойство не является обязательным и может быть не задано. | |
179 | |
180 =head2 C<[get]location> | |
181 | |
182 Объект типа C<IMPL::Web::AutoLocator> или аналогичный описывающий адрес текущего | |
183 ресурса, может быть как явно передан при создании ресурса, так и вычислен | |
184 автоматически (только для ресурсов имеющих родителя). Следует заметить, что | |
185 адрес ресурса не содержит параметров запроса, а только путь. | |
186 | |
229
47f77e6409f7
heavily reworked the resource model of the web application:
sergey
parents:
diff
changeset
|
187 =cut |