File Coverage

lib/Egg/Manager.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package Egg::Manager;
2             #
3             # Masatoshi Mizuno E<lt>lusheE<64>cpan.orgE<gt>
4             #
5             # $Id: Manager.pm 337 2008-05-14 12:30:09Z lushe $
6             #
7 1     1   415 use strict;
  1         3  
  1         41  
8 1     1   7 use warnings;
  1         2  
  1         34  
9 1     1   6 use Carp qw/ croak /;
  1         2  
  1         67  
10 1     1   6 use base qw/ Egg::Component Egg::Base /;
  1         3  
  1         73  
11              
12             our $VERSION= '3.03';
13              
14             sub initialize {
15             my($class, $myname)= @_;
16             for (qw/ myname _default /) {
17             $class->mk_classdata($_) unless $class->can($_);
18             }
19             $class->myname($myname);
20             $class->SUPER::initialize;
21             }
22             sub setup_manager {
23             my($self) = @_;
24             my $class = ref($self);
25             my $myname= ucfirst $self->myname;
26             my $c= $self->e->config->{uc $myname} || [];
27             my $p= $self->e->project_name;
28             no strict 'refs'; ## no critic.
29             no warnings 'redefine';
30             for my $v (@$c) {
31             $v= [$v, undef] unless ref($v);
32             next if (! $v->[0] or $v->[0]=~m{^\-});
33             my($label, $pkg);
34             if ($v->[0]=~m{^\+(.+)}) {
35             $pkg= $1;
36             $label ||= lc($pkg);
37             } else {
38             $pkg= "Egg::${myname}::$v->[0]";
39             $label ||= lc($v->[0]);
40             }
41             my $p_class= "${p}::${myname}::$v->[0]";
42             my $p_path = $p->path_to('lib_project', "${myname}/$v->[0].pm");
43             my $handler;
44             my $load= -e $p_path ? do {
45             $p_class->require or die $@;
46             ($pkg, $handler)= ($p_class, "${p_class}::handler");
47             0;
48             }: do {
49             *{"${p_class}::config"}= sub {
50             my $proto= shift;
51             @_ ? $v->[1]= shift : ($v->[1] || {});
52             };
53             $handler= "${pkg}::handler";
54             1;
55             };
56             $class->isa_register($load, $label, $pkg, $v->[1]);
57             $handler->can('new')
58             || die qq{$class - Constructor of '${handler}' is not found. };
59             }
60             $class->isa_terminator;
61             $self->_default( (keys %{$self->regists})[0] || "" );
62             $self->_setup($self->e);
63             }
64             sub new {
65             my($class, $e)= @_;
66             bless { e=> $e }, $class;
67             }
68             sub default {
69             my $self= shift;
70             return $self->{default}= shift if @_;
71             $self->{default} ||= $self->_default
72             || croak ucfirst($self->myname). qq{ - default is empty. };
73             }
74             sub reset {
75             %{$_[0]}= ( e=> ($_[1] || die q{ I want egg context. }) );
76             }
77             sub context {
78             my $default= 0;
79             my $self = shift;
80             my $label= shift || do { $default= 1; $self->default };
81             $label= lc($label);
82             $self->{"$label.$default"} ||= do {
83             my $comp= $self->regists->{$label}
84             || croak ref($self). qq{ - '$label' is not set up. };
85             my $conf= $comp->[2] || {};
86             if (my $accept= $comp->[0]->can('ACCEPT_CONTEXT')) {
87             $accept->($comp->[0], $self->e, $conf, $default, @_);
88             } elsif (my $handler= "$comp->[0]::handler"->can('new')) {
89             $handler->
90             ("$comp->[0]::handler", $self->e, $conf, $default, @_);
91             } else {
92             $comp->[0]->new($self->e, $conf, $default, @_);
93             }
94             };
95             }
96             sub reset_context {
97             my $self = shift;
98             my $label= lc(shift) || croak ref($self). qq{ - I want label. };
99             for (0..1) { undef($self->{"$label.$_"}) if $self->{"$label.$_"} }
100             $self;
101             }
102             sub add_register {
103             my($self, $load)= splice @_, 0, 2;
104             my $label= lc(shift) || croak ref($self). qq{ - I want label. };
105             my $attr = $self->SUPER::add_register($load, $label, @_);
106             my $handler= "$attr->[0]::handler";
107             $handler->config($attr->[2])
108             if ($handler->isa('Egg::Base') and ! $handler->config);
109             $attr;
110             }
111             *register= \&add_register;
112              
113             sub any_hook {
114             my $self= shift;
115             my $base= shift || croak 'I want name of component';
116             my $hook= shift || croak 'I want name of hook.';
117             $base= $self->e->project_name. "::$base";
118             $base->can('labels')
119             || die qq{The labels method is not prepared in '$base'};
120             for my $label (keys %{$base->labels}) {
121             my $handle= $self->{"$label.0"} || $self->{"$label.1"} || next;
122             $handle->$hook($self->e);
123             }
124             $self;
125             }
126              
127             1;
128              
129             __END__
130              
131             =head1 NAME
132              
133             Egg::Manager - Model manager and view manager's base classes.
134              
135             =head1 DESCRIPTION
136              
137             It is a base class succeeded to by the handler of L<Egg::Manager::Model> and
138             L<Egg::Manager::View>.
139              
140             =head1 METHODS
141              
142             =head2 initialize
143              
144             When starting, it initializes it.
145              
146             =head2 setup_manager
147              
148             Initial is set up.
149              
150             The component specified by the configuration is concretely read, and it registers
151             in @ISA of the manager handler.
152              
153             =head2 new
154              
155             Constructor.
156              
157             =head2 default ([LABEL_STRING])
158              
159             It defaults to the component of LABEL_STRING and it sets it.
160              
161             The label of the component of the default decided that LABEL_STRING is omitted
162             by an initial setup is returned.
163              
164             =head2 reset ([PROJECT_OBJYECT])
165              
166             The object is initialized. PROJECT_OBJYECT is indispensable.
167              
168             =head2 context ([LABEL_STRING])
169              
170             The object of the component corresponding to LABEL_STRING is returned.
171              
172             When LABEL_STRING is omitted, default is used.
173              
174             =head2 reset_context ([LABEL_STRING])
175              
176             The constructor of the component is made to move again when the context method
177             is called next annulling the object of the component corresponding to LABEL_STRING
178             maintained with this object.
179              
180             =head2 add_register ([LOAD_BOOL], [LABEL_STRING], [PACKAGE_STRING], [CONFIG])
181              
182             The component is registered and to call it by the context method, it sets it up.
183             However, @ISA is not operated.
184              
185             Require is done at the same time as registering the module of PACKAGE_STRING when
186             an effective value to LOAD_BOOL is passed.
187              
188             LABEL_STRING gives the name to call it by the context method.
189              
190             PACKAGE_STRING gives the package name of the registered component. The value of
191             LABEL_STRING is misappropriated when omitting it.
192              
193             CONFIG can be omitted. It is preserved in the registration data when giving it.
194             Moreover, if "PACKAGE_STRING::handler" exists and the class has succeeded to
195             L<Egg::Base>, CONFIG is defined in the config method of the class.
196              
197             The main of this method is add_register method of L<Egg::Component>.
198              
199             =over 4
200              
201             =item * Alias = register
202              
203             =back
204              
205             =head2 any_hook ([CLASS_NAME], [CALL_HOOK])
206              
207             The CALL_HOOK method of the component managed by 'labels' method of the CLASS_NAME
208             class is continuously called.
209              
210             The project name is added to the head of CLASS_NAME. Therefore, the name since
211             the project name is passed.
212              
213             CALL_HOOK is a name of the method of wanting the call of the hook.
214              
215             # If it is MyApp::Model::Hooo.
216             $e->model_manager->any_hook(qw/ Model::Hooo _finish /);
217              
218             Nothing is done if there is no 'labels' method in the CLASS_NAME class.
219              
220             The data obtained by the 'labels' method should be HASH reference.
221             Moreover, the label name and the content of the called component should be the
222             structures of object of the component in the key to the HASH.
223              
224             =head1 SEE ALSO
225              
226             L<Egg::Release>,
227             L<Egg::Component>,
228             L<Egg::Base>,
229              
230             =head1 AUTHOR
231              
232             Masatoshi Mizuno E<lt>lusheE<64>cpan.orgE<gt>
233              
234             =head1 COPYRIGHT AND LICENSE
235              
236             Copyright (C) 2008 Bee Flag, Corp. E<lt>L<http://egg.bomcity.com/>E<gt>.
237              
238             This library is free software; you can redistribute it and/or modify
239             it under the same terms as Perl itself, either Perl version 5.8.6 or,
240             at your option, any later version of Perl 5 you may have available.
241              
242             =cut
243