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;