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;