# HG changeset patch # User cin # Date 1385991878 -14400 # Node ID 935629bf80df4d186c7d3fcbfe25a4196b260370 # Parent 7c621bb95e53e28b342d5b6e1292a035547cb355 model metadata, in progress diff -r 7c621bb95e53 -r 935629bf80df Lib/IMPL/Web/View/Metadata/BaseMeta.pm --- a/Lib/IMPL/Web/View/Metadata/BaseMeta.pm Mon Dec 02 02:13:12 2013 +0400 +++ b/Lib/IMPL/Web/View/Metadata/BaseMeta.pm Mon Dec 02 17:44:38 2013 +0400 @@ -14,6 +14,7 @@ props => [ model => PROP_RO, modelType => PROP_RO, + holdingType => PROP_RO, provider => PROP_RO, name => PROP_RO, label => PROP_RO, @@ -39,40 +40,57 @@ #mixin other args if ($args) { - $this->$_($args->{$_}) foreach grep $args->{$_}, qw(name label container template); + $this->$_($args->{$_}) foreach grep $args->{$_}, qw(name label container template holdingType); } } -sub GetChild { +sub GetProperty { my ($this,$name) = @_; - if(my $child = $this->_childMap->{$name}) { - return $child; - } else { - return $this->_childMap->{$name} = $this->provider->GetChild($this,$name); - } + $this->_PopulateProperties() + unless $this->_childNames; + + return $this->_childMap->{$name}; } -sub GetChildren { +sub GetProperties { my ($this) = @_; if ($this->_childNames) { return [ map $this->_childMap->{$_}, @{$this->_childNames} ]; } else { - my @childNames; - my %childMap; - my @result; + return $this->_PopulateProperties; + } +} + +sub _PopulateProperties { + my ($this) = @_; - foreach my $child (@{$this->provider->PopulateChildren($this)}) { - $childMap{$child->name} = $child; - push @childNames, $child->name; - push @result, $child; - } - - $this->_childMap(\%childMap); - $this->_childNames(\@childNames); - return \@result; - } + my @childNames; + my %childMap; + my @result; + + foreach my $child (@{$this->provider->PopulateProperties($this)}) { + $childMap{$child->name} = $child; + push @childNames, $child->name; + push @result, $child; + } + + $this->_childMap(\%childMap); + $this->_childNames(\@childNames); + return \@result; +} + +sub GetItems { + my ($this) = @_; + + return $this->provider->GetItems($this); +} + +sub GetItem { + my ($this,$index) = @_; + + return $this->provider->GetItem($this,$index); } 1; diff -r 7c621bb95e53 -r 935629bf80df Lib/IMPL/Web/View/Metadata/FormMeta.pm --- a/Lib/IMPL/Web/View/Metadata/FormMeta.pm Mon Dec 02 02:13:12 2013 +0400 +++ b/Lib/IMPL/Web/View/Metadata/FormMeta.pm Mon Dec 02 17:44:38 2013 +0400 @@ -37,7 +37,6 @@ shift->decl->isOptional; } - sub GetOwnErrors { my ($this) = @_; @@ -88,12 +87,15 @@ быть более одного в то время, как C или, напротив, ни одного при C. +Как правило для построения формы данное свойство не требуется. + =head2 C<[get]modelType> Название типа данных из схемы документа (C<< schema->name >>), если тип не имеет название, то это C для сложных узлов и C для простых. -Для моделей с множественными значениями это свойство означает тип элементов. +Для моделей с множественными значениями это свойство не задано. Тип элементов +храниться в свойстве C =head2 C<[get]decl> @@ -119,10 +121,17 @@ =begin code for(my $i=0; $i< 10; $i++) { - display_model( - $meta->model->[$i], - schema => meta->schema, - ); + display_for($i,'template'); +} + +sub display_for { + my ($index,$tmpl) = @_; + + if ($index =~ /^\d+$/) { + return render($tmpl, meta => { $meta->GetItem($index) }); + } else { + return render($tmpl, meta => { $meta->GetProperty($index) }); + } } =end code diff -r 7c621bb95e53 -r 935629bf80df Lib/IMPL/Web/View/Metadata/FormProvider.pm --- a/Lib/IMPL/Web/View/Metadata/FormProvider.pm Mon Dec 02 02:13:12 2013 +0400 +++ b/Lib/IMPL/Web/View/Metadata/FormProvider.pm Mon Dec 02 17:44:38 2013 +0400 @@ -1,41 +1,82 @@ package IMPL::Web::View::Metadata::FormProvider; use strict; +ues IMPL::lang ; use IMPL::declare { require => { - Meta => 'IMPL::Web::View::Metadata::FormMeta' + Meta => 'IMPL::Web::View::Metadata::FormMeta', + + Exception => 'IMPL::Exception', + ArgException => '-IMPL::InvalidArgumentException' }, base => [ 'IMPL::Object' => undef ] }; -sub GetFormMetadata { - my ($this,$model, $form) = @_; -} - -sub PopulateChildren { +sub PopulateProperties { my ($this,$meta) = @_; - map Meta->new($this,), $meta->schema->content->childNodes; + die ArgException->new(meta => 'A FormMeta is required') + unless is($meta,Meta); + + my @props; + + # return empty list of properties in case of multiple values + return \@props if $meta->isMultiple; + + my $navi = SchemaNavigator->new($meta->schema); + + foreach my $decl (@{$meta->schema->content->childNodes}) { + + my $schema = $navi->NavigateName($decl->name); + + my @nodes = $meta->model && $meta->model->selectNodes( sub { $_->schemaSource == $decl } ); + + my %args = ( + name => $decl->name, + decl => $decl, + schema => $schema, + nodes => \@nodes, + errors => [grep _IsErrorRelates(\@nodes,$decl,$_), @{$meta->errors || []}] + ); + + my ($model,$type); + + if ($decl->isMultiple) { + $model = \@nodes; + $type = 'ARRAY'; + $args{holdingType} = $decl->type; + } else { + $model = shift @nodes; + $type = $decl->type; + } + + push @props, Meta->new( + $this, + \@nodes, + $decl->type, + { + name => $decl->name, + schema => $schema, + } + ) + } } -sub GetChild { - -} sub _IsErrorRelates { - my ($node,$source,$err) = @_; + my ($nodes,$source,$err) = @_; # this is an own error - return 1 if ($node && $err->node && $err->node == $node) || (not($node) && $err->schema == $source ); + return 1 if ($err->node && grep($err->node == $_, @$nodes)) || (not(@$nodes) && $err->schema == $source ); # this error relates to the child control - return 0 unless $node; + return 0 unless @$nodes; for (my $n = $err->parent; $n ; $n = $n->parentNode) { - return 1 if $n == $node; + return 1 if grep($n == $_, @$nodes); } return 0;