comparison Lib/IMPL/Web/Application/Resource.pm @ 230:6d8092d8ce1b

*reworked IMPL::Security *reworked IMPL::Web::Security *refactoring
author sergey
date Mon, 08 Oct 2012 03:37:37 +0400
parents 47f77e6409f7
children a02b110da931
comparison
equal deleted inserted replaced
229:47f77e6409f7 230:6d8092d8ce1b
1 package IMPL::Web::Application::Resource; 1 package IMPL::Web::Application::Resource;
2 use strict; 2 use strict;
3 3
4 use IMPL::lang qw(:constants); 4 use IMPL::Const qw(:prop);
5 use IMPL::declare { 5 use IMPL::declare {
6 require => { 6 require => {
7 Exception => 'IMPL::Exception', 7 Exception => 'IMPL::Exception',
8 ArgumentException => '-IMPL::InvalidArgumentException', 8 ArgumentException => '-IMPL::InvalidArgumentException',
9 OperationException => '-IMPL::InvalidOperationException', 9 OperationException => '-IMPL::InvalidOperationException',
34 $this->parent( $args{parent} ); 34 $this->parent( $args{parent} );
35 $this->model( $args{model} ); 35 $this->model( $args{model} );
36 $this->id( $args{id} ); 36 $this->id( $args{id} );
37 $this->contract( $args{contract} ); 37 $this->contract( $args{contract} );
38 38
39 # если расположение явно не указано, что обычно делается для корневого 39 # если расположение явно не указано, то оно вычисляется автоматически,
40 # ресурса, то оно вычисляется автоматически, либо остается не заданным 40 # либо остается не заданным
41 $this->location( $args{location} 41 $this->location( $args{location} || eval { $this->parent->location->Child( $this->id ) } );
42 || eval { $this->parent->location->Child( $this->id ) } );
43 )
44
45 } 42 }
46 43
47 sub InvokeHttpVerb { 44 sub InvokeHttpVerb {
48 my ( $this, $verb, $action ) = @_; 45 my ( $this, $verb, $action ) = @_;
49 46
50 my $verb = $this->contract->verbs->{ lc($verb) }; 47 my $operation = $this->contract->verbs->{ lc($verb) };
48
49 die NotAllowedException->new(
50 allow => join( ',', map( uc, keys %{ $this->contract->verbs } ) )
51 )
52 unless $operation;
51 53
52 die NotAllowedException->new( 54 return $operation->Invoke( $this, $action );
53 allow => join( ',' map( uc, keys %{ $this->contract->verbs } ) ) )
54 unless $verb;
55
56 return $verb->Invoke( $this, $action );
57 } 55 }
58 56
59 # это реализация по умолчанию, базируется информации о ресурсах, содержащийся 57 # это реализация по умолчанию, базируется информации о ресурсах, содержащийся
60 # в контракте. 58 # в контракте.
61 sub FetchChildResource { 59 sub FetchChildResource {
62 my ( $this, $childId ) = @_; 60 my ( $this, $childId ) = @_;
63 61
64 my $info = $this->contract->FindChildResourceInfo($childId); 62 my ($info,$childIdParts) = $this->contract->FindChildResourceInfo($childId);
65 63
66 die NotFoundException->new() unless $info; 64 die NotFoundException->new($this->location->url,$childId) unless $info;
67 65
68 my $binding = $this->{binding}; 66 my $binding = $info->{binding};
69 my $contract = $this->{contract} 67 my $contract = $info->{contract}
70 or die OperationException->new("Can't fetch a contract for the resource", $childId); 68 or die OperationException->new("Can't fetch a contract for the resource", $childId);
71 69
72 my %args = ( 70 my %args = (
73 parent => $this, 71 parent => $this,
74 id => $childId 72 id => $childId
75 ); 73 );
76 74
77 $args{model} = _InvokeDelegate($binding,$this); 75 $args{model} = _InvokeDelegate($binding,$this,@$childIdParts);
78 76
79 return $contract->CreateResource(%args); 77 return $contract->CreateResource(%args);
80 } 78 }
81 79
82 sub _InvokeDelegate { 80 sub _InvokeDelegate {
83 my $delegate = shift; 81 my $delegate = shift;
84 82
85 return $delegete->(@_) if ref $delegate eq 'CODE'; 83 return $delegate->(@_) if ref $delegate eq 'CODE';
86 return $delegate->Invoke(@_) if eval { $delegate->can('Invoke')}; 84 return $delegate->Invoke(@_) if eval { $delegate->can('Invoke')};
87 } 85 }
88 86
89 1; 87 1;
90 88
143 Если объект реализует два вышеуказанных метода, он является веб-ресурсом, а 141 Если объект реализует два вышеуказанных метода, он является веб-ресурсом, а
144 детали его реализации, котнракт и прочее уже не важно, поэтому можно реализовать 142 детали его реализации, котнракт и прочее уже не важно, поэтому можно реализовать
145 собственный класс ресурса, например унаследованный от 143 собственный класс ресурса, например унаследованный от
146 C<IMPL::Web::Application::CustomResource>. 144 C<IMPL::Web::Application::CustomResource>.
147 145
146 =head1 MEMBERS
147
148 =head2 C<[get]contract>
149
150 Обязательное свойство для ресурса, ссылается, на контракт, соотсетствующий
151 данному ресурсу, используется для выполнения C<HTTP> методов и получения
152 дочерних ресурсов.
153
154 =head2 C<[get]id>
155
156 Обязательное свойство ресурса, идентифицирует его в родительском контейнере,
157 для корневого ресурса может иметь произвольное значение.
158
159 =head2 C<[get]parent>
160
161 Ссылка на родительский ресурс, для корневого ресурса не определена.
162
163 =head2 C<[get]model>
164
165 Ссылка на объект предметной области, представляемый данным ресурсом. Данное
166 свойство не является обязательным и может быть не задано.
167
168 =head2 C<[get]location>
169
170 Объект типа C<IMPL::Web::AutoLocator> или аналогичный описывающий адрес текущего
171 ресурса, может быть как явно передан при создании ресурса, так и вычислен
172 автоматически (только для ресурсов имеющих родителя). Следует заметить, что
173 адрес ресурса не содержит параметров запроса, а только путь.
174
148 =cut 175 =cut