view Lib/IMPL/Web/View/Metadata/FormProvider.pm @ 366:935629bf80df

model metadata, in progress
author cin
date Mon, 02 Dec 2013 17:44:38 +0400
parents 7c621bb95e53
children 608e74bc309f
line wrap: on
line source

package IMPL::Web::View::Metadata::FormProvider;
use strict;

ues IMPL::lang ;
use IMPL::declare {
	require => {
		Meta => 'IMPL::Web::View::Metadata::FormMeta',
		
		Exception => 'IMPL::Exception',
		ArgException => '-IMPL::InvalidArgumentException'
	},
	base => [
		'IMPL::Object' => undef
	]
};

sub PopulateProperties {
	my ($this,$meta) = @_;
	
	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 _IsErrorRelates {
    my ($nodes,$source,$err) = @_;
    
    # this is an own error
    return 1 if ($err->node && grep($err->node == $_, @$nodes)) || (not(@$nodes) && $err->schema == $source );
    
    # this error relates to the child control 
    
    return 0 unless @$nodes;
    
    for (my $n = $err->parent; $n ; $n = $n->parentNode) {
        return 1 if grep($n == $_, @$nodes);
    }
    
    return 0;
} 

1;