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