Mercurial > pub > Impl
diff Lib/IMPL/DOM/Navigator/Builder.pm @ 104:196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
Minor and major fixes almost for everything.
A 'Source' property of the ValidationErrors generated from a NodeSet or a NodeList is subject to change in the future.
author | wizard |
---|---|
date | Tue, 11 May 2010 02:42:59 +0400 |
parents | c289ed9662ca |
children | 83e356614c1e |
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Navigator/Builder.pm Fri May 07 18:17:40 2010 +0400 +++ b/Lib/IMPL/DOM/Navigator/Builder.pm Tue May 11 02:42:59 2010 +0400 @@ -6,12 +6,14 @@ use IMPL::Class::Property; use IMPL::Class::Property::Direct; require IMPL::DOM::Navigator::SchemaNavigator; +require IMPL::DOM::Schema::ValidationError; BEGIN { private _direct property _schemaNavi => prop_all; private _direct property _nodesPath => prop_all; private _direct property _nodeCurrent => prop_all; private _direct property _docClass => prop_all; + public _direct property BuildErrors => prop_get | prop_list; public _direct property Document => prop_get | owner_set; } @@ -26,8 +28,9 @@ my ($this,$nodeName,%props) = @_; if (my $schemaNode = $this->{$_schemaNavi}->NavigateName($nodeName)) { - my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType : 'IMPL::DOM::Node'; - $this->inflateProperties($schemaNode,\%props); + my $class = $schemaNode->can('nativeType') ? $schemaNode->nativeType || 'IMPL::DOM::Node' : 'IMPL::DOM::Node'; + + my @errors = $this->inflateProperties($schemaNode,\%props); my $node; if (! $this->{$Document}) { @@ -41,6 +44,20 @@ $this->{$_nodeCurrent} = $node; + if (@errors) { + $this->BuildErrors->Append( + map { + IMPL::DOM::Schema::ValidationError->new( + Node => $node, + Source => $this->{$_schemaNavi}->SourceSchemaNode, + Schema => $schemaNode, + Message => $schemaNode->messageInflateError, + Error => $_ + ) + } @errors + ); + } + return $node; } else { die new IMPL::InvalidOperationException("The specified node is undefined", $nodeName); @@ -49,22 +66,36 @@ sub inflateProperties { my ($this,$schemaNode,$refProps) = @_; - - $refProps->{$_->name} = $_->inflator->new($refProps->{$_->name}) - foreach $schemaNode->selectNodes( - sub { - $_->nodeName eq 'Property' and exists $refProps->{$_->name} and $_->inflator - } - ); + my @errors; + foreach my $schemaProp ( $schemaNode->selectNodes('Property') ) { + next if not exists $refProps->{$schemaProp->name}; + my $result = eval {$schemaProp->inflateValue($refProps->{$schemaProp->name}) }; + if (my $e = $@) { + push @errors, $e; + } else { + $refProps->{$schemaProp->name} = $result; + } + } + return @errors; } sub inflateValue { - my ($this,$value) = @_; - my $schemaNode = $this->{$_schemaNavi}->Current; - if ($schemaNode->can('inflator') and my $inflator = $schemaNode->inflator) { - return $inflator->new($value); + my ($this,$value,$node) = @_; + + my $nodeSchema = $this->{$_schemaNavi}->Current; + + my $result = eval { $nodeSchema->inflateValue($value) }; + if (my $e=$@) { + $this->BuildErrors->Append(new IMPL::DOM::Schema::ValidationError( + Schema => $nodeSchema, + Node => $node, + Error => $e, + Message => $nodeSchema->messageInflateError, + Source => $this->{$_schemaNavi}->SourceSchemaNode + )); + return $value; } else { - return $value; + return $result; } }