Mercurial > pub > Impl
comparison 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 |
comparison
equal
deleted
inserted
replaced
333:cd6409f66a5f | 334:71221d79e6b4 |
---|---|
3 | 3 |
4 use IMPL::Const qw(:prop); | 4 use IMPL::Const qw(:prop); |
5 | 5 |
6 use IMPL::declare { | 6 use IMPL::declare { |
7 require => { | 7 require => { |
8 Factory => 'IMPL::Object::Factory', | 8 NotAllowedException => 'IMPL::Web::NotAllowedException', |
9 CustomResourceContract => 'IMPL::Web::Application::CustomResourceContract' | 9 HttpResponse => 'IMPL::Web::HttpResponse' |
10 }, | 10 }, |
11 base => [ | 11 base => [ |
12 'IMPL::Web::Application::Resource' => '@_' | 12 'IMPL::Web::Application::Resource' => '@_' |
13 ], | 13 ], |
14 props => [ | 14 props => [ |
15 accessCheck => PROP_RW | 15 accessCheck => PROP_RW |
16 ] | 16 ] |
17 }; | 17 }; |
18 | 18 |
19 __PACKAGE__->static_accessor(contractFactory => CustomResourceContract ); | 19 our %RESOURCE_BINDINGS = ( |
20 __PACKAGE__->static_accessor_own(_contractInstance => undef); | 20 GET => 'HttpGet', |
21 POST => 'HttpPost', | |
22 PUT => 'HttpPut', | |
23 DELETE => 'HttpDelete', | |
24 HEAD => 'HttpHead' | |
25 ); | |
26 | |
27 __PACKAGE__->static_accessor(_rxResourcesMap => undef, 'own'); | |
28 __PACKAGE__->static_accessor(_nameResourcesMap => undef, 'own'); | |
29 | |
30 sub namedResources { | |
31 shift->_nameResourcesMap; | |
32 } | |
33 | |
34 sub regexResources { | |
35 shift->_rxResourcesMap; | |
36 } | |
21 | 37 |
22 sub CTOR { | 38 sub CTOR { |
23 my ($this,%args) = @_; | 39 my ($this,%args) = @_; |
24 | 40 |
25 $this->accessCheck($args{accessCheck}) | 41 $this->accessCheck($args{accessCheck}) |
26 if $args{accessCheck}; | 42 if $args{accessCheck}; |
27 } | 43 |
28 | 44 $this->verbs->{options} ||= \&_HttpOptionsBinding; |
29 sub contractInstance { | 45 |
46 while(my ($verb,$methodName) = each %RESOURCE_BINDINGS) { | |
47 $this->verbs->{lc($verb)} ||= sub { | |
48 my ($resource,$action) = @_; | |
49 | |
50 if (eval { $resource->can($methodName) }) { | |
51 return $resource->$methodName($action); | |
52 } else { | |
53 die NotAllowedException->new(allow => join(',', _GetAllowedHttpMethods($resource))); | |
54 } | |
55 } | |
56 } | |
57 } | |
58 | |
59 sub FindChildResourceInfo { | |
60 my ( $this, $name ) = @_; | |
61 | |
62 $this->_PrepareResourcesCache() | |
63 unless($this->_nameResourcesMap); | |
64 | |
65 return $this->next::method($name); | |
66 } | |
67 | |
68 sub PrepareResourcesCache { | |
69 # suppress default caching mechanisn | |
70 } | |
71 | |
72 sub _PrepareResourcesCache { | |
73 # a little bit wired | |
30 my ($self) = @_; | 74 my ($self) = @_; |
31 | 75 my %nameMap; |
32 $self = ref $self || $self; | 76 my @rxMap; |
33 $self->_contractInstance ? $self->_contractInstance : $self->InitContract(); | 77 |
34 } | 78 foreach my $res ($self->GetChildResources()) { |
35 | 79 #skip resources without contract |
36 sub InitContract { | 80 next unless $res->{contract}; |
37 my ($self) = @_; | 81 |
38 $self->_contractInstance( | 82 if ( my $name = $res->{name} ) { |
39 $self->contractFactory->new( | 83 $nameMap{$name} = $res; |
40 resourceFactory => $self, | 84 } |
41 resources => [ $self->GetChildResources() ] | 85 if ( $res->{match} ) { |
42 ) | 86 push @rxMap,$res; |
43 ); | 87 } |
44 } | 88 } |
45 | 89 |
46 sub CreateContract { | 90 $self->_rxResourcesMap(\@rxMap); |
47 my ($self, %args) = @_; | 91 $self->_nameResourcesMap(\%nameMap); |
48 | |
49 $self->contractFactory->new( | |
50 resourceFactory => Factory->new( | |
51 $self, | |
52 \%args | |
53 ), | |
54 resources => [ $self->GetChildResources() ] | |
55 ) | |
56 } | |
57 | |
58 sub CreateResource { | |
59 my ($self,%args) = @_; | |
60 | |
61 $self->CreateContract()->CreateResource(%args); | |
62 } | 92 } |
63 | 93 |
64 sub AccessCheck { | 94 sub AccessCheck { |
65 my ($this,$verb) = @_; | 95 my ($this,$verb) = @_; |
66 | 96 |
67 my $handler = $this->accessCheck; | 97 my $handler = $this->accessCheck; |
68 | 98 |
69 if(ref($handler) eq 'CODE') { | 99 if(ref($handler) eq 'CODE') { |
70 &$handler($this,$verb); | 100 return &$handler($this,$verb); |
71 } | 101 } |
72 } | 102 } |
73 | 103 |
74 sub GetChildResources { | 104 sub GetChildResources { |
75 | 105 |
106 } | |
107 | |
108 sub _HttpOptionsBinding { | |
109 my ($this) = @_; | |
110 | |
111 my @allow = $this->_GetAllowedHttpMethods(); | |
112 return HttpResponse->new( | |
113 status => '200 OK', | |
114 headers => { | |
115 allow => join ( ',', @allow ) | |
116 } | |
117 ); | |
118 } | |
119 | |
120 sub _GetAllowedHttpMethods { | |
121 my ($this) = @_; | |
122 return grep $this->can($RESOURCE_BINDINGS{$_}), keys %RESOURCE_BINDINGS; | |
76 } | 123 } |
77 | 124 |
78 | 125 |
79 1; | 126 1; |
80 | 127 |
109 my $form = MyApp::Web::Schema::UpdateUser->new(); | 156 my $form = MyApp::Web::Schema::UpdateUser->new(); |
110 | 157 |
111 $this->model->update( $form->Bind($action) ); | 158 $this->model->update( $form->Bind($action) ); |
112 } | 159 } |
113 | 160 |
114 our %COMPONENTS = ( | 161 sub GetChildResources { |
115 item => { | 162 return { |
116 verbs => { | 163 name => 'create', |
117 get => sub { | 164 contract => { |
118 shift->model; | 165 class => 'My::Web::FormResource', |
119 } | 166 formName => 'create', |
120 }, | 167 schema => 'profile.schema' |
121 resources => [ | 168 } |
122 edit => | 169 }, |
123 ] | 170 { |
124 } | 171 match => qr/^(.*)$/, |
125 ); | 172 contract => { |
173 class => 'My::Web::ItemResource' | |
174 } | |
175 } | |
176 } | |
126 | 177 |
127 =end code | 178 =end code |
128 | 179 |
129 =head1 MEMBERS | 180 =head1 MEMBERS |
130 | 181 |