Mercurial > pub > Impl
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__ |