Mercurial > pub > Impl
diff Lib/IMPL/Web/Application/CustomResource.pm @ 334:71221d79e6b4
removing web resources contracts
author | cin |
---|---|
date | Thu, 13 Jun 2013 02:24:57 +0400 |
parents | 04a093f0a5a6 |
children | e8be9062ecf2 |
line wrap: on
line diff
--- a/Lib/IMPL/Web/Application/CustomResource.pm Tue Jun 11 20:22:52 2013 +0400 +++ b/Lib/IMPL/Web/Application/CustomResource.pm Thu Jun 13 02:24:57 2013 +0400 @@ -5,8 +5,8 @@ use IMPL::declare { require => { - Factory => 'IMPL::Object::Factory', - CustomResourceContract => 'IMPL::Web::Application::CustomResourceContract' + NotAllowedException => 'IMPL::Web::NotAllowedException', + HttpResponse => 'IMPL::Web::HttpResponse' }, base => [ 'IMPL::Web::Application::Resource' => '@_' @@ -16,49 +16,79 @@ ] }; -__PACKAGE__->static_accessor(contractFactory => CustomResourceContract ); -__PACKAGE__->static_accessor_own(_contractInstance => undef); +our %RESOURCE_BINDINGS = ( + GET => 'HttpGet', + POST => 'HttpPost', + PUT => 'HttpPut', + DELETE => 'HttpDelete', + HEAD => 'HttpHead' +); + +__PACKAGE__->static_accessor(_rxResourcesMap => undef, 'own'); +__PACKAGE__->static_accessor(_nameResourcesMap => undef, 'own'); + +sub namedResources { + shift->_nameResourcesMap; +} + +sub regexResources { + shift->_rxResourcesMap; +} sub CTOR { my ($this,%args) = @_; $this->accessCheck($args{accessCheck}) if $args{accessCheck}; + + $this->verbs->{options} ||= \&_HttpOptionsBinding; + + while(my ($verb,$methodName) = each %RESOURCE_BINDINGS) { + $this->verbs->{lc($verb)} ||= sub { + my ($resource,$action) = @_; + + if (eval { $resource->can($methodName) }) { + return $resource->$methodName($action); + } else { + die NotAllowedException->new(allow => join(',', _GetAllowedHttpMethods($resource))); + } + } + } } -sub contractInstance { - my ($self) = @_; +sub FindChildResourceInfo { + my ( $this, $name ) = @_; - $self = ref $self || $self; - $self->_contractInstance ? $self->_contractInstance : $self->InitContract(); + $this->_PrepareResourcesCache() + unless($this->_nameResourcesMap); + + return $this->next::method($name); } -sub InitContract { - my ($self) = @_; - $self->_contractInstance( - $self->contractFactory->new( - resourceFactory => $self, - resources => [ $self->GetChildResources() ] - ) - ); +sub PrepareResourcesCache { + # suppress default caching mechanisn } -sub CreateContract { - my ($self, %args) = @_; - - $self->contractFactory->new( - resourceFactory => Factory->new( - $self, - \%args - ), - resources => [ $self->GetChildResources() ] - ) -} +sub _PrepareResourcesCache { + # a little bit wired + my ($self) = @_; + my %nameMap; + my @rxMap; -sub CreateResource { - my ($self,%args) = @_; - - $self->CreateContract()->CreateResource(%args); + foreach my $res ($self->GetChildResources()) { + #skip resources without contract + next unless $res->{contract}; + + if ( my $name = $res->{name} ) { + $nameMap{$name} = $res; + } + if ( $res->{match} ) { + push @rxMap,$res; + } + } + + $self->_rxResourcesMap(\@rxMap); + $self->_nameResourcesMap(\%nameMap); } sub AccessCheck { @@ -67,7 +97,7 @@ my $handler = $this->accessCheck; if(ref($handler) eq 'CODE') { - &$handler($this,$verb); + return &$handler($this,$verb); } } @@ -75,6 +105,23 @@ } +sub _HttpOptionsBinding { + my ($this) = @_; + + my @allow = $this->_GetAllowedHttpMethods(); + return HttpResponse->new( + status => '200 OK', + headers => { + allow => join ( ',', @allow ) + } + ); +} + +sub _GetAllowedHttpMethods { + my ($this) = @_; + return grep $this->can($RESOURCE_BINDINGS{$_}), keys %RESOURCE_BINDINGS; +} + 1; @@ -111,18 +158,22 @@ $this->model->update( $form->Bind($action) ); } -our %COMPONENTS = ( - item => { - verbs => { - get => sub { - shift->model; - } - }, - resources => [ - edit => - ] - } -); +sub GetChildResources { + return { + name => 'create', + contract => { + class => 'My::Web::FormResource', + formName => 'create', + schema => 'profile.schema' + } + }, + { + match => qr/^(.*)$/, + contract => { + class => 'My::Web::ItemResource' + } + } +} =end code