comparison Lib/IMPL/DOM/Schema/Validator/Compare.pm @ 389:5aff94ba842f

DOM Schema refactoring complete
author cin
date Wed, 12 Feb 2014 13:36:24 +0400
parents 89179bb8c388
children
comparison
equal deleted inserted replaced
388:648dfaf642e0 389:5aff94ba842f
1 package IMPL::DOM::Schema::Validator::Compare; 1 package IMPL::DOM::Schema::Validator::Compare;
2 use strict; 2 use strict;
3 3
4 use parent qw(IMPL::DOM::Schema::Validator); 4 use IMPL::Const qw(:prop);
5 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 };
6 use IMPL::Resources::Format qw(FormatMessage); 29 use IMPL::Resources::Format qw(FormatMessage);
7 use IMPL::Class::Property;
8
9 BEGIN {
10 public property targetProperty => prop_all;
11 public property op => prop_all;
12 public property nodePath => prop_all;
13 public property optional => prop_all;
14 private property _pathTranslated => prop_all;
15 private property _targetNode => prop_all;
16 private property _sourceSchema => prop_all;
17 public property message => prop_all;
18 }
19
20 our %CTOR = (
21 'IMPL::DOM::Schema::Validator' => sub {
22 my %args = @_;
23 $args{nodeName} ||= 'Compare';
24 delete @args{qw(targetProperty op nodePath optional message)};
25 %args;
26 }
27 );
28 30
29 our %Ops = ( 31 our %Ops = (
30 '=' => \&_equals, 32 '=' => \&_equals,
31 'eq' => \&_equalsString, 33 'eq' => \&_equalsString,
32 '!=' => \&_notEquals, 34 '!=' => \&_notEquals,
45 my ($this,%args) = @_; 47 my ($this,%args) = @_;
46 48
47 $this->targetProperty($args{targetProperty} || 'nodeValue'); 49 $this->targetProperty($args{targetProperty} || 'nodeValue');
48 $this->op( $Ops{ $args{op} || '=' } ) or die new IMPL::InvalidArgumentException("Invalid parameter value",'op',$args{op},$this->path); 50 $this->op( $Ops{ $args{op} || '=' } ) or die new IMPL::InvalidArgumentException("Invalid parameter value",'op',$args{op},$this->path);
49 $this->nodePath($args{nodePath}) or die new IMPL::InvalidArgumentException("The argument is required", 'nodePath', $this->path); 51 $this->nodePath($args{nodePath}) or die new IMPL::InvalidArgumentException("The argument is required", 'nodePath', $this->path);
50 $this->message($args{message} || 'The value of %node.path% %source.op% %value% (%source.nodePath%)' ); 52 $this->message($args{message} || 'The value of %node.path% %schemaNode.op% %value% (%schemaNode.nodePath%)' );
51 $this->optional($args{optional}) if $args{optional}; 53 $this->optional($args{optional}) if $args{optional};
52 } 54 }
53 55
54 sub TranslatePath { 56 sub TranslatePath {
55 my ($this,$path) = @_; 57 my ($this,$path) = @_;
92 _resovleProperty($node,$_->{prop}), 94 _resovleProperty($node,$_->{prop}),
93 FormatMessage($_->{value},{ 95 FormatMessage($_->{value},{
94 Schema => $this->parentNode, 96 Schema => $this->parentNode,
95 Node => $this->_targetNode, 97 Node => $this->_targetNode,
96 schema => $this->parentNode, 98 schema => $this->parentNode,
99 schemaType => $this->parentNode,
97 node => $this->_targetNode, 100 node => $this->_targetNode,
98 source => $this->_sourceSchema 101 source => $this->_schemaNode,
102 schemaNode => $this->_schemaNode
99 },\&_resovleProperty) 103 },\&_resovleProperty)
100 ) or return 0 foreach @parsedFilters; 104 ) or return 0 foreach @parsedFilters;
101 return 1; 105 return 1;
102 }; 106 };
103 } else { 107 } else {
115 sub Validate { 119 sub Validate {
116 my ($this,$node,$ctx) = @_; 120 my ($this,$node,$ctx) = @_;
117 121
118 my @result; 122 my @result;
119 123
120 my $Source = $ctx && $ctx->{Source} || $this->parentNode; 124 my $schemaNode = $ctx->{schemaNode};
121 125 my $schemaType = $ctx->{schemaType};
122 $this->_sourceSchema($Source); 126
127 $this->_schemaNode($schemaNode);
123 128
124 $this->_targetNode($node); 129 $this->_targetNode($node);
125 130
126 my $query = $this->_pathTranslated() || $this->_pathTranslated($this->TranslatePath($this->nodePath)); 131 my $query = $this->_pathTranslated() || $this->_pathTranslated($this->TranslatePath($this->nodePath));
127 132
136 $value = FormatMessage($value, { Schema => $this->parentNode, Node => $this->_targetNode, ForeignNode => $foreignNode },\&_resovleProperty); 141 $value = FormatMessage($value, { Schema => $this->parentNode, Node => $this->_targetNode, ForeignNode => $foreignNode },\&_resovleProperty);
137 } else { 142 } else {
138 $value = $foreignNode->nodeValue; 143 $value = $foreignNode->nodeValue;
139 } 144 }
140 145
141 push @result, new IMPL::DOM::Schema::ValidationError( 146 push @result, ValidationError->new(
142 node => $node, 147 node => $node,
143 foreignNode => $foreignNode, 148 foreignNode => $foreignNode,
144 value => $value, 149 value => $value,
145 source => $Source, 150 schemaNode => $schemaNode,
146 schema => $this->parentNode, 151 schemaType => $schemaType,
147 message => $this->message 152 message => $this->_MakeLabel($this->message)
148 ) unless $this->op->(_resovleProperty($node,$this->targetProperty),$value); 153 ) unless $this->op->(_resovleProperty($node,$this->targetProperty),$value);
149 } elsif (not $this->optional) { 154 } elsif (not $this->optional) {
150 push @result, new IMPL::DOM::Schema::ValidationError( 155 push @result, ValidationError->new(
151 node => $node, 156 node => $node,
152 value => '', 157 value => '',
153 source => $Source, 158 schemaNode => $schemaNode,
154 schema => $this->parentNode, 159 schemaType => $schemaType,
155 message => $this->message 160 message => $this->_MakeLabel( $this->message )
156 ); 161 );
157 } 162 }
158 163
159 $this->_targetNode(undef); 164 $this->_targetNode(undef);
160 $this->_sourceSchema(undef); 165 $this->_schemaNode(undef);
161 166
162 return @result; 167 return @result;
163 } 168 }
164 169
165 sub _resovleProperty { 170 sub _resovleProperty {
214 219
215 sub _greaterEq { 220 sub _greaterEq {
216 $_[0] >= $_[1]; 221 $_[0] >= $_[1];
217 } 222 }
218 223
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
219 1; 234 1;
220 235
221 __END__ 236 __END__
222 237
223 =pod 238 =pod
233 248
234 =begin code xml 249 =begin code xml
235 250
236 <schema> 251 <schema>
237 <SimpleType type="retype_field"> 252 <SimpleType type="retype_field">
238 <Property name="linkedNode" message="Для узла %Node.nodeName% необходимо задать свойство %Source.name%"/> 253 <Property name="linkedNode" message="Для узла %node.nodeName% необходимо задать свойство %schemaNode.name%"/>
239 <Compare op="eq" nodePath="sibling:*[nodeName eq '%Node.linkedNode%']"/> 254 <Compare op="eq" nodePath="sibling:*[nodeName eq '%node.linkedNode%']"/>
240 </SimpleType> 255 </SimpleType>
241 </schema> 256 </schema>
242 257
243 =begin code xml 258 =begin code xml
244 259