comparison Lib/IMPL/Web/View/Metadata/FormMeta.pm @ 367:608e74bc309f

form metadata, mostly done
author cin
date Tue, 03 Dec 2013 17:55:36 +0400
parents 935629bf80df
children 010ceafd0c5a
comparison
equal deleted inserted replaced
366:935629bf80df 367:608e74bc309f
3 3
4 use IMPL::Const qw(:prop); 4 use IMPL::Const qw(:prop);
5 use IMPL::declare { 5 use IMPL::declare {
6 require => { 6 require => {
7 Exception => 'IMPL::Exception', 7 Exception => 'IMPL::Exception',
8 ArgException => '-IMPL::InvalidArgumentException' 8 ArgException => '-IMPL::InvalidArgumentException',
9 OpException => '-IMPL::InvalidOperationException',
10 SchemaNavigator => 'IMPL::DOM::Navigator::SchemaNavigator'
9 }, 11 },
10 base => [ 12 base => [
11 'IMPL::Web::View::Metadata::BaseMeta' => '@_' 13 'IMPL::Web::View::Metadata::BaseMeta' => '@_'
12 ], 14 ],
13 props => [ 15 props => [
14 nodes => PROP_RO, 16 nodes => PROP_RO,
15 decl => PROP_RO, 17 decl => PROP_RO,
16 schema => PROP_RO, 18 schema => PROP_RO,
17 errors => PROP_RO 19 errors => PROP_RO,
20 group => PROP_RO
18 ] 21 ]
19 }; 22 };
20 23
24 use constant {
25 Meta => __PACKAGE__
26 };
27
21 sub CTOR { 28 sub CTOR {
22 my ($this,$provider,$model,$type,$args) = @_; 29 my ($this,$model,$type,$args) = @_;
23 30
24 if ($args) { 31 if ($args) {
25 $this->$_($args->{$_}) foreach grep $args->{$_}, qw(decl schema nodes errors); 32 $this->$_($args->{$_}) foreach grep $args->{$_}, qw(decl schema nodes errors group);
26 } 33 }
27 34
28 $this->$_() || die ArgException->new($_ => "The $_ is required") 35 $this->$_() || die ArgException->new($_ => "The $_ is required")
29 foreach qw(decl schema); 36 foreach qw(schema);
30 } 37 }
31 38
32 sub isMultiple { 39 sub isMultiple {
33 shift->decl->isMultiple; 40 my ($this) = @_;
41 $this->decl && $this->decl->isMultiple;
34 } 42 }
35 43
36 sub isOptional { 44 sub isOptional {
37 shift->decl->isOptional; 45 my ($this) = @_;
46 not($this->decl) || $this->decl->isOptional;
38 } 47 }
39 48
40 sub GetOwnErrors { 49 sub GetOwnErrors {
41 my ($this) = @_; 50 my ($this) = @_;
42 51
43 my $node = undef; 52 my $nodes = $this->nodes;
44
45 $node = not($this->isMultiple) && $this->nodes ? $this->nodes->[0] : undef;
46 53
47 return [ 54 return [
48 grep { 55 grep _IsOwnError($nodes,$this->decl,$_), @{$this->errors || []}
49 ($node && $_->node && $_->node == $node) || (not($node) && $_->schema == $this->decl )
50 } @{$this->errors || []}
51 ]; 56 ];
57 }
58
59 sub _IsOwnError {
60 my ($nodes,$source,$err) = @_;
61
62 return 1 if ($err->node && grep($err->node == $_, @$nodes)) || (not(@$nodes) && $err->schema == $source );
63
64 return 0;
65 }
66
67 sub _IsErrorRelates {
68 my ($nodes,$source,$err) = @_;
69
70 # this is an own error
71 return 1 if _IsOwnError($nodes,$source,$err);
72
73 # this error relates to the child control
74
75 return 0 unless @$nodes;
76
77 for (my $n = $err->parent; $n ; $n = $n->parentNode) {
78 return 1 if grep($n == $_, @$nodes);
79 }
80
81 return 0;
82 }
83
84 sub PopulateProperties {
85 my ($this) = @_;
86
87 my @props;
88
89 # return empty list of properties in case of multiple values
90 return \@props if $this->isMultiple;
91
92 my $navi = SchemaNavigator->new($this->schema);
93
94 foreach my $decl (@{$this->schema->content->childNodes}) {
95
96 my $schema = $navi->NavigateName($decl->name);
97 $navi->SchemaBack();
98
99 my @nodes = $this->model && $this->model->selectNodes( sub { $_->schemaSource == $decl } );
100
101 my %args = (
102 name => $decl->name,
103 decl => $decl,
104 schema => $schema,
105 nodes => \@nodes,
106 errors => [grep _IsErrorRelates(\@nodes,$decl,$_), @{$this->errors || []}]
107 );
108
109 my ($model,$type);
110
111 if ($decl->isMultiple) {
112 $model = \@nodes;
113 $type = 'ARRAY';
114 $args{holdingType} = $decl->type;
115 } else {
116 $model = shift @nodes;
117 $type = $decl->type;
118 }
119
120 push @props, Meta->new($model,$type,\%args);
121 }
122
123 return \@props;
124 }
125
126 sub GetItems {
127 my ($this) = @_;
128
129 die OpException->new("The operation must be performed on the container")
130 unless $this->isMultiple;
131
132 my $i = 0;
133
134 return [
135 map $this->_GetItemMeta($_,$i++), @{$this->model || []}
136 ];
137 }
138
139 sub GetItem {
140 my ($this,$index) = @_;
141
142 die OpException->new("The operation must be performed on the container")
143 unless $this->isMultiple;
144
145 my $node = $this->model->[$index];
146
147 return $this->GetItemMeta($node,$index);
148 }
149
150 sub _GetItemMeta {
151 my ($this,$node,$index) = @_;
152
153 return Meta->new(
154 $node,
155 $this->decl->type,
156 {
157 name => $index,
158 schema => $this->schema,
159 errors => [grep _IsOwnError([$node],$this->decl,$_), @{$this->errors ||[]} ],
160 group => $this
161 }
162 );
52 } 163 }
53 164
54 1; 165 1;
55 166
56 __END__ 167 __END__