File Coverage

blib/lib/WebService/GData/Base.pm
Criterion Covered Total %
statement 95 103 92.2
branch 34 44 77.2
condition 5 15 33.3
subroutine 21 21 100.0
pod 11 11 100.0
total 166 194 85.5


line stmt bran cond sub pod time code
1             package WebService::GData::Base;
2 5     5   96341 use WebService::GData 'private';
  5         14  
  5         27  
3 5     5   30 use base 'WebService::GData';
  5         8  
  5         480  
4              
5 5     5   3404 use WebService::GData::Query;
  5         12  
  5         63  
6 5     5   41 use WebService::GData::Error;
  5         8  
  5         52  
7 5     5   27 use WebService::GData::Constants qw(:all);
  5         18  
  5         2046  
8              
9 5     5   6602 use JSON;
  5         94183  
  5         30  
10 5     5   6406 use LWP;
  5         238572  
  5         10629  
11              
12             #the base class specifies the basic get/post/insert/update/delete methods
13              
14             our $VERSION = 0.02_03;
15              
16             sub __set {
17 1     1   3 my ($this,$func,$val)=@_;
18 1 50       6 die new WebService::GData::Error('forbidden_method_call',
19             'agent() is used internally.' ) if $func eq 'agent';
20              
21 1 50       19 if(my $code = $this->{__UA__}->can($func)){
22 1         8 $code->($this->{__UA__},$val);
23 1         24 return $this;
24             }
25 0         0 die new WebService::GData::Error('unknown_method_call',
26             $func.'() is not a LWP::UserAgent Method.' );
27             }
28              
29             sub __get {
30 2     2   5 my ($this,$func)=@_;
31 2 100       23 die new WebService::GData::Error('forbidden_method_call',
32             'agent() is used internally.' ) if $func eq 'agent';
33 1         8 my $code = $this->{__UA__}->can($func);
34 1 50       7 return $code->($this->{__UA__}) if $code;
35 0         0 die new WebService::GData::Error('unknown_method_call',
36             $func.'() is not a LWP::UserAgent Method.' );
37             }
38              
39             sub __init {
40 3     3   9 my ( $this, %params ) = @_;
41              
42 3         224 $this->{__COMPRESSION__}= FALSE;
43 3         9 $this->{__OVERRIDE__} = FALSE;
44 3         8 $this->{__AUTH__} = undef;
45 3         7 $this->{__URI__} = undef;
46 3         29 $this->{__UA__} = LWP::UserAgent->new;
47 3         672750 $this->{__UA_NAME__} = '';
48 3         49 $this->query( new WebService::GData::Query() );
49              
50 3 50       17 $this->auth( $params{auth} )
51             if ( defined $params{auth} );
52             }
53              
54             sub auth {
55 48     48 1 73 my ( $this, $auth ) = @_;
56              
57 48 100       106 if ( _is_auth_object_compliant($auth) ) {
58 1         3 $this->{__AUTH__} = $auth;
59 1         4 $this->_set_ua_name;
60             }
61 48         713 return $this->{__AUTH__};
62             }
63              
64             sub query {
65 22     22 1 1036 my ( $this, $query ) = @_;
66 22 100       65 $this->{_basequery} = $query
67             if ( _is_query_object_compliant($query) );
68 22         145 return $this->{_basequery};
69             }
70              
71             sub override_method {
72 12     12 1 4026 my ( $this, $override ) = @_;
73              
74 12 100       94 return $this->{__OVERRIDE__} if ( !$override );
75              
76 4 100       20 if ( $override eq TRUE ) {
77 2         9 $this->{__OVERRIDE__} = TRUE;
78             }
79 4 100       21 if ( $override eq FALSE ) {
80 1         4 $this->{__OVERRIDE__} = FALSE;
81             }
82             }
83              
84             sub enable_compression {
85 32     32 1 1288 my ( $this, $compression ) = @_;
86              
87 32 100       158 return $this->{__COMPRESSION__} if ( !$compression );
88              
89 4 100       13 if ( $compression eq TRUE ) {
90 2         5 $this->{__COMPRESSION__} = TRUE;
91             }
92 4 100       15 if ( $compression eq FALSE ) {
93 2         5 $this->{__COMPRESSION__} = FALSE;
94             }
95 4         12 $this->_set_ua_name;
96             }
97              
98             sub user_agent_name {
99 8     8 1 1706 my ($this,$name) = @_;
100 8 100       49 return $this->{__UA__}->agent if not defined $name;
101 2         4 $this->{__UA_NAME__}=$name;
102 2         8 $this->_set_ua_name;
103            
104             }
105              
106             sub get_uri {
107 2     2 1 6 my $this = shift;
108 2         23 return $this->{__URI__};
109             }
110              
111              
112             sub get {
113 2     2 1 9 my ( $this, $uri,$with_query_string ) = @_;
114              
115             #the url from the feeds contain the version but not the one we pass directly
116 2 50       5 $this->query->set_from_query_string($uri) if $with_query_string;
117            
118 2         45 $uri = _delete_query_string($uri);
119              
120 2 50 33     15 _error_invali_uri('get') if ( !$uri || length($uri) == 0 );
121              
122 2         4 $this->{__URI__} = $uri;
123 2         5 my $req = HTTP::Request->new( GET => $uri . $this->query->to_query_string );
124 2         30 $req->content_type('application/atom+xml; charset=UTF-8');
125              
126 2         122 $this->_prepare_request($req);
127              
128 2         7 my $ret = $this->_request($req);
129 2 100       88 return $this->query->get('alt') =~ m/^jsonc*$/ ? from_json($ret) : $ret;
130              
131             }
132              
133             sub post {
134 1     1 1 3 my ( $this, $uri, $content ) = @_;
135              
136 1 50 33     9 _error_invali_uri('post') if ( !$uri || length($uri) == 0 );
137              
138 0         0 $this->{__URI__} = $uri;
139 0         0 my $req = HTTP::Request->new( POST => $uri );
140 0         0 $req->content_type('application/x-www-form-urlencoded');
141 0         0 $this->_prepare_request( $req, length($content) );
142 0         0 $req->content($content);
143 0         0 return $this->_request($req);
144             }
145              
146             sub insert {
147 1     1 1 483 my ( $this, $uri, $content, $callback ) = @_;
148              
149 1 50 33     11 _error_invali_uri('insert') if ( !$uri || length($uri) == 0 );
150              
151 1         5 return $this->_save( 'POST', $uri, $content, $callback );
152             }
153              
154             sub update {
155 2     2 1 2461 my ( $this, $uri, $content, $callback ) = @_;
156              
157 2 50 33     18 _error_invali_uri('update') if ( !$uri || length($uri) == 0 );
158              
159 2         9 return $this->_save( 'PUT', $uri, $content, $callback );
160             }
161              
162             sub delete {
163 2     2 1 1037 my ( $this, $uri ) = @_;
164              
165 2 50 33     17 _error_invali_uri('delete') if ( !$uri || length($uri) == 0 );
166              
167 2         5 $this->{__URI__} = $uri;
168 2         2 my $req;
169 2 100       6 if ( $this->override_method eq TRUE ) {
170 1         5 $req = HTTP::Request->new( POST => $uri );
171 1         11 $req->header( 'X-HTTP-Method-Override' => 'DELETE' );
172             }
173             else {
174 1         5 $req = HTTP::Request->new( DELETE => $uri );
175             }
176 2         72 $req->content_type('application/atom+xml; charset=UTF-8');
177 2         110 $this->_prepare_request($req);
178              
179 2         123 return $this->_request($req);
180             }
181              
182             ###PRIVATE###
183              
184             #methods#
185              
186             private _set_ua_name => sub {
187             my ( $this ) = @_;
188             my $custom = $this->{__UA_NAME__} ? $this->{__UA_NAME__}.' ' : '';
189             my $name = $custom._ua_base_name();
190             $name = $this->auth->source . ' ' . $name if $this->auth;
191             $name.= ' (gzip)' if $this->enable_compression eq TRUE;
192             $this->{__UA__}->agent($name);
193             };
194              
195             private _request => sub {
196             my ( $this, $req ) = @_;
197              
198             $this->_set_ua_name();
199            
200             if($this->enable_compression eq TRUE) {
201             my $compressions = HTTP::Message::decodable();
202             $this->{__UA__}->default_header('Accept-Encoding' => $compressions) if $compressions=~m/gzip/;
203             }
204              
205             my $res = $this->{__UA__}->request($req);
206              
207             if ( $res->is_success ) {
208             return $this->enable_compression eq TRUE ? $res->decoded_content():$res->content();
209             }
210             else {
211             die new WebService::GData::Error( $res->code, $res->content );
212             }
213             };
214              
215             private _save => sub {
216             my ( $this, $method, $uri, $content, $callback ) = @_;
217             $this->{__URI__} = $uri;
218             my $req;
219             if ( $this->override_method eq TRUE && $method =~ m/PUT|PATCH/ ) {
220             $req = HTTP::Request->new( POST => $uri );
221             $req->header( 'X-HTTP-Method-Override' => $method );
222             }
223             else {
224             $req = HTTP::Request->new( "$method" => $uri );
225             }
226             $req->content_type('application/atom+xml; charset=UTF-8');
227              
228              
229              
230             $this->_prepare_request( $req, length($content) );
231             $req->content($content);
232             if ($callback) {
233             &$callback($req);
234             }
235              
236             return $this->_request($req);
237             };
238              
239             private _prepare_request => sub {
240             my ( $this, $req, $length ) = @_;
241             $req->header( 'GData-Version' => $this->query->get('v') );
242             $req->header( 'Content-Length' => $length ) if ($length);
243             if ( $this->auth ) {
244             $this->auth->set_authorization_headers( $this, $req );
245             $this->auth->set_service_headers( $this, $req );
246             }
247             };
248              
249             #sub#
250              
251             private _error_invali_uri => sub {
252             my $method = shift;
253             die new WebService::GData::Error( 'invalid_uri',
254             'The uri is empty in ' . $method . '().' );
255             };
256              
257             private _ua_base_name => sub {
258             return __PACKAGE__ . "/" . $VERSION;
259             };
260              
261              
262             private _is_object => sub {
263             my $val = shift;
264             eval { $val->can('can'); };
265             return undef if ($@);
266             return 1;
267              
268             };
269              
270             #duck typing has I don't want to enfore inheritance
271             private _is_auth_object_compliant => sub {
272             my $auth = shift;
273             return 1
274             if ( _is_object($auth)
275             && $auth->can('set_authorization_headers')
276             && $auth->can('set_service_headers')
277             && $auth->can('source') );
278             return undef;
279             };
280              
281             private _is_query_object_compliant => sub {
282             my $query = shift;
283             return 1
284             if ( _is_object($query)
285             && $query->can('to_query_string')
286             && $query->can('get')
287             && int( $query->get('v') ) >= GDATA_MINIMUM_VERSION );
288             return undef;
289             };
290              
291             private _delete_query_string => sub {
292             my $uri = shift;
293             $uri =~ s/\?.*//;
294             return $uri;
295             };
296              
297             "The earth is blue like an orange.";
298              
299             __END__