# HG changeset patch
# User cin
# Date 1386078936 -14400
# Node ID 608e74bc309f115de7856bfe366daebd86179590
# Parent 935629bf80df4d186c7d3fcbfe25a4196b260370
form metadata, mostly done
diff -r 935629bf80df -r 608e74bc309f Lib/IMPL/Web/View/Metadata/BaseMeta.pm
--- a/Lib/IMPL/Web/View/Metadata/BaseMeta.pm Mon Dec 02 17:44:38 2013 +0400
+++ b/Lib/IMPL/Web/View/Metadata/BaseMeta.pm Tue Dec 03 17:55:36 2013 +0400
@@ -6,7 +6,8 @@
use IMPL::declare {
require => {
Exception => 'IMPL::Exception',
- ArgException => '-IMPL::InvalidArgumentException'
+ ArgException => '-IMPL::InvalidArgumentException',
+ NotImplException => '-IMPL::NotImplementedException'
},
base => [
'IMPL::Object' => undef
@@ -14,8 +15,6 @@
props => [
model => PROP_RO,
modelType => PROP_RO,
- holdingType => PROP_RO,
- provider => PROP_RO,
name => PROP_RO,
label => PROP_RO,
container => PROP_RO,
@@ -27,27 +26,22 @@
};
sub CTOR {
- my ($this,$provider,$model,$type,$args) = @_;
-
- $type ||= typeof($model);
+ my ($this,$model,$type,$args) = @_;
- die ArgException->new(provider => 'A provider must be specified');
-
- $this->provider($provider);
$this->model($model);
$this->modelType($type);
- $this->childMap({});
+ $this->_childMap({});
#mixin other args
if ($args) {
- $this->$_($args->{$_}) foreach grep $args->{$_}, qw(name label container template holdingType);
+ $this->$_($args->{$_}) foreach grep $args->{$_}, qw(name label container template);
}
}
sub GetProperty {
my ($this,$name) = @_;
- $this->_PopulateProperties()
+ $this->GetProperties()
unless $this->_childNames;
return $this->_childMap->{$name};
@@ -59,38 +53,38 @@
if ($this->_childNames) {
return [ map $this->_childMap->{$_}, @{$this->_childNames} ];
} else {
- return $this->_PopulateProperties;
+ my @childNames;
+ my %childMap;
+ my @result;
+
+ foreach my $child (@{$this->PopulateProperties($this)}) {
+ $childMap{$child->name} = $child;
+ push @childNames, $child->name;
+ push @result, $child;
+ }
+
+ $this->_childMap(\%childMap);
+ $this->_childNames(\@childNames);
+ return \@result;
}
}
-sub _PopulateProperties {
+sub PopulateProperties {
my ($this) = @_;
- 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;
+ die NotImplException->new();
}
sub GetItems {
my ($this) = @_;
- return $this->provider->GetItems($this);
+ die NotImplException->new();
}
sub GetItem {
my ($this,$index) = @_;
- return $this->provider->GetItem($this,$index);
+ die NotImplException->new();
}
1;
diff -r 935629bf80df -r 608e74bc309f Lib/IMPL/Web/View/Metadata/FormMeta.pm
--- a/Lib/IMPL/Web/View/Metadata/FormMeta.pm Mon Dec 02 17:44:38 2013 +0400
+++ b/Lib/IMPL/Web/View/Metadata/FormMeta.pm Tue Dec 03 17:55:36 2013 +0400
@@ -5,7 +5,9 @@
use IMPL::declare {
require => {
Exception => 'IMPL::Exception',
- ArgException => '-IMPL::InvalidArgumentException'
+ ArgException => '-IMPL::InvalidArgumentException',
+ OpException => '-IMPL::InvalidOperationException',
+ SchemaNavigator => 'IMPL::DOM::Navigator::SchemaNavigator'
},
base => [
'IMPL::Web::View::Metadata::BaseMeta' => '@_'
@@ -14,43 +16,152 @@
nodes => PROP_RO,
decl => PROP_RO,
schema => PROP_RO,
- errors => PROP_RO
+ errors => PROP_RO,
+ group => PROP_RO
]
};
+use constant {
+ Meta => __PACKAGE__
+};
+
sub CTOR {
- my ($this,$provider,$model,$type,$args) = @_;
+ my ($this,$model,$type,$args) = @_;
if ($args) {
- $this->$_($args->{$_}) foreach grep $args->{$_}, qw(decl schema nodes errors);
+ $this->$_($args->{$_}) foreach grep $args->{$_}, qw(decl schema nodes errors group);
}
$this->$_() || die ArgException->new($_ => "The $_ is required")
- foreach qw(decl schema);
+ foreach qw(schema);
}
sub isMultiple {
- shift->decl->isMultiple;
+ my ($this) = @_;
+ $this->decl && $this->decl->isMultiple;
}
sub isOptional {
- shift->decl->isOptional;
+ my ($this) = @_;
+ not($this->decl) || $this->decl->isOptional;
}
sub GetOwnErrors {
my ($this) = @_;
- my $node = undef;
-
- $node = not($this->isMultiple) && $this->nodes ? $this->nodes->[0] : undef;
+ my $nodes = $this->nodes;
return [
- grep {
- ($node && $_->node && $_->node == $node) || (not($node) && $_->schema == $this->decl )
- } @{$this->errors || []}
+ grep _IsOwnError($nodes,$this->decl,$_), @{$this->errors || []}
];
}
+sub _IsOwnError {
+ my ($nodes,$source,$err) = @_;
+
+ return 1 if ($err->node && grep($err->node == $_, @$nodes)) || (not(@$nodes) && $err->schema == $source );
+
+ return 0;
+}
+
+sub _IsErrorRelates {
+ my ($nodes,$source,$err) = @_;
+
+ # this is an own error
+ return 1 if _IsOwnError($nodes,$source,$err);
+
+ # 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;
+}
+
+sub PopulateProperties {
+ my ($this) = @_;
+
+ my @props;
+
+ # return empty list of properties in case of multiple values
+ return \@props if $this->isMultiple;
+
+ my $navi = SchemaNavigator->new($this->schema);
+
+ foreach my $decl (@{$this->schema->content->childNodes}) {
+
+ my $schema = $navi->NavigateName($decl->name);
+ $navi->SchemaBack();
+
+ my @nodes = $this->model && $this->model->selectNodes( sub { $_->schemaSource == $decl } );
+
+ my %args = (
+ name => $decl->name,
+ decl => $decl,
+ schema => $schema,
+ nodes => \@nodes,
+ errors => [grep _IsErrorRelates(\@nodes,$decl,$_), @{$this->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($model,$type,\%args);
+ }
+
+ return \@props;
+}
+
+sub GetItems {
+ my ($this) = @_;
+
+ die OpException->new("The operation must be performed on the container")
+ unless $this->isMultiple;
+
+ my $i = 0;
+
+ return [
+ map $this->_GetItemMeta($_,$i++), @{$this->model || []}
+ ];
+}
+
+sub GetItem {
+ my ($this,$index) = @_;
+
+ die OpException->new("The operation must be performed on the container")
+ unless $this->isMultiple;
+
+ my $node = $this->model->[$index];
+
+ return $this->GetItemMeta($node,$index);
+}
+
+sub _GetItemMeta {
+ my ($this,$node,$index) = @_;
+
+ return Meta->new(
+ $node,
+ $this->decl->type,
+ {
+ name => $index,
+ schema => $this->schema,
+ errors => [grep _IsOwnError([$node],$this->decl,$_), @{$this->errors ||[]} ],
+ group => $this
+ }
+ );
+}
+
1;
__END__
diff -r 935629bf80df -r 608e74bc309f Lib/IMPL/Web/View/Metadata/FormProvider.pm
--- a/Lib/IMPL/Web/View/Metadata/FormProvider.pm Mon Dec 02 17:44:38 2013 +0400
+++ b/Lib/IMPL/Web/View/Metadata/FormProvider.pm Tue Dec 03 17:55:36 2013 +0400
@@ -30,6 +30,7 @@
foreach my $decl (@{$meta->schema->content->childNodes}) {
my $schema = $navi->NavigateName($decl->name);
+ $navi->SchemaBack();
my @nodes = $meta->model && $meta->model->selectNodes( sub { $_->schemaSource == $decl } );
@@ -52,34 +53,21 @@
$type = $decl->type;
}
- push @props, Meta->new(
- $this,
- \@nodes,
- $decl->type,
- {
- name => $decl->name,
- schema => $schema,
- }
- )
+ push @props, Meta->new($this,$model,$type,\%args);
}
}
+sub GetItems {
+ my ($this,$meta) = @_;
+
+ if ($meta->isMultiple)
+}
+
+sub GetItem {
+ my ($this,$meta,$index) = @_;
+}
+
-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;
\ No newline at end of file
diff -r 935629bf80df -r 608e74bc309f _test/Resources/person.schema.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/_test/Resources/person.schema.xml Tue Dec 03 17:55:36 2013 +0400
@@ -0,0 +1,20 @@
+
+