Mercurial > pub > Impl
diff Lib/IMPL/Web/Application/Resource.pm @ 268:4abda21186cd
*refactoring IMPL::Web: added 'application' property to resources
author | cin |
---|---|
date | Mon, 21 Jan 2013 02:08:17 +0400 |
parents | 32aceba4ee6d |
children | 546957c50a36 |
line wrap: on
line diff
--- a/Lib/IMPL/Web/Application/Resource.pm Thu Jan 17 02:39:44 2013 +0400 +++ b/Lib/IMPL/Web/Application/Resource.pm Mon Jan 21 02:08:17 2013 +0400 @@ -17,11 +17,12 @@ 'IMPL::Web::Application::ResourceInterface' => undef ], props => [ - parent => PROP_RO, - model => PROP_RO, - id => PROP_RO, - contract => PROP_RO, - location => PROP_RO, + application => PROP_RO, + parent => PROP_RO, + model => PROP_RO, + id => PROP_RO, + contract => PROP_RO, + location => PROP_RO, ] }; @@ -37,64 +38,67 @@ $this->model( $args{model} ); $this->id( $args{id} ); $this->contract( $args{contract} ); + $this->application( $args{application} || ($args{parent} && $args{parent}->application) ); - # если расположение явно не указано, то оно вычисляется автоматически, - # либо остается не заданным - $this->location( $args{location} || eval { $this->parent->location->Child( $this->id ) } ); +# если расположение явно не указано, то оно вычисляется автоматически, +# либо остается не заданным + $this->location( $args{location} + || eval { $this->parent->location->Child( $this->id ) } ); } sub InvokeHttpVerb { - my ( $this, $verb, $action ) = @_; + my ( $this, $verb, $action ) = @_; + + my $operation = $this->contract->verbs->{ lc($verb) }; - my $operation = $this->contract->verbs->{ lc($verb) }; - - die NotAllowedException->new( - allow => join( ',', map( uc, keys %{ $this->contract->verbs } ) ) - ) - unless $operation; - - # в случае, когда один ресурс вызывает HTTP метод другого ресурса, нужно - # сохранить оригинальный resourceLocation - $action->context->{resourceLocation} ||= $this->location; + die NotAllowedException->new( + allow => join( ',', map( uc, keys %{ $this->contract->verbs } ) ) ) + unless $operation; - return $operation->Invoke( $this, $action ); +# в случае, когда один ресурс вызывает HTTP метод другого ресурса, нужно +# сохранить оригинальный resourceLocation + $action->context->{resourceLocation} ||= $this->location; + + return _InvokeDelegate($operation, $this, $action ); } # это реализация по умолчанию, базируется информации о ресурсах, содержащийся # в контракте. sub FetchChildResource { - my ( $this, $childId ) = @_; - - my ($info,$childIdParts) = $this->contract->FindChildResourceInfo($childId); - - die NotFoundException->new($this->location->url,$childId) unless $info; - - my $binding = $info->{binding}; - my $contract = $info->{contract}; - - if (ref $contract eq 'CODE') { - $contract = $contract->(); - $info->{contract} = $contract; - } - - die OperationException->new("Can't fetch a contract for the resource", $childId) - unless $contract; - - my %args = ( - parent => $this, - id => $childId - ); - - $args{model} = _InvokeDelegate($binding,$this,@$childIdParts); + my ( $this, $childId ) = @_; + + my ( $info, $childIdParts ) = + $this->contract->FindChildResourceInfo($childId); + + die NotFoundException->new( $this->location->url, $childId ) unless $info; + + my $binding = $info->{binding}; + my $contract = $info->{contract}; + my $model = _InvokeDelegate( $binding, $this, @$childIdParts ); - return $contract->CreateResource(%args); + if ( ref $contract eq 'CODE' || $contract->can('Invoke')) { + $contract = _InvokeDelegate($contract,$this,$model); + $info->{contract} = $contract; + } + + die OperationException->new( "Can't fetch a contract for the resource", + $childId ) + unless $contract; + + my %args = ( + parent => $this, + id => $childId, + model => $model + ); + + return $contract->CreateResource(%args); } sub _InvokeDelegate { my $delegate = shift; - + return $delegate->(@_) if ref $delegate eq 'CODE'; - return $delegate->Invoke(@_) if eval { $delegate->can('Invoke')}; + return $delegate->Invoke(@_) if eval { $delegate->can('Invoke') }; } 1; @@ -158,6 +162,12 @@ =head1 MEMBERS +=head2 C<[get]application> + +Ссылка на приложение, к которому относится данный ресурс. Его следует задавать +только для коренвых ресурсов, дочерние ресурсы получают это свойство от +родителей. + =head2 C<[get]contract> Обязательное свойство для ресурса, ссылается, на контракт, соответствующий @@ -185,4 +195,16 @@ автоматически (только для ресурсов имеющих родителя). Следует заметить, что адрес ресурса не содержит параметров запроса, а только путь. +=head2 C<[get]FetchChildResource($id)> + +Возвращает дочерний ресурс, по его идентификатору. + +Данная реализация использует контракт текущего ресурса для поиска информации о +дочернем ресурсе C<< $this->contract->FindChildResourceInfo($id) >>. + +Затем осуществляется привязка к моделе, тоесть, выполняется делегат, для +получения модели дочернего ресурса, а затем осуществляется привязка к контракту, +при этом в делегат, который должен вернуть контракт дочернего ресурса передаются +текущий ресурc и модель дочернего ресурса. + =cut