Mercurial > pub > Impl
comparison Lib/Form/Container.pm @ 0:03e58a454b20
Создан репозитарий
author | Sergey |
---|---|
date | Tue, 14 Jul 2009 12:54:37 +0400 |
parents | |
children | 16ada169ca75 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:03e58a454b20 |
---|---|
1 package Form::Container; | |
2 use strict; | |
3 use Common; | |
4 use Form::Filter; | |
5 use base qw(Form::Item); | |
6 | |
7 BEGIN { | |
8 DeclareProperty Schema => ACCESS_READ; | |
9 DeclareProperty Children => ACCESS_READ; | |
10 } | |
11 | |
12 sub CTOR { | |
13 my ($this,%args) = @_; | |
14 $args{Schema} or die new Exception('A schema is required'); | |
15 | |
16 $this->SUPER::CTOR(@args{qw(Id Form Parent Attributes)}); | |
17 $this->{$Schema} = $args{Schema}; | |
18 } | |
19 | |
20 sub ResolveItem { | |
21 my ($this,$ItemId) = @_; | |
22 | |
23 if (my $schemaChild = $this->{$Schema}->FindChild($ItemId->Name)) { | |
24 if ($schemaChild->isMulti) { | |
25 defined $ItemId->InstanceID or die new Exception('Instance id is required for a muti element'); | |
26 if (my $child = $this->{$Children}{$ItemId->Name}[$ItemId->InstanceID]){ | |
27 return $child; | |
28 } else { | |
29 return undef if not $this->Form->AutoCreate; | |
30 return $this->{$Children}{$ItemId->Name}[$ItemId->InstanceID] = $this->Form->CreateInstance($schemaChild,$ItemId,$this); | |
31 } | |
32 | |
33 } else { | |
34 defined $ItemId->InstanceID and die new Exception('The child is a single element',$this->Id->Canonical,$ItemId->Name); | |
35 if(my $child = $this->{$Children}{$ItemId->Name}) { | |
36 return $child; | |
37 } else { | |
38 return undef if not $this->Form->AutoCreate; | |
39 return $this->{$Children}{$ItemId->Name} = $this->Form->CreateInstance($schemaChild,$ItemId,$this); | |
40 } | |
41 } | |
42 } else { | |
43 die new Exception('The requested item isn\'t exists in the schema', $this->Id->Canonical,$ItemId->Name); | |
44 } | |
45 } | |
46 | |
47 sub isEmpty { | |
48 my ($this) = @_; | |
49 | |
50 foreach my $child (values %{$this->{$Children} || {} }) { | |
51 if (ref $child eq 'ARRAY') { | |
52 foreach my $inst (@$child) { | |
53 return 0 if not $child->isEmpty; | |
54 } | |
55 } else { | |
56 return 0 if not $child->isEmpty; | |
57 } | |
58 } | |
59 | |
60 return 1; | |
61 } | |
62 | |
63 =pod | |
64 Ïîëó÷àåò äî÷åðíèå êîíòåíåðû â âèäå ñïèñêà, ïðè òîì òîëüêî íå ïóñòûå êîíòåéíåðû. | |
65 Åñëè äî÷åðííèé êîíòåéíåð íå ìíîæåñòâåííûé, òî ñïèñîê áóäåò ñîñòîÿòü èç îäíîãî ýëåìåíòà. | |
66 =cut | |
67 sub GetChild { | |
68 my ($this,$name) = @_; | |
69 return unless exists $this->{$Children}{$name}; | |
70 return( grep $_, map { UNIVERSAL::isa($_,'ARRAY') ? @{$_} : $_ } $this->{$Children}{$name} ); | |
71 } | |
72 | |
73 =pod | |
74 Âûïîëíÿåò ôèëüòðû ïî ñõåìå äëÿ ñåáÿ è âñåõ äåòåé. | |
75 Ôèëüòðû îïðåäåëÿþòñÿ ïî ñõåìå è âûçûâàþòñÿ â ðàçëè÷íõ êîíòåêñòàõ | |
76 | |
77 * ñíà÷àëà äëÿ ãðóïïû, | |
78 * ïîòîì äëÿ äåòèøåê, ïðè÷åì åñëè | |
79 * äåòèøêè ìíîæåñòâåííûå, òî | |
80 * ñíñ÷àëà äëÿ íàáîðà äåòèøåê, à ïîòîì | |
81 * äëÿ êàæäîãî â îòäåëüíîñòè | |
82 =cut | |
83 sub Validate { | |
84 my ($this,$rhDisableFilters) = @_; | |
85 | |
86 $rhDisableFilters ||= {}; | |
87 | |
88 my @errors; | |
89 | |
90 foreach my $filter (grep {$_->SUPPORTED_CONTEXT & (Form::Filter::CTX_SINGLE) and not exists $rhDisableFilters->{$_}} map {$_->Instance} $this->{$Schema}->Filters) { | |
91 my $result = $filter->Invoke($this,Form::Filter::CTX_SINGLE | Form::Filter::CTX_EXISTENT,$this->{$Schema}); | |
92 if ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) { | |
93 return (); | |
94 } elsif ($result->State == Form::FilterResult::STATE_ERROR) { | |
95 push @errors,$result; | |
96 } | |
97 } | |
98 | |
99 CHILD_LOOP: foreach my $schemaChild ($this->{$Schema}->Children) { | |
100 | |
101 if ($schemaChild->isMulti) { | |
102 my %DisableFilters; | |
103 foreach my $filter (grep {$_->SUPPORTED_CONTEXT & Form::Filter::CTX_SET} map {$_->Instance} $schemaChild->Filters) { | |
104 | |
105 my $result = $filter->Invoke($this->{$Children}{$schemaChild->Name},Form::Filter::CTX_SET,$schemaChild,$this); | |
106 if ($result->State == Form::FilterResult::STATE_ERROR) { | |
107 push @errors,$result; | |
108 # íå ïðîâåðÿòü äðóãèå ôèëüòðû âîîáùå | |
109 next CHILD_LOOP; | |
110 } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) { | |
111 # íå ïðîâåðÿòü äðóãèå ôèëüòðû âîîáùå | |
112 next CHILD_LOOP; | |
113 } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STAY) { | |
114 # íå ïðîâåðÿòü äàííûé ôèëüòð íà êàæäîì ýêçåìïëÿðå | |
115 $DisableFilters{$filter} = 1; | |
116 } else { | |
117 # STATE_SUCCESS - âñå îê | |
118 } | |
119 } | |
120 | |
121 $_ and push @errors,$_->Validate(\%DisableFilters) foreach grep !$_->isEmpty, $this->GetChild($schemaChild->Name); | |
122 | |
123 } else { | |
124 my %DisableFilters; | |
125 | |
126 # ïðîâåðÿåì ôèëüòðû, êîòîðûå ìîãóò ïðèìåíÿòüñÿ íà íåñóùåñòâóþùåì çíà÷åíèè | |
127 foreach my $filter (grep { $_->SUPPORTED_CONTEXT & Form::Filter::CTX_SINGLE and not $_->SUPPORTED_CONTEXT & Form::Filter::CTX_EXISTENT} map {$_->Instance} $schemaChild->Filters) { | |
128 my $result = $filter->Invoke($this->{$Children}{$schemaChild->Name},Form::Filter::CTX_SINGLE,$schemaChild,$this); | |
129 | |
130 if ($result->State == Form::FilterResult::STATE_ERROR) { | |
131 push @errors,$result; | |
132 # íå ïðîâåðÿòü äðóãèå ôèëüòðû âîîáùå | |
133 next CHILD_LOOP; | |
134 } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) { | |
135 # íå ïðîâåðÿòü äðóãèå ôèëüòðû âîîáùå | |
136 next CHILD_LOOP; | |
137 } else { | |
138 # STATE_SUCCESS(_STAY) - âñå îê | |
139 $DisableFilters{$filter} = 1; | |
140 } | |
141 } | |
142 | |
143 # åñëè çíà÷åíèå ñóùåñòâóåò, òî ïðèìåíÿåì îñòàâøèåñÿ ôèëüòðû | |
144 push @errors,$this->{$Children}{$schemaChild->Name}->Validate(\%DisableFilters) if $this->{$Children}{$schemaChild->Name}; | |
145 } | |
146 | |
147 } | |
148 | |
149 return @errors; | |
150 } | |
151 | |
152 sub Dispose { | |
153 my ($this) = @_; | |
154 | |
155 foreach my $child (values %{ $this->{$Children} || {} }) { | |
156 if (ref $child eq 'ARRAY') { | |
157 foreach my $inst (@$child) { | |
158 $inst->Dispose; | |
159 } | |
160 } else { | |
161 die new IMPL::Exception("Child is null",%{ $this->{$Children} }) if not $child; | |
162 $child->Dispose; | |
163 } | |
164 } | |
165 | |
166 delete @$this{$Schema,$Children}; | |
167 | |
168 $this->SUPER::Dispose; | |
169 } | |
170 1; |