Mercurial > pub > Impl
comparison Lib/IMPL/Web/Application/Resource.pm @ 359:833e663796c4
TTView: added view variable to pass rendering context between controls
TTView: display function renamed to display_for
WebResource: resources now marked with roles for searching a desired resource by a role in the resource chain
| author | sergey |
|---|---|
| date | Mon, 25 Nov 2013 02:19:31 +0400 |
| parents | ec58c47edb52 |
| children |
comparison
equal
deleted
inserted
replaced
| 358:248f95c1762a | 359:833e663796c4 |
|---|---|
| 19 base => [ | 19 base => [ |
| 20 'IMPL::Object' => undef, | 20 'IMPL::Object' => undef, |
| 21 'IMPL::Web::Application::ResourceInterface' => undef | 21 'IMPL::Web::Application::ResourceInterface' => undef |
| 22 ], | 22 ], |
| 23 props => [ | 23 props => [ |
| 24 request => PROP_RO, | 24 request => PROP_RO, |
| 25 application => PROP_RO, | 25 application => PROP_RO, |
| 26 parent => PROP_RO, | 26 parent => PROP_RO, |
| 27 model => PROP_RO, | 27 model => PROP_RO, |
| 28 id => PROP_RO, | 28 id => PROP_RO, |
| 29 location => PROP_RO, | 29 location => PROP_RO, |
| 30 role => PROP_RO | PROP_LIST | |
| 30 ] | 31 ] |
| 31 }; | 32 }; |
| 32 | 33 |
| 33 sub CTOR { | 34 sub CTOR { |
| 34 my ( $this, %args ) = @_; | 35 my ( $this, %args ) = @_; |
| 48 | 49 |
| 49 # если расположение явно не указано, то оно вычисляется автоматически, | 50 # если расположение явно не указано, то оно вычисляется автоматически, |
| 50 # либо остается не заданным | 51 # либо остается не заданным |
| 51 $this->location( $args{location} | 52 $this->location( $args{location} |
| 52 || eval { $this->parent->location->Child( $this->id ) } ); | 53 || eval { $this->parent->location->Child( $this->id ) } ); |
| 54 | |
| 55 if (my $role = $args{role}) { | |
| 56 if (ref($role) eq 'ARRAY') { | |
| 57 $this->role($role); | |
| 58 } elsif (not ref($role)) { | |
| 59 $this->role(split(/\s+/, $role)); | |
| 60 } else { | |
| 61 die ArgumentException->new( role => 'A invalid value is provided, expected ARRAY or SCALAR'); | |
| 62 } | |
| 63 } | |
| 53 } | 64 } |
| 54 | 65 |
| 55 sub InvokeHttpVerb { | 66 sub InvokeHttpVerb { |
| 56 my ( $this, $verb ) = @_; | 67 my ( $this, $verb ) = @_; |
| 57 | 68 |
| 100 | 111 |
| 101 sub AccessCheck { | 112 sub AccessCheck { |
| 102 | 113 |
| 103 } | 114 } |
| 104 | 115 |
| 105 sub PrepareEnvironment { | |
| 106 my ($this) = @_; | |
| 107 | |
| 108 my @stack; | |
| 109 my $env = {}; | |
| 110 | |
| 111 for ( my $res = $this ; $res ; $res = $res->parent ) { | |
| 112 push @stack, $res if $res->can('SetupEnvironment'); | |
| 113 } | |
| 114 | |
| 115 map $_->SetupEnvironment($env), reverse @stack; | |
| 116 | |
| 117 return $env; | |
| 118 } | |
| 119 | |
| 120 # это реализация по умолчанию, базируется информации о ресурсах, содержащийся | 116 # это реализация по умолчанию, базируется информации о ресурсах, содержащийся |
| 121 # в контракте. | 117 # в контракте. |
| 122 sub FetchChildResource { | 118 sub FetchChildResource { |
| 123 my ( $this, $childId ) = @_; | 119 my ( $this, $childId ) = @_; |
| 124 | 120 |
| 173 | 169 |
| 174 return $delegate->(@_) if ref $delegate eq 'CODE'; | 170 return $delegate->(@_) if ref $delegate eq 'CODE'; |
| 175 return $delegate->Invoke(@_) if eval { $delegate->can('Invoke') }; | 171 return $delegate->Invoke(@_) if eval { $delegate->can('Invoke') }; |
| 176 } | 172 } |
| 177 | 173 |
| 174 sub Seek { | |
| 175 my ($this, $role) = @_; | |
| 176 | |
| 177 my @roles; | |
| 178 | |
| 179 if (ref($role) eq 'ARRAY') { | |
| 180 @roles = @{$role}; | |
| 181 } elsif (not ref($role)) { | |
| 182 @roles = split(/\s+/, $role); | |
| 183 } else { | |
| 184 die ArgumentException->new( role => 'A invalid value is provided, expected ARRAY or SCALAR'); | |
| 185 } | |
| 186 | |
| 187 | |
| 188 for(my $r = $this; $r; $r = $r->parent) { | |
| 189 return $r if $r->HasRole(@roles); | |
| 190 } | |
| 191 return; | |
| 192 } | |
| 193 | |
| 194 sub HasRole { | |
| 195 my ($this, @roles) = @_; | |
| 196 my %cache = map { $_, 1 } @{$this->role}; | |
| 197 return scalar(grep not($cache{$_}), @roles) ? 0 : 1; | |
| 198 } | |
| 199 | |
| 178 1; | 200 1; |
| 179 | 201 |
| 180 __END__ | 202 __END__ |
| 181 | 203 |
| 182 =pod | 204 =pod |
| 270 Объект типа C<IMPL::Web::AutoLocator> или аналогичный описывающий адрес текущего | 292 Объект типа C<IMPL::Web::AutoLocator> или аналогичный описывающий адрес текущего |
| 271 ресурса, может быть как явно передан при создании ресурса, так и вычислен | 293 ресурса, может быть как явно передан при создании ресурса, так и вычислен |
| 272 автоматически (только для ресурсов имеющих родителя). Следует заметить, что | 294 автоматически (только для ресурсов имеющих родителя). Следует заметить, что |
| 273 адрес ресурса не содержит параметров запроса, а только путь. | 295 адрес ресурса не содержит параметров запроса, а только путь. |
| 274 | 296 |
| 297 =head2 C<[get,list]role> | |
| 298 | |
| 299 Список ролей ресурса. Роль это условный маркер, который позволяет определить | |
| 300 функции выполняемые ресурсом, например контейнер, профиль пользователя и т.п. | |
| 301 | |
| 302 Используется при построении цепочек навигации, а также при поиске с использованием | |
| 303 метода C<seek>. | |
| 304 | |
| 305 =head2 C<seek($role)> | |
| 306 | |
| 307 Ищет ресурс в цепочке родителей (включая сам ресурс) с подходящими ролями. | |
| 308 | |
| 309 Роли могут быть переданы в виде массива или строки, где роли разделены пробелами | |
| 310 | |
| 275 =head2 C<[get]FetchChildResource($id)> | 311 =head2 C<[get]FetchChildResource($id)> |
| 276 | 312 |
| 277 Возвращает дочерний ресурс, по его идентификатору. | 313 Возвращает дочерний ресурс, по его идентификатору. |
| 278 | 314 |
| 279 Данная реализация использует контракт текущего ресурса для поиска информации о | 315 Данная реализация использует контракт текущего ресурса для поиска информации о |
