File Coverage

blib/lib/WebDAO/Container.pm
Criterion Covered Total %
statement 34 135 25.1
branch 0 52 0.0
condition 0 12 0.0
subroutine 10 20 50.0
pod 2 2 100.0
total 46 221 20.8


line stmt bran cond sub pod time code
1             package WebDAO::Container;
2              
3             #$Id$
4              
5             =head1 NAME
6              
7             WebDAO::Container - Group of objects
8              
9             =head1 SYNOPSIS
10              
11             =head1 DESCRIPTION
12              
13             WebDAO::Container - Group of objects
14              
15             =cut
16              
17             our $VERSION = '0.02';
18              
19 6     6   1729 use WebDAO::Element;
  6         17  
  6         272  
20 6     6   68 use base qw(WebDAO::Element);
  6         17  
  6         399  
21 6     6   40 use strict 'vars';
  6         12  
  6         142  
22 6     6   30 use warnings;
  6         64  
  6         3352  
23              
24             __PACKAGE__->mk_attr( __post_childs => '', __pre_childs => '', __childs => '' );
25              
26             sub _sysinit {
27 1     1   3 my $self = shift;
28              
29             #First invoke parent _init;
30 1         11 $self->SUPER::_sysinit(@_);
31              
32             #init childs
33 1         5 $self->_clear_childs_();
34             }
35              
36             =head1 METHODS (chidls)
37              
38             =head2 _get_childs_()
39              
40             Return ref to childs array
41              
42             =cut
43              
44             sub _get_childs_ {
45 1     1   2 my $self = shift;
46             return [
47 1         23 @{ $self->__pre_childs() },
48 1         15 @{ $self->__childs() },
49 1         2 @{ $self->__post_childs() }
  1         15  
50             ];
51             }
52              
53             =head3 _add_childs_($object1[, $object2])
54              
55             Insert set of objects into container
56              
57             =cut
58              
59             sub _add_childs_ {
60 0     0   0 my $self = shift;
61 0         0 $self->__add_childs__( 1, @_ );
62             }
63              
64             =head2 _clear_childs_
65              
66             Clear all childs (pre, post also)
67              
68             =cut
69              
70             sub _clear_childs_ {
71 1     1   3 my $self = shift;
72 1         27 $self->__post_childs( [] );
73 1         46 $self->__childs( [] );
74 1         23 $self->__pre_childs( [] );
75             }
76              
77             =head2 _set_childs_ @childs_set
78              
79             Clear all childs (except "pre" and "post" objects), and set to C<@childs_set>
80              
81             =cut
82              
83             # 0 - pre, 1 - fetch , 2 - post
84             sub __set_childs__ {
85 0     0   0 my $self = shift;
86 0         0 my $type = shift;
87 0 0       0 my $dst = $type == 0
    0          
88             ? $self->__pre_childs #0
89             : $type == 1 ? $self->__childs() #1
90             : $self->__post_childs; #2
91 0         0 for ( @{$dst} ) {
  0         0  
92 0         0 $_->_destroy;
93             }
94 0         0 $self->__add_childs__( $type, @_ );
95             }
96              
97             # 0 - pre, 1 - fetch , 2 - post
98             sub __add_childs__ {
99 0     0   0 my $self = shift;
100 0         0 my $type = shift;
101 0 0       0 my $dst = $type == 0
    0          
102             ? $self->__pre_childs #0
103             : $type == 1 ? $self->__childs() #1
104             : $self->__post_childs; #2
105             my @childs =
106 0         0 grep { ref $_ }
107 0 0       0 map { ref($_) eq 'ARRAY' ? @$_ : $_ }
108 0         0 map { $_->__get_self_refs }
109 0 0       0 grep { ref($_) && $_->can('__get_self_refs') }
110 0 0       0 map { ref($_) eq 'ARRAY' ? @$_ : $_ } @_;
  0         0  
111 0 0       0 return unless @childs;
112 0 0       0 if ( $self->__parent ) {
113 0         0 $_->_set_parent($self) for @childs;
114             }
115 0         0 push( @{$dst}, @childs );
  0         0  
116             }
117              
118             sub _set_childs_ {
119 0     0   0 my $self = shift;
120              
121             #first destoroy
122 0         0 for ( @{ $self->__childs() } ) {
  0         0  
123 0         0 $_->_destroy;
124             }
125 0         0 $self->__childs( [] );
126 0         0 $self->_add_childs_(@_);
127             }
128              
129             =head1 OUTPUT_METHODS
130              
131             =head2 pre_fetch ($session)
132              
133             Output data precede to fetch method. By default output "pre" objects;
134              
135             =cut
136              
137             sub pre_fetch {
138 0     0 1 0 my $self = shift;
139 0         0 @{ $self->__pre_childs };
  0         0  
140             }
141              
142             =head2 post_fetch ($session)
143              
144             Output data follow to fetch method. By default output "post" objects;
145              
146             =cut
147              
148             sub post_fetch {
149 0     0 1 0 my $self = shift;
150 0         0 @{ $self->__post_childs };
  0         0  
151             }
152              
153             =head1 OTHER
154             =cut
155              
156             #it for container
157             sub _set_parent {
158 1     1   4 my ( $self, $par ) = @_;
159 1         7 $self->SUPER::_set_parent($par);
160 1         2 foreach my $ref ( @{ $self->_get_childs_ } ) {
  1         6  
161 0           $ref->_set_parent($self);
162             }
163             }
164              
165             sub __any_path {
166 0     0     my $self = shift;
167 0           my $sess = shift;
168 0           my ($method) = @_;
169 0           my ( $res, $path ) = $self->SUPER::__any_path( $sess, @_ );
170              
171             #process routes
172 0 0         unless ( defined($res) ) {
  0            
173 6     6   43 no strict 'refs';
  6         677  
  6         751  
174 0           my $pkg = ref($self);
175 0           my %routes = %{"${pkg}::_WEBDAO_ROUTE_"};
  0            
176 0 0 0       if ( exists $routes{$method} and my $class = $routes{$method} ) {
177 0 0         unless ( UNIVERSAL::isa( $class, 'WebDAO::Container' ) ) {
178 0           my $isa = \@{"${class}::ISA"};
  0            
179 0           push @$isa, 'WebDAO::Container';
180             }
181 0           my $obj = $self->_root_->_create_( $method, $class );
182 0           $self->_add_childs_($obj);
183 0           $path = \@_;
184 0           $res = $self;
185             }
186 6     6   38 use strict 'refs';
  6         13  
  6         2395  
187             }
188 0 0         return undef unless defined($res);
189 0 0         if ( ref($res) eq 'ARRAY' ) {
190              
191             #make container
192 0           my $cont = $self->__engine->_create_( $method, __PACKAGE__ );
193 0           $cont->_set_childs_(@$res);
194 0           $res = [$cont];
195 0           unshift( @$path, $method );
196             }
197 0           return ( $res, $path );
198             }
199              
200             #Return ( object witch handle req and result )
201             sub _traverse_ {
202 0     0     my $self = shift;
203 0           my $sess = shift;
204              
205             #if empty path return $self
206 0 0         unless ( scalar(@_) ) { return ( $self, $self ) }
  0            
207              
208 0           my ( $next_name, @path ) = @_;
209              
210             #$src - object wich handle answer, $res - answer
211 0           my ( $src, $res ) = ( $self, undef );
212              
213             #check if exist object with some name
214 0 0         if ( my $obj = $self->_get_obj_by_name($next_name) ) {
215              
216             #if last in path return him
217 0           ( $src, $res ) = $obj->_traverse_( $sess, @path );
218              
219             }
220             else { #try get other ways
221              
222             #try get objects by special methods
223 0           my $last_path;
224 0           ( $res, $last_path ) = $self->__any_path( $sess, $next_name, @path );
225 0 0         return ( $self, undef ) unless defined $res; #break search
226 0 0         if ( UNIVERSAL::isa( $res, 'WebDAO::Response' ) ) {
    0          
227 0           return ( $self, $res );
228             }
229             elsif ( ref($res) eq 'ARRAY' ) {
230              
231             #for objects array attach them into collection
232 0           $self->_set_childs_(@$res);
233              
234             #return ref to container if array to self
235 0           $res = $self;
236             }
237              
238             #analyze $last_path
239 0           my @rest_path = ();
240 0 0         if ($last_path) {
241 0 0         if ( ref($last_path) eq 'ARRAY' ) {
242 0           @rest_path = @$last_path;
243             }
244             }
245 0 0         if (@rest_path) {
246 0           ( $src, $res ) = $self->_traverse_( $sess, @rest_path );
247             }
248             }
249             #
250 0 0 0       if ( $res && $src && ( $src eq $res ) && !UNIVERSAL::isa( $src, 'WebDAO::Modal' ) ) {
      0        
      0        
251              
252             #force set root object for Modal
253 0 0         $src = $res = $self if UNIVERSAL::isa( $self, 'WebDAO::Modal' );
254             }
255 0           return ( $src, $res );
256             }
257              
258             sub _get_obj_by_name {
259 0     0     my $self = shift;
260 0           my $name = shift;
261 0 0         return unless defined $name;
262 0           my $res;
263 0           foreach my $obj ( $self, @{ $self->_get_childs_ } ) {
  0            
264 0 0         if ( $obj->_obj_name eq $name ) {
265 0           return $obj;
266             }
267             }
268 0           return;
269             }
270              
271             sub _destroy {
272 0     0     my $self = shift;
273 0           my @res;
274 0           for my $a ( @{ $self->_get_childs_ } ) {
  0            
275 0           $a->_destroy;
276             }
277 0           $self->_clear_childs_();
278 0           $self->SUPER::_destroy;
279             }
280              
281             1;
282             __DATA__
283              
284             =head1 SEE ALSO
285              
286             http://webdao.sourceforge.net
287              
288             =head1 AUTHOR
289              
290             Zahatski Aliaksandr, E<lt>zag@cpan.orgE<gt>
291              
292             =head1 COPYRIGHT AND LICENSE
293              
294             Copyright 2002-2012 by Zahatski Aliaksandr
295              
296             This library is free software; you can redistribute it and/or modify
297             it under the same terms as Perl itself.
298              
299             =cut
300