Mercurial > pub > Impl
annotate Lib/IMPL/DOM/Schema/Validator/Compare.pm @ 396:6f2a494579cb
sync
author | sergey |
---|---|
date | Mon, 24 Feb 2014 01:55:46 +0400 |
parents | 5aff94ba842f |
children |
rev | line source |
---|---|
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
1 package IMPL::DOM::Schema::Validator::Compare; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
2 use strict; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
3 |
389 | 4 use IMPL::Const qw(:prop); |
5 use IMPL::declare { | |
6 require => { | |
7 Label => 'IMPL::DOM::Schema::Label', | |
8 ValidationError => 'IMPL::DOM::Schema::ValidationError' | |
9 }, | |
10 base => [ | |
11 'IMPL::DOM::Schema::Validator' => sub { | |
12 my %args = @_; | |
13 $args{nodeName} ||= 'Compare'; | |
14 delete @args{qw(targetProperty op nodePath optional message)}; | |
15 %args; | |
16 } | |
17 ], | |
18 props => [ | |
19 targetProperty => PROP_RW, | |
20 op => PROP_RW, | |
21 nodePath => PROP_RW, | |
22 optional => PROP_RW, | |
23 _pathTranslated => PROP_RW, | |
24 _targetNode => PROP_RW, | |
25 _schemaNode => PROP_RW, | |
26 message => PROP_RW | |
27 ] | |
28 }; | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
29 use IMPL::Resources::Format qw(FormatMessage); |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
30 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
31 our %Ops = ( |
194 | 32 '=' => \&_equals, |
33 'eq' => \&_equalsString, | |
34 '!=' => \&_notEquals, | |
35 'ne' => \&_notEqualsString, | |
36 '=~' => \&_matchRx, | |
37 '!~' => \&_notMatchRx, | |
38 '<' => \&_less, | |
39 '>' => \&_greater, | |
40 'lt' => \&_lessString, | |
41 'gt' => \&_greaterString | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
42 ); |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
43 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
44 my $rxOps = map qr/$_/, join( '|', keys %Ops ); |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
45 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
46 sub CTOR { |
194 | 47 my ($this,%args) = @_; |
48 | |
49 $this->targetProperty($args{targetProperty} || 'nodeValue'); | |
50 $this->op( $Ops{ $args{op} || '=' } ) or die new IMPL::InvalidArgumentException("Invalid parameter value",'op',$args{op},$this->path); | |
51 $this->nodePath($args{nodePath}) or die new IMPL::InvalidArgumentException("The argument is required", 'nodePath', $this->path); | |
389 | 52 $this->message($args{message} || 'The value of %node.path% %schemaNode.op% %value% (%schemaNode.nodePath%)' ); |
194 | 53 $this->optional($args{optional}) if $args{optional}; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
54 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
55 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
56 sub TranslatePath { |
194 | 57 my ($this,$path) = @_; |
58 | |
59 $path ||= ''; | |
60 | |
61 my @selectQuery; | |
62 | |
63 my $i = 0; | |
64 | |
65 foreach my $chunk (split /\//,$path) { | |
66 $chunk = 'document:*' if $i == 0 and not length $chunk; | |
67 next if not length $chunk; | |
68 | |
69 my $query; | |
70 my ($axis,$filter) = ( $chunk =~ /^(?:(\w+):)?(.*)$/); | |
71 | |
72 if ($filter =~ /^\w+|\*$/ ) { | |
73 $query = $filter eq '*' ? undef : $filter; | |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
74 } elsif ( $filter =~ /^(\w+|\*)\s*((?:\[\s*\w+\s*(?:=|!=|=~|!~|eq|ne|lt|gt)\s*["'](?:[^\\'"]|\\[\\"'])*["']\])+)$/) { |
194 | 75 my ($nodeName,$filterArgs) = ($1,$2); |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
76 |
194 | 77 |
78 my @parsedFilters = map { | |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
79 my ($prop,$op,$value) = ($_ =~ /\s*(\w+)\s*(=|!=|=~|!~|eq|ne|lt|gt)\s*(?:["']((?:[^\\'"]|\\[\\"'])*)["'])/); |
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
80 |
194 | 81 $value =~ s/\\[\\'"]/$1/g; |
82 { | |
83 prop => $prop, | |
84 op => $Ops{$op}, | |
85 value => $value | |
86 } | |
87 } grep ( $_, split ( /[\]\[]+/,$filterArgs ) ); | |
88 | |
89 $query = sub { | |
90 my ($node) = shift; | |
91 | |
92 $node->nodeName eq $nodeName or return 0 if $nodeName ne '*'; | |
93 $_->{op}->( | |
94 _resovleProperty($node,$_->{prop}), | |
95 FormatMessage($_->{value},{ | |
96 Schema => $this->parentNode, | |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
97 Node => $this->_targetNode, |
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
98 schema => $this->parentNode, |
389 | 99 schemaType => $this->parentNode, |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
100 node => $this->_targetNode, |
389 | 101 source => $this->_schemaNode, |
102 schemaNode => $this->_schemaNode | |
194 | 103 },\&_resovleProperty) |
104 ) or return 0 foreach @parsedFilters; | |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
105 return 1; |
194 | 106 }; |
107 } else { | |
108 die new IMPL::Exception("Invalid query syntax",$path,$chunk); | |
109 } | |
110 | |
111 push @selectQuery, $axis ? { $axis => $query } : $query; | |
112 | |
113 $i++; | |
114 } | |
115 | |
116 return \@selectQuery; | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
117 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
118 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
119 sub Validate { |
194 | 120 my ($this,$node,$ctx) = @_; |
121 | |
122 my @result; | |
123 | |
389 | 124 my $schemaNode = $ctx->{schemaNode}; |
125 my $schemaType = $ctx->{schemaType}; | |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
126 |
389 | 127 $this->_schemaNode($schemaNode); |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
128 |
194 | 129 $this->_targetNode($node); |
130 | |
131 my $query = $this->_pathTranslated() || $this->_pathTranslated($this->TranslatePath($this->nodePath)); | |
132 | |
133 my ($foreignNode) = $node->selectNodes(@$query); | |
134 | |
266
89179bb8c388
*corrected TTView to handle plain (and undefined) values
cin
parents:
238
diff
changeset
|
135 |
194 | 136 |
137 if ($foreignNode) { | |
138 my $value = $this->nodeValue; | |
139 | |
140 if ($value) { | |
141 $value = FormatMessage($value, { Schema => $this->parentNode, Node => $this->_targetNode, ForeignNode => $foreignNode },\&_resovleProperty); | |
142 } else { | |
143 $value = $foreignNode->nodeValue; | |
144 } | |
145 | |
389 | 146 push @result, ValidationError->new( |
236 | 147 node => $node, |
148 foreignNode => $foreignNode, | |
149 value => $value, | |
389 | 150 schemaNode => $schemaNode, |
151 schemaType => $schemaType, | |
152 message => $this->_MakeLabel($this->message) | |
194 | 153 ) unless $this->op->(_resovleProperty($node,$this->targetProperty),$value); |
154 } elsif (not $this->optional) { | |
389 | 155 push @result, ValidationError->new( |
236 | 156 node => $node, |
157 value => '', | |
389 | 158 schemaNode => $schemaNode, |
159 schemaType => $schemaType, | |
160 message => $this->_MakeLabel( $this->message ) | |
194 | 161 ); |
162 } | |
163 | |
164 $this->_targetNode(undef); | |
389 | 165 $this->_schemaNode(undef); |
194 | 166 |
167 return @result; | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
168 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
169 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
170 sub _resovleProperty { |
194 | 171 my ($node,$prop) = @_; |
172 | |
173 return $node->can($prop) ? $node->$prop() : $node->nodeProperty($prop); | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
174 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
175 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
176 sub _matchRx { |
194 | 177 $_[0] =~ $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
178 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
179 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
180 sub _notMatchRx { |
194 | 181 $_[0] !~ $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
182 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
183 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
184 sub _equals { |
194 | 185 $_[0] == $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
186 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
187 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
188 sub _notEquals { |
194 | 189 $_[0] != $_[0]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
190 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
191 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
192 sub _equalsString { |
194 | 193 $_[0] eq $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
194 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
195 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
196 sub _notEqualsString { |
194 | 197 $_[0] ne $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
198 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
199 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
200 sub _less { |
194 | 201 $_[0] < $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
202 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
203 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
204 sub _greater { |
194 | 205 $_[0] > $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
206 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
207 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
208 sub _lessString { |
194 | 209 $_[0] lt $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
210 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
211 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
212 sub _greaterString { |
194 | 213 $_[0] gt $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
214 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
215 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
216 sub _lessEq { |
194 | 217 $_[0] <= $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
218 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
219 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
220 sub _greaterEq { |
194 | 221 $_[0] >= $_[1]; |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
222 } |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
223 |
389 | 224 sub _MakeLabel { |
225 my ($this,$label) = @_; | |
226 | |
227 if ($label =~ /^ID:(\w+)$/) { | |
228 return Label->new($this->document->stringMap, $1); | |
229 } else { | |
230 return $label; | |
231 } | |
232 } | |
233 | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
234 1; |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
235 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
236 __END__ |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
237 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
238 =pod |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
239 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
240 =head1 NAME |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
241 |
180 | 242 C<IMPL::DOM::Schema::Validator::Compare> - ограничение на содержимое текущего узла, |
243 сравнивая его со значением другого узла. | |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
244 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
245 =head1 SYNOPSIS |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
246 |
180 | 247 Пример типа описания поля с проверочным полем |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
248 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
249 =begin code xml |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
250 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
251 <schema> |
194 | 252 <SimpleType type="retype_field"> |
389 | 253 <Property name="linkedNode" message="Для узла %node.nodeName% необходимо задать свойство %schemaNode.name%"/> |
254 <Compare op="eq" nodePath="sibling:*[nodeName eq '%node.linkedNode%']"/> | |
194 | 255 </SimpleType> |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
256 </schema> |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
257 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
258 =begin code xml |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
259 |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
260 =head1 DESCRIPTION |
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
261 |
180 | 262 Позволяет сравнивать значение текущего узла со значением другого узла. |
104
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
wizard
parents:
diff
changeset
|
263 |
180 | 264 =cut |