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; |
