Mercurial > pub > Impl
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 |