File Coverage

blib/lib/Eve/Registry.pm
Criterion Covered Total %
statement 37 39 94.8
branch n/a
condition n/a
subroutine 13 13 100.0
pod n/a
total 50 52 96.1


line stmt bran cond sub pod time code
1             package Eve::Registry;
2              
3 8     8   50 use parent qw(Eve::Class);
  8         25  
  8         67  
4              
5 8     8   409 use strict;
  8         72  
  8         305  
6 8     8   41 use warnings;
  8         16  
  8         429  
7              
8 8     8   47 use File::Basename ();
  8         13  
  8         159  
9              
10 8     8   5659 use Eve::Email;
  8         30  
  8         264  
11 8     8   5435 use Eve::EventMap;
  8         20  
  8         222  
12 8     8   3936 use Eve::HttpOutput;
  8         19  
  8         200  
13 8     8   4364 use Eve::HttpRequest::Psgi;
  8         33  
  8         311  
14 8     8   5482 use Eve::HttpDispatcher;
  8         25  
  8         6877  
15 8     8   10628 use Eve::HttpResource::Template;
  8         43  
  8         384  
16 8     8   5259 use Eve::HttpResponse::Psgi;
  8         42  
  8         343  
17 8     8   5052 use Eve::Json;
  8         24  
  8         218  
18 8     8   4291 use Eve::PgSql;
  0            
  0            
19             use Eve::Session;
20             use Eve::Template;
21             use Eve::Uri;
22              
23             =head1 NAME
24              
25             B - a service provider class.
26              
27             =head1 SYNOPSIS
28              
29             my $registry = Eve::Registry->new(
30             # some literals declarations);
31              
32             my $service = $registry->get_service();
33              
34             =head1 DESCRIPTION
35              
36             B is the class that provides all services that are
37             required by the application and manages their dependencies.
38              
39             =head3 Constructor arguments
40              
41             =over 4
42              
43             =item C
44              
45             =item C
46              
47             =item C
48              
49             an optional base URI alias string list
50              
51             =item C
52              
53             =item C
54              
55             =item C
56              
57             =item C
58              
59             =item C
60              
61             =item C
62              
63             =item C
64              
65             =item C
66              
67             an interval of idling from the last access when the session is
68             considered actual (0 cancels expiration), 30 days is set by default,
69              
70             =item C
71              
72             =item C
73              
74             =item C
75              
76             =item C
77              
78             a hash of variables that will be made available for the templates.
79              
80             =back
81              
82             the C literals except C are C by default
83             so an attempt will be made to use standard PostgreSQL environment
84             variables. For the C the default 'public' value will be
85             used.
86              
87             =head1 METHODS
88              
89             =head2 B
90              
91             =cut
92              
93             sub init {
94             my ($self, %arg_hash) = @_;
95             Eve::Support::arguments(
96             \%arg_hash,
97              
98             my $working_dir_string = File::Spec->catdir(
99             File::Basename::dirname(__FILE__), '..', '..'),
100              
101             my $base_uri_string,
102             my $alias_base_uri_string_list = [],
103              
104             my $email_from_string,
105              
106             my $pgsql_database = \undef,
107             my $pgsql_host = \undef,
108             my $pgsql_port = \undef,
109             my $pgsql_user = \undef,
110             my $pgsql_password = \undef,
111             my $pgsql_schema = \undef,
112              
113             my $session_storage_path = File::Spec->catdir(
114             File::Spec->curdir(), 'tmp', 'session'),
115             my $session_expiration_interval = 30 * 24 * 60 * 60,
116             my $session_cookie_domain = \undef,
117              
118             my $template_path = File::Spec->catdir(
119             File::Spec->curdir(), 'template'),
120             my $template_compile_path = File::Spec->catdir(
121             File::Spec->curdir(), 'tmp', 'template'),
122             my $template_expiration_interval = 60,
123             my $template_var_hash = {});
124              
125             $self->{'working_dir_string'} = $working_dir_string;
126              
127             $self->{'base_uri_string'} = $base_uri_string;
128             $self->{'alias_base_uri_string_list'} = $alias_base_uri_string_list;
129              
130             $self->{'email_from_string'} = $email_from_string;
131              
132             $self->{'pgsql_database'} = $pgsql_database;
133             $self->{'pgsql_host'} = $pgsql_host;
134             $self->{'pgsql_port'} = $pgsql_port;
135             $self->{'pgsql_user'} = $pgsql_user;
136             $self->{'pgsql_password'} = $pgsql_password;
137             $self->{'pgsql_schema'} = $pgsql_schema;
138              
139             $self->{'session_storage_path'} = $session_storage_path;
140             $self->{'session_expiration_interval'} = $session_expiration_interval;
141             $self->{'session_cookie_domain'} = $session_cookie_domain;
142              
143             $self->{'template_path'} = $template_path;
144             $self->{'template_compile_path'} = $template_compile_path;
145             $self->{'template_expiration_interval'} = $template_expiration_interval;
146             $self->{'template_var_hash'} = $template_var_hash;
147              
148             $self->{'_lazy_hash'} = {};
149             }
150              
151             =head1 SERVICES
152              
153             The registry's purpose is to provide different services, which can be
154             simple literals as well as lists, hashes and objects. For objects
155             there are two types of services: B and B:
156              
157             =head3 Lazy loader
158              
159             A lazy loader service is a service that creates the object it
160             provides upon first request. All subsequent requests of this service
161             will return the same object that was created the first time.
162              
163             use Eve::Registry;
164              
165             sub first_sub {
166             my $registry = Eve::Registry->new();
167             my $lazy_service = $registry->get_lazy_service();
168              
169             $lazy_service->set_state(true);
170             }
171              
172             sub second_sub {
173             my $registry = Eve::Registry->new();
174             my $lazy_service = $registry->get_lazy_service();
175              
176             # Returns state set in previous sub
177             print $lazy_service->get_state();
178             }
179              
180             =head3 Prototype
181              
182             A prototype service is a service that creates the provided object
183             each time it is requested.
184              
185             use Eve::Registry;
186              
187             sub third_sub {
188             my $registry = Eve::Registry->new();
189             my $first_service = $registry->get_proto_service();
190             my $second_service = $registry->get_proto_service();
191              
192             if ($first_service eq $second_service) {
193             die("This will never get executed");
194             }
195             }
196              
197             =head2 B
198              
199             Creates a service object if it hasn't been created and returns
200             it. Otherwise returns a stored copy of a previously service object.
201              
202             =head3 Arguments
203              
204             =over 4
205              
206             =item C
207              
208             A unique name for a service,
209              
210             =item C
211              
212             A code reference that must create and return the service object.
213              
214             =back
215              
216             =cut
217              
218             sub lazy_load {
219             my ($self, %arg_hash) = @_;
220             Eve::Support::arguments(\%arg_hash, my ($name, $code));
221              
222             if (not defined $self->_lazy_hash->{$name}) {
223             $self->_lazy_hash->{$name} = $code->();
224             }
225              
226             return $self->_lazy_hash->{$name};
227             }
228              
229             =head2 B
230              
231             A URI prototype service.
232              
233             =head3 Arguments
234              
235             =over 4
236              
237             =item C
238              
239             a URI string that will be used to create a new URI object.
240              
241             =back
242              
243             =cut
244              
245             sub get_uri {
246             my $self = shift;
247              
248             return Eve::Uri->new(@_);
249             }
250              
251             =head2 B
252              
253             A base URI prototype service.
254              
255             =cut
256              
257             sub get_base_uri {
258             my $self = shift;
259              
260             return $self->get_uri(string => $self->base_uri_string);
261             }
262              
263             =head2 B
264              
265             A list of alias base URIs prototype service.
266              
267             =cut
268              
269             sub get_alias_base_uri_list {
270             my $self = shift;
271              
272             return [
273             map { $self->get_uri(string => $_) }
274             @{$self->alias_base_uri_string_list}];
275             }
276              
277             =head2 B
278              
279             An HTTP request lazy loader service.
280              
281             =cut
282              
283             sub get_http_request {
284             my $self = shift;
285              
286             return Eve::HttpRequest::Psgi->new(
287             uri_constructor => sub { return $self->get_uri(@_); },
288             @_);
289             }
290              
291             =head2 B
292              
293             An HTTP response lazy loader service.
294              
295             =cut
296              
297             sub get_http_response {
298             my $self = shift;
299              
300             return Eve::HttpResponse::Psgi->new();
301             }
302              
303             =head2 B
304              
305             An event map lazy loader service.
306              
307             =cut
308              
309             sub get_event_map {
310             my $self = shift;
311              
312             return $self->lazy_load(
313             name => 'event_map',
314             code => sub {
315             return Eve::EventMap->new();
316             });
317             }
318              
319             =head2 B
320              
321             A mailer lazy loader service.
322              
323             =cut
324              
325             sub get_email {
326             my $self = shift;
327              
328             return $self->lazy_load(
329             name => 'email',
330             code => sub {
331             return Eve::Email->new(from => $self->email_from_string);
332             });
333             }
334              
335             =head2 B
336              
337             An HTTP resource dispatcher lazy loader service.
338              
339             =cut
340              
341             sub get_http_dispatcher {
342             my $self = shift;
343              
344             return $self->lazy_load(
345             name => 'http_dispatcher',
346             code => sub {
347             return Eve::HttpDispatcher->new(
348             request_constructor => sub {
349             return $self->get_http_request(@_);
350             },
351             response => $self->get_http_response(),
352             event_map => $self->get_event_map(),
353             base_uri => $self->get_base_uri(),
354             alias_base_uri_list => $self->get_alias_base_uri_list());
355             });
356             }
357              
358             =head2 B
359              
360             An HTTP output lazy service.
361              
362             =cut
363              
364             sub get_http_output {
365             my $self = shift;
366              
367             return $self->lazy_load(
368             name => 'http_output',
369             code => sub {
370             return Eve::HttpOutput->new(filehandle => *STDOUT);
371             });
372             }
373              
374             =head2 B
375              
376             A Template lazy loader service.
377              
378             =cut
379              
380             sub get_template {
381             my $self = shift;
382              
383             return $self->lazy_load(
384             name => 'template',
385             code => sub {
386             return Eve::Template->new(
387             path => $self->template_path,
388             compile_path => $self->template_compile_path,
389             expiration_interval => $self->template_expiration_interval,
390             var_hash => $self->get_template_var_hash());
391             });
392             }
393              
394             =head2 B
395              
396             A lazy template hash getter service.
397              
398             =cut
399              
400             sub get_template_var_hash {
401             my $self = shift;
402              
403             return {%{$self->template_var_hash or {}}, @_};
404             }
405              
406             =head2 B
407              
408             A persistent session prototype service.
409              
410             =head3 Arguments
411              
412             =over 4
413              
414             =item C
415              
416             a session identifier md5 string
417              
418             =back
419              
420             =cut
421              
422             sub get_session {
423             my $self = shift;
424              
425             return Eve::Session->new(
426             storage_path => $self->session_storage_path,
427             expiration_interval => $self->session_expiration_interval,
428             @_);
429             }
430              
431             =head2 B
432              
433             A PostgreSQL registry lazy loader service.
434              
435             =cut
436              
437             sub get_pgsql {
438             my $self = shift;
439              
440             return $self->lazy_load(
441             name => 'pgsql',
442             code => sub {
443             return Eve::PgSql->new(
444             database => $self->pgsql_database,
445             host => $self->pgsql_host,
446             port => $self->pgsql_port,
447             user => $self->pgsql_user,
448             password => $self->pgsql_password,
449             schema => $self->pgsql_schema);
450             });
451             }
452              
453             =head2 B
454              
455             A JSON converter adapter class lazy loader service.
456              
457             =cut
458              
459             sub get_json {
460             my $self = shift;
461              
462             return $self->lazy_load(
463             name => 'json',
464             code => sub {
465             return Eve::Json->new();
466             });
467             }
468              
469             =head2 B
470              
471             A shorthand method for binding resources to specific URI
472             patterns. Accepts arguments as a simple list, which are resource
473             binding name, pattern and constructor code reference. The fourth
474             argument is a hash reference that is added to the C method call.
475              
476             =cut
477              
478             sub add_binding {
479             my ($self, $name, $pattern, $resource_constructor) = @_;
480              
481             my $http_dispatcher = $self->get_http_dispatcher();
482              
483             return $http_dispatcher->bind(
484             name => $name,
485             pattern => $pattern,
486             resource_constructor => $resource_constructor);
487             }
488              
489             =head2 B
490              
491             Binds HTTP event handlers for standard request/response functionality.
492              
493             =cut
494              
495             sub bind_http_event_handlers {
496             my $self = shift;
497              
498             my $event_map = $self->get_event_map();
499              
500             $event_map->bind(
501             event_class => 'Eve::Event::PsgiRequestReceived',
502             handler => $self->get_http_dispatcher());
503             }
504              
505             sub _get_http_resource_parameter_list {
506             my $self = shift;
507              
508             return {
509             'response' => $self->get_http_response(),
510             'session_constructor' => sub { return $self->get_session(@_); },
511             'dispatcher' => $self->get_http_dispatcher(),
512             (defined $self->session_cookie_domain ?
513             ('session_cookie_domain' => $self->session_cookie_domain) : ())};
514             }
515              
516             sub _get_template_http_resource_parameter_list {
517             my $self = shift;
518              
519             return {
520             %{$self->_get_http_resource_parameter_list()},
521             template => $self->get_template(),
522             template_var_hash => $self->get_template_var_hash(),
523             text_var_hash => $self->template_text_hash};
524             }
525              
526             sub _get_graph_http_resource_parameter_list {
527             my $self = shift;
528              
529             return {
530             %{$self->_get_http_resource_parameter_list()},
531             'json' => $self->get_json()};
532             }
533              
534             =head1 SEE ALSO
535              
536             =over 4
537              
538             =item L
539              
540             =item L
541              
542             =item L
543              
544             =item L
545              
546             =item L
547              
548             =item L
549              
550             =item L
551              
552             =item L
553              
554             =item L
555              
556             =item L
557              
558             =item L
559              
560             =item L
561              
562             =item L
563              
564             =item L
565              
566             =item L
567              
568             =back
569              
570             =head1 LICENSE AND COPYRIGHT
571              
572             Copyright 2012 Igor Zinovyev.
573              
574             This program is free software; you can redistribute it and/or modify it
575             under the terms of either: the GNU General Public License as published
576             by the Free Software Foundation; or the Artistic License.
577              
578             See http://dev.perl.org/licenses/ for more information.
579              
580              
581             =head1 AUTHOR
582              
583             =over 4
584              
585             =item L
586              
587             =item L
588              
589             =back
590              
591             =cut
592              
593             1;