Mercurial > pub > Impl
comparison Lib/IMPL/Web/Application/RestBaseResource.pm @ 200:a9dbe534d236
sync
author | sergey |
---|---|
date | Tue, 24 Apr 2012 02:34:49 +0400 |
parents | |
children | 0c018a247c8a |
comparison
equal
deleted
inserted
replaced
199:e743a8481327 | 200:a9dbe534d236 |
---|---|
1 package IMPL::Web::Application::RestBaseResource; | |
2 use strict; | |
3 | |
4 use IMPL::lang qw(:declare :constants); | |
5 use IMPL::declare { | |
6 require => { | |
7 Exception => 'IMPL::Exception', | |
8 ArgumentException => '-IMPL::InvalidArgumentException', | |
9 NotImplException => '-IMPL::NotImplementedException', | |
10 ForbiddenException => 'IMPL::Web::ForbiddenException', | |
11 TTransform => '-IMPL::Transform', | |
12 TResolve => '-IMPL::Config::Resolve' | |
13 }, | |
14 base => { | |
15 'IMPL::Object' => undef, | |
16 'IMPL::Object::Autofill' => '@_' | |
17 } | |
18 }; | |
19 | |
20 | |
21 BEGIN { | |
22 public property id => PROP_GET | PROP_OWNERSET; | |
23 public property parent => PROP_GET | PROP_OWNERSET; | |
24 public property contract => PROP_GET | PROP_OWNERSET; | |
25 } | |
26 | |
27 sub target { | |
28 shift; | |
29 } | |
30 | |
31 sub CTOR { | |
32 my ($this) = @_; | |
33 | |
34 die ArgumentException->new("id","Identifier is required for non-root resources") if $this->id and not length $this->id; | |
35 die ArgumentException->new("A contract is required") unless $this->contract; | |
36 } | |
37 | |
38 sub GetHttpImpl { | |
39 my($this,$method) = @_; | |
40 | |
41 my %map = ( | |
42 GET => 'GetImpl', | |
43 PUT => 'PutImpl', | |
44 POST => 'PostImpl', | |
45 DELETE => 'DeleteImpl' | |
46 ); | |
47 | |
48 return $map{$method}; | |
49 } | |
50 | |
51 sub InvokeHttpMethod { | |
52 my ($this,$method,$childId,$action) = @_; | |
53 | |
54 my $impl = $this->GetHttpImpl($method) || 'HttpFallbackImpl'; | |
55 | |
56 return $this->$impl($childId,$action); | |
57 } | |
58 | |
59 sub GetImpl { | |
60 die NotImplException->new(); | |
61 } | |
62 | |
63 sub PutImpl { | |
64 die NotImplException->new(); | |
65 } | |
66 | |
67 sub PostImpl { | |
68 die NotImplException->new(); | |
69 } | |
70 | |
71 sub DeleteImpl { | |
72 die NotImplException->new(); | |
73 } | |
74 | |
75 sub HttpFallbackImpl { | |
76 die ForbiddenException->new(); | |
77 } | |
78 | |
79 sub InvokeMember { | |
80 my ($this,$method,$action) = @_; | |
81 | |
82 die ArgumentException->new("method","No method information provided") unless $method; | |
83 | |
84 #normalize method info | |
85 if (not ref $method) { | |
86 $method = { | |
87 method => $method | |
88 }; | |
89 } | |
90 | |
91 if (ref $method eq 'HASH') { | |
92 my $member = $method->{method} or die InvalidOpException->new("A member name isn't specified"); | |
93 my @args; | |
94 | |
95 if (my $params = $method->{parameters}) { | |
96 if (ref $params eq 'HASH') { | |
97 @args = map { | |
98 $_, | |
99 $this->MakeParameter($params->{$_},$action) | |
100 } keys %$params; | |
101 } elsif (ref $params eq 'ARRAY') { | |
102 @args = map $this->MakeParameter($_,$action), @$params; | |
103 } else { | |
104 @args = ($this->MakeParameter($params,$action)); | |
105 } | |
106 } | |
107 return $this->target->$member(@args); | |
108 } elsif (ref $method eq TResolve) { | |
109 return $method->Invoke($this->target); | |
110 } elsif (ref $method eq 'CODE') { | |
111 return $method->($this->target,$action); | |
112 } else { | |
113 die InvalidOpException->new("Unsupported type of the method information", ref $method); | |
114 } | |
115 } | |
116 | |
117 sub MakeParameter { | |
118 my ($this,$param,$action) = @_; | |
119 | |
120 if ($param) { | |
121 if (is $param, TTransform ) { | |
122 return $param->Transform($this,$action->query); | |
123 } elsif ($param and not ref $param) { | |
124 my %std = ( | |
125 id => $this->id, | |
126 action => $action, | |
127 query => $action->query | |
128 ); | |
129 | |
130 return $std{$param} || $action->query->param($param); | |
131 } | |
132 } else { | |
133 return undef; | |
134 } | |
135 } | |
136 | |
137 | |
138 1; |