File Coverage

blib/lib/Dancer/App.pm
Criterion Covered Total %
statement 122 136 89.7
branch 43 52 82.6
condition 16 19 84.2
subroutine 28 29 96.5
pod 1 17 5.8
total 210 253 83.0


line stmt bran cond sub pod time code
1             package Dancer::App;
2             our $AUTHORITY = 'cpan:SUKRIA';
3             # ABSTRACT: Base application class for Dancer.
4             $Dancer::App::VERSION = '1.3514_04'; # TRIAL
5             $Dancer::App::VERSION = '1.351404';
6 171     171   167369 use strict;
  171         293  
  171         4039  
7 171     171   784 use warnings;
  171         256  
  171         3222  
8 171     171   675 use Carp;
  171         263  
  171         13702  
9 171     171   969 use base 'Dancer::Object';
  171         1554  
  171         66098  
10              
11 171     171   71064 use Dancer::Config;
  171         458  
  171         8169  
12 171     171   1140 use Dancer::ModuleLoader;
  171         298  
  171         3191  
13 171     171   68069 use Dancer::Route::Registry;
  171         494  
  171         4596  
14 171     171   9322 use Dancer::Logger;
  171         605  
  171         4194  
15 171     171   878 use Dancer::Exception qw(:all);
  171         287  
  171         15448  
16 171     171   1062 use Dancer::Deprecation;
  171         285  
  171         30604  
17              
18             Dancer::App->attributes(qw(name app_prefix prefix registry settings on_lexical_prefix));
19              
20             # singleton that saves any app created, we want unicity for app names
21             my $_apps = {};
22 1962     1962 0 6792 sub applications { values %$_apps }
23              
24             sub app_exists {
25 1444     1444 0 2242 my ( $self, $name ) = @_;
26 1444         2557 grep { $_ eq $name } keys %$_apps;
  1522         5565  
27             }
28              
29             sub set_running_app {
30 16     16 0 37 my ($self, $name) = @_;
31 16         37 my $app = Dancer::App->get($name);
32 16 100       79 $app = Dancer::App->new(name => $name) unless defined $app;
33 16         39 Dancer::App->current($app);
34             }
35              
36             sub set_app_prefix {
37 1     1 0 2 my ($self, $prefix) = @_;
38 1         4 $self->app_prefix($prefix);
39 1         2 $self->prefix($prefix);
40             }
41              
42             sub get_prefix {
43             # return the current prefix (if undefined, return an empty string)
44 3   100 3 0 8 return Dancer::App->current->prefix || '';
45             }
46              
47             sub incr_lexical_prefix {
48 171     171   1098 no warnings; # for undefined
  171         376  
  171         187740  
49 15     15 0 40 $_[0]->on_lexical_prefix( $_[0]->on_lexical_prefix + 1 );
50             }
51              
52             sub dec_lexical_prefix {
53 15     15 0 44 $_[0]->on_lexical_prefix( $_[0]->on_lexical_prefix - 1 );
54             }
55              
56             sub set_prefix {
57 29     29 0 52 my ($self, $prefix, $cb) = @_;
58              
59 29 100 100     107 undef $prefix if defined($prefix) and $prefix eq "/";
60              
61 29 100 100     155 raise core_app => "not a valid prefix: `$prefix', must start with a /"
62             if defined($prefix) && $prefix !~ /^\//;
63              
64 28 100       66 my $app_prefix = defined $self->app_prefix ? $self->app_prefix : "";
65 28         55 my $previous = Dancer::App->current->prefix;
66              
67 28   100     64 $prefix ||= "";
68              
69 28 100       68 if (Dancer::App->current->on_lexical_prefix) {
70 10         21 Dancer::App->current->prefix($previous.$prefix);
71             } else {
72 18         44 Dancer::App->current->prefix($app_prefix.$prefix);
73             }
74              
75 28 100       92 if (ref($cb) eq 'CODE') {
76 15         25 Dancer::App->current->incr_lexical_prefix;
77 15         23 eval { $cb->() };
  15         25  
78 15         27 my $e = $@;
79 15         28 Dancer::App->current->dec_lexical_prefix;
80 15         43 Dancer::App->current->prefix($previous);
81 15 50       31 die $e if $e;
82             }
83 28         63 return 1; # prefix may have been set to undef
84             }
85              
86             sub routes {
87 2     2 0 6 my ($self, $method) = @_;
88 2         3 map { $_->pattern } @{$self->registry->{'routes'}{$method}};
  1         3  
  2         5  
89             }
90              
91             sub reload_apps {
92 0     0 0 0 my ($class) = @_;
93              
94 0         0 Dancer::Deprecation->deprecated(
95             feature => 'auto_reload',
96             reason => 'use plackup -r instead',
97             );
98              
99 0         0 my @missing_modules = grep { not Dancer::ModuleLoader->load($_) }
  0         0  
100             qw(Module::Refresh Clone);
101              
102 0 0       0 if (not @missing_modules) {
103              
104             # saving apps & purging app registries
105 0         0 my $orig_apps = {};
106 0         0 while (my ($name, $app) = each %$_apps) {
107 0         0 $orig_apps->{$name} = $app->clone;
108 0         0 $app->registry->init();
109             }
110              
111             # reloading changed modules, getting apps reloaded
112 0         0 Module::Refresh->refresh;
113              
114             # make sure old apps that didn't get reloaded are kept
115 0         0 while (my ($name, $app) = each %$orig_apps) {
116 0 0       0 $_apps->{$name} = $app unless defined $_apps->{$name};
117 0 0       0 $_apps->{$name} = $app if $_apps->{$name}->registry->is_empty;
118             }
119              
120             }
121             else {
122 0         0 carp "Modules required for auto_reload are missing. Install modules"
123             . " [@missing_modules] or unset 'auto_reload' in your config file.";
124             }
125             }
126              
127             sub find_route_through_apps {
128 586     586 0 1169 my ($class, $request) = @_;
129 586         1234 for my $app (Dancer::App->current, Dancer::App->applications) {
130 622         1438 my $route = $app->find_route($request);
131 622 100       1280 if ($route) {
132 559         1411 Dancer::App->current($route->app);
133 559         1449 return $route;
134             }
135 63 50       130 return $route if $route;
136             }
137 27         78 return;
138             }
139              
140             # instance
141              
142             sub find_route {
143 622     622 0 1076 my ($self, $request) = @_;
144 622         1229 my $method = lc($request->method);
145              
146             # if route cache is enabled, we check if we handled this path before
147 622 100       1740 if (Dancer::Config::setting('route_cache')) {
148 84         286 my $route = Dancer::Route::Cache->get->route_from_path($method,
149             $request->path_info, $self->name);
150              
151             # NOTE maybe we should cache the match data as well
152 84 100       202 if ($route) {
153 36         90 $route->match($request);
154 36         70 return $route;
155             }
156             }
157              
158 586         863 my @routes = @{$self->registry->routes($method)};
  586         1371  
159              
160 586         1197 for my $r (@routes) {
161 1554         3469 my $match = $r->match($request);
162              
163 1554 100       3179 if ($match) {
164 537 100 100     1286 next if $r->has_options && (not $r->validate_options($request));
165              
166             # if we have a route cache, store the result
167 523 100       1277 if (Dancer::Config::setting('route_cache')) {
168 48         121 Dancer::Route::Cache->get->store_path($method,
169             $request->path_info => $r, $self->name);
170             }
171              
172 523         1351 return $r;
173             }
174             }
175 63         111 return;
176             }
177              
178             sub init {
179 116     116 1 410 my ($self) = @_;
180 116 100       434 $self->name('main') unless defined $self->name;
181              
182             raise core_app => "an app named '" . $self->name . "' already exists"
183 116 100       388 if exists $_apps->{$self->name};
184              
185             # default values for properties
186 115         518 $self->settings({});
187 115         412 $self->init_registry();
188              
189 115         537 $_apps->{$self->name} = $self;
190             }
191              
192             sub init_registry {
193 115     115 0 292 my ($self, $reg) = @_;
194 115   33     1418 $self->registry($reg || Dancer::Route::Registry->new);
195              
196             }
197              
198             # singleton that saves the current active Dancer::App object
199             my $_current;
200              
201             sub current {
202 8217     8217 0 12969 my ($class, $app) = @_;
203 8217 100       13588 return $_current = $app if defined $app;
204              
205 7159 100       10619 if (not defined $_current) {
206 99   66     503 $_current = Dancer::App->get('main') || Dancer::App->new();
207             }
208              
209 7159         14598 return $_current;
210             }
211              
212             sub get {
213 770     770 0 3715 my ($class, $name) = @_;
214 770         2298 $_apps->{$name};
215             }
216              
217             sub setting {
218 2401     2401 0 3169 my $self = shift;
219              
220 2401 100       4528 if ($self->name eq 'main') {
221 2259 100       5954 return (@_ > 1)
222             ? Dancer::Config::setting( @_ )
223             : Dancer::Config::setting( $_[0] );
224             }
225              
226 142 100       255 if (@_ > 1) {
227 38         81 $self->_set_settings(@_)
228             } else {
229 104         124 my $name = shift;
230 104 100       196 exists($self->settings->{$name}) ? $self->settings->{$name}
231             : Dancer::Config::setting($name);
232             }
233             }
234              
235             sub _set_settings {
236 38     38   46 my $self = shift;
237 38 50       84 die "Odd number of elements in set" unless @_ % 2 == 0;
238 38         67 while (@_) {
239 38         45 my $name = shift;
240 38         45 my $value = shift;
241 38         102 $self->settings->{$name} =
242             Dancer::Config->normalize_setting($name => $value);
243             }
244             }
245              
246              
247             1;
248              
249             __END__