annotate Lib/IMPL/Web/Application/Resource.pm @ 250:129e48bb5afb

DOM refactoring ObjectToDOM methods are virtual QueryToDOM uses inflators Fixed transform for the complex values in the ObjectToDOM QueryToDOM doesn't allow to use complex values (HASHes) as values for nodes (overpost problem)
author sergey
date Wed, 07 Nov 2012 04:17:53 +0400
parents 814d755e5d12
children 827cf96faa1c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
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
a02b110da931 refactoring
sergey
parents: 230
diff changeset
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
40 # если расположение явно не указано, то оно вычисляется автоматически,
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
41 # либо остается не заданным
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
48 my $operation = $this->contract->verbs->{ lc($verb) };
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
49
229
47f77e6409f7 heavily reworked the resource model of the web application:
sergey
parents:
diff changeset
50 die NotAllowedException->new(
230
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
51 allow => join( ',', map( uc, keys %{ $this->contract->verbs } ) )
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
52 )
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
53 unless $operation;
245
7c517134c42f Added Unsupported media type Web exception
sergey
parents: 244
diff changeset
54
7c517134c42f Added Unsupported media type Web exception
sergey
parents: 244
diff changeset
55 # в случае, когда один ресурс вызывает HTTP метод другого ресурса, нужно
7c517134c42f Added Unsupported media type Web exception
sergey
parents: 244
diff changeset
56 # сохранить оригинальный resourceLocation
7c517134c42f Added Unsupported media type Web exception
sergey
parents: 244
diff changeset
57 $action->context->{resourceLocation} ||= $this->location;
229
47f77e6409f7 heavily reworked the resource model of the web application:
sergey
parents:
diff changeset
58
230
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
71 my $binding = $info->{binding};
248
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
72 my $contract = $info->{contract};
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
73
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
74 if (ref $contract eq 'CODE') {
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
75 $contract = $contract->();
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
76 $info->{contract} = $contract;
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
77 }
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
78
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
79 die OperationException->new("Can't fetch a contract for the resource", $childId)
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
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
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
158 =head1 MEMBERS
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
159
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
160 =head2 C<[get]contract>
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
161
248
814d755e5d12 Minor fixes
sergey
parents: 245
diff changeset
162 Обязательное свойство для ресурса, ссылается, на контракт, соответствующий
230
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
163 данному ресурсу, используется для выполнения C<HTTP> методов и получения
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
164 дочерних ресурсов.
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
165
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
166 =head2 C<[get]id>
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
167
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
168 Обязательное свойство ресурса, идентифицирует его в родительском контейнере,
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
169 для корневого ресурса может иметь произвольное значение.
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
170
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
171 =head2 C<[get]parent>
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
172
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
173 Ссылка на родительский ресурс, для корневого ресурса не определена.
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
174
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
175 =head2 C<[get]model>
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
176
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
177 Ссылка на объект предметной области, представляемый данным ресурсом. Данное
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
178 свойство не является обязательным и может быть не задано.
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
179
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
180 =head2 C<[get]location>
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
181
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
182 Объект типа C<IMPL::Web::AutoLocator> или аналогичный описывающий адрес текущего
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
183 ресурса, может быть как явно передан при создании ресурса, так и вычислен
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
184 автоматически (только для ресурсов имеющих родителя). Следует заметить, что
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
185 адрес ресурса не содержит параметров запроса, а только путь.
6d8092d8ce1b *reworked IMPL::Security
sergey
parents: 229
diff changeset
186
229
47f77e6409f7 heavily reworked the resource model of the web application:
sergey
parents:
diff changeset
187 =cut