File Coverage

blib/lib/HTML/WebDAO/Container.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             #$Id: Container.pm 215 2007-11-13 08:44:47Z zag $
2              
3             package HTML::WebDAO::Container;
4 5     5   4477 use HTML::WebDAO::Element;
  0            
  0            
5             use Data::Dumper;
6             use base qw(HTML::WebDAO::Element);
7             use strict 'vars';
8              
9             #no strict 'refs';
10             __PACKAGE__->attributes qw/ __childs/;
11              
12             sub _sysinit {
13             my $self = shift;
14              
15             #First invoke parent _init;
16             $self->SUPER::_sysinit(@_);
17              
18             #initalize "childs" array for this container
19             $self->__childs( [] );
20              
21             }
22              
23             sub _get_vars {
24             my $self = shift;
25             my ( $res, $ref );
26             $res = $self->SUPER::_get_vars;
27             return $res;
28             }
29              
30             sub _set_vars {
31             my ( $self, $ref ) = @_;
32             my $chld_name;
33             $self->SUPER::_set_vars($ref);
34             }
35              
36             =head3 _get_childs()
37              
38             Return ref to childs array
39              
40             =cut
41              
42             sub _get_childs {
43             return $_[0]->__childs;
44             }
45              
46             =head3 _add_childs($object1[, $object2])
47              
48             Insert set of objects into container
49              
50             =cut
51              
52             sub _add_childs {
53             my $self = shift;
54             my @childs =
55             grep { ref $_ }
56             map { ref($_) eq 'ARRAY' ? @$_ : $_ }
57             map { $_->__get_self_refs }
58             grep { ref($_) && $_->can('__get_self_refs') } @_;
59             return unless @childs;
60             if ( $self->__parent ) {
61             $_->_set_parent($self) for @childs;
62             $self->getEngine->__restore_session_attributes(@childs);
63             }
64             push( @{ $self->__childs }, @childs );
65             }
66              
67             #it for container
68             sub _set_parent {
69             my ( $self, $par ) = @_;
70             $self->SUPER::_set_parent($par);
71             foreach my $ref ( @{ $self->__childs } ) {
72             $ref->_set_parent($self);
73             }
74             }
75              
76             sub _call_method {
77             my $self = shift;
78             my ( $name, @path ) = @{ shift @_ };
79             return $self->SUPER::_call_method( [ $name, @path ], @_ ) || do {
80             if ( my $obj = $self->_get_obj_by_name($name) ) {
81             if ( ref($obj) eq 'HASH' ) {
82             LOG $self Dumper( [ map { [ caller($_) ] } ( 1 .. 6 ) ] );
83             $self->LOG( " got $obj for $name" . Dumper($obj) );
84             }
85             $obj->_call_method( \@path, @_ );
86             }
87             else {
88             _log4 $self "Cant find obj for name $name in "
89             . $self->__my_name() . ":"
90             . Dumper( [ map { $_->__my_name } @{ $self->_get_childs } ] );
91             return;
92             }
93             }
94             }
95              
96             sub _get_obj_by_name {
97             my $self = shift;
98             my $name = shift;
99             return unless defined $name;
100             my $res;
101             foreach my $obj ( $self, @{ $self->__childs } ) {
102             if ( $obj->_obj_name eq $name ) {
103             return $obj;
104             }
105             }
106             return;
107             }
108              
109             =head2 fetch(@_), default call by webdao: fetch( $session )
110              
111             Interate call fetch(@_) on childs
112              
113             =cut
114              
115             sub fetch {
116             my $self = shift;
117             my @res;
118             for my $a ( @{ $self->__childs } ) {
119             push( @res, @{ $a->_format(@_) } );
120             }
121             return \@res;
122              
123             }
124              
125             sub _destroy {
126             my $self = shift;
127             my @res;
128             for my $a ( @{ $self->__childs } ) {
129             $a->_destroy;
130             }
131             $self->__childs( [] );
132             $self->SUPER::_destroy;
133             }
134              
135             =head2 _get_object_by_path <$path>, [$session]
136              
137             Return first Element object for path.
138             Try to load objects for current object.
139              
140             =cut
141              
142             sub _get_object_by_path {
143             my $self = shift;
144             my $path = shift;
145             my $session = shift;
146             # _log1 $self Dumper {'$self'=>ref($self), path=>$path};
147             my @backup_path = @$path;
148             my $next_name = $path->[0];
149             #first try get by name
150             if ( my $obj = $self->_get_obj_by_name($next_name) ) {
151             shift @$path; #skip first name
152             #ok got it
153             #check if it container
154             #skip extra path
155             if ( UNIVERSAL::can( $obj, '__extra_path' ) ) {
156             my $extra_path = $obj->__extra_path;
157              
158             #if extra path defined and not ref convert to ref
159             if ( defined $extra_path ) {
160             $extra_path = [$extra_path] unless ref($extra_path);
161             }
162             if ( ref($extra_path) ) {
163             my @extra = @$extra_path;
164              
165             #now skip extra
166             for (@extra) {
167             if ( $path->[0] eq $_ ) {
168             shift @$path;
169             }
170             else {
171             _log2 $self "Break __extra_path "
172             . $path->[0] . " <> "
173             . $_
174             . " for : $obj";
175             last;
176             }
177             }
178             }
179             }
180             if ( $obj->isa('HTML::WebDAO::Container') ) {
181             return $obj unless @$path; # return object if end of path
182             return $obj->_get_object_by_path( $path, $session );
183             }
184             else {
185              
186             #if element return point in any way
187             return $obj
188              
189             # my $method = $path->[0] || 'index_html';
190             # #if it element try to can method
191             # return $obj->can($method) ? $obj : undef;
192             }
193             }
194             else {
195              
196             #try get objects by special methods
197             my $dyn = $self->__get_objects_by_path( $path, $session )
198             || return; #break search
199              
200             #handle self controlled objects
201             if ( $dyn eq $self ) {
202             return $self;
203             }
204             $dyn = [$dyn] unless ref($dyn) eq 'ARRAY';
205              
206             #now try find object in returned array
207             my $next;
208             foreach (@$dyn) {
209              
210             #skip non objects
211             next unless $_->_obj_name eq $next_name;
212             $next = $_;
213             last; #exit from loop loop
214             }
215             unless ($next) {
216             return # return undef unless find objects
217             }
218             else {
219              
220             # yes, from returned object present traverse continue
221             #if defined $session ( load scene)
222             if ($session) {
223             $self->_add_childs(@$dyn);
224             return $self->_get_object_by_path( $path, $session );
225             }
226             else {
227              
228             #if query without session
229             #try to find by name
230             #ok got it
231             #check if it container
232             if ( $next->isa('HTML::WebDAO::Container') ) {
233             return $next->_get_object_by_path( $path, $session );
234             }
235             else {
236              
237             #return object referense in any way
238             return $next;
239             }
240             }
241              
242             }
243             }
244             }
245              
246             =head2 __get_objects_by_path [path], $session
247              
248             Return next object for path
249              
250             =cut
251              
252             sub __get_objects_by_path {
253             my $self = shift;
254             my ( $path, $session ) = @_;
255             # check if path point to method
256             return $self if $self->can($path->[0]);
257             return; # default return undef
258             }
259              
260             1;