diff Lib/Form/Container.pm @ 49:16ada169ca75

migrating to the Eclipse IDE
author wizard@linux-odin.local
date Fri, 26 Feb 2010 10:49:21 +0300
parents 03e58a454b20
children 76515373dac0
line wrap: on
line diff
--- a/Lib/Form/Container.pm	Fri Feb 26 01:43:42 2010 +0300
+++ b/Lib/Form/Container.pm	Fri Feb 26 10:49:21 2010 +0300
@@ -1,170 +1,170 @@
-package Form::Container;
-use strict;
-use Common;
-use Form::Filter;
-use base qw(Form::Item);
-
-BEGIN {
-    DeclareProperty Schema => ACCESS_READ;
-    DeclareProperty Children => ACCESS_READ;
-}
-
-sub CTOR {
-    my ($this,%args) = @_;
-    $args{Schema} or die new Exception('A schema is required');
-    
-    $this->SUPER::CTOR(@args{qw(Id Form Parent Attributes)});
-    $this->{$Schema} = $args{Schema};
-}
-
-sub ResolveItem {
-    my ($this,$ItemId) = @_;
-    
-    if (my $schemaChild = $this->{$Schema}->FindChild($ItemId->Name)) {
-        if ($schemaChild->isMulti) {
-            defined $ItemId->InstanceID or die new Exception('Instance id is required for a muti element');
-            if (my $child = $this->{$Children}{$ItemId->Name}[$ItemId->InstanceID]){
-                return $child;
-            } else {
-                return undef if not $this->Form->AutoCreate;
-                return $this->{$Children}{$ItemId->Name}[$ItemId->InstanceID] = $this->Form->CreateInstance($schemaChild,$ItemId,$this);
-            }
-            
-        } else {
-            defined $ItemId->InstanceID and die new Exception('The child is a single element',$this->Id->Canonical,$ItemId->Name);
-            if(my $child = $this->{$Children}{$ItemId->Name}) {
-                return $child;
-            } else {
-                return undef if not $this->Form->AutoCreate;
-                return $this->{$Children}{$ItemId->Name} = $this->Form->CreateInstance($schemaChild,$ItemId,$this);
-            }
-        }
-    } else {
-        die new Exception('The requested item isn\'t exists in the schema', $this->Id->Canonical,$ItemId->Name);
-    }
-}
-
-sub isEmpty {
-    my ($this) = @_;
-
-    foreach my $child (values %{$this->{$Children} || {} }) {
-        if (ref $child eq 'ARRAY') {
-            foreach my $inst (@$child) {
-                return 0 if not $child->isEmpty;
-            }
-        } else {
-            return 0 if not $child->isEmpty;
-        }
-    }
-
-    return 1;
-}
-
-=pod
-Получает дочерние контенеры в виде списка, при том только не пустые контейнеры.
-Если дочернний контейнер не множественный, то список будет состоять из одного элемента.
-=cut
-sub GetChild {
-    my ($this,$name) = @_;
-    return unless exists $this->{$Children}{$name};
-    return( grep $_, map { UNIVERSAL::isa($_,'ARRAY') ? @{$_} : $_ } $this->{$Children}{$name} );
-}
-
-=pod
-Выполняет фильтры по схеме для себя и всех детей.
-Фильтры определяются по схеме и вызываются в различнх контекстах
-
-* сначала для группы,
-* потом для детишек, причем если
-    * детишки множественные, то
-        * снсчала для набора детишек, а потом
-        * для каждого в отдельности
-=cut
-sub Validate {
-    my ($this,$rhDisableFilters) = @_;
-    
-    $rhDisableFilters ||= {};
-
-    my @errors;
-
-    foreach my $filter (grep {$_->SUPPORTED_CONTEXT & (Form::Filter::CTX_SINGLE) and not exists $rhDisableFilters->{$_}} map {$_->Instance} $this->{$Schema}->Filters) {
-        my $result = $filter->Invoke($this,Form::Filter::CTX_SINGLE | Form::Filter::CTX_EXISTENT,$this->{$Schema});
-        if ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) {
-            return ();
-        } elsif ($result->State == Form::FilterResult::STATE_ERROR) {
-            push @errors,$result;
-        }
-    }
-
-    CHILD_LOOP: foreach my $schemaChild ($this->{$Schema}->Children) {
-        
-        if ($schemaChild->isMulti) {
-            my %DisableFilters;
-            foreach my $filter (grep {$_->SUPPORTED_CONTEXT & Form::Filter::CTX_SET} map {$_->Instance} $schemaChild->Filters) {
-                
-                my $result = $filter->Invoke($this->{$Children}{$schemaChild->Name},Form::Filter::CTX_SET,$schemaChild,$this);
-                if ($result->State == Form::FilterResult::STATE_ERROR) {
-                    push @errors,$result;
-                    # не проверять другие фильтры вообще
-                    next CHILD_LOOP;
-                } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) {
-                    # не проверять другие фильтры вообще
-                    next CHILD_LOOP;
-                } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STAY) {
-                    # не проверять данный фильтр на каждом экземпляре
-                    $DisableFilters{$filter} = 1;
-                } else {
-                    # STATE_SUCCESS - все ок
-                }
-            }
-            
-            $_ and push @errors,$_->Validate(\%DisableFilters) foreach grep !$_->isEmpty, $this->GetChild($schemaChild->Name);
-            
-        } else {
-            my %DisableFilters;
-            
-            # проверяем фильтры, которые могут применяться на несуществующем значении
-            foreach my $filter (grep { $_->SUPPORTED_CONTEXT & Form::Filter::CTX_SINGLE and not $_->SUPPORTED_CONTEXT & Form::Filter::CTX_EXISTENT} map {$_->Instance} $schemaChild->Filters) {
-                my $result = $filter->Invoke($this->{$Children}{$schemaChild->Name},Form::Filter::CTX_SINGLE,$schemaChild,$this);
-                
-                if ($result->State == Form::FilterResult::STATE_ERROR) {
-                    push @errors,$result;
-                    # не проверять другие фильтры вообще
-                    next CHILD_LOOP;
-                } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) {
-                    # не проверять другие фильтры вообще
-                    next CHILD_LOOP;
-                } else {
-                    # STATE_SUCCESS(_STAY) - все ок
-                    $DisableFilters{$filter} = 1;
-                }
-            }
-            
-            # если значение существует, то применяем оставшиеся фильтры
-            push @errors,$this->{$Children}{$schemaChild->Name}->Validate(\%DisableFilters) if $this->{$Children}{$schemaChild->Name};
-        }
-        
-    }
-    
-    return @errors;
-}
-
-sub Dispose {
-    my ($this) = @_;
-    
-    foreach my $child (values %{ $this->{$Children} || {} }) {
-        if (ref $child eq 'ARRAY') {
-            foreach my $inst (@$child) {
-                $inst->Dispose;
-            }
-        } else {
-            die new IMPL::Exception("Child is null",%{ $this->{$Children} }) if not $child;
-            $child->Dispose;
-        }
-    }
-    
-    delete @$this{$Schema,$Children};
-    
-    $this->SUPER::Dispose;
-}
-1;
\ No newline at end of file
+package Form::Container;
+use strict;
+use Common;
+use Form::Filter;
+use base qw(Form::Item);
+
+BEGIN {
+    DeclareProperty Schema => ACCESS_READ;
+    DeclareProperty Children => ACCESS_READ;
+}
+
+sub CTOR {
+    my ($this,%args) = @_;
+    $args{Schema} or die new Exception('A schema is required');
+    
+    $this->SUPER::CTOR(@args{qw(Id Form Parent Attributes)});
+    $this->{$Schema} = $args{Schema};
+}
+
+sub ResolveItem {
+    my ($this,$ItemId) = @_;
+    
+    if (my $schemaChild = $this->{$Schema}->FindChild($ItemId->Name)) {
+        if ($schemaChild->isMulti) {
+            defined $ItemId->InstanceID or die new Exception('Instance id is required for a muti element');
+            if (my $child = $this->{$Children}{$ItemId->Name}[$ItemId->InstanceID]){
+                return $child;
+            } else {
+                return undef if not $this->Form->AutoCreate;
+                return $this->{$Children}{$ItemId->Name}[$ItemId->InstanceID] = $this->Form->CreateInstance($schemaChild,$ItemId,$this);
+            }
+            
+        } else {
+            defined $ItemId->InstanceID and die new Exception('The child is a single element',$this->Id->Canonical,$ItemId->Name);
+            if(my $child = $this->{$Children}{$ItemId->Name}) {
+                return $child;
+            } else {
+                return undef if not $this->Form->AutoCreate;
+                return $this->{$Children}{$ItemId->Name} = $this->Form->CreateInstance($schemaChild,$ItemId,$this);
+            }
+        }
+    } else {
+        die new Exception('The requested item isn\'t exists in the schema', $this->Id->Canonical,$ItemId->Name);
+    }
+}
+
+sub isEmpty {
+    my ($this) = @_;
+
+    foreach my $child (values %{$this->{$Children} || {} }) {
+        if (ref $child eq 'ARRAY') {
+            foreach my $inst (@$child) {
+                return 0 if not $child->isEmpty;
+            }
+        } else {
+            return 0 if not $child->isEmpty;
+        }
+    }
+
+    return 1;
+}
+
+=pod
+Получает дочерние контенеры в виде списка, при том только не пустые контейнеры.
+Если дочернний контейнер не множественный, то список будет состоять из одного элемента.
+=cut
+sub GetChild {
+    my ($this,$name) = @_;
+    return unless exists $this->{$Children}{$name};
+    return( grep $_, map { UNIVERSAL::isa($_,'ARRAY') ? @{$_} : $_ } $this->{$Children}{$name} );
+}
+
+=pod
+Выполняет фильтры по схеме для себя и всех детей.
+Фильтры определяются по схеме и вызываются в различнх контекстах
+
+* сначала для группы,
+* потом для детишек, причем если
+    * детишки множественные, то
+        * снсчала для набора детишек, а потом
+        * для каждого в отдельности
+=cut
+sub Validate {
+    my ($this,$rhDisableFilters) = @_;
+    
+    $rhDisableFilters ||= {};
+
+    my @errors;
+
+    foreach my $filter (grep {$_->SUPPORTED_CONTEXT & (Form::Filter::CTX_SINGLE) and not exists $rhDisableFilters->{$_}} map {$_->Instance} $this->{$Schema}->Filters) {
+        my $result = $filter->Invoke($this,Form::Filter::CTX_SINGLE | Form::Filter::CTX_EXISTENT,$this->{$Schema});
+        if ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) {
+            return ();
+        } elsif ($result->State == Form::FilterResult::STATE_ERROR) {
+            push @errors,$result;
+        }
+    }
+
+    CHILD_LOOP: foreach my $schemaChild ($this->{$Schema}->Children) {
+        
+        if ($schemaChild->isMulti) {
+            my %DisableFilters;
+            foreach my $filter (grep {$_->SUPPORTED_CONTEXT & Form::Filter::CTX_SET} map {$_->Instance} $schemaChild->Filters) {
+                
+                my $result = $filter->Invoke($this->{$Children}{$schemaChild->Name},Form::Filter::CTX_SET,$schemaChild,$this);
+                if ($result->State == Form::FilterResult::STATE_ERROR) {
+                    push @errors,$result;
+                    # не проверять другие фильтры вообще
+                    next CHILD_LOOP;
+                } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) {
+                    # не проверять другие фильтры вообще
+                    next CHILD_LOOP;
+                } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STAY) {
+                    # не проверять данный фильтр на каждом экземпляре
+                    $DisableFilters{$filter} = 1;
+                } else {
+                    # STATE_SUCCESS - все ок
+                }
+            }
+            
+            $_ and push @errors,$_->Validate(\%DisableFilters) foreach grep !$_->isEmpty, $this->GetChild($schemaChild->Name);
+            
+        } else {
+            my %DisableFilters;
+            
+            # проверяем фильтры, которые могут применяться на несуществующем значении
+            foreach my $filter (grep { $_->SUPPORTED_CONTEXT & Form::Filter::CTX_SINGLE and not $_->SUPPORTED_CONTEXT & Form::Filter::CTX_EXISTENT} map {$_->Instance} $schemaChild->Filters) {
+                my $result = $filter->Invoke($this->{$Children}{$schemaChild->Name},Form::Filter::CTX_SINGLE,$schemaChild,$this);
+                
+                if ($result->State == Form::FilterResult::STATE_ERROR) {
+                    push @errors,$result;
+                    # не проверять другие фильтры вообще
+                    next CHILD_LOOP;
+                } elsif ($result->State == Form::FilterResult::STATE_SUCCESS_STOP) {
+                    # не проверять другие фильтры вообще
+                    next CHILD_LOOP;
+                } else {
+                    # STATE_SUCCESS(_STAY) - все ок
+                    $DisableFilters{$filter} = 1;
+                }
+            }
+            
+            # если значение существует, то применяем оставшиеся фильтры
+            push @errors,$this->{$Children}{$schemaChild->Name}->Validate(\%DisableFilters) if $this->{$Children}{$schemaChild->Name};
+        }
+        
+    }
+    
+    return @errors;
+}
+
+sub Dispose {
+    my ($this) = @_;
+    
+    foreach my $child (values %{ $this->{$Children} || {} }) {
+        if (ref $child eq 'ARRAY') {
+            foreach my $inst (@$child) {
+                $inst->Dispose;
+            }
+        } else {
+            die new IMPL::Exception("Child is null",%{ $this->{$Children} }) if not $child;
+            $child->Dispose;
+        }
+    }
+    
+    delete @$this{$Schema,$Children};
+    
+    $this->SUPER::Dispose;
+}
+1;